001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2005, Institut de Recherche pour le Développement
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * This package contains documentation from OpenGIS specifications.
018: * OpenGIS consortium's work is fully acknowledged here.
019: */
020: package org.geotools.referencing.factory;
021:
022: // J2SE dependencies and extensions
023: import java.util.Map;
024: import java.util.Set;
025: import java.util.LinkedHashSet;
026: import java.util.Collection;
027:
028: // OpenGIS dependencies
029: import org.opengis.referencing.*;
030:
031: // Geotools dependencies
032: import org.geotools.factory.Hints;
033:
034: /**
035: * The base class for authority factories that create referencing object directly. This is
036: * in contrast with other factories like the {@linkplain AuthorityFactoryAdapter adapter}
037: * or {@linkplain BufferedAuthorityFactory buffered} ones, which delegates their work to
038: * an other factory.
039: *
040: * @since 2.3
041: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/DirectAuthorityFactory.java $
042: * @version $Id: DirectAuthorityFactory.java 25955 2007-06-20 17:07:52Z desruisseaux $
043: * @author Martin Desruisseaux
044: */
045: public abstract class DirectAuthorityFactory extends
046: AbstractAuthorityFactory {
047:
048: // IMPLEMENTATION NOTE: The reason why this class exist is that we don't want "indirect"
049: // factories like BufferedAuthorityFactory to inherit the factories field. If this field
050: // existed in their super-class, then the super-class constructor could try to initialize
051: // it while in fact BufferedAuthorityFactory don't need it. Experience with Geotools 2.2
052: // suggest that it can lead to tricky recursivity problems in FactoryFinder, because most
053: // factories registered in META-INF/services are some kind of BufferedAuthorityFactory.
054:
055: /**
056: * The underlying factories used for objects creation.
057: */
058: protected final ReferencingFactoryContainer factories;
059:
060: /**
061: * Tells if {@link ReferencingFactoryContainer#hints} has been invoked. It must be
062: * invoked exactly once, but can't be invoked in the constructor because it causes
063: * a {@link StackOverflowError} in some situations.
064: */
065: private boolean hintsInitialized;
066:
067: /**
068: * Constructs an instance using the specified set of factories.
069: *
070: * @param factories The low-level factories to use.
071: * @param priority The priority for this factory, as a number between
072: * {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
073: * {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
074: */
075: protected DirectAuthorityFactory(
076: final ReferencingFactoryContainer factories,
077: final int priority) {
078: super (priority);
079: this .factories = factories;
080: ensureNonNull("factories", factories);
081: }
082:
083: /**
084: * Constructs an instance using the specified hints. This constructor recognizes the
085: * {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS}, {@link Hints#DATUM_FACTORY DATUM}
086: * and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM} {@code FACTORY} hints.
087: *
088: * @param hints The hints, or {@code null} if none.
089: * @param priority The priority for this factory, as a number between
090: * {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
091: * {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
092: */
093: protected DirectAuthorityFactory(final Hints hints,
094: final int priority) {
095: super (priority);
096: factories = ReferencingFactoryContainer.instance(hints);
097: // Do not copies the user-provided hints to this.hints, because
098: // this is up to sub-classes to decide which hints are relevant.
099: }
100:
101: /**
102: * Returns the implementation hints for this factory. The returned map contains values for
103: * {@link Hints#CRS_FACTORY CRS}, {@link Hints#CS_FACTORY CS}, {@link Hints#DATUM_FACTORY DATUM}
104: * and {@link Hints#MATH_TRANSFORM_FACTORY MATH_TRANSFORM} {@code FACTORY} hints. Other values
105: * may be provided as well, at implementation choice.
106: */
107: public Map getImplementationHints() {
108: synchronized (hints) { // Note: avoid lock on public object.
109: if (!hintsInitialized) {
110: hintsInitialized = true;
111: hints.putAll(factories.getImplementationHints());
112: }
113: }
114: return super .getImplementationHints();
115: }
116:
117: /**
118: * Returns the direct {@linkplain Factory factory} dependencies.
119: */
120: //@Override
121: Collection/*<?>*/dependencies() {
122: if (factories != null) {
123: final Set dependencies = new LinkedHashSet(8);
124: dependencies.add(factories.getCRSFactory());
125: dependencies.add(factories.getCSFactory());
126: dependencies.add(factories.getDatumFactory());
127: return dependencies;
128: }
129: return super.dependencies();
130: }
131: }
|