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
737 stars 745 forks source link

lombok delegation pattern not returning all methods in model.json(Json Exporter) for Tabs component #1586

Open cqsapient opened 3 years ago

cqsapient commented 3 years ago
package com.test.internal.models;

import com.adobe.cq.export.json.ComponentExporter;
import com.adobe.cq.export.json.ContainerExporter;
import com.adobe.cq.export.json.ExporterConstants;
import com.adobe.cq.wcm.core.components.internal.models.v1.TabsImpl;
import com.adobe.cq.wcm.core.components.models.Component;
import com.adobe.cq.wcm.core.components.models.Container;
import com.adobe.cq.wcm.core.components.models.ListItem;
import com.adobe.cq.wcm.core.components.models.Tabs;
import com.adobe.cq.wcm.core.components.models.datalayer.ComponentData;
import lombok.experimental.Delegate;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.models.annotations.*;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
import org.apache.sling.models.annotations.via.ResourceSuperType;

import javax.inject.Inject;
import java.util.List;

@Model(
        adaptables = {Resource.class, SlingHttpServletRequest.class},
        adapters = {Tabs.class,ComponentExporter.class, ContainerExporter.class, Container.class},
        resourceType = Accordion.RESOURCE_TYPE
)
@Exporter(
        name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
        extensions = ExporterConstants.SLING_MODEL_EXTENSION
)
public class Accordion implements Tabs {

    static final String RESOURCE_TYPE = "test/components/accordion";

    @Self @Via(type = ResourceSuperType.class)
    @Delegate(types = Tabs.class,excludes = DelegationExclusion.class)
    private com.adobe.cq.wcm.core.components.models.Tabs delegate;

    @Override
    public String getActiveItem() {

        return "test";
    }

    private interface DelegationExclusion { // Here we define the methods we want to override
        String getActiveItem();
    }

}

above is the sling model I wrote. I am using delegation pattern using lombok - hoping all getter method of parent super type will be exported in model.json

I am trying to override the getActiveItem method for Tabs component. But it's not populating the items properly - they are empty in the json - just returning the overridden method in the json -

"accordion": {
"items": [],
"activeItem": "test",
":itemsOrder": [],
":items": {}
}

when I remove this Sling model from the bundle - the OOTB sling model comes into picture and returns everything -

"accordion": {
"id": "accordion-5248ba2449",
"activeItem": "item_1",
":itemsOrder": [
"item_1",
"item_2",
"ctabutton"
],
":items": {
"item_1": {
"gridClassNames": "aem-Grid aem-Grid--12 aem-Grid--default--12",
"columnClassNames": {
"backbutton": "aem-GridColumn aem-GridColumn--default--12"
},
"columnCount": 12,
"allowedComponents": {
"components": [],
"applicable": false
},
":itemsOrder": [
"backbutton"
],
":items": {
"backbutton": {
":type": "test/components/backbutton",
"btnLabel": "View More"
}
},
":type": "test/components/container",
"cq:panelTitle": "FAQ 1"
},
"item_2": {
"gridClassNames": "aem-Grid aem-Grid--12 aem-Grid--default--12",
"columnClassNames": {},
"columnCount": 12,
"allowedComponents": {
"components": [],
"applicable": false
},
":itemsOrder": [],
":items": {},
":type": "test/components/container",
"cq:panelTitle": "FAQ 2"
},
"ctabutton": {
":type": "test/components/ctabutton",
"btnAlignment": "left",
"lightboxId": "sadasdasdasdasdas",
"btnType": "cta-primary",
"btnLabel": "View More",
"openLightbox": "true",
"cq:panelTitle": null
}
},
":type": "test/components/accordion"
}

can someone please let me know what is missing in sling model that it's not returning the items properly

vladbailescu commented 3 years ago

I don't have experience with Lombok but shouldn't @Delegate(types = Tabs.class, excludes = DelegationExclusion.class) be @Delegate(types = {Tabs.class, Container.class}, excludes = DelegationExclusion.class), to ensure the methods from the Container interfaces are also delegated?

I see @Delegate is deprecated and moved to experimental (https://projectlombok.org/features/experimental/Delegate)