Expand my Community achievements bar.

Don’t miss the AEM Skill Exchange in SF on Nov 14—hear from industry leaders, learn best practices, and enhance your AEM strategy with practical tips.

SlingModel @ChildResource annotation not using the defaultInjectionStrategy defined at model class level

Avatar

Level 1

I have a sling model in which I am injecting a multifield resources using @ChildResource annotation. This works fine when the multifield has been populated but fails if its not. I have defined the defaultInjectionStrategy as OPTIONAL at class level but its not used, I even tried @Optional annotation but it also doesn't work. However if I provide optional=true to the @ChildResource annotation, the injection works fine in case of absent multifield nodes. 

I am using AEM 6.1 SP1 for running this model. As per the documentation for @ChildResource the optional's use is deprecated, What can I do not use the optional param but use injection strategy to fix the issue. Here is my code - 

@Model(adaptables = SlingHttpServletRequest.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL) public class HeaderSlingModel { /** * Inject property via resource, named fileReference. */ @Inject @Via("resource") @Named("fileReference") private String qrCodeImage; /** * Inject property via resource, helpCustomerService. */ @Inject @Via("resource") private String helpCustomerService; /** * Inject property via resource, helpDeltaAssist. */ @Inject @Via("resource") private String helpDeltaAssist; /** * Inject property via resource, helpReservationOffice. */ @Inject @Via("resource") private String helpReservationOffice; /** * Inject property via resource, logoLink. */ @Inject @Via("resource") private String logoLink; /** * Inject property via resource, navDepth. */ @Inject @Via("resource") private String navDepth; /** * Inject property via resource, navRootPath. */ @Inject @Via("resource") private String navRootPath; /** * Inject resource list under node quickLink. */ @ChildResource(optional = true) @Optional() private List<Resource> quickLink; /** * Inject resource list under node alert. */ @ChildResource(optional = true) @Optional private List<Resource> alert; /** * Inject resource. */ @Inject private Resource resource; /** * Inject currentPage. */ @Inject private Page currentPage; /** * List of quicklinks. */ private List<QuickLink> quickLinks; /** * List of alerts. */ private List<Alert> alerts; /** * navigation items. */ private List<Navigation> navigation; /** * Processing method. */ @PostConstruct public final void init() { if (null != quickLink && !quickLink.isEmpty()) { quickLinks = quickLink.stream() .map(qLink -> qLink.adaptTo(QuickLink.class)) .collect(Collectors.toList()); } if (null != alert && !alert.isEmpty()) { alerts = alert.stream() .map(entry -> entry.adaptTo(Alert.class)) .collect(Collectors.toList()); } buildNavigation(); } /** * Build the navigation elements. */ private void buildNavigation() { final Resource navRootResource = resource.getResourceResolver().getResource(navRootPath); if (null == navRootResource || ResourceUtil.isNonExistingResource(navRootResource)) { throw new IllegalArgumentException(format("Could not get resource for navigation root at path %s", navRootPath)); } final Page navRootPage = navRootResource.adaptTo(Page.class); if (null == navRootPage) { throw new IllegalArgumentException(format("Could not get page for navigation root at path %s", navRootPath)); } final Iterable<Page> children = () -> navRootPage.listChildren(); final Stream<Page> navigationStream = StreamSupport.stream(children.spliterator(), false); navigation = navigationStream.filter(navPage -> !navPage.isHideInNav()) .map(navPage -> new Navigation(currentPage, navPage, Long.parseLong(navDepth) - 1)) .collect(Collectors.toList()); } /** * Get the image path for the QR Code. * * @return path to image. */ public final String getQrCodeImage() { return qrCodeImage; } /** * Get property helpCustomerService number. * * @return helpCustomerService number. */ public final String getHelpCustomerService() { return helpCustomerService; } /** * Get helpDeltaAssist handler, twitter handle. * * @return helpDeltaAssist handle. */ public final String getHelpDeltaAssist() { return helpDeltaAssist; } /** * Get reservation office number. * * @return reservation ofc number. */ public final String getHelpReservationOffice() { return helpReservationOffice; } /** * Get logo redirect link. If publish instance return transformed URL. * * @return logo link. */ public final String getLogoLink() { return logoLink; } /** * Get dept/ number of levels for navigation. * * @return nav depth. */ public final String getNavDepth() { return navDepth; } /** * Get root path for the navigation. * * @return root path. */ public final String getNavRootPath() { return navRootPath; } /** * Getter QuickLink. * * @return List of @Link Quicklink. */ public final List<QuickLink> getQuickLinks() { return quickLinks; } /** * Getter alerts. * * @return alerts list. */ public final List<Alert> getAlerts() { return alerts; } /** * Getter Navigation items. * * @return list of navigation items. */ public final List<Navigation> getNavigation() { return navigation; } }
3 Replies

Avatar

Level 1

attached snapshot of the node structure

Avatar

Level 10

IN the Sling Model docs (https://sling.apache.org/documentation/bundles/models.html) - it states: 

Those annotations replace @Via@Filter@Named@Optional@Required@Source and @Inject. Instead of using the deprecated annotation element optional you should rather use injectionStrategy with the values DEFAULTOPTIONAL or REQUIRED (see alsoSLING-4155). @Default may still be used in addition to the injector-specific annotation to set default values. All elements given above are optional.

 

Have you tried what is suggested? 

Avatar

Level 1

Hi Scott,

I did, compilation fails as it cant find the Enum InjectionStrategy.

[ERROR] symbol:   method injectionStrategy()
[ERROR] location: @interface org.apache.sling.models.annotations.injectorspecific.ChildResource
[ERROR] ............../ui/slingmodel/components/global/header/HeaderSlingModel.java:[91,40] cannot find symbol
[ERROR] symbol:   variable InjectionStrategy

This is what I did - 

@ChildResource(injectionStrategy = InjectionStrategy.OPTIONAL)

Its because the InjectionStrategy enum was introduced in Sling Model API v 1.2.0, where as 6.1 SP1 is on v 1.1.0 so we either update the sling model api or use the deprecated option.

Thanks for the help!!