Class CollectedProductConversionUtil

java.lang.Object
com.broadleafcommerce.datafeed.service.publisher.file.transformer.CollectedProductConversionUtil

public class CollectedProductConversionUtil extends Object
Utility class for common data retrieval functions for CollectedProduct. This is most useful during transformation of the collected information into the target vendor data feed format.
  • Field Details

  • Constructor Details

    • CollectedProductConversionUtil

      public CollectedProductConversionUtil()
  • Method Details

    • getVariants

      @NonNull public List<com.fasterxml.jackson.databind.node.ObjectNode> getVariants(@NonNull com.fasterxml.jackson.databind.node.ObjectNode productSource, @Nullable Function<Map<CollectedProductConversionUtil.OptionValueCombo,List<com.fasterxml.jackson.databind.node.ObjectNode>>,List<com.fasterxml.jackson.databind.node.ObjectNode>> variantFilter)
      Retrieve all variants for active product options. Active product options are those defined as having 'searchOnOption' set to true and having a type of VARIANT_DISTINGUISHING. When more variants are available than active product options target alone, an arbitrary mid-range variant is selected and the other un-attributed variants are ignored in the response from this method. Note, if more selectivity is desired for the selection of variants, an optional filter may be used.
      Parameters:
      productSource - The node representing the product. Usually extracted from CollectedProduct.getJsonMap().
      variantFilter - Filter implementation that outputs the desired list of variant nodes based on a collated map of variants by active option values. Optional.
      Returns:
      The list of relevant variants. Empty list if no variants found.
    • getAllVariants

      public List<com.fasterxml.jackson.databind.node.ObjectNode> getAllVariants(CollectedProduct collectedProduct)
      Gets all variants from the collectedProduct without applying any filtration.
      Parameters:
      collectedProduct - the source collected product to get variants for
      Returns:
      all variants for the product, else empty
    • getVariantsWithMatchingSearchOnOptionValues

      public List<com.fasterxml.jackson.databind.node.ObjectNode> getVariantsWithMatchingSearchOnOptionValues(com.fasterxml.jackson.databind.node.ObjectNode variant, CollectedProduct collectedProduct)
      Given a variant, finds all variants on the collectedProduct that have the same optionValues for option attribute names where 'searchOnOption = true'.

      For example, assume 'color' is marked 'searchOnOption = true' and 'size' is marked 'searchOnOption = false' and a red medium variant is given. This would find all red variants on the specified product (for example, red small, red medium, red large).

      Alternatively, if 'color' and 'size' are both marked 'searchOnOption = true' and a red medium variant is given, this would find all red medium variants on the specified product.

      Such a method can be useful to derive things like inventory availability, where you may only want to consider a product out of stock if all variants in a 'family' are out-of-stock.

      Parameters:
      variant - the variant whose searchOnOption optionValues should be matched
      collectedProduct - the product from which to filter and return variants
      Returns:
      variants with matching searchOnOption optionValues, else empty
    • getOptions

      @Nullable public com.fasterxml.jackson.databind.node.ArrayNode getOptions(CollectedProduct sourceElement)
      Gets the options from the given product, else null if unavailable.
      Parameters:
      sourceElement - the product get options from
      Returns:
      the arraynode representing the product options
    • getAttributeChoiceOfType

      public Optional<com.fasterxml.jackson.databind.node.ObjectNode> getAttributeChoiceOfType(@NonNull com.fasterxml.jackson.databind.node.ArrayNode options, @NonNull String type)
      Given an array of options, filters to the variant distinguishing option with an attribute choice of the specified type, and then returns that attribute choice.
      Parameters:
      options - the options to filter from
      type - the attribute choice type to match
      Returns:
      the attribute choice that matches, else Optional.empty()
    • getOptionForAttributeChoiceOfType

      public Optional<com.fasterxml.jackson.databind.node.ObjectNode> getOptionForAttributeChoiceOfType(@NonNull com.fasterxml.jackson.databind.node.ArrayNode options, @NonNull String type)
      Given an array of options, filters to the variant distinguishing option with an attribute choice of the specified type.
      Parameters:
      options - the options to filter from
      type - the attribute choice type to match
      Returns:
      the option that matches, else Optional.empty()
    • extractAttributeChoiceType

      @Nullable protected String extractAttributeChoiceType(com.fasterxml.jackson.databind.node.ObjectNode option)
    • extractAttributeChoice

      public Optional<com.fasterxml.jackson.databind.node.ObjectNode> extractAttributeChoice(com.fasterxml.jackson.databind.node.ObjectNode option)
      Extracts the attribute choice from the given product option.
      Parameters:
      option - an object node representing a product option
      Returns:
      the attribute choice for the option if found, else empty
    • getAllProductAssets

      public List<com.fasterxml.jackson.databind.node.ObjectNode> getAllProductAssets(CollectedProduct collectedProduct)
      Gets all the product assets for the given product.
      Parameters:
      collectedProduct - the product to get the product assets from
      Returns:
      all the product assets for the given product
    • getProductAssetsWithAnyTagMatching

      public Stream<com.fasterxml.jackson.databind.node.ObjectNode> getProductAssetsWithAnyTagMatching(List<com.fasterxml.jackson.databind.node.ObjectNode> productAssets, Predicate<String> tagFilter)
      Returns a filtered stream of the input product assets where an asset will be included in the result if any of its tags match the given filter.
      Parameters:
      productAssets - the assets to filter
      tagFilter - the filter that any of an asset's tags must match in order for the asset to be included in the result
      Returns:
      a filtered stream of the given assets
    • buildAssetTagsFromVariantOptionValues

      public Set<String> buildAssetTagsFromVariantOptionValues(com.fasterxml.jackson.databind.node.ObjectNode variant)
      Creates asset tags of format 'optionValueName:optionValue' from the variant.
      Parameters:
      variant - the variant to create the asset tags for
      Returns:
      the created asset tags
    • getProductAssetMatchingVariantOptionValue

      public Stream<com.fasterxml.jackson.databind.node.ObjectNode> getProductAssetMatchingVariantOptionValue(@Nullable List<com.fasterxml.jackson.databind.node.ObjectNode> allProductAssets, com.fasterxml.jackson.databind.node.ObjectNode variant)
      Finds the product assets for the provided variant. By default, this is found by looking for a product asset where any of its tags matches 'optionValueName:optionValue' (ignoring case) for any option value in the variant.
      Parameters:
      allProductAssets - all product assets for the parent product
      variant - the variant for which to find a matching asset
      Returns:
      the object node representing the found asset, else Optional.empty()
    • isProductInStock

      public boolean isProductInStock(CollectedProduct collectedProduct, @Nullable List<com.fasterxml.jackson.databind.node.ObjectNode> variants)
      When this is a variant-based product, availability is determined by whether any of the given variants are available. Otherwise, we just get the inventory details for this specific product.
      Parameters:
      collectedProduct - collected product to check stock status for
      variants - (optional) variants of the product that should be considered for inventory availability
      Returns:
      true if the product is in stock, false otherwise
    • getVariantAvailableStockCounts

      protected LongStream getVariantAvailableStockCounts(@NonNull CollectedProduct collectedProduct, @NonNull List<com.fasterxml.jackson.databind.node.ObjectNode> variants)
    • getDirectProductAvailableStockCount

      protected long getDirectProductAvailableStockCount(@NonNull CollectedProduct collectedProduct)
    • getAvailableInventoryCount

      public long getAvailableInventoryCount(CollectedProduct collectedProduct, @Nullable List<com.fasterxml.jackson.databind.node.ObjectNode> variants)
      When this is a variant-based product, returns the total available quantity for each of the given variants. Otherwise, we just get the inventory count for the specific product.
      Parameters:
      collectedProduct - collected product to get available inventory count for
      variants - (optional) variants of the product that should be considered for inventory availability
      Returns:
      the total available inventory count for this product
    • getDefaultPriceAmountForProduct

      @Nullable public javax.money.MonetaryAmount getDefaultPriceAmountForProduct(CollectedProduct collectedProduct)
      Gets the 'default' price for the product based on pricing information in CollectedProduct.getPriceInfo().
      Parameters:
      collectedProduct - the product to get the default price for
      Returns:
      the default price if found, else null. Note that it should be extremely unlikely for this to return null since the price details should always be set by the collectors, but this method allows for the possibility.
    • getSalePriceAmountForProduct

      @Nullable public javax.money.MonetaryAmount getSalePriceAmountForProduct(CollectedProduct collectedProduct)
      Gets the 'sale' price for the product based on pricing information in CollectedProduct.getPriceInfo().
      Parameters:
      collectedProduct - the product to get the default price for
      Returns:
      the sale price if found, else the default price, else null. Note that it should be extremely unlikely for this to return null since the price details should always be set by the collectors, but this method allows for the possibility.
    • getDefaultPriceAmountForVariant

      @Nullable public javax.money.MonetaryAmount getDefaultPriceAmountForVariant(CollectedProduct collectedProduct, com.fasterxml.jackson.databind.node.ObjectNode variant)
      Gets the 'default' price for the variant based on pricing information in CollectedProduct.getSkuPrices().
      Parameters:
      collectedProduct - the main product
      variant - the variant to get the default price for
      Returns:
      the default price if found, else null. Note that it should be extremely unlikely for this to return null since the price details should always be set by the collectors, but this method allows for the possibility.
    • getSalePriceAmountForVariant

      @Nullable public javax.money.MonetaryAmount getSalePriceAmountForVariant(CollectedProduct collectedProduct, com.fasterxml.jackson.databind.node.ObjectNode variant)
      Gets the 'sale' price for the variant based on pricing information in CollectedProduct.getSkuPrices().
      Parameters:
      collectedProduct - the main product
      variant - the variant to get the default price for
      Returns:
      the sale price if found, else the default price, else null. Note that it should be extremely unlikely for this to return null since the price details should always be set by the collectors, but this method allows for the possibility.
    • getBrandDisplayValue

      @Nullable public String getBrandDisplayValue(CollectedProduct source, List<Translation> translations, Locale locale)
      Gets the translated display value for the product's brand.
      Parameters:
      source - the product to get the brand for
      translations - all translations for the product
      locale - the locale for which to find the translation for
      Returns:
      the translated or default value for the product's brand display value, or null if nothing was found
    • safeGetObjectListField

      public List<com.fasterxml.jackson.databind.node.ObjectNode> safeGetObjectListField(@NonNull com.fasterxml.jackson.databind.node.ObjectNode source, @NonNull String jsonPointerExpression)
      This method will return a list of objects at the specified JSON pointer expression, if the field is an array of objects.
      Parameters:
      source - the object to get the field from
      jsonPointerExpression - a JSON pointer expression targeting an array of objects in source
      Returns:
      the list of objects in the provided field, else empty
    • safeGetObjectField

      @Nullable public com.fasterxml.jackson.databind.node.ObjectNode safeGetObjectField(@NonNull com.fasterxml.jackson.databind.node.ObjectNode source, @NonNull String jsonPointerExpression)
      This method will return an object at the specified JSON pointer expression, if the field is an object.
      Parameters:
      source - the object to get the field from
      jsonPointerExpression - a JSON pointer expression targeting an object field in source
      Returns:
      the object in the provided field, else null
    • identifyElement

      @NonNull public String identifyElement(@NonNull com.fasterxml.jackson.databind.node.ObjectNode sourceElement)
      Retrieve the identifier for the given source node (usually a product or variant). It will attempt to identify and extract one of the following values (in order): sku, externalId, id.
      Parameters:
      sourceElement - Source node from which to extract the identifier
      Returns:
      The extracted identifier
      Throws:
      IllegalArgumentException - if none of the values are available
    • getFieldTranslation

      @Nullable public String getFieldTranslation(@NonNull com.fasterxml.jackson.databind.node.ObjectNode sourceElement, @Nullable com.fasterxml.jackson.databind.node.ObjectNode variantSource, @Nullable List<Translation> translations, @NonNull String fieldName, @Nullable String variantFieldName, @NonNull Locale locale)
      Get a translation for the requested field. If a translation is not found, the default field value is returned.
      Parameters:
      sourceElement - The element to which the field translation belongs (usually a Product)
      variantSource - The variant that may provide an override of the field translation. Optional.
      translations - The translations in which to search for a match. Optional.
      fieldName - The name of the field for which a translation may exist
      variantFieldName - The name of the field on the variant that represents an override for fieldName. Optional.
      locale - The locale for the translation
      Returns:
      The translated field value, or the default field value if a translation does not exist. Null if no default field value is available.
    • getOptionTranslation

      @Nullable public String getOptionTranslation(@NonNull com.fasterxml.jackson.databind.node.ObjectNode productSource, @NonNull com.fasterxml.jackson.databind.node.ObjectNode variantSource, @Nullable List<Translation> translations, @NonNull String attributeChoiceType, @NonNull Locale locale)
      TODO migrate callers away from this method and towards getTranslatedAttributeChoiceValueLabel(ObjectNode, String, String, String, List, Locale) for more comprehensive defaulting logic.

      Get a translation for the label for the option value corresponding to the provided attributeChoiceType. If a translation is not found, the default option value is returned.

      Parameters:
      productSource - The product to which the options belong.
      variantSource - The variant to which the option labels belong.
      translations - The translations in which to search for a match. Optional.
      attributeChoiceType - the attribute choice type to find the option label translation for
      locale - The locale for the translation.
      Returns:
      The translated option label, of the default option label if a translation does not exist. Null if no default option label is available.
    • getProductId

      @Nullable protected String getProductId(com.fasterxml.jackson.databind.node.ObjectNode productSource)
    • buildTranslationFieldNameForAttributeChoiceAllowedValueLabel

      protected String buildTranslationFieldNameForAttributeChoiceAllowedValueLabel(String optionId, String attributeChoiceAllowedValueId)
    • getTranslatedAttributeChoiceValueLabel

      @Nullable public String getTranslatedAttributeChoiceValueLabel(com.fasterxml.jackson.databind.node.ObjectNode attributeChoice, String valueToMatch, String parentOptionId, String parentProductId, @Nullable List<Translation> translations, Locale locale)
      Given an attribute choice, finds the translated label corresponding to a particular allowed value.
      Parameters:
      attributeChoice - the attribute choice object
      valueToMatch - the attribute choice value to get the translated label for
      parentOptionId - the ID of the parent product option containing attributeChoice
      parentProductId - the ID of the parent product containing attributeChoice
      translations - the list of translations for the product
      locale - the locale to get the translated value for
      Returns:
      the translated label for the specified allowed value, else the default label for the allowed value, else the allowed value's actual value itself
    • safeGetProductAttributeValue

      @Nullable public String safeGetProductAttributeValue(@NonNull com.fasterxml.jackson.databind.JsonNode productSource, @NonNull String attributeName)
      Retrieve an attribute from the product based on the attribute name.
      Parameters:
      productSource - The product to which the attribute belongs.
      attributeName - The name of the attribute to search for.
      Returns:
      The attribute value. Null if nothing is found.
    • safeGetProductAttributeValue

      @Nullable public String safeGetProductAttributeValue(@NonNull com.fasterxml.jackson.databind.JsonNode productSource, @Nullable com.fasterxml.jackson.databind.JsonNode variantSource, @NonNull String attributeName)
      Retrieve an attribute from the product based on the attribute name.
      Parameters:
      productSource - The product to which the attribute belongs.
      attributeName - The name of the attribute to search for.
      Returns:
      The attribute value. Null if nothing is found.
    • safeGetTranslatedProductAttributeLabel

      @Nullable public String safeGetTranslatedProductAttributeLabel(@NonNull com.fasterxml.jackson.databind.node.ObjectNode productSource, @NonNull String attributeName, @Nullable List<Translation> translations, Locale locale)
      Retrieve a translated attribute value from the product based on the attribute name.
      Parameters:
      productSource - The product to which the attribute belongs.
      attributeName - The name of the attribute to search for.
      translations - the list of translations for the product
      locale - the locale to translate for
      Returns:
      the translated attribute label, else the standard label, else the translated value, else the standard value
    • buildTranslationFieldNameForProductAttributeField

      protected String buildTranslationFieldNameForProductAttributeField(String attributeName, String attributeFieldName)
    • safeGet

      @Nullable public String safeGet(@NonNull com.fasterxml.jackson.databind.JsonNode productSource, @Nullable com.fasterxml.jackson.databind.JsonNode variantSource, @NonNull String pointerExpression, @Nullable String variantPointerExpression, @Nullable String defaultValue)
      Find a value on the provided nodes based on the pointer expression.
      Parameters:
      productSource - The product node on which to search for the value.
      variantSource - The variant source on which to search for an override value. Optional.
      pointerExpression - The pointer expression to the value on the product.
      variantPointerExpression - The pointer expression to the override value on the variant. Optional.
      defaultValue - The default value to return if nothing is found. Optional.
      Returns:
      The override value from the optional variant. Otherwise, the value from the product. Failing both, the default value is returned.
    • safeGet

      @Nullable public String safeGet(@NonNull com.fasterxml.jackson.databind.JsonNode productSource, @Nullable com.fasterxml.jackson.databind.JsonNode variantSource, @NonNull String pointerExpression)
      Find a value on the provided nodes based on the pointer expression.
      Parameters:
      productSource - The product node on which to search for the value.
      variantSource - The variant source on which to search for an override value. Optional.
      pointerExpression - The pointer expression to the value on the product (and variant, if applicable).
      Returns:
      The override value from the optional variant. Otherwise, the value from the product.
    • safeGet

      @Nullable public String safeGet(@NonNull com.fasterxml.jackson.databind.JsonNode sourceElement, @NonNull String pointerExpression, @Nullable String defaultValue)
      Find a value on the provided nodes based on the pointer expression.
      Parameters:
      sourceElement - The source node on which to search for the value (usually Product).
      pointerExpression - The pointer expression to the value on the source node.
      defaultValue - The default value to return if the value is not found on the source node. Optional.
      Returns:
      The value found on the source node, or the default value if not found.
    • safeGet

      @Nullable public String safeGet(@NonNull com.fasterxml.jackson.databind.JsonNode sourceElement, @NonNull String pointerExpression)
      Find a value on the provided nodes based on the pointer expression.
      Parameters:
      sourceElement - The source node on which to search for the value (usually Product).
      pointerExpression - The pointer expression to the value on the source node.
      Returns:
      The value found on the source node. Null if not found.
    • getOrThrow

      @NonNull public String getOrThrow(@NonNull com.fasterxml.jackson.databind.JsonNode sourceElement, @NonNull String pointerExpression)
      Find a value on the provided nodes based on the pointer expression.
      Parameters:
      sourceElement - The source node on which to search for the value (usually Product).
      pointerExpression - The pointer expression to the value on the source node.
      Returns:
      The value found on the source node.
      Throws:
      IllegalArgumentException - If the value is not found on the source node.