/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.factory;
import java.util.Arrays;
import java.util.Set;
import org.geotools.data.FeatureLockFactory;
import org.geotools.data.FileDataStoreFactorySpi;
import org.geotools.feature.FeatureCollections;
import org.geotools.feature.LenientFeatureFactoryImpl;
import org.geotools.filter.FunctionExpression;
import org.geotools.filter.FunctionImpl;
import org.geotools.resources.LazySet;
import org.geotools.styling.StyleFactory;
import org.opengis.feature.FeatureFactory;
import org.opengis.feature.type.FeatureTypeFactory;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.expression.Function;
/**
* Defines static methods used to access the application's default implementation for some
* common factories. Those "common" factories comprise the {@linkplain StyleFactory style}
* and {@linkplain FilterFactory filter} factories. Note that some specialized factories
* finder like {@linkplain org.geotools.referencing.ReferencingFactoryFinder referencing} and
* {@linkplain org.geotools.coverage.GeometryFactoryFinder coverage} are defined in specialized
* classes.
* <p>
* <b>Tip:</b> The {@link BasicFactories} classes provides an other way to access the various
* factories from a central point.
*
* @since 2.4
* @source $URL$
* @version $Id$
* @author Martin Desruisseaux
* @author Jody Garnett
*/
public final class CommonFactoryFinder extends FactoryFinder {
/**
* The service registry for this manager.
* Will be initialized only when first needed.
*/
private static FactoryRegistry registry;
/**
* Do not allows any instantiation of this class.
*/
private CommonFactoryFinder() {
// singleton
}
/**
* Returns the service registry. The registry will be created the first
* time this method is invoked.
*/
private static FactoryRegistry getServiceRegistry() {
assert Thread.holdsLock(CommonFactoryFinder.class);
if (registry == null) {
registry = new FactoryCreator(Arrays.asList(new Class<?>[] {
StyleFactory.class,
FilterFactory.class,
FeatureLockFactory.class,
FileDataStoreFactorySpi.class,
FunctionImpl.class,
FunctionExpression.class,//TODO: remove
Function.class,
FeatureFactory.class,
FeatureTypeFactory.class,
FeatureCollections.class}));
}
return registry;
}
/**
* Returns the first implementation of {@link StyleFactory} matching the specified hints.
* If no implementation matches, a new one is created if possible or an exception is thrown
* otherwise.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return The first style factory that matches the supplied hints.
* @throws FactoryRegistryException if no implementation was found or can be created for the
* {@link StyleFactory} interface.
*
* @see Hints#STYLE_FACTORY
*/
public static synchronized StyleFactory getStyleFactory(Hints hints)
throws FactoryRegistryException
{
hints = mergeSystemHints(hints);
return (StyleFactory) getServiceRegistry().getServiceProvider(
StyleFactory.class, null, hints, Hints.STYLE_FACTORY);
}
/**
* Returns a set of all available implementations for the {@link StyleFactory} interface.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return Set of available style factory implementations.
*/
public static synchronized Set getStyleFactories(Hints hints) {
hints = mergeSystemHints(hints);
return new LazySet(getServiceRegistry().getServiceProviders(
StyleFactory.class, null, hints));
}
/**
* Returns a set of all available implementations for the {@link FunctionExpression} interface.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return Set of available style factory implementations.
* @deprecated Use FunctionExpression is now @deprecated
*/
public static synchronized Set getFunctionExpressions(Hints hints) {
hints = mergeSystemHints(hints);
return new LazySet(getServiceRegistry().getServiceProviders(
FunctionExpression.class, null, hints));
}
/**
* Returns a set of all available implementations for the {@link Function} interface.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return Set of available function expression implementations.
*/
public static synchronized Set getFunctions(Hints hints) {
hints = mergeSystemHints(hints);
return new LazySet(getServiceRegistry().getServiceProviders(
Function.class, null, hints));
}
/**
* Returns the first implementation of {@link FeatureLockFactory} matching the specified hints.
* If no implementation matches, a new one is created if possible or an exception is thrown
* otherwise.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return The first feature lock factory that matches the supplied hints.
* @throws FactoryRegistryException if no implementation was found or can be created for the
* {@link FeatureLockFactory} interface.
*
* @see Hints#FEATURE_LOCK_FACTORY
*/
public static synchronized FeatureLockFactory getFeatureLockFactory(Hints hints) {
hints = mergeSystemHints(hints);
return (FeatureLockFactory) getServiceRegistry().getServiceProvider(
FeatureLockFactory.class, null, hints, Hints.FEATURE_LOCK_FACTORY);
}
/**
* Returns a set of all available implementations for the {@link FeatureLockFactory} interface.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return Set<FeatureLockFactory> of available style factory implementations.
*/
public static synchronized Set getFeatureLockFactories(Hints hints) {
hints = mergeSystemHints(hints);
return new LazySet(getServiceRegistry().getServiceProviders(
FeatureLockFactory.class, null, hints));
}
/**
* Returns a set of all available implementations for the {@link FileDataStoreFactorySpi} interface.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return Set of available file data store factory implementations.
*/
public static synchronized Set getFileDataStoreFactories(Hints hints) {
hints = mergeSystemHints(hints);
return new LazySet(getServiceRegistry().getServiceProviders(
FileDataStoreFactorySpi.class, null, hints));
}
/** Return the first implementation of {@link FeatureFactory} matching the specified hints.
* <p>
* If no implementation matches, a new one is created if possible or an exception is thrown.
*
* @param hints An optional map of hints; or {@code null} if none
* @return Instance of FeatureFactory matching the supplied hints
* @throws FactoryRegistryException if no implementation could be provided
* @see Hints#FEATURE_FACTORY
*/
public static synchronized FeatureFactory getFeatureFactory(Hints hints) {
hints = mergeSystemHints(hints);
if(hints.get(Hints.FEATURE_FACTORY) == null)
hints.put(Hints.FEATURE_FACTORY, LenientFeatureFactoryImpl.class);
return (FeatureFactory) getServiceRegistry().getServiceProvider(
FeatureFactory.class, null, hints, Hints.FEATURE_FACTORY);
}
/** Return the first implementation of {@link FeatureTypeFactory} matching the specified hints.
* <p>
* If no implementation matches, a new one is created if possible or an exception is thrown.
*
* @param hints An optional map of hints; or {@code null} if none
* @return Instance of FeatureTypeFactory matching the supplied hints
* @throws FactoryRegistryException if no implementation could be provided
* @see Hints#FEATURE_TYPE_FACTORY
*/
public static synchronized FeatureTypeFactory getFeatureTypeFactory(Hints hints) {
hints = mergeSystemHints(hints);
return (FeatureTypeFactory) getServiceRegistry().getServiceProvider(
FeatureTypeFactory.class, null, hints, Hints.FEATURE_TYPE_FACTORY);
}
/**
* Returns the first implementation of {@link FeatureCollections} matching the specified hints.
* If no implementation matches, a new one is created if possible or an exception is thrown
* otherwise.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return The first feature collections that matches the supplied hints.
* @throws FactoryRegistryException if no implementation was found or can be created for the
* {@link FeatureCollections} interface.
*
* @see Hints#FEATURE_COLLECTIONS
*/
public static synchronized FeatureCollections getFeatureCollections(Hints hints) {
hints = mergeSystemHints(hints);
return (FeatureCollections) getServiceRegistry().getServiceProvider(
FeatureCollections.class, null, hints, Hints.FEATURE_COLLECTIONS);
}
/**
* Returns a set of all available implementations for the {@link FeatureCollections} interface.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return Set of available feature collections implementations.
*/
public static synchronized Set getFeatureCollectionsSet(Hints hints) {
hints = mergeSystemHints(hints);
return new LazySet(getServiceRegistry().getServiceProviders(
FeatureCollections.class, null, hints));
}
/**
* Returns the first implementation of {@link FilterFactory} matching the specified hints.
* If no implementation matches, a new one is created if possible or an exception is thrown
* otherwise.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return The first filter factory that matches the supplied hints.
* @throws FactoryRegistryException if no implementation was found or can be created for the
* {@link FilterFactory} interface.
*
* @see Hints#FILTER_FACTORY
*/
public static synchronized FilterFactory getFilterFactory(Hints hints)
throws FactoryRegistryException
{
hints = mergeSystemHints(hints);
return (FilterFactory) getServiceRegistry().getServiceProvider(
FilterFactory.class, null, hints, Hints.FILTER_FACTORY);
}
/**
* Returns a set of all available implementations for the {@link FilterFactory} interface.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return Set of available filter factory implementations.
*/
public static synchronized Set getFilterFactories(Hints hints) {
hints = mergeSystemHints(hints);
return new LazySet(getServiceRegistry().getServiceProviders(
FilterFactory.class, null, hints));
}
/**
* Returns the first implementation of {@link FilterFactory2} matching the specified hints.
* This is a convenience method invoking {@link #getFilterFactory} with a hint value set
* for requerying a {@link FactoryFilter2} implementation.
*
* @param hints An optional map of hints, or {@code null} if none.
* @return The first filter factory that matches the supplied hints.
* @throws FactoryRegistryException if no implementation was found or can be created for the
* {@link FilterFactory2} interface.
*
* @see Hints#FILTER_FACTORY
*/
public static FilterFactory2 getFilterFactory2(Hints hints)
throws FactoryRegistryException
{
hints = mergeSystemHints(hints);
final Object h = hints.get(Hints.FILTER_FACTORY);
if (!(h instanceof Class ? FilterFactory2.class.isAssignableFrom((Class) h)
: h instanceof FilterFactory2))
{
/*
* Add the hint value only if the user didn't provided a suitable hint.
* In any case, do not change the user-supplied hints; clone them first.
*/
hints = new Hints(hints);
hints.put(Hints.FILTER_FACTORY, FilterFactory2.class);
}
return (FilterFactory2) getFilterFactory(hints);
}
/**
* Scans for factory plug-ins on the application class path. This method is
* needed because the application class path can theoretically change, or
* additional plug-ins may become available. Rather than re-scanning the
* classpath on every invocation of the API, the class path is scanned
* automatically only on the first invocation. Clients can call this
* method to prompt a re-scan. Thus this method need only be invoked by
* sophisticated applications which dynamically make new plug-ins
* available at runtime.
*/
public static synchronized void scanForPlugins() {
if (registry != null) {
registry.scanForPlugins();
}
}
}