Details
-
Bug
-
Status: Closed
-
Blocker
-
Resolution: Fixed
-
None
-
None
-
None
-
Quasar
-
Puma Sprint 242
Description
This only happens for old-style-component-items.
What can happen here is that a component below hst:components or hst:pages references another component which is a tree of components which get deep-copied into the referencee.
However, if the referenced tree contains items which should have DynamicComponentParameters, it can happen that these are not populated yet, and thus a deep copy is done without population, which does not happen after the deep copy any more, since only the 'canonical components' get their DynamicComponentParameters populated and deep-copies get it copy of it.
The fix is super simple: instead of
public void populateComponentReferences(final Collection<HstComponentConfiguration> populate, final ClassLoader websiteClassLoader) { for (HstComponentConfiguration child : populate) { if (isNotEmpty(child.getComponentDefinition())) { ((HstComponentConfigurationService) child).populateCatalogItemReference(availableContainerItems); } } final Map<String, List<DynamicParameter>> legacyComponentParametersCache = new HashMap<>(); final Map<String, List<DynamicFieldGroup>> legacyComponentFieldGroupsCache = new HashMap<>(); for (HstComponentConfiguration child : populate) { if (isEmpty(child.getComponentDefinition())) { // In case the component is a container item, this is legacy component instances support. For components // which are not container items, this is not legacy! // If component instance does not have a component definition reference, explicitly populate component parameters. ((HstComponentConfigurationService) child).populateLegacyComponentParameters(websiteClassLoader,legacyComponentParametersCache); ((HstComponentConfigurationService) child).populateLegacyFieldGroups(websiteClassLoader, legacyComponentFieldGroupsCache); ((HstComponentConfigurationService) child).populateComponentReferences(canonicalComponentConfigurations); } } }
we must do
public void populateComponentReferences(final Collection<HstComponentConfiguration> populate, final ClassLoader websiteClassLoader) { final Map<String, List<DynamicParameter>> legacyComponentParametersCache = new HashMap<>(); final Map<String, List<DynamicFieldGroup>> legacyComponentFieldGroupsCache = new HashMap<>(); for (HstComponentConfiguration child : populate) { if (isNotEmpty(child.getComponentDefinition())) { ((HstComponentConfigurationService) child).populateCatalogItemReference(availableContainerItems); } else { // In case the component is a container item, this is legacy component instances support. For components // which are not container items, this is not legacy! // If component instance does not have a component definition reference, explicitly populate component parameters. ((HstComponentConfigurationService) child).populateLegacyComponentParameters(websiteClassLoader,legacyComponentParametersCache); ((HstComponentConfigurationService) child).populateLegacyFieldGroups(websiteClassLoader, legacyComponentFieldGroupsCache); } } for (HstComponentConfiguration child : populate) { if (isEmpty(child.getComponentDefinition())) { // Only AFTER #populateCatalogItemReference, #populateLegacyComponentParameters and #populateLegacyFieldGroups // have been done it is allowed to invoke #populateComponentReferences : If we do it while not all // components have the 'component parameters' set, the result can be that referenced component items are // already merged/deep copied into another component while not having their 'dynamic component parameters' set, and // thus are not fully functional! ((HstComponentConfigurationService) child).populateComponentReferences(canonicalComponentConfigurations); } } }