diff --git a/CHANGELOG.md b/CHANGELOG.md index e5cca6c850..39721c863d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,9 +15,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com) - #3460 - Fixes issue where double parameters were not working for the parameterized include ### Changed - -- #3420 - Redirect Map Manager - enable Redirect Map Manager in AEM CS (would require a specific - not public yet - AEM - CS release version, TBA) +- #3385 Made nesting parameterized includes inside a multi-field (ignored resource types) possible ## 6.8.0 - 2024-10-17 diff --git a/bundle/src/main/java/com/adobe/acs/commons/granite/ui/components/impl/include/IncludeDecoratorFilterImpl.java b/bundle/src/main/java/com/adobe/acs/commons/granite/ui/components/impl/include/IncludeDecoratorFilterImpl.java index 6236b4f81a..3cd4254890 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/granite/ui/components/impl/include/IncludeDecoratorFilterImpl.java +++ b/bundle/src/main/java/com/adobe/acs/commons/granite/ui/components/impl/include/IncludeDecoratorFilterImpl.java @@ -104,30 +104,39 @@ public void doFilter(ServletRequest servletRequest, ServletResponse servletRespo ValueMap parameters = ValueMap.EMPTY; - if(servletRequest instanceof SlingHttpServletRequest){ - - SlingHttpServletRequest request = (SlingHttpServletRequest) servletRequest; - - Predicate typeCheckFn = (resourceType) -> request.getResourceResolver().isResourceType(request.getResource(), resourceType); - - if(typeCheckFn.test(RESOURCE_TYPE)){ - performFilter(request, servletResponse, chain, parameters); - return; - }else if(resourceTypesIgnoreChildren.stream().anyMatch(typeCheckFn)){ - boolean ignoreChildren = resourceTypesIgnoreChildren.stream().anyMatch(typeCheckFn); - if(ignoreChildren){ - request.setAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE, request.getResource().getResourceType()); - } - chain.doFilter(servletRequest, servletResponse); - if(ignoreChildren){ - request.removeAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE); - } - return; - } + if(!(servletRequest instanceof SlingHttpServletRequest)){ + chain.doFilter(servletRequest, servletResponse); + return; + } + SlingHttpServletRequest request = (SlingHttpServletRequest) servletRequest; + Predicate typeCheckFn = (resourceType) -> request.getResourceResolver().isResourceType(request.getResource(), resourceType); + + if(typeCheckFn.test(RESOURCE_TYPE)){ + Object ignoreResourceType = request.getAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE); + Object namespace = request.getAttribute(REQ_ATTR_NAMESPACE); + //if children ignore is active, but we have a new include, we de-activate the ignore children. + if(ignoreResourceType != null){ + request.removeAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE); + request.removeAttribute(REQ_ATTR_NAMESPACE); + } + performFilter(request, servletResponse, chain, parameters); + // we are now out of the nested include context. re-activate the ignore children if it was active before. + if(ignoreResourceType != null){ + request.setAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE, ignoreResourceType); + request.setAttribute(REQ_ATTR_NAMESPACE, namespace); + } + }else if(resourceTypesIgnoreChildren.stream().anyMatch(typeCheckFn)){ + boolean ignoreChildren = resourceTypesIgnoreChildren.stream().anyMatch(typeCheckFn); + if(ignoreChildren){ + request.setAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE, request.getResource().getResourceType()); + } + chain.doFilter(servletRequest, servletResponse); + if(ignoreChildren){ + request.removeAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE); + } } - chain.doFilter(servletRequest, servletResponse); } private void performFilter(SlingHttpServletRequest request, ServletResponse servletResponse, FilterChain chain, ValueMap parameters) throws IOException, ServletException { diff --git a/bundle/src/test/java/com/adobe/acs/commons/granite/ui/components/impl/include/IncludeDecoratorFilterImplTest.java b/bundle/src/test/java/com/adobe/acs/commons/granite/ui/components/impl/include/IncludeDecoratorFilterImplTest.java index 57c73c9d37..9ee0161109 100644 --- a/bundle/src/test/java/com/adobe/acs/commons/granite/ui/components/impl/include/IncludeDecoratorFilterImplTest.java +++ b/bundle/src/test/java/com/adobe/acs/commons/granite/ui/components/impl/include/IncludeDecoratorFilterImplTest.java @@ -37,13 +37,13 @@ import static com.adobe.acs.commons.granite.ui.components.impl.include.IncludeDecoratorFilterImpl.REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE; import static com.adobe.acs.commons.granite.ui.components.impl.include.IncludeDecoratorFilterImpl.REQ_ATTR_NAMESPACE; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; @RunWith(MockitoJUnitRunner.class) public class IncludeDecoratorFilterImplTest { + public static final String IGNORE_CHILDREN_RESOURCE_TYPE = "ignore/children/resource/type"; @Mock FilterChain filterChain; @@ -69,7 +69,7 @@ public Class annotationType() { @Override public String[] resourceTypesIgnoreChildren() { - return new String[]{"ignore/children/resource/type"}; + return new String[]{IGNORE_CHILDREN_RESOURCE_TYPE}; } }); @@ -98,7 +98,7 @@ public void test_disable_namespacing_children() throws IOException, ServletExcep Mockito.doAnswer(invocationOnMock -> { SlingHttpServletRequest captured = invocationOnMock.getArgument(0, SlingHttpServletRequest.class); - assertEquals("ignore/children/resource/type", captured.getAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE)); + assertEquals(IGNORE_CHILDREN_RESOURCE_TYPE, captured.getAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE)); return null; }).when(filterChain).doFilter(any(SlingHttpServletRequest.class), any(SlingHttpServletResponse.class)); @@ -109,6 +109,26 @@ public void test_disable_namespacing_children() throws IOException, ServletExcep assertTrue("namespace is removed after the filter is performed", context.request().getAttribute(REQ_ATTR_NAMESPACE) == null); } + @Test + public void test_ignored_types_reactivate() throws IOException, ServletException { + + Mockito.doAnswer(invocationOnMock -> { + + SlingHttpServletRequest captured = invocationOnMock.getArgument(0, SlingHttpServletRequest.class); + assertEquals("block1", captured.getAttribute(REQ_ATTR_NAMESPACE)); + assertNull(captured.getAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE)); + return null; + + }).when(filterChain).doFilter(any(SlingHttpServletRequest.class), any(SlingHttpServletResponse.class)); + + context.request().setAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE, IGNORE_CHILDREN_RESOURCE_TYPE); + context.request().setAttribute(REQ_ATTR_NAMESPACE, "nested"); + systemUnderTest.doFilter(context.request(), context.response(), filterChain); + + assertEquals("nested", context.request().getAttribute(REQ_ATTR_NAMESPACE)); + assertEquals(IGNORE_CHILDREN_RESOURCE_TYPE, context.request().getAttribute(REQ_ATTR_IGNORE_CHILDREN_RESOURCE_TYPE)); + } + @Test public void test_nested_include() throws IOException, ServletException {