diff --git a/CHANGELOG.md b/CHANGELOG.md index 7107c642b4..6b910f0f5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,12 +14,17 @@ The format is based on [Keep a Changelog](http://keepachangelog.com) - #3275 - CCVAR: Fixed Same Attribute not updating correctly. -## Added +### Added - #3333 - Use lodash embedded by ACS AEM Commons - #3323 - Add Provider Type Checker Plugin - #3338 - Prevent URL modification on dismiss +### Fixed + +- #3241 - Fix overlapping Service-Component header entries leading to double registration of components +- #3362 - Prevent System notification while exporting / updating experience fragment to Adobe Target + ## 6.6.0 - 2024-04-15 ## Added diff --git a/bundle/bnd.bnd b/bundle/bnd.bnd index 80f83c7b1d..703ee8a1d3 100644 --- a/bundle/bnd.bnd +++ b/bundle/bnd.bnd @@ -20,4 +20,10 @@ Import-Package: \ !org.bouncycastle.jce.*,\ !org.checkerframework.checker.nullness.qual,\ * +# support processing of legacy Felix SCR annotations through the felix.scr.bnd plugin, look at https://github.com/apache/felix/blob/trunk/tools/org.apache.felix.scr.bnd/src/main/java/org/apache/felix/scrplugin/bnd/SCRDescriptorBndPlugin.java#L60 +# paths require special handling: https://bnd.bndtools.org/chapters/820-instructions.html#file +-plugin.felixscr: org.apache.felix.scrplugin.bnd.SCRDescriptorBndPlugin;destdir="$(basedir)/target/classes";log=error +# also detect scr descriptors from bundle fragments (https://docs.osgi.org/specification/osgi.cmpn/8.0.0/service.component.html#d0e30931) +# this is not properly merged with entries from Felix SCR Bnd plugin, therefore later on patched with m-shade-p +Service-Component: OSGI-INF/*.xml -classpath: $(basedir)/target/aem-sdk-api-info/ \ No newline at end of file diff --git a/bundle/pom.xml b/bundle/pom.xml index 1a135b6b2d..6657fb390e 100644 --- a/bundle/pom.xml +++ b/bundle/pom.xml @@ -76,6 +76,15 @@ biz.aQute.bnd bnd-maven-plugin + + + + org.apache.felix + org.apache.felix.scr.bnd + 1.9.6 + + org.apache.maven.plugins @@ -243,6 +252,14 @@ + + + + + OSGI-INF/*.xml + + + diff --git a/bundle/src/main/java/com/adobe/acs/commons/models/injectors/impl/AemObjectInjector.java b/bundle/src/main/java/com/adobe/acs/commons/models/injectors/impl/AemObjectInjector.java index b85a17a808..69f1af77c2 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/models/injectors/impl/AemObjectInjector.java +++ b/bundle/src/main/java/com/adobe/acs/commons/models/injectors/impl/AemObjectInjector.java @@ -17,8 +17,11 @@ */ package com.adobe.acs.commons.models.injectors.impl; -import com.adobe.acs.commons.util.impl.ReflectionUtil; +import com.adobe.granite.asset.api.AssetManager; +import com.day.cq.commons.Externalizer; +import com.day.cq.search.QueryBuilder; import com.day.cq.tagging.TagManager; +import com.day.cq.wcm.api.policies.ContentPolicyManager; import org.apache.sling.xss.XSSAPI; import com.day.cq.wcm.api.Page; import com.day.cq.wcm.api.PageManager; @@ -36,27 +39,14 @@ import org.apache.sling.models.spi.DisposalCallbackRegistry; import org.apache.sling.models.spi.Injector; import org.osgi.framework.Constants; -import com.adobe.acs.commons.i18n.I18nProvider; import com.adobe.acs.commons.models.injectors.annotation.AemObject; -import com.day.cq.i18n.I18n; import javax.jcr.Session; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Type; import java.util.Locale; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getComponentContext; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getCurrentDesign; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getCurrentPage; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getCurrentStyle; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getDesigner; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getPageManager; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getResource; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getResourceDesign; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getResourcePage; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getResourceResolver; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getSession; -import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.getXssApi; +import static com.adobe.acs.commons.models.injectors.impl.InjectorUtils.*; import static com.adobe.acs.commons.util.impl.ReflectionUtil.getClassOrGenericParam; /** @@ -129,8 +119,6 @@ public Object getValue(Object adaptable, String name, Type declaredType, Annotat return getComponentContext(adaptable); case PAGE_MANAGER: return getPageManager(adaptable); - case TAG_MANAGER: - return getTagManager(adaptable); case CURRENT_PAGE: return getCurrentPage(adaptable); case RESOURCE_PAGE: @@ -149,19 +137,23 @@ public Object getValue(Object adaptable, String name, Type declaredType, Annotat return resolveXssApi(adaptable); case LOCALE: return resolveLocale(adaptable); + case TAG_MANAGER: + return adaptFromResourceResolver(adaptable, TagManager.class); + case ASSET_MANAGER: + return adaptFromResourceResolver(adaptable, AssetManager.class); + case ASSET_MANAGER_OLD: + return adaptFromResourceResolver(adaptable, com.day.cq.dam.api.AssetManager.class); + case QUERY_BUILDER: + return adaptFromResourceResolver(adaptable, QueryBuilder.class); + case CONTENT_POLICY_MANAGER: + return adaptFromResourceResolver(adaptable,ContentPolicyManager.class); + case EXTERNALIZER: + return adaptFromResourceResolver(adaptable, Externalizer.class); default: return null; } } - private TagManager getTagManager(Object adaptable) { - final ResourceResolver resourceResolver = getResourceResolver(adaptable); - - if(resourceResolver != null){ - return resourceResolver.adaptTo(TagManager.class); - } - return null; - } private Object resolveLocale(Object adaptable) { final Page page = getResourcePage(adaptable); @@ -204,6 +196,11 @@ private enum ObjectType { SESSION, LOCALE, TAG_MANAGER, + QUERY_BUILDER, + CONTENT_POLICY_MANAGER, + ASSET_MANAGER, + ASSET_MANAGER_OLD, + EXTERNALIZER, XSS_API; private static final String RESOURCE_PAGE_STRING = "resourcePage"; @@ -235,6 +232,16 @@ public static ObjectType fromClassAndName(Class classOrGenericParam, String n return ObjectType.XSS_API; } else if(classOrGenericParam.isAssignableFrom(Locale.class)){ return ObjectType.LOCALE; + } else if(classOrGenericParam.isAssignableFrom(AssetManager.class)){ + return ObjectType.ASSET_MANAGER; + } else if(classOrGenericParam.isAssignableFrom(com.day.cq.dam.api.AssetManager.class)){ + return ObjectType.ASSET_MANAGER_OLD; + } else if(classOrGenericParam.isAssignableFrom(QueryBuilder.class)){ + return ObjectType.QUERY_BUILDER; + } else if(classOrGenericParam.isAssignableFrom(ContentPolicyManager.class)){ + return ObjectType.CONTENT_POLICY_MANAGER; + } else if(classOrGenericParam.isAssignableFrom(Externalizer.class)){ + return ObjectType.EXTERNALIZER; } return null; diff --git a/bundle/src/main/java/com/adobe/acs/commons/models/injectors/impl/InjectorUtils.java b/bundle/src/main/java/com/adobe/acs/commons/models/injectors/impl/InjectorUtils.java index 034a95b9e3..1c5c17fe8e 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/models/injectors/impl/InjectorUtils.java +++ b/bundle/src/main/java/com/adobe/acs/commons/models/injectors/impl/InjectorUtils.java @@ -29,11 +29,9 @@ import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; -import org.apache.sling.api.scripting.SlingBindings; import org.apache.sling.xss.XSSAPI; import javax.jcr.Session; -import javax.servlet.ServletRequest; /** * Common methods for the injectors @@ -81,6 +79,13 @@ public static ContentPolicy getContentPolicy(Object adaptable){ return null; } + public static T adaptFromResourceResolver(Object adaptable, Class clazz){ + ResourceResolver resourceResolver = getResourceResolver(adaptable); + if(resourceResolver != null){ + return resourceResolver.adaptTo(clazz); + } + return null; + } public static ResourceResolver getResourceResolver(Object adaptable) { if (adaptable instanceof SlingHttpServletRequest) { return ((SlingHttpServletRequest) adaptable).getResourceResolver(); diff --git a/bundle/src/main/java/com/adobe/acs/commons/wcm/notifications/impl/SystemNotificationsImpl.java b/bundle/src/main/java/com/adobe/acs/commons/wcm/notifications/impl/SystemNotificationsImpl.java index 2c88942fc9..b4af0459b6 100644 --- a/bundle/src/main/java/com/adobe/acs/commons/wcm/notifications/impl/SystemNotificationsImpl.java +++ b/bundle/src/main/java/com/adobe/acs/commons/wcm/notifications/impl/SystemNotificationsImpl.java @@ -140,6 +140,11 @@ protected boolean accepts(final ServletRequest servletRequest, return false; } + // Do not apply when exporting / updating experience fragments to Adobe Target + if (StringUtils.contains(slingRequest.getQueryString(), "wcmmode=disabled")) { + return false; + } + return super.accepts(servletRequest, servletResponse); } diff --git a/bundle/src/test/java/com/adobe/acs/commons/indesign/dynamicdeckdynamo/services/impl/DynamicDeckServiceImplTest.java b/bundle/src/test/java/com/adobe/acs/commons/indesign/dynamicdeckdynamo/services/impl/DynamicDeckServiceImplTest.java new file mode 100644 index 0000000000..81563a820f --- /dev/null +++ b/bundle/src/test/java/com/adobe/acs/commons/indesign/dynamicdeckdynamo/services/impl/DynamicDeckServiceImplTest.java @@ -0,0 +1,98 @@ +/*- + * #%L + * ACS AEM Commons Bundle + * %% + * Copyright (C) 2013 - 2024 Adobe + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ +package com.adobe.acs.commons.indesign.dynamicdeckdynamo.services.impl; + +import com.adobe.acs.commons.indesign.dynamicdeckdynamo.exception.DynamicDeckDynamoException; +import com.adobe.acs.commons.indesign.dynamicdeckdynamo.services.DynamicDeckConfigurationService; +import com.adobe.acs.commons.indesign.dynamicdeckdynamo.services.XMLGeneratorService; +import io.wcm.testing.mock.aem.junit5.AemContext; +import io.wcm.testing.mock.aem.junit5.AemContextExtension; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.resource.ResourceResolver; +import org.apache.sling.event.jobs.JobManager; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.assertThrows; + +@ExtendWith({AemContextExtension.class, MockitoExtension.class}) +class DynamicDeckServiceImplTest { + + private final AemContext context = new AemContext(); + + private ResourceResolver resourceResolver; + + @Mock + private DynamicDeckConfigurationService configurationService; + + @Mock + private XMLGeneratorService xmlGeneratorService; + + @Mock + private JobManager jobManager; + + @InjectMocks + private DynamicDeckServiceImpl dynamicDeckService; + + @BeforeEach + void setUp() { + context.load().json("/com/adobe/acs/commons/dynamicdeckdynamo/dynamicdeckResources.json", "/content"); + resourceResolver = context.resourceResolver(); + + context.registerService(DynamicDeckConfigurationService.class, configurationService); + context.registerService(XMLGeneratorService.class, xmlGeneratorService); + context.registerService(JobManager.class, jobManager); + dynamicDeckService = context.registerInjectActivateService(new DynamicDeckServiceImpl()); + } + + @Test + void shouldThrowExceptionInCaseOfTemplateAbsents() { + context.request().setPathInfo("/content/some/en/en/some.json"); + List assetResourceList = Collections.singletonList(Mockito.mock(Resource.class)); + Resource masterAssetResource = resourceResolver.getResource("/content/dam/dynamic-deck-dynamo/master-assets"); + Resource templateFolderResource = resourceResolver.getResource("/content/dam/dynamic-deck-dynamo/templates/simple-template-2018"); + Resource destinationFolderResource = resourceResolver.getResource("/content/dam/dynamic-deck-dynamo/destination"); + + assertThrows(DynamicDeckDynamoException.class, () -> + dynamicDeckService.createDeck("deckTitle", masterAssetResource, assetResourceList, templateFolderResource, + destinationFolderResource, resourceResolver)); + } + + @Test + void shouldThrowExceptionInCaseOfDamAssetResourceNull() { + context.request().setPathInfo("/content/some/en/en/some.json"); + List assetResourceList = Collections.singletonList(Mockito.mock(Resource.class)); + Resource masterAssetResource = resourceResolver.getResource("/content/dam/dynamic-deck-dynamo/master-assets"); + Resource templateFolderResource = resourceResolver.getResource("/content/dam/dynamic-deck-dynamo/templates/simple-template-2019"); + Resource destinationFolderResource = resourceResolver.getResource("/content/dam/dynamic-deck-dynamo/destination"); + + assertThrows(DynamicDeckDynamoException.class, () -> + dynamicDeckService.createDeck("deckTitle", masterAssetResource, assetResourceList, templateFolderResource, + destinationFolderResource, resourceResolver)); + } +} \ No newline at end of file diff --git a/bundle/src/test/java/com/adobe/acs/commons/models/injectors/impl/AemObjectInjectorTest.java b/bundle/src/test/java/com/adobe/acs/commons/models/injectors/impl/AemObjectInjectorTest.java index a4081795f8..8d70e73b2d 100644 --- a/bundle/src/test/java/com/adobe/acs/commons/models/injectors/impl/AemObjectInjectorTest.java +++ b/bundle/src/test/java/com/adobe/acs/commons/models/injectors/impl/AemObjectInjectorTest.java @@ -28,7 +28,11 @@ import javax.inject.Inject; import javax.jcr.Session; +import com.adobe.granite.asset.api.AssetManager; +import com.day.cq.commons.Externalizer; +import com.day.cq.search.QueryBuilder; import com.day.cq.tagging.TagManager; +import com.day.cq.wcm.api.policies.ContentPolicyManager; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; @@ -62,6 +66,21 @@ public class AemObjectInjectorTest { @Mock private TagManager tagManager; + @Mock + private AssetManager assetManager; + + @Mock + private com.day.cq.dam.api.AssetManager oldAssetManager; + + @Mock + private QueryBuilder queryBuilder; + + @Mock + private ContentPolicyManager contentPolicyManager; + + @Mock + private Externalizer externalizer; + @Mock private Page resourcePage; @@ -80,6 +99,11 @@ public final void setUp() throws Exception { context.registerService(PageManager.class,pageManager); context.registerService(Designer.class,designer); context.registerService(TagManager.class, tagManager); + context.registerService(AssetManager.class, assetManager); + context.registerService(com.day.cq.dam.api.AssetManager.class, oldAssetManager); + context.registerService(QueryBuilder.class, queryBuilder); + context.registerService(ContentPolicyManager.class, contentPolicyManager); + context.registerService(Externalizer.class, externalizer); context.addModelsForClasses(TestResourceModel.class); @@ -102,6 +126,12 @@ public final void testResourceInjection() { assertNotNull(testResourceModel.getTagManager()); assertNotNull(testResourceModel.getDesigner()); assertNotNull(testResourceModel.getLocale()); + assertNotNull(testResourceModel.getAssetManager()); + assertNotNull(testResourceModel.getOldAssetManager()); + assertNotNull(testResourceModel.getExternalizer()); + assertNotNull(testResourceModel.getContentPolicyManager()); + assertNotNull(testResourceModel.getQueryBuilder()); + assertEquals(Locale.ENGLISH, testResourceModel.getLocale()); // TODO: Tests for the remaining injectable objects @@ -120,6 +150,11 @@ public final void testSlingHttpServiceRequestInjection() { assertNotNull(testResourceModel.getTagManager()); assertNotNull(testResourceModel.getDesigner()); assertNotNull(testResourceModel.getLocale()); + assertNotNull(testResourceModel.getAssetManager()); + assertNotNull(testResourceModel.getOldAssetManager()); + assertNotNull(testResourceModel.getExternalizer()); + assertNotNull(testResourceModel.getContentPolicyManager()); + assertNotNull(testResourceModel.getQueryBuilder()); assertEquals(Locale.ENGLISH, testResourceModel.getLocale()); // TODO: Tests for the remaining injectable objects } @@ -163,6 +198,21 @@ public static class TestResourceModel { @Inject @Optional private Locale locale; + @Inject @Optional + private AssetManager assetManager; + + @Inject @Optional + private com.day.cq.dam.api.AssetManager oldAssetManager; + + @Inject @Optional + private Externalizer externalizer; + + @Inject @Optional + private QueryBuilder queryBuilder; + + @Inject @Optional + private ContentPolicyManager contentPolicyManager; + public Resource getResource() { return resource; } @@ -218,5 +268,25 @@ public XSSAPI getXssApi() { public Locale getLocale() { return locale; } + + public AssetManager getAssetManager() { + return assetManager; + } + + public com.day.cq.dam.api.AssetManager getOldAssetManager() { + return oldAssetManager; + } + + public Externalizer getExternalizer() { + return externalizer; + } + + public QueryBuilder getQueryBuilder() { + return queryBuilder; + } + + public ContentPolicyManager getContentPolicyManager() { + return contentPolicyManager; + } } } diff --git a/bundle/src/test/resources/com/adobe/acs/commons/dynamicdeckdynamo/dynamicdeckResources.json b/bundle/src/test/resources/com/adobe/acs/commons/dynamicdeckdynamo/dynamicdeckResources.json index 0d383a8afd..8164a28b03 100644 --- a/bundle/src/test/resources/com/adobe/acs/commons/dynamicdeckdynamo/dynamicdeckResources.json +++ b/bundle/src/test/resources/com/adobe/acs/commons/dynamicdeckdynamo/dynamicdeckResources.json @@ -7,6 +7,33 @@ "jcr:primaryType": "sling:Folder", "simple-template-2018": { "jcr:primaryType": "sling:Folder" + }, + "simple-template-2019": { + "jcr:primaryType": "sling:Folder", + "asset.indd": { + "jcr:primaryType": "dam:Asset" + }, + "asset.xml": { + "jcr:primaryType": "dam:Asset", + "jcr:content": { + "renditions": { + "original.dir": { + "jcr:primaryType": "nt:file", + "jcr:content": { + } + }, + "original": { + "jcr:primaryType": "nt:file", + "jcr:content": { + "jcr:primaryType": "oak:Resource", + "jcr:mimeType": "application/x-indesign", + "jcr:data": { + } + } + } + } + } + } } }, "master-assets": { diff --git a/pom.xml b/pom.xml index 63bfbf042e..6560d44974 100644 --- a/pom.xml +++ b/pom.xml @@ -244,15 +244,10 @@ Bundle-DocURL: https://adobe-consulting-services.github.io/acs-aem-commons/ # enable plugins (https://bnd.bndtools.org/instructions/plugin.html) -plugin.models: org.apache.sling.bnd.models.ModelsScannerPlugin -plugin.cac: org.apache.sling.caconfig.bndplugin.ConfigurationClassScannerPlugin -# support processing of legacy Felix SCR annotations through the felix.scr.bnd plugin, look at https://github.com/apache/felix/blob/trunk/tools/org.apache.felix.scr.bnd/src/main/java/org/apache/felix/scrplugin/bnd/SCRDescriptorBndPlugin.java#L60 -# paths require special handling: https://bnd.bndtools.org/chapters/820-instructions.html#file --plugin.felixscr: org.apache.felix.scrplugin.bnd.SCRDescriptorBndPlugin;destdir="$(basedir)/target/classes";log=error -plugin.providertype:org.apache.sling.providertype.bndplugin.ProviderTypeScanner # support only DS 1.4 (https://github.com/bndtools/bnd/pull/3121/files) -dsannotations-options: version;maximum=1.4.0,inherit -metatypeannotations-options: version;maximum=1.4.0 -# also detect scr descriptors from bundle fragments (https://docs.osgi.org/specification/osgi.cmpn/8.0.0/service.component.html#d0e30931) -Service-Component: OSGI-INF/*.xml ]]> @@ -270,13 +265,6 @@ Service-Component: OSGI-INF/*.xml org.apache.sling.caconfig.bnd-plugin 1.0.2 - - - org.apache.felix - org.apache.felix.scr.bnd - 1.9.6 - org.apache.sling