Class TypeFactory

java.lang.Object
com.broadleafcommerce.common.extension.TypeFactory

public class TypeFactory extends Object

Inject this factory into other components when you need to perform an object creation based on a known TypeSupplier. TypeSuppliers are purposefully non-descriptive in regard to type in order to avoid premature recognition by the classloader. Since one of the primary use cases for the TypeFactory is to provide domain object instances (either the framework type, or a more derived type described by an extension), it is interesting to avoid classloader recognition of the domain type to early, which would thwart load time weaving (LTW) concerns. Broadleaf does not employ LTW, but a given implementation that leverages the framework may. See TypeSupplier for docs on how to setup a type supplier, either for a new custom type, or to override an out-of-the-box type supplier provided by Broadleaf.

As this TypeFactory is initialized, TypeSuppliers that appear later in the list overwrite TypeSupplier values supplied earlier.

Author:
Jeff Fischer, Phillip Verheyden (phillipuniverse)
See Also:
  • Constructor Details

  • Method Details

    • get

      @NonNull public <T> T get(@NonNull Class<T> type)

      Get a new instance of the requested type based on the the configured suppliers. The requested type being passed in is used as a key to look at the configured TypeSuppliers to determine the concrete instance to create.

      If there is no TypeSupplier configured, the type will attempt to be instantiated using its zero-argument constructor (using reflection to make this public if needed). If there is no such constructor or the type is an abstract class or interface, an is thrown.

      Type Parameters:
      T - The type that is instantiated
      Parameters:
      type - Class describing the type to instantiate. Usually a superclass or interface
      Returns:
      An instance of the type. Will throw IllegalArgumentException if no supporting TypeSupplier is found or if the given class cannot be instantiated
      Throws:
      IllegalArgumentException - if the given type cannot be constructed
    • addReference

      public void addReference(Class<?> reference, Class<? extends ReferenceAware<?>> referenceAware)
      Given a reference class (usually a domain class), specify a matching auto-generated projection class.
      Parameters:
      reference - The originating class
      referenceAware - The auto generated projection
    • addClassMapping

      public Class<?> addClassMapping(Class<?> from, Class<?> to)
      Adds class mapping to classMappings and clear the classMappingsReverseLookupCache, as adding a new mapping could change the highest-level mapping. If the mapping already exists, the given mapping will overwrite the existing one.
      Parameters:
      from - the originating class
      to - the derived class
      Returns:
      the previous derived class value associated with given originating class key, or null if there was no mapping for the given originating class
    • addClassMappingIfAbsent

      public Class<?> addClassMappingIfAbsent(Class<?> from, Class<?> to)
      Adds class mapping to classMappings if absent and clear the classMappingsReverseLookupCache only if the new mapping is added, as adding a new mapping could change the highest-level mapping.
      Parameters:
      from - the originating class
      to - the derived class
      Returns:
      the previous derived class value associated with given originating class key, or null if there was no mapping for the given originating class
    • getRelated

      @Nullable public Class<? extends ReferenceAware<?>> getRelated(Class<?> reference)
      Based on a reference class (usually a domain class), retrieve a auto-generated projection that was previously registered with the system. Will return null of no projection is found.
      Parameters:
      reference - The originating class
      Returns:
      The auto generated projection, if available
    • getMostDerivedMapping

      @NonNull public Class<?> getMostDerivedMapping(@NonNull Class<?> type)

      Determine from this factory the most derived type from all of the TypeSuppliers available.

      This method traverses by continually using a looked-up class as a key to determine if there is a more specific derived type to use.

      If there is no TypeSupplier.TypeMapping present for the given type, the original is returned.

      Parameters:
      type - Class describing the type to instantiate. Usually a superclass or interface
      Returns:
      the most derived type in the factory or the given type if there are no type suppliers configured
      See Also:
    • getHighestLevelMapping

      @NonNull public Class<?> getHighestLevelMapping(@NonNull Class<?> type)
      Determine from this factory the most top-level type from all of the TypeSuppliers available.

      This method first looks at the classMappingsReverseLookupCache, if no cache exists for the given type, then it traverses classMappings continually to determine if there is a more specific top-level type to use.

      If there is no TypeSupplier.TypeMapping present for the given type, the original is returned.

      Parameters:
      type - class type to find the highest level type
      Returns:
      the highest level type in the factory or the given type if there are no type suppliers configured
      See Also:
    • getHighestLevelMappingInternal

      @NonNull protected Class<?> getHighestLevelMappingInternal(@NonNull Class<?> type)
    • getClassMappings

      public Map<Class<?>,Class<?>> getClassMappings()
    • getRegistered

      public Map<Class<?>,Class<? extends ReferenceAware<?>>> getRegistered()