diff --git a/changes.xml b/changes.xml index c1e786be..14ab95bf 100644 --- a/changes.xml +++ b/changes.xml @@ -23,6 +23,13 @@ xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 http://maven.apache.org/plugins/maven-changes-plugin/xsd/changes-1.0.0.xsd"> + + <rendition>/jcr:content/metadata, + don't generate additional metadata by Media Handler and read it directly from there instead. + ]]> + + Web-Optimized Image Delivery: Use relative (percentage) parameters for cropping instead of absolute parameters. This should create more reliable renditions esp. for original images in low resolution. diff --git a/src/main/java/io/wcm/handler/mediasource/dam/impl/metadata/RenditionMetadataGenerator.java b/src/main/java/io/wcm/handler/mediasource/dam/impl/metadata/RenditionMetadataGenerator.java index afdc1f30..5fb40ff9 100644 --- a/src/main/java/io/wcm/handler/mediasource/dam/impl/metadata/RenditionMetadataGenerator.java +++ b/src/main/java/io/wcm/handler/mediasource/dam/impl/metadata/RenditionMetadataGenerator.java @@ -268,7 +268,7 @@ public boolean renditionRemoved(String renditionPath) throws PersistenceExceptio // check if rendition still exist (or exists again) - in this case skip removing of renditions metadata Resource renditionResource = resourceResolver.getResource(renditionPath); - if (renditionResource != null) { + if (renditionResource != null && !hasAemRenditionMetadata(renditionResource.getPath())) { log.debug("Skip removing of metadata for existing rendition {}", renditionPath); return false; } diff --git a/src/test/java/io/wcm/handler/mediasource/dam/AssetRenditionTest.java b/src/test/java/io/wcm/handler/mediasource/dam/AssetRenditionTest.java index 086710f9..c5f84216 100644 --- a/src/test/java/io/wcm/handler/mediasource/dam/AssetRenditionTest.java +++ b/src/test/java/io/wcm/handler/mediasource/dam/AssetRenditionTest.java @@ -20,6 +20,9 @@ package io.wcm.handler.mediasource.dam; import static com.day.cq.commons.jcr.JcrConstants.JCR_CONTENT; +import static com.day.cq.dam.api.DamConstants.METADATA_FOLDER; +import static com.day.cq.dam.api.DamConstants.TIFF_IMAGELENGTH; +import static com.day.cq.dam.api.DamConstants.TIFF_IMAGEWIDTH; import static io.wcm.handler.mediasource.dam.impl.metadata.RenditionMetadataNameConstants.NN_RENDITIONS_METADATA; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -87,6 +90,16 @@ void testGetDimension() { assertEquals(new Dimension(10, 5), AssetRendition.getDimension(rendition)); } + @Test + void testGetDimension_WithAemRenditionMetadata() { + // add rendition metadata as provided by AEMaaCS asset compute (has higher priority) + context.create().resource(rendition, JCR_CONTENT + "/" + METADATA_FOLDER, + TIFF_IMAGEWIDTH, 100, TIFF_IMAGELENGTH, 50); + + assertEquals(new Dimension(16, 9), AssetRendition.getDimension(original)); + assertEquals(new Dimension(100, 50), AssetRendition.getDimension(rendition)); + } + @Test @SuppressWarnings("null") void testGetDimension_SVG() { @@ -115,6 +128,22 @@ void testGetDimensionWithoutRenditionsMetadata() throws PersistenceException { assertEquals(new Dimension(10, 5), AssetRendition.getDimension(rendition, true)); } + @Test + void testGetDimensionWithoutRenditionsMetadata_WithAemRenditionMetadata() throws PersistenceException { + // remove renditions metadata generated by DamRenditionMetadataService + Resource renditionsMetadata = AdaptTo.notNull(asset, Resource.class).getChild(JCR_CONTENT + "/" + NN_RENDITIONS_METADATA); + if (renditionsMetadata != null) { + context.resourceResolver().delete(renditionsMetadata); + } + + // add rendition metadata as provided by AEMaaCS asset compute + context.create().resource(rendition, JCR_CONTENT + "/" + METADATA_FOLDER, + TIFF_IMAGEWIDTH, 100, TIFF_IMAGELENGTH, 50); + + assertEquals(new Dimension(16, 9), AssetRendition.getDimension(original, true)); + assertEquals(new Dimension(100, 50), AssetRendition.getDimension(rendition, true)); + } + @Test void testIsThumbnailRendition() { assertTrue(AssetRendition.isThumbnailRendition(renditionByName("cq5dam.thumbnail.10.10.png"))); diff --git a/src/test/java/io/wcm/handler/mediasource/dam/impl/metadata/RenditionMetadataWorkflowProcessTest.java b/src/test/java/io/wcm/handler/mediasource/dam/impl/metadata/RenditionMetadataWorkflowProcessTest.java index 79df810d..713ec43a 100644 --- a/src/test/java/io/wcm/handler/mediasource/dam/impl/metadata/RenditionMetadataWorkflowProcessTest.java +++ b/src/test/java/io/wcm/handler/mediasource/dam/impl/metadata/RenditionMetadataWorkflowProcessTest.java @@ -19,8 +19,12 @@ */ package io.wcm.handler.mediasource.dam.impl.metadata; +import static com.day.cq.commons.jcr.JcrConstants.JCR_CONTENT; import static com.day.cq.commons.jcr.JcrConstants.JCR_LASTMODIFIED; import static com.day.cq.commons.jcr.JcrConstants.JCR_LAST_MODIFIED_BY; +import static com.day.cq.dam.api.DamConstants.METADATA_FOLDER; +import static com.day.cq.dam.api.DamConstants.TIFF_IMAGELENGTH; +import static com.day.cq.dam.api.DamConstants.TIFF_IMAGEWIDTH; import static io.wcm.handler.mediasource.dam.impl.metadata.RenditionMetadataNameConstants.NN_RENDITIONS_METADATA; import static io.wcm.handler.mediasource.dam.impl.metadata.RenditionMetadataNameConstants.PN_IMAGE_HEIGHT; import static io.wcm.handler.mediasource.dam.impl.metadata.RenditionMetadataNameConstants.PN_IMAGE_WIDTH; @@ -49,6 +53,7 @@ import com.adobe.granite.workflow.exec.WorkflowData; import com.adobe.granite.workflow.metadata.MetaDataMap; import com.day.cq.dam.api.Asset; +import com.day.cq.dam.api.Rendition; import io.wcm.handler.media.testcontext.AppAemContext; import io.wcm.testing.mock.aem.junit5.AemContext; @@ -96,11 +101,18 @@ void testWithAssetPayload() { context.create().assetRendition(asset, "rendition1.jpg", 12, 12, "image/jpg"); context.create().assetRendition(asset, "rendition2.png", 10, 5, "image/png"); context.create().assetRendition(asset, "rendition3.txt", "/sample.txt", "text/plain"); + + // prepare rendition with asset compute metadata + Rendition rendition4 = context.create().assetRendition(asset, "rendition4.jpg", 15, 15, "image/jpg"); + context.create().resource(rendition4, JCR_CONTENT + "/" + METADATA_FOLDER, + TIFF_IMAGEWIDTH, 15, TIFF_IMAGELENGTH, 15); + when(workflowData.getPayload()).thenReturn(asset.getPath()); assertNoRenditionMetadata(asset, "rendition1.jpg"); assertNoRenditionMetadata(asset, "rendition2.png"); assertNoRenditionMetadata(asset, "rendition3.txt"); + assertNoRenditionMetadata(asset, "rendition4.jpg"); underTest.execute(workItem, workflowSession, metaDataMap); @@ -108,6 +120,8 @@ void testWithAssetPayload() { assertRenditionMetadata(asset, "rendition2.png", 10, 5); // no metadata expected for non-image rendition assertNoRenditionMetadata(asset, "rendition3.txt"); + // no metadata expected when asset compute metadata is present + assertNoRenditionMetadata(asset, "rendition4.jpg"); } @Test @@ -150,26 +164,41 @@ void testWithWorkflowPackagePayload() { void testRemovalOfObsoleteRenditionMetadata() { Asset asset = context.create().asset("/content/dam/asset1.jpg", 10, 10, "image/jpeg"); context.create().assetRendition(asset, "rendition1.jpg", 12, 12, "image/jpg"); + + // prepare rendition with asset compute metadata + Rendition rendition4 = context.create().assetRendition(asset, "rendition4.jpg", 15, 15, "image/jpg"); + context.create().resource(rendition4, JCR_CONTENT + "/" + METADATA_FOLDER, + TIFF_IMAGEWIDTH, 15, TIFF_IMAGELENGTH, 15); + when(workflowData.getPayload()).thenReturn(asset.getPath()); // create some obsolete rendition metadata with no rendition attached - String obsoletePath = asset.getPath() + "/jcr:content/" + NN_RENDITIONS_METADATA + "/obsolete.jpg"; + String obsoletePath = asset.getPath() + "/" + JCR_CONTENT + "/" + NN_RENDITIONS_METADATA + "/obsolete.jpg"; context.create().resource(obsoletePath, PN_IMAGE_WIDTH, 20, PN_IMAGE_HEIGHT, 10, JCR_LASTMODIFIED, Calendar.getInstance(), JCR_LAST_MODIFIED_BY, "dummy"); + // create some obsolete rendition metadata for rendition with asset compute metadata + obsoletePath = asset.getPath() + "/" + JCR_CONTENT + "/" + NN_RENDITIONS_METADATA + "/rendition4.jpg"; + context.create().resource(obsoletePath, + PN_IMAGE_WIDTH, 15, + PN_IMAGE_HEIGHT, 15, + JCR_LASTMODIFIED, Calendar.getInstance(), + JCR_LAST_MODIFIED_BY, "dummy"); + assertNoRenditionMetadata(asset, "rendition1.jpg"); assertRenditionMetadata(asset, "obsolete.jpg", 20, 10); + assertRenditionMetadata(asset, "rendition4.jpg", 15, 15); underTest.execute(workItem, workflowSession, metaDataMap); assertRenditionMetadata(asset, "rendition1.jpg", 12, 12); assertNoRenditionMetadata(asset, "obsolete.jpg"); + assertNoRenditionMetadata(asset, "rendition4.jpg"); } - @SuppressWarnings("null") private void assertRenditionMetadata(Asset asset, String renditionName, int width, int height) { String renditionPath = asset.getPath() + "/jcr:content/" + NN_RENDITIONS_METADATA + "/" + renditionName; Resource metadata = context.resourceResolver().getResource(renditionPath);