org.geotoolkit.factory
Class Factory

Object
  extended by Factory
Direct Known Subclasses:
AbstractCoverageProcessor, DefaultNameFactory, GridCoverageFactory, MetadataFactory, ReferencingFactory, TileManagerFactory

public abstract class Factory
extends Object

Base class for Geotoolkit.org factories. FactoryRegistry handles Factory subclasses specially, but extending this class is not mandatory (FactoryRegistry will work with arbitrary implementations as well). This base class provides some convenience features for subclasses:


How hints are set
Hints are used for two purposes. The distinction is important because the set of hints may not be identical in both cases:

  1. Hints are used for creating new factories.
  2. Hints are used in order to check if an existing factory is suitable.

This Factory base class does not provide any facility for the first case. Subclasses shall inspect themselves all relevant hints supplied by the user, and pass them to any dependencies. Do not use the hints field for that; use the hints provided by the user in the constructor. If all dependencies are created at construction time (constructor injection), there is no need to keep all user's hints once the construction is finished.

The hints field is for the second case only. Implementations shall copy in this field only the user's hints that are know to be relevant to this factory. If a hint is relevant but the user didn't specified any value, the hint key should be added to the hints map anyway with a null value. Only direct dependencies shall be put in the hints map. Indirect dependencies (i.e. hints used by other factories used by this factory) will be inspected automatically by FactoryRegistry in a recursive way.


Guidline for subclasses


Example
An application supplied a datum factory hint, being passed to a datum authority factory so that all datum created from an authority code will come from the supplied datum factory.

Java code
class DatumAuthorityFactory extends Factory {
    final DatumFactory datumFactory;

    DatumAuthorityFactory() {
        this(EMPTY_HINTS);
    }

    DatumAuthorityFactory(Hints userHints) {
        datumFactory = FactoryFinder.getDatumFactory(userHints);
        hints.put(Hints.DATUM_FACTORY, datumFactory);
    }
}
Remarks

As seen in those examples this concept of a hint becomes more interesting when the operation being controlled is discovery of other services used by the factory. By supplying appropriate hints one can chain together several factories and retarget them to an application specific task.

Since:
2.1
Version:
3.03
Author:
Ian Schneider, Martin Desruisseaux (IRD, Geomatys), Jody Garnett (Refractions)
See Also:
Hints, FactoryRegistry
Module:
utility/geotk-utility (download)    View source code for this class

Nested Class Summary
protected  class Factory.Availability
          The default conformance result returned by availability().
protected  class Factory.Organizer
          Controls the ordering of the enclosing factory relative to other factories.
 
Field Summary
static Hints EMPTY_HINTS
          An immutable empty set of hints.
protected  Map<RenderingHints.Key,Object> hints
          The implementation hints.
 
Constructor Summary
protected Factory()
          Creates a new factory instance.
 
Method Summary
 ConformanceResult availability()
          Returns whatever this factory is ready for use.
protected  void dispose(boolean shutdown)
          Disposes resources used by this factory.
 boolean equals(Object object)
          Compares this factory with the specified object for equality.
 Map<RenderingHints.Key,?> getImplementationHints()
          Returns an unmodifiable view of hints used by this factory to customize its use.
protected  boolean hasCompatibleHints(Hints hints)
          Returns true if this factory meets the requirements specified by a map of hints.
 int hashCode()
          Returns a hash value for this factory.
protected  void setOrdering(Factory.Organizer organizer)
          Invoked by FactoryRegistry after registration in order to set the relative ordering.
 String toString()
          Returns a string representation of this factory.
 
Methods inherited from class Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
 

Field Detail

EMPTY_HINTS

public static final Hints EMPTY_HINTS
An immutable empty set of hints. This is different than a null hints, which means default hints and may not be empty.

Since:
3.00

hints

protected final Map<RenderingHints.Key,Object> hints
The implementation hints. This map should be filled by subclasses at construction time. If possible, constructors should not copy blindly all user-provided hints. They should select only the relevant hints and resolve them as of implementation hints contract. For example if a datum authority factory uses an ordinary datum factory, its method could be implemented as below (note that we should not check if the datum factory is null, since key with null value is the expected behavior in this case).
hints.put(Hints.DATUM_FACTORY, datumFactory);
This field is not an instance of Hints because:

Constructor Detail

Factory

protected Factory()
Creates a new factory instance.

Method Detail

setOrdering

protected void setOrdering(Factory.Organizer organizer)
Invoked by FactoryRegistry after registration in order to set the relative ordering. The default implementation does nothing. Subclasses should override this method and invoke Organizer.before(...) or Organizer.after(...) if they know which factory should have precedence over an other factory.

Parameters:
organizer - A handler given by FactoryRegistry for controlling the ordering of this factory relative to other factories.
Since:
3.00

getImplementationHints

public Map<RenderingHints.Key,?> getImplementationHints()
Returns an unmodifiable view of hints used by this factory to customize its use. This map is not guaranteed to contains all the hints supplied by the user; it may be only a subset. Consequently, hints provided here are usually not suitable for creating new factories.

The primary purpose of this method is to determine if an existing factory instance can be reused for a set of user-supplied hints. This method is invoked by FactoryRegistry in order to compare this factory's hints against user's hints. This is dependency introspection only; FactoryRegistry never invokes this method for creating new factories.

Content
Keys are usually static constants from the Hints class, while values are instances of some key-dependent class. The key set must contains at least all hints impacting functionality. While the key set may contains all hints supplied by the user, it is recommended to limit the set to only the hints used by this particular factory instance. A minimal set will helps FactoryRegistry to compare only hints that matter and avoid the creation of unnecessary instances of this factory.

The hint values may be different than the one supplied by the user. If a user supplied a hint as a Class object, this method shall replace it by the actual instance used, if possible.

Lifetime
If possible, do not keep a reference to the returned map or map entries for a long time. The map may reference resources to make elligible for garbage collection at a later time. This is especially true for factories created by DynamicFactoryRegistry.

Returns:
The map of hints, or an empty map if none.

hasCompatibleHints

protected boolean hasCompatibleHints(Hints hints)
Returns true if this factory meets the requirements specified by a map of hints. The default implementation checks if, for any key in the given map which is also presents in this factory's implementation hints, the corresponding values are compatible. Values are considered compatible if they meet one of the following conditions:

If this factory has dependencies toward other factories (or to be more specific, if the values of some implementation hints are instances of Factory), then this method will invokes itself recursively for those factory instances, with a guard against infinite loops if there is cyclic dependencies.

Parameters:
hints - The user requirements (never null).
Returns:
true if this factory meets the hints requirements.
Since:
3.00

availability

public ConformanceResult availability()
Returns whatever this factory is ready for use. The ConformanceResult.pass() method shall returns false if this factory is not available in the current configuration, typically because some external resources were not found. Implementors are encouraged to provide an explanation when the factory is not available.

This method can not be used as a manager for automatic download of external resources. It is just a way to tell to FactoryRegistry that this factory exists, but can't do its job for whatever reasons, so FactoryRegistry has to choose an other factory. In other words, this method is used only as a filter.

Note also that FactoryRegistry is not designed for factories with intermittent state (i.e. value of availability().pass() varying with time). The behavior is undetermined in such case.

In the default implementation, the conformance result passes as long as this factory has not been disposed.

Returns:
A conformance result with pass() == true if this factory is ready for use.
Since:
3.03

dispose

protected void dispose(boolean shutdown)
Disposes resources used by this factory. This method is invoked mainly by DynamicFactoryRegistry; users are not expected to dispose resources themself since factories may be shared by many classes in the system.

The default implementation clears the hints map and remember that this factory has been disposed. Subclasses should override this method as below if they can perform more resource disposal.

protected synchronized void dispose(boolean shutdown) {
    // Disposes more resources here.
    super.dispose(shutdown);
}

Parameters:
shutdown - false for normal disposal, or true if this method is invoked during the process of a JVM shutdown. In the later case this method may dispose resources more aggressively. For example ThreadedEpsgFactory may shutdown the JavaDB embedded database.
Since:
3.00

hashCode

public final int hashCode()
Returns a hash value for this factory. This method computes the hash value using only immutable properties. This computation does not rely on implementation hints, since there is no guarantee that they will not change.

Overrides:
hashCode in class Object
Since:
2.3

equals

public final boolean equals(Object object)
Compares this factory with the specified object for equality. This method returns true if and only if:

The requirement for the exact same class is needed for consistency with the factory registry working, since at most one instance of a given class is allowed in a registry.

Overrides:
equals in class Object
Parameters:
object - The object to compare.
Returns:
true if the given object is equal to this factory.
Since:
2.3

toString

public String toString()
Returns a string representation of this factory. This method is mostly for debugging purpose, so the string format may vary across different implementations or versions. The default implementation formats all implementation hints as a tree. If the implementation hints include some factory dependencies, then the implementation hints for those dependencies will appears under a tree branch.

Overrides:
toString in class Object
Returns:
A string representation of this factory.
Since:
2.3


Copyright © 2009-2013 Geotoolkit.org. All Rights Reserved.