Class ProductCharacteristicManagementUtility<P extends Product>
- Type Parameters:
P- the type ofProductthis utility is for.
It is designed to be used by services that need to manage product characteristics as part of their business logic.
-
Constructor Summary
ConstructorsConstructorDescriptionProductCharacteristicManagementUtility(com.broadleafcommerce.common.extension.TypeFactory typeFactory, ProductCharacteristicService<ProductCharacteristic> productCharacteristicService, BusinessTypeService<BusinessType> businessTypeService) -
Method Summary
Modifier and TypeMethodDescriptionprotected booleanareCharacteristicValuesDifferent(ProductCharacteristic pc, ProductCharacteristic existingProductCharacteristic, Map<String, BusinessType> businessTypesByKey, Map<String, P> productsById) Compares the values of an incomingProductCharacteristicwith an existing one to determine if they are different.protected ProductCharacteristicManagementResultbuildResult(Map<String, Map<String, ProductCharacteristic>> prodCharsByIdByProductId) Builds the final result from the persisted characteristics.protected com.broadleafcommerce.data.tracking.core.filtering.domain.ChangeContainercopyChangeContainer(com.broadleafcommerce.data.tracking.core.filtering.domain.ChangeContainer changeContainer) Creates a copy of the givenChangeContainer.protected voidforceInitializeProductIdValueOnProdChars(Map<String, List<ProductCharacteristic>> requestedCharacteristicsByProductId) The API caller may or may not have setProductCharacteristic.getProductId()on the API payload (and almost certainly not if this is a create operation).protected BusinessTypeService<BusinessType>protected Map<String,List<ProductCharacteristic>> getExistingCharacteristics(Set<String> productIds, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Retrieves the existing product characteristics for the given product IDs.protected Map<String,Map<String, ProductCharacteristic>> getProdCharsByIdByProductId(Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId) Organizes existing product characteristics into a nested map structure for efficient lookup.protected com.broadleafcommerce.common.extension.TypeFactoryprotected Map<String,BusinessType> hydrateBusinessTypes(ProductCharacteristicManagementRequest request, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Hydrates the business types for the products in the request.protected List<ProductCharacteristic>identifyCharacteristicsToCreate(ProductCharacteristicManagementRequest request, Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId, Map<String, BusinessType> businessTypesByKey, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Identifies the product characteristics that need to be created.protected List<com.broadleafcommerce.data.tracking.core.service.Update<ProductCharacteristic>>identifyCharacteristicsToUpdate(ProductCharacteristicManagementRequest request, Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId, Map<String, BusinessType> businessTypesByKey, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Identifies the product characteristics that need to be updated.protected booleanisExistingCharacteristic(ProductCharacteristic pc, Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId) Checks if the characteristic already exists.protected booleanisNewCharacteristic(ProductCharacteristic pc, Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId) Checks if the characteristic is considered new.manageProductCharacteristics(ProductCharacteristicManagementRequest request, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Manages the characteristics for a batch of products.voidmapLatestCharacteristicsStateOntoResponse(com.broadleafcommerce.data.tracking.core.service.BulkPersistenceResponse<P> response, ProductCharacteristicManagementResult latestState) Maps the latest characteristic state onto a bulk persistence response.voidmapLatestCharacteristicsStateOntoResponse(List<P> response, ProductCharacteristicManagementResult latestState) Maps the latest characteristic state onto a list of product responses.voidmapLatestCharacteristicsStateOntoResponse(P response, ProductCharacteristicManagementResult latestState) Maps the latest characteristic state onto a single product response.protected booleanChecks if the given ProductCharacteristic exactly matches the characteristic value defined on the parent BusinessType.protected ProductCharacteristicmatchExistingCharacteristicByFieldNameAndSetId(ProductCharacteristic pc, Map<String, List<ProductCharacteristic>> existingCharacteristics) Matches an incoming product characteristic to an existing one based on field name.protected voidpersistCharacteristicChanges(List<ProductCharacteristic> toCreate, List<com.broadleafcommerce.data.tracking.core.service.Update<ProductCharacteristic>> toUpdate, Map<String, Map<String, ProductCharacteristic>> prodCharsByIdByProductId, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Persists the created and updated characteristics.protected ProductCharacteristicsetOverrideChangeContainer(ProductCharacteristic pc, com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Sets the override change container on theProductCharacteristicto ensure it is tracked under the product's change container context.protected booleanshouldUpdateCharacteristic(ProductCharacteristic pc, Map<String, List<ProductCharacteristic>> existingCharacteristics, Map<String, BusinessType> businessTypesByKey, Map<String, P> productsById) Checks if the value of aProductCharacteristichas changed compared to the existing characteristics.
-
Constructor Details
-
ProductCharacteristicManagementUtility
public ProductCharacteristicManagementUtility(com.broadleafcommerce.common.extension.TypeFactory typeFactory, ProductCharacteristicService<ProductCharacteristic> productCharacteristicService, BusinessTypeService<BusinessType> businessTypeService)
-
-
Method Details
-
manageProductCharacteristics
public ProductCharacteristicManagementResult manageProductCharacteristics(ProductCharacteristicManagementRequest request, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Manages the characteristics for a batch of products. This method orchestrates the process of identifying which characteristics are new, which are updated, and which are unchanged, and then persists those changes.- Parameters:
request- aProductCharacteristicManagementRequestcontaining the products and their requested characteristicscontext- the context information for the request- Returns:
- a
ProductCharacteristicManagementResultcontaining the latest state of the product characteristics for all processed products
-
hydrateBusinessTypes
protected Map<String,BusinessType> hydrateBusinessTypes(ProductCharacteristicManagementRequest request, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Hydrates the business types for the products in the request.- Parameters:
request- the management requestcontext- the context info- Returns:
- a map of business types by their type key
-
getExistingCharacteristics
protected Map<String,List<ProductCharacteristic>> getExistingCharacteristics(Set<String> productIds, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Retrieves the existing product characteristics for the given product IDs.- Parameters:
productIds- the set of product IDscontext- the context info- Returns:
- a map of existing characteristics grouped by product ID
-
getProdCharsByIdByProductId
protected Map<String,Map<String, getProdCharsByIdByProductIdProductCharacteristic>> (Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId) Organizes existing product characteristics into a nested map structure for efficient lookup.- Parameters:
existingCharacteristicsByProdId- A map where keys are product IDs and values are lists ofProductCharacteristics associated with that product.- Returns:
- A nested map where the outer key is the product ID, and the inner map's key is the
product characteristic ID, with the
ProductCharacteristicas the value. This facilitates quick access to a specific characteristic of a specific product.
-
identifyCharacteristicsToCreate
protected List<ProductCharacteristic> identifyCharacteristicsToCreate(ProductCharacteristicManagementRequest request, Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId, Map<String, BusinessType> businessTypesByKey, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Identifies the product characteristics that need to be created.- Parameters:
request- the management requestexistingCharacteristicsByProdId- the map of existing characteristicsbusinessTypesByKey- the map of business typescontext- the context info- Returns:
- a list of characteristics to create
-
identifyCharacteristicsToUpdate
protected List<com.broadleafcommerce.data.tracking.core.service.Update<ProductCharacteristic>> identifyCharacteristicsToUpdate(ProductCharacteristicManagementRequest request, Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId, Map<String, BusinessType> businessTypesByKey, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Identifies the product characteristics that need to be updated.- Parameters:
request- the management requestexistingCharacteristicsByProdId- the map of existing characteristicsbusinessTypesByKey- the map of business typescontext- the context info- Returns:
- a list of updates for characteristics
-
persistCharacteristicChanges
protected void persistCharacteristicChanges(List<ProductCharacteristic> toCreate, List<com.broadleafcommerce.data.tracking.core.service.Update<ProductCharacteristic>> toUpdate, Map<String, Map<String, ProductCharacteristic>> prodCharsByIdByProductId, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Persists the created and updated characteristics.- Parameters:
toCreate- the list of characteristics to createtoUpdate- the list of characteristics to updateprodCharsByIdByProductId- the map to store the persisted characteristicscontext- the context info
-
buildResult
protected ProductCharacteristicManagementResult buildResult(Map<String, Map<String, ProductCharacteristic>> prodCharsByIdByProductId) Builds the final result from the persisted characteristics.- Parameters:
prodCharsByIdByProductId- the map of persisted characteristics- Returns:
- the product characteristic management result
-
mapLatestCharacteristicsStateOntoResponse
public void mapLatestCharacteristicsStateOntoResponse(com.broadleafcommerce.data.tracking.core.service.BulkPersistenceResponse<P> response, ProductCharacteristicManagementResult latestState) Maps the latest characteristic state onto a bulk persistence response. This ensures that the product instances in the response reflect the most up-to-date characteristic values.- Parameters:
response- the bulk persistence responselatestState- the result from the characteristic management process
-
mapLatestCharacteristicsStateOntoResponse
public void mapLatestCharacteristicsStateOntoResponse(P response, ProductCharacteristicManagementResult latestState) Maps the latest characteristic state onto a single product response.- Parameters:
response- the product responselatestState- the result from the characteristic management process
-
mapLatestCharacteristicsStateOntoResponse
public void mapLatestCharacteristicsStateOntoResponse(List<P> response, ProductCharacteristicManagementResult latestState) Maps the latest characteristic state onto a list of product responses.- Parameters:
response- the list of product responseslatestState- the result from the characteristic management process
-
forceInitializeProductIdValueOnProdChars
protected void forceInitializeProductIdValueOnProdChars(@Nullable Map<String, List<ProductCharacteristic>> requestedCharacteristicsByProductId) The API caller may or may not have setProductCharacteristic.getProductId()on the API payload (and almost certainly not if this is a create operation). We force-set the value here to match the ID of the product the characteristics were provided under. This guarantees the API caller neither has to supply the value, nor can they accidentally affect characteristics of unintended unrelated products by supplying an invalid product ID.- Parameters:
requestedCharacteristicsByProductId- the caller provided characteristics values mapped by product id
-
isNewCharacteristic
protected boolean isNewCharacteristic(ProductCharacteristic pc, Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId) Checks if the characteristic is considered new.A characteristic is new if it has a null ID, or if it has an ID but that ID is not found in the existing characteristics for the product.
- Parameters:
pc- the characteristic to checkexistingCharacteristicsByProdId- the map of existing characteristics by product ID- Returns:
- true if new, false otherwise
-
isExistingCharacteristic
protected boolean isExistingCharacteristic(ProductCharacteristic pc, Map<String, List<ProductCharacteristic>> existingCharacteristicsByProdId) Checks if the characteristic already exists.A characteristic exists if it has a non-null ID and that ID is found in the existing characteristics for the product.
- Parameters:
pc- the characteristic to checkexistingCharacteristicsByProdId- the map of existing characteristics by product ID- Returns:
- true if existing, false otherwise
-
matchesParentBusinessType
Checks if the given ProductCharacteristic exactly matches the characteristic value defined on the parent BusinessType.- Parameters:
pc- the incoming product characteristicbt- the parent business type- Returns:
- true if the provided product characteristic details match their counterparts in the parent business type
-
shouldUpdateCharacteristic
protected boolean shouldUpdateCharacteristic(ProductCharacteristic pc, Map<String, List<ProductCharacteristic>> existingCharacteristics, Map<String, BusinessType> businessTypesByKey, Map<String, P> productsById) Checks if the value of aProductCharacteristichas changed compared to the existing characteristics.This method looks up the existing characteristic in the provided map using the product ID and characteristic ID. If found, it delegates to
areCharacteristicValuesDifferent(ProductCharacteristic, ProductCharacteristic, Map, Map)to compare values.If the characteristic is not found in the existing map (but has an ID), this returns true to ensure an update is attempted.
- Parameters:
pc- the incoming product characteristic to checkexistingCharacteristics- a map of existing characteristics grouped by product ID- Returns:
- true if the value has changed or the characteristic is not found, false otherwise
-
areCharacteristicValuesDifferent
protected boolean areCharacteristicValuesDifferent(ProductCharacteristic pc, ProductCharacteristic existingProductCharacteristic, Map<String, BusinessType> businessTypesByKey, Map<String, P> productsById) Compares the values of an incomingProductCharacteristicwith an existing one to determine if they are different.For non-enum field types, this filters the existing values to only include active ones before comparing.
- Parameters:
pc- the incoming product characteristicexistingProductCharacteristic- the existing product characteristic from the database- Returns:
- true if the values are different, false otherwise
-
matchExistingCharacteristicByFieldNameAndSetId
protected ProductCharacteristic matchExistingCharacteristicByFieldNameAndSetId(ProductCharacteristic pc, Map<String, List<ProductCharacteristic>> existingCharacteristics) Matches an incoming product characteristic to an existing one based on field name.If a match is found in the provided map of existing characteristics (keyed by product ID), the ID of the incoming characteristic is updated to match the existing one. This ensures that updates happen instead of deletes.
- Parameters:
pc- the incoming product characteristic to matchexistingCharacteristics- a map of existing characteristics grouped by product ID
-
setOverrideChangeContainer
protected ProductCharacteristic setOverrideChangeContainer(ProductCharacteristic pc, @Nullable com.broadleafcommerce.data.tracking.core.context.ContextInfo context) Sets the override change container on theProductCharacteristicto ensure it is tracked under the product's change container context.If a change container is present on the context request, it is copied to preserve context (like catalog and route key).
This sets the container ID to the product ID from the characteristic, and sets the container name and sub-container name to "PRODUCT" and "PRODUCT_CHARACTERISTIC" respectively. This ensures that changes to the characteristic are grouped with the product.
- Parameters:
pc- the product characteristic to updatecontext- context information containing the request context- Returns:
- the product characteristic with the override change container set
-
copyChangeContainer
protected com.broadleafcommerce.data.tracking.core.filtering.domain.ChangeContainer copyChangeContainer(com.broadleafcommerce.data.tracking.core.filtering.domain.ChangeContainer changeContainer) Creates a copy of the givenChangeContainer. This is used to ensure that each characteristic has its own change container instance, preventing unintended side effects.- Parameters:
changeContainer- the change container to copy- Returns:
- a new instance of
ChangeContainerwith the same properties as the original
-
getTypeFactory
protected com.broadleafcommerce.common.extension.TypeFactory getTypeFactory() -
getProductCharacteristicService
-
getBusinessTypeService
-