Class AbstractFactory

  • All Implemented Interfaces:
    Factory, RegistrableFactory
    Direct Known Subclasses:
    ClasspathGridShiftLocator, EPSGCRSAuthorityFactory, GridCoverageFactory, ReferencingFactory

    public class AbstractFactory
    extends Object
    implements Factory, RegistrableFactory
    Skeletal implementation of factories. This base classe provides no createFoo methods, (they must be provided by subclasses), but provides two convenience features:

    When more than one factory implementation is registered for the same category (i.e. they implement the same Factory sub-interface), the actual instance to be used is selected according their ordering and user-supplied hints. Hints have precedence. If more than one factory matches the hints (including the common case where the user doesn't provide any hint at all), then ordering matter.

    The ordering is unspecified for every pairs of factories with the same priority. This implies that the ordering is unspecified between all factories created with the default constructor, since they all have the same default priority level.

    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.

    AbstractFactory do not provides any facility for the first case. Factories implementations 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 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.

    Note: The lack of constructor expecting a Map argument is intentional. This is in order to discourage blind-copy of all user-supplied hints to the hints map.

    Example: Lets two factories, A and B. Factory A need an instance of Factory B. Factory A can be implemented as below:

    CodeObservations
     class FactoryA extends AbstractFactory {
         FactoryB fb;
    
         FactoryA(Hints userHints) {
             fb = FactoryFinder.getFactoryB(userHints);
             hints.put(Hints.FACTORY_B, fb);
         }
     }
     
    • The user-supplied map (userHints) is never modified.
    • All hints relevant to other factories are used in the constructor. Hints relevant to factory B are used when FactoryFinder.getFactoryB(...) is invoked.
    • The FactoryA constructor stores only the hints relevant to FactoryA. Indirect dependencies (e.g. hints relevant to FactoryB) will be inspected recursively by FactoryRegistry.
    • In the above example, hints will never be used for creating new factories.
    Since:
    2.1
    Author:
    Martin Desruisseaux
    • Constructor Detail

      • AbstractFactory

        protected AbstractFactory()
        Creates a new factory with the default priority.
      • AbstractFactory

        protected AbstractFactory​(int priority)
        Constructs a factory with the specified priority.
        Parameters:
        priority - The priority for this factory, as a number between MINIMUM_PRIORITY and MAXIMUM_PRIORITY inclusive.
    • Method Detail

      • getPriority

        public int getPriority()
        Returns the priority for this factory, as a number between MINIMUM_PRIORITY and MAXIMUM_PRIORITY inclusive. Priorities are used by FactoryRegistry for selecting a preferred factory when many are found for the same service. The default implementation returns priority with no change. Subclasses should override this method if they want to return a higher or lower priority.
        Since:
        2.3
      • addImplementationHints

        protected boolean addImplementationHints​(RenderingHints map)
        Adds the specified hints to this factory hints. This method can be used as a replacement for hints.putAll(map) when the map is an instance of Hints - the above was allowed in Java 4, but is no longuer allowed since Java 5 and parameterized types.
        Parameters:
        map - The hints to add.
        Returns:
        true if at least one value changed as a result of this call.
        Since:
        2.5
      • getImplementationHints

        public Map<RenderingHints.Key,​?> getImplementationHints()
        Returns an unmodifiable view of hints.
        Specified by:
        getImplementationHints in interface Factory
        Returns:
        The map of hints, or an empty map if none.
      • onRegistration

        public void onRegistration​(FactoryRegistry registry,
                                   Class<?> category)
        Called when this factory is added to the given category of the given registry. The factory may already be registered under another category or categories.

        This method is invoked automatically when this factory is registered as a plugin, and should not be invoked directly by the user. The default implementation iterates through all services under the same category that extends the AbstractFactory class, and set the ordering according the priority given at construction time.

        Specified by:
        onRegistration in interface RegistrableFactory
        Parameters:
        registry - A factory registry where this factory has been registered.
        category - The registry category under which this object has been registered.
        See Also:
        MINIMUM_PRIORITY, MAXIMUM_PRIORITY
      • onDeregistration

        public void onDeregistration​(FactoryRegistry registry,
                                     Class category)
        Called when this factory is removed from the given category of the given registry. The object may still be registered under another category or categories.

        This method is invoked automatically when this factory is no longer registered as a plugin, and should not be invoked directly by the user.

        Specified by:
        onDeregistration in interface RegistrableFactory
        Parameters:
        registry - A service registry from which this object is being (wholly or partially) deregistered.
        category - The registry category from which this object is being deregistered.
      • hashCode

        public final int hashCode()
        Returns a hash value for this factory. The default implementation computes the hash value using only immutable properties. This computation do not relies on implementation hints, since there is no garantee 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. The default implementation returns true if and only if:

        • Both objects are of the exact same class (a is instance of relationship is not enough).
        • implementation hints are equal.

        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 {@linkplain FactoryRegistry#getFactoryByClass) is allowed} in a registry.

        Overrides:
        equals in class Object
        Parameters:
        object - The object to compare.
        Returns:
        true if the given object is equals 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
        Since:
        2.3