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. SeeTypeSupplier
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 overwriteTypeSupplier
values supplied earlier.- Author:
- Jeff Fischer, Phillip Verheyden (phillipuniverse)
- See Also:
TypeSupplier
-
-
Constructor Summary
Constructors Constructor Description TypeFactory(Collection<TypeSupplier> suppliers)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description Class<?>
addClassMapping(Class<?> from, Class<?> to)
Adds class mapping toclassMappings
and clear theclassMappingsReverseLookupCache
, as adding a new mapping could change the highest-level mapping.Class<?>
addClassMappingIfAbsent(Class<?> from, Class<?> to)
Adds class mapping toclassMappings
if absent and clear theclassMappingsReverseLookupCache
only if the new mapping is added, as adding a new mapping could change the highest-level mapping.void
addReference(Class<?> reference, Class<? extends ReferenceAware<?>> referenceAware)
Given a reference class (usually a domain class), specify a matching auto-generated projection class.<T> T
get(Class<T> type)
Get a new instance of the requested type based on the the configured suppliers.Map<Class<?>,Class<?>>
getClassMappings()
Class<?>
getHighestLevelMapping(Class<?> type)
Determine from this factory the most top-level type from all of theTypeSuppliers
available.protected Class<?>
getHighestLevelMappingInternal(Class<?> type)
Class<?>
getMostDerivedMapping(Class<?> type)
Determine from this factory the most derived type from all of theTypeSuppliers
available.Map<Class<?>,Class<? extends ReferenceAware<?>>>
getRegistered()
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.
-
-
-
Constructor Detail
-
TypeFactory
public TypeFactory(Collection<TypeSupplier> suppliers)
-
-
Method Detail
-
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
TypeSupplier
s 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 thispublic
if needed). If there is no such constructor or the type is an abstract class or interface, anis 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 giventype
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 classreferenceAware
- The auto generated projection
-
addClassMapping
public Class<?> addClassMapping(Class<?> from, Class<?> to)
Adds class mapping toclassMappings
and clear theclassMappingsReverseLookupCache
, 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 classto
- 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 toclassMappings
if absent and clear theclassMappingsReverseLookupCache
only if the new mapping is added, as adding a new mapping could change the highest-level mapping.- Parameters:
from
- the originating classto
- 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 giventype
, 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:
get(Class)
-
getHighestLevelMapping
@NonNull public Class<?> getHighestLevelMapping(@NonNull Class<?> type)
Determine from this factory the most top-level type from all of theTypeSuppliers
available.This method first looks at the
classMappingsReverseLookupCache
, if no cache exists for the given type, then it traversesclassMappings
continually to determine if there is a more specific top-level type to use.If there is no
TypeSupplier.TypeMapping
present for the giventype
, 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(Class)
-
getHighestLevelMappingInternal
@NonNull protected Class<?> getHighestLevelMappingInternal(@NonNull Class<?> type)
-
getRegistered
public Map<Class<?>,Class<? extends ReferenceAware<?>>> getRegistered()
-
-