Class ContextStateBuilder
- java.lang.Object
-
- com.broadleafcommerce.data.tracking.core.mapping.ContextStateBuilder
-
- Direct Known Subclasses:
AlwaysMutableContextStateBuilder
public class ContextStateBuilder extends Object
- Author:
- Nathan Moore (nathandmoore)
-
-
Field Summary
Fields Modifier and Type Field Description protected static Comparator<ChangeDetail>
DETAIL_LEVEL_COMPARATOR
protected static Comparator<ChangeDetail>
DETAIL_TIMESTAMP_COMPARATOR
protected static Comparator<FieldChange>
FIELD_LEVEL_COMPARATOR
-
Constructor Summary
Constructors Constructor Description ContextStateBuilder(com.broadleafcommerce.common.extension.TypeFactory factory, TrackableBehaviorUtil behaviorUtil, com.fasterxml.jackson.databind.ObjectMapper fieldChangeMapper, org.modelmapper.ModelMapper cloneMapper)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected String
buildBusinessCollectionAccessorName(String fieldName, Object businessItem, String itemId)
Builds the name of the accessor of one of the businessItem's embedded collections to invoke in order to obtain the value of that field when settingContextState
on embedded collections ofContextStateAware entities
.ContextState
buildContextState(Trackable domain, ContextInfo contextInfo)
BuildsContextState information
for aContextStateAware business instance
corresponding to the givenTrackable domain instance
that can be inspected for additional metadata around the entity in relation to the context of the requester.protected List<FieldChange>
buildContextStateFieldChanges(Trackable domain)
Builds a list ofFieldChanges
for theContextState
of aContextStateAware business instance
corresponding to a givenTrackable domain instance
.protected <T> List<T>
deserializeCollectionValue(String collectionName, Class<?> collectionType, com.fasterxml.jackson.databind.JavaType javaType, Class<?> parentType, String parentId, String serializedValue)
Deserializes either the afterValue or beforeValue of aChangeDetail
for an embedded collection field, depending on which is passed as the serializedValue param, when settingContextState
on embedded collections ofContextStateAware entities
.protected boolean
determineApplicationContextStateMutability(Trackable domain, ContextInfo contextInfo)
Determines whether the domain is mutable given the requesting context based on the application and tenancy state of the domain and context.protected Boolean
determineArchived(Trackable domain)
Determines theContextState.getArchived()
.protected Integer
determineContextStateLevel(Trackable domain)
Determines theContextState.getLevel()
.protected boolean
determineContextStateMutability(Trackable domain, ContextInfo contextInfo)
Determines whether the domain is mutable given the requesting context.protected com.fasterxml.jackson.databind.JavaType
determinePersistentCollectionJavaType(ChangeDetail detail, Class<?> collectionType, Class<?> memberType, Class<?> parentType, String parentId)
Determines theJavaType
of collections on persistent domains that correspond toContextStateAware entities
when deserializing the before and after values of aChangeDetail
when settingContextState
on embedded collections ofContextStateAware entities
.protected boolean
determinePolicyContextStateMutability(Trackable domain, ContextInfo contextInfo)
Determines whether the domain is mutable given the requesting context based on permissions and policy validation.protected String
determineSandboxChangeType(Trackable domain)
Returns thetracking's object's
sandbox change type.protected TrackableBehaviorUtil
getBehaviorUtil()
protected org.modelmapper.ModelMapper
getCloneMapper()
protected Field
getCollectionField(String fieldName, Class<?> parentType)
protected com.broadleafcommerce.common.extension.TypeFactory
getFactory()
protected com.fasterxml.jackson.databind.ObjectMapper
getFieldChangeMapper()
protected <T> List<T>
getOtherBusinessCollectionValue(String fieldName, Class<T> collectionMemberType, Object businessItem, String itemId)
Extension point for getting the values of an embedded collection not supported by default on a business item implementingContextStateAware
where the collection's members also implementContextStateAware
when settingContextState
on embedded collections ofContextStateAware entities
.protected Optional<Class<?>>
getOtherCollectionMemberType(String fieldName, Class<?> parentType, String parentId)
Extension point for determining the member type of a collection not supported by default when settingEmbeddedContextState
on embedded collection member items ofContextStateAware entities
.protected PolicyUtils
getPolicyUtils()
protected boolean
isLatestChangeToFieldAtAnyLevel(ChangeDetail detail, Collection<? extends ChangeDetail> otherDetails)
Checks that the givenChangeDetail
any of: The only change for a field The highestChangeDetail.getLevel()
of any change for a field The newest change for that field (comparingChangeDetail.getTimestamp()
All obsolete changes are automatically excluded (seeChangeDetail.getObsolete()
).protected boolean
isNotObsoleteChange(ChangeDetail detail)
protected boolean
isNotProductionChange(ChangeDetail detail)
protected boolean
isRebasedChange(ChangeDetail detail)
protected void
setApplicationInfo(Trackable domain, ContextState contextState, TrackableBehaviorPackage behavior)
protected void
setCatalogInfo(Trackable domain, ContextState contextState, TrackableBehaviorPackage behavior)
void
setChangeStateForEmbeddedCollections(Trackable domain, ContextStateAware businessItem, org.modelmapper.ModelMapper fromMeMapper)
Sets theEmbeddedContextState
on a businessItem's embedded collections where the member items areEmbeddedContextStateAware
.protected void
setCollectionItemContextState(EmbeddedContextStateAware item, List<String> fieldsChanged)
Builds and sets aContextState
onto the givenEmbeddedContextStateAware collection item
.protected void
setContextStateTrackingInfo(Trackable domain, ContextState contextState)
Adds additional info to aContextState
being built for aContextStateAware business instance
corresponding to a givenTrackable domain instance
.protected void
setCustomerContext(Trackable domain, ContextState contextState, TrackableBehaviorPackage behavior)
void
setPolicyUtils(PolicyUtils policyUtils)
protected void
setTenant(Trackable domain, ContextState contextState, TrackableBehaviorPackage behavior)
-
-
-
Field Detail
-
DETAIL_LEVEL_COMPARATOR
protected static final Comparator<ChangeDetail> DETAIL_LEVEL_COMPARATOR
-
FIELD_LEVEL_COMPARATOR
protected static final Comparator<FieldChange> FIELD_LEVEL_COMPARATOR
-
DETAIL_TIMESTAMP_COMPARATOR
protected static final Comparator<ChangeDetail> DETAIL_TIMESTAMP_COMPARATOR
-
-
Constructor Detail
-
ContextStateBuilder
public ContextStateBuilder(com.broadleafcommerce.common.extension.TypeFactory factory, TrackableBehaviorUtil behaviorUtil, com.fasterxml.jackson.databind.ObjectMapper fieldChangeMapper, org.modelmapper.ModelMapper cloneMapper)
-
-
Method Detail
-
setPolicyUtils
@Autowired(required=false) public void setPolicyUtils(@Nullable PolicyUtils policyUtils)
-
buildContextState
@NonNull public ContextState buildContextState(@NonNull Trackable domain, @Nullable ContextInfo contextInfo)
BuildsContextState information
for aContextStateAware business instance
corresponding to the givenTrackable domain instance
that can be inspected for additional metadata around the entity in relation to the context of the requester. This information can be used to make determination around mutability, as well as details around the nature of field change state (if any).- Parameters:
domain
- Arepository domain instance
to use as the basis for theContextState
being built.contextInfo
- The context information used to determine sandbox and multitenant state in tracking- Returns:
- The
ContextState information
for aContextStateAware business instance
corresponding to the givenTrackable domain instance
.
-
determineSandboxChangeType
@Nullable protected String determineSandboxChangeType(Trackable domain)
Returns thetracking's object's
sandbox change type.- Parameters:
domain
- TheTrackable instance
to retrieve the sandbox change type from.- Returns:
- The sandbox change type, or null if there is no sandbox change type.
- See Also:
SandboxInfo.getChangeType()
,Tracking.getSandbox()
-
setChangeStateForEmbeddedCollections
public void setChangeStateForEmbeddedCollections(@NonNull Trackable domain, @NonNull ContextStateAware businessItem, @Nullable org.modelmapper.ModelMapper fromMeMapper)
Sets theEmbeddedContextState
on a businessItem's embedded collections where the member items areEmbeddedContextStateAware
.By default, checks for
ChangeDetails
related to embedded collections on the businessItem. Then, deserializes and comparesChangeDetail.getBeforeValue()
andChangeDetail.getAfterValue()
to determine which member items within the collections have changed. Then, updates theirContextState
, assuming those items areEmbeddedContextStateAware
. Filters out all changes that are obsolete or older than another change for the same field in the same or highertracking level
(e.g., if 2 changes are found to a 'name' field and both are inthe USER level
, the older one is filtered out).- Parameters:
domain
- TheTrackable instance
representing the persistent entity from which to gleanChangeDetails
businessItem
- The business item corresponding to the domain whose embedded collections should have theirContextStates
set.fromMeMapper
- ifdomain
isModelMapperMappable
, this should contain the result ofModelMapperMappable.fromMe()
. This mapper is used to convert the embedded items from persisted instances to business instances. Ifdomain
is notModelMapperMappable
, then this should be left null.- Throws:
IllegalContextStateException
- Thrown when a problem in the context state is found. This is normally because of one of the following scenarios:- a collection is found on the businessItem but the corresponding field on the domain is not a collection.
- the accessor for a collection field on the businessItem cannot be invoked because of access security or the name of the accessor is unknown.
ContextStateProcessingException
- Thrown when an error occurs when attempting to set theContextState
on the members of a businessItem's embedded collection. Some examples:- when invoking (not finding) the correct accessor of a collection field on the businessItem encounters an error.
- when a
ChangeDetail's
before or after values cannot be deserialized once a change for a collection has been detected.
-
determineContextStateMutability
protected boolean determineContextStateMutability(Trackable domain, @Nullable ContextInfo contextInfo)
Determines whether the domain is mutable given the requesting context. Generally, factors such as permissions, application tenancy, and catalog mutability are considered.- Parameters:
domain
- TheTrackable domain instance
under consideration for mutabilitycontextInfo
- The context information used to determine sandbox and multitenant state in tracking- Returns:
- whether the given domain instance is mutable in the current request context.
-
determineApplicationContextStateMutability
protected boolean determineApplicationContextStateMutability(Trackable domain, @Nullable ContextInfo contextInfo)
Determines whether the domain is mutable given the requesting context based on the application and tenancy state of the domain and context.If the domain doesn't belong to the requesting context's application, then it should not be mutable.
- Parameters:
domain
- TheTrackable domain instance
under consideration for mutabilitycontextInfo
- The context information used to determine sandbox and multitenant state in tracking- Returns:
- whether the given domain instance is mutable in the current request context according to application tenancy
-
determinePolicyContextStateMutability
protected boolean determinePolicyContextStateMutability(Trackable domain, @Nullable ContextInfo contextInfo)
Determines whether the domain is mutable given the requesting context based on permissions and policy validation.- Parameters:
domain
- TheTrackable domain instance
under consideration for mutabilitycontextInfo
- The context information used to determine sandbox and multitenant state in tracking- Returns:
- whether the given domain instance is mutable in the current request context according to permissions and policies
-
determineContextStateLevel
protected Integer determineContextStateLevel(Trackable domain)
Determines theContextState.getLevel()
. This is generally the same as the givenTrackable domain instance's tracking
level
.- Parameters:
domain
- Adomain instance
being used as the basis for building aContextState
.- Returns:
- The
TrackingLevel
to set on theContextState
.
-
determineArchived
protected Boolean determineArchived(Trackable domain)
Determines theContextState.getArchived()
. This is generally the same as the givenTrackable domain instance's tracking
archived
.- Parameters:
domain
- Adomain instance
being used as the basis for building aContextState
.- Returns:
- The archived status to set on the
ContextState
.
-
buildContextStateFieldChanges
protected List<FieldChange> buildContextStateFieldChanges(Trackable domain)
Builds a list ofFieldChanges
for theContextState
of aContextStateAware business instance
corresponding to a givenTrackable domain instance
.- Parameters:
domain
- TheTrackable domain instance
being used as a basis for building aContextState
.- Returns:
- A list of
FieldChanges
to set on aContextState
.
-
isRebasedChange
protected final boolean isRebasedChange(ChangeDetail detail)
-
isNotObsoleteChange
protected final boolean isNotObsoleteChange(ChangeDetail detail)
-
isNotProductionChange
protected final boolean isNotProductionChange(ChangeDetail detail)
-
setContextStateTrackingInfo
protected void setContextStateTrackingInfo(Trackable domain, ContextState contextState)
Adds additional info to aContextState
being built for aContextStateAware business instance
corresponding to a givenTrackable domain instance
. Such info usually includesSandboxInfo
,CatalogInfo
, andApplicationInfo
as applicable to the given trackable.- Parameters:
domain
- ATrackable domain instance
being used as the basis for building aContextState
.contextState
- AContextState
being built for aContextStateAware business instance
corresponding to the given trackable domain.
-
setTenant
protected void setTenant(Trackable domain, ContextState contextState, TrackableBehaviorPackage behavior)
-
setCustomerContext
protected void setCustomerContext(Trackable domain, ContextState contextState, TrackableBehaviorPackage behavior)
-
setApplicationInfo
protected void setApplicationInfo(Trackable domain, ContextState contextState, TrackableBehaviorPackage behavior)
-
setCatalogInfo
protected void setCatalogInfo(Trackable domain, ContextState contextState, TrackableBehaviorPackage behavior)
-
isLatestChangeToFieldAtAnyLevel
protected final boolean isLatestChangeToFieldAtAnyLevel(ChangeDetail detail, Collection<? extends ChangeDetail> otherDetails)
Checks that the givenChangeDetail
any of:- The only change for a field
- The highest
ChangeDetail.getLevel()
of any change for a field - The newest change for that field (comparing
ChangeDetail.getTimestamp()
ChangeDetail.getObsolete()
).
-
getOtherCollectionMemberType
protected Optional<Class<?>> getOtherCollectionMemberType(String fieldName, Class<?> parentType, String parentId)
Extension point for determining the member type of a collection not supported by default when settingEmbeddedContextState
on embedded collection member items ofContextStateAware entities
. Default supported collections areIterable
,Map
, and arrays. The following should also be extended:deserializeCollectionValue(String, Class, JavaType, Class, String, String)
,getOtherBusinessCollectionValue(String, Class, Object, String)
, anddeterminePersistentCollectionJavaType(ChangeDetail, Class, Class, Class, String)
- Parameters:
fieldName
- Name of the field on an entity (business or persistent) that may be a collection for whose member items we need the typeparentType
- TheClass
of the parent entityparentId
- Id of the parent entity- Returns:
- the
Class
of the member items inside of an embedded collection orOptional.empty()
if not a collection.
-
getOtherBusinessCollectionValue
protected <T> List<T> getOtherBusinessCollectionValue(String fieldName, Class<T> collectionMemberType, Object businessItem, String itemId)
Extension point for getting the values of an embedded collection not supported by default on a business item implementingContextStateAware
where the collection's members also implementContextStateAware
when settingContextState
on embedded collections ofContextStateAware entities
. Default supported collections areIterable
,Map
, and arrays. For more, extend this method,deserializeCollectionValue(String, Class, JavaType, Class, String, String)
,getOtherCollectionMemberType(String, Class, String)
, anddeterminePersistentCollectionJavaType(ChangeDetail, Class, Class, Class, String)
- Parameters:
fieldName
- Name of the field on an business entity that is an unsupported type of collectioncollectionMemberType
- TheClass
of the collection's member itembusinessItem
- The business item that owns the embedded collectionitemId
- The id of the business item that owns the embedded collection- Returns:
- The values of an embedded collection on a business item that implements
ContextStateAware
where the collection's members also implementContextStateAware
and require theirContextStates
to be set.
-
buildBusinessCollectionAccessorName
protected String buildBusinessCollectionAccessorName(String fieldName, Object businessItem, String itemId)
Builds the name of the accessor of one of the businessItem's embedded collections to invoke in order to obtain the value of that field when settingContextState
on embedded collections ofContextStateAware entities
.- Parameters:
fieldName
- Name of the embedded collection on the businessItembusinessItem
- Business instance of a persistent entity that is having its embedded collections'ContextStates
set.itemId
- ID of the businessItem- Returns:
- name of the accessor of one of the businessItem's embedded collections
-
determinePersistentCollectionJavaType
protected com.fasterxml.jackson.databind.JavaType determinePersistentCollectionJavaType(ChangeDetail detail, Class<?> collectionType, Class<?> memberType, Class<?> parentType, String parentId)
Determines theJavaType
of collections on persistent domains that correspond toContextStateAware entities
when deserializing the before and after values of aChangeDetail
when settingContextState
on embedded collections ofContextStateAware entities
.The
JavaType
returned is used to inform anObjectMapper
of how to read the serialized before or after value from the ChangeDetail: seeObjectMapper.readValue(String, JavaType)
.Default supported collections are
Iterable
,Map
, and arrays. If other types should be supported, extend this method,deserializeCollectionValue(String, Class, JavaType, Class, String, String)
,getOtherCollectionMemberType(String, Class, String)
, andgetOtherBusinessCollectionValue(String, Class, Object, String)
- Parameters:
detail
- theChangeDetail
with info on the changes to an embedded collection that should be used to set theContextState
on a member of the corresponding business domain's collection.collectionType
- theClass
of the persistent embedded collection to which theChangeDetail
belongs.memberType
- theClass
of the member items within the embedded collectionparentType
- TheClass
of the persistent entity that owns the embedded collectionparentId
- The id of the persistent entity that owns the embedded collection- Returns:
- The
JavaType
of the persistent collection required for deserialization.
-
deserializeCollectionValue
protected <T> List<T> deserializeCollectionValue(String collectionName, Class<?> collectionType, com.fasterxml.jackson.databind.JavaType javaType, Class<?> parentType, String parentId, String serializedValue)
Deserializes either the afterValue or beforeValue of aChangeDetail
for an embedded collection field, depending on which is passed as the serializedValue param, when settingContextState
on embedded collections ofContextStateAware entities
. If a collection type other than array,Map
, orIterable
should be supported, extend this method,determinePersistentCollectionJavaType(ChangeDetail, Class, Class, Class, String)
,getOtherCollectionMemberType(String, Class, String)
, andgetOtherBusinessCollectionValue(String, Class, Object, String)
- Parameters:
collectionName
- The name of the collection field to which values belongcollectionType
- TheClass
of the collectionjavaType
- TheJavaType
to pass to theObjectMapper
into which to deserialize the serializedValueparentType
- TheClass
of the entity that owns the collectionparentId
- The id of the entity that owns the collectionserializedValue
- The before or after value from aChangeDetail
to deserialize- Returns:
- A List representing the deserialized collection
- Throws:
ContextStateProcessingException
- Thrown if deserialization fails for any reason.
-
setCollectionItemContextState
protected void setCollectionItemContextState(EmbeddedContextStateAware item, List<String> fieldsChanged)
Builds and sets aContextState
onto the givenEmbeddedContextStateAware collection item
.- Parameters:
item
- TheEmbeddedContextStateAware collection item
.fieldsChanged
- List of the names of the fields on the changed item that were actually changed
-
getFactory
@NonNull protected com.broadleafcommerce.common.extension.TypeFactory getFactory()
-
getBehaviorUtil
@NonNull protected TrackableBehaviorUtil getBehaviorUtil()
-
getFieldChangeMapper
@NonNull protected com.fasterxml.jackson.databind.ObjectMapper getFieldChangeMapper()
-
getCloneMapper
@NonNull protected org.modelmapper.ModelMapper getCloneMapper()
-
getPolicyUtils
@Nullable protected PolicyUtils getPolicyUtils()
-
-