001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.factory;
017:
018: // J2SE dependencies
019: import java.util.Map;
020: import javax.imageio.spi.ServiceRegistry; // For javadoc
021:
022: /**
023: * Base interface for Geotools factories (i.e. service discovery).
024: *
025: * <p>This interfaces forms the core of the Geotools plug-in system, by which capabilities
026: * can be added to the library at runtime. Each sub-interface defines a <cite>service</cite>.
027: * Most services are set up with concrete implementation being registered for use in
028: * a <cite>service registry</cite>, which acts as a container for service implementations.</p>
029: *
030: * <p>Service registries don't need to be a Geotools implementation. They can be (but are not
031: * limited to) any {@link ServiceRegistry} subclass. If the standard {@code ServiceRegistry}
032: * (or its Geotools extension {@link FactoryRegistry}) is selected as a container for services,
033: * then factory implementations should be declared as below (select only one way):</p>
034: *
035: * <ul>
036: * <li><strong>Register for automatic discovery</strong></li>
037: * <ul>
038: * <li>Provide a public no-arguments constructor.</li>
039: * <li>Add the fully qualified name of the <u>implementation</u> class in the
040: * {@code META-INF/services/}<var>classname</var> file where <var>classname</var>
041: * is the fully qualified name of the service <u>interface</u>.</li>
042: * <li>The factory implementations will be discovered when
043: * {@link FactoryRegistry#scanForPlugins} will be invoked.</li>
044: * </ul>
045: * <li><strong><u>Or</u> register explicitly by application code</strong></li>
046: * <ul>
047: * <li>Invoke {@link ServiceRegistry#registerServiceProvider} in application code.</li>
048: * </ul>
049: * </ul>
050: *
051: * <p>In addition, it is recommended that implementations provide a constructor expecting
052: * a single {@link Hints} argument. This optional argument gives to the user some control
053: * of the factory's low-level details. The amount of control is factory specific. The geotools
054: * library defines a global class called {@link Hints} that is ment as API (i.e. you can assume
055: * these hints are supported). Factories may also provide information on their own custom hints
056: * as part of their javadoc class description.</p>
057: *
058: * <strong>Examples:</strong>
059: * <ul>
060: * <li><p>An application supplied a {@linkplain Hints#DATUM_FACTORY datum factory hint}, being
061: * passed to a {@linkplain org.opengis.referencing.datum.DatumAuthorityFactory datum authority
062: * factory} so that all datum created from an authority code will come from the supplied datum
063: * factory.</p></li>
064: *
065: * <li><p>An application supplied a {@link org.geotools.feature.FeatureFactory} (ensuring all
066: * constructed features support the Eclipse's {@code IAdaptable} interface), being passed to a
067: * {@link org.geotools.feature.FeatureTypeFactory} so that all {@code FeatureTypes}
068: * constructed will produce features supporting the indicated interface.<p></li>
069: * </ul>
070: *
071: * <p>As seen in those examples this concept of a hint becomes more interesting when
072: * the operation being controlled is discovery of other services used by the Factory.
073: * By supplying appropriate hints one can chain together several factories and retarget
074: * them to an application specific task.</p>
075: *
076: * @author Ian Schneider
077: * @author Martin Desruisseaux
078: * @author Jody Garnett
079: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/metadata/src/main/java/org/geotools/factory/Factory.java $
080: * @version $Id: Factory.java 25262 2007-04-23 21:11:16Z desruisseaux $
081: *
082: * @see Hints
083: * @see FactoryRegistry
084: */
085: public interface Factory {
086: /**
087: * Map of hints (maybe {@linkplain java.util.Collections#unmodifiableMap unmodifiable})
088: * used by this factory to customize its use. This map is <strong>not</strong> guaranteed
089: * to contains all the hints supplied by the user; it may be only a subset. Consequently,
090: * hints provided here are usually not suitable for creating new factories, unless the
091: * implementation make some additional garantees
092: * (e.g. {@link FactoryUsingVolatileDependencies}).
093: * <p>
094: * The primary purpose of this method is to determine if an <strong>existing</strong>
095: * factory instance can be reused for a set of user-supplied hints. This method is invoked by
096: * {@link FactoryRegistry} in order to compare this factory's hints against user's hints.
097: * This is dependency introspection only; {@code FactoryRegistry} <strong>never</strong>
098: * invokes this method for creating new factories.
099: * <p>
100: * Keys are usually static constants from the {@link Hints} class, while values are
101: * instances of some key-dependent class. The {@linkplain Map#keySet key set} must contains
102: * at least all hints impacting functionality. While the key set may contains all hints
103: * supplied by the user, it is recommended to limit the set to only the hints used by this
104: * particular factory instance. A minimal set will helps {@link FactoryRegistry} to compare
105: * only hints that matter and avoid the creation of unnecessary instances of this factory.
106: * <p>
107: * The hint values may be different than the one supplied by the user. If a user supplied a
108: * hint as a {@link Class} object, this method shall replace it by the actual instance used,
109: * if possible.
110: * <p>
111: * Implementations of this method are usually quite simple. For example if a
112: * {@linkplain org.opengis.referencing.datum.DatumAuthorityFactory datum authority factory}
113: * uses an ordinary {@linkplain org.opengis.referencing.datum.DatumFactory datum factory},
114: * its method could be implemented as below (note that we should not check if the datum
115: * factory is null, since key with null value is the expected behaviour in this case).
116: * Example:
117: *
118: * <pre><code>
119: * Map hints = new HashMap();
120: * hints.put({@linkplain Hints#DATUM_FACTORY}, datumFactory);
121: * return hints;
122: * </code></pre>
123: *
124: * @return The map of hints, or an {@linkplain java.util.Collections#EMPTY_MAP empty map}
125: * if none.
126: */
127: Map/*<RenderingHints.Key,Object>*/getImplementationHints();
128: }
|