adobe / aem-core-wcm-components

Standardized components to build websites with AEM.
https://docs.adobe.com/content/help/en/experience-manager-core-components/using/introduction.html
Apache License 2.0
733 stars 741 forks source link

[Container] Delegate fails for Container Component #1946

Open chintan97 opened 2 years ago

chintan97 commented 2 years ago

Bug Report

Current Behavior A custom container component extends container component by extending Java logic using Sling model delegation pattern. I created ContainerModel interface that extends Container interface from com.adobe.cq.wcm.core.components.models and implementing ContainerModel in ContainerModelImpl.class. I am using Model and Exporter annotations for exporting json through model.json.

@Model(
        adaptables = SlingHttpServletRequest.class,
        adapters = { ContainerModel.class, ComponentExporter.class},
        resourceType = ContainerModelImpl.RESOURCE_TYPE,
        defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
@Exporter(
        name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
        extensions = ExporterConstants.SLING_MODEL_EXTENSION
)

My RESOURCE_TYPE is set to 'mysite/components/container'. I am delegating Container as below.

@Self
@Via(type = ResourceSuperType.class)
private Container delegate;

Upon using delegate.getId() or any other methods to delegate to Container component, it ends up with NullPointerException after warning as below.

*WARN*  GET /content/mysite/us/en/mysitepage.model.json HTTP/1.1] org.apache.sling.models.impl.via.ResourceSuperTypeViaProvider Could not determine forced resource type for ResourceTypeForcingResourceWrapper, type=wcm/foundation/components/responsivegrid, path=/content/mysite/us/en/mysitepage/jcr:content/root, resource=[ResourceTypeForcingResourceWrapper, type=core/wcm/components/container/v1/container, path=/content/mysite/us/en/mysitepage/jcr:content/root, resource=[JcrNodeResource, type=mysite/components/container, superType=null, path=/content/mysite/us/en/mysitepage/jcr:content/root]] using via value .

Expected behavior/code In the above example delegate.getId() and other delegated methods should deliver data.

Environment

EDIT There is a way to get it implemented through LayoutContainer. However, that option does not return child data in model.json. For reproducing the issue, add text component underneath container component and check model.json output with custom sling model implemented through LayoutContainer and without any custom sling model. The one without custom sling model returns all child json data as well in model.json and that data is populated when custom sling model is used even with delegating methods.

vladbailescu commented 2 years ago

@chintan97 , unless your container component has a super type of one of the panel containers (accordion, carousel, tabs), this won't work as the super-type delegate will not resolve to an implementation.

As you noted in your edit, the LayoutContainer can be used when using sling:resourceSuperType="core/wcm/components/container/v1/container" and you can get the children through getExportedItems.

See https://aemcomponents.dev/content/core-components-examples/library/container/container.html for example: image

Blaris commented 1 year ago

What is the reason for not being able to customize the container object itself? Because it is re-used in panel components?

Our use case would be to customize the container component in order to force a specific rendition when using the background image, as right now, it pulls the raw source, which can be large.