Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parameterized renditions #1029

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion all/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<groupId>com.adobe.aem.commons</groupId>
<artifactId>assetshare</artifactId>
<version>3.8.1-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion core.cloud/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<parent>
<groupId>com.adobe.aem.commons</groupId>
<artifactId>assetshare</artifactId>
<version>3.8.1-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.adobe.aem.commons.assetshare.components.actions.download.impl.DownloadImpl;
import com.adobe.aem.commons.assetshare.content.AssetModel;
import com.adobe.aem.commons.assetshare.content.renditions.AssetRendition;
import com.adobe.aem.commons.assetshare.content.renditions.AssetRenditionParameters;
import com.adobe.aem.commons.assetshare.content.renditions.AssetRenditions;
import com.adobe.aem.commons.assetshare.content.renditions.download.DownloadExtensionResolver;
import com.adobe.aem.commons.assetshare.content.renditions.download.async.DownloadArchiveNamer;
Expand All @@ -30,6 +31,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.commons.mime.MimeTypeService;
import org.osgi.service.component.annotations.*;

Expand Down Expand Up @@ -57,7 +59,9 @@ public class ExpressionDownloadArchiveNamer implements DownloadArchiveNamer {
public String getArchiveFilePath(final AssetModel assetModel, final AssetRendition assetRendition, final DownloadTarget downloadTarget) {
final ResourceResolver resourceResolver = assetModel.getResource().getResourceResolver();
final Resource downloadComponentResource = resourceResolver.getResource(downloadTarget.getParameter(DownloadTargetParameters.DOWNLOAD_COMPONENT_PATH.toString(), String.class));
final String renditionName = downloadTarget.getParameter(DownloadTargetParameters.RENDITION_NAME.toString(), String.class);
final String renditionNameWithParameters = downloadTarget.getParameter(DownloadTargetParameters.RENDITION_NAME.toString(), String.class);
final ValueMap renditionParameters = AssetRenditionParameters.getParameters(renditionNameWithParameters);
final String renditionName = renditionParameters.get(AssetRenditionParameters.PARAMETER_RENDITION_DISPLAY_NAME, AssetRenditionParameters.getRenditionName(renditionNameWithParameters));

if (downloadComponentResource == null || renditionName == null) {
return null;
Expand All @@ -82,7 +86,7 @@ public String getArchiveFilePath(final AssetModel assetModel, final AssetRenditi
final String expression = downloadComponentResource.getValueMap().get(DownloadImpl.PN_ARCHIVE_FILE_NAME_EXPRESSION, DownloadImpl.DEFAULT_ARCHIVE_FILE_NAME_EXPRESSION);

if (StringUtils.isNotBlank(expression)) {
return assetRenditions.evaluateExpression(assetModel, renditionName, expression) + StringUtils.defaultIfBlank(extension, "");
return assetRenditions.evaluateExpression(assetModel, renditionName, expression, AssetRenditionParameters.getParameters(renditionNameWithParameters)) + StringUtils.defaultIfBlank(extension, "");
} else {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,23 @@ public class NamedRenditionDownloadTargetProcessor implements DownloadTargetProc
public Collection<DownloadFile> processTarget(DownloadTarget target, ResourceResolver resourceResolver) throws DownloadException {
final List<DownloadFile> downloadFiles = new ArrayList<>();

log.error("!!!!! processTarget !!!!!");

final String path = target.getParameter(DownloadTargetParameters.ASSET_PATH.toString(), String.class);
final String renditionName = target.getParameter(DownloadTargetParameters.RENDITION_NAME.toString(), String.class);
final String renditionNameWithParameters = target.getParameter(DownloadTargetParameters.RENDITION_NAME.toString(), String.class);
final String archiveName = target.getParameter(DownloadTargetParameters.ARCHIVE_NAME.toString(), String.class);
final String userId = target.getParameter(DownloadTargetParameters.USER_ID.toString(), String.class);

final Resource resource = resourceResolver.getResource(path);
final AssetModel assetModel = resource.adaptTo(AssetModel.class);
final AssetRenditionParameters assetRenditionParameters = new AssetRenditionParameters(assetModel, renditionName);

final AssetRenditionParameters assetRenditionParameters = new AssetRenditionParameters(assetModel, renditionNameWithParameters);

assetRenditionParameters.setOtherProperty("userId", userId);

for (final AssetRenditionDispatcher assetRenditionDispatcher : assetRenditionDispatchers.getAssetRenditionDispatchers()) {

if (assetRenditionDispatcher.accepts(assetModel, renditionName)) {
if (assetRenditionDispatcher.accepts(assetModel, assetRenditionParameters.getRenditionName())) {
if (log.isDebugEnabled()) {
log.debug("Setting DownloadTarget for [ {} ] using AssetRenditionDispatcher [ {} ]", assetModel.getPath(), assetRenditionDispatcher.getName());
}
Expand All @@ -108,6 +112,8 @@ public Collection<DownloadFile> processTarget(DownloadTarget target, ResourceRes
log.debug("Obtained AssetRendition [ {} ] details for [ {} ]", assetRendition.getBinaryUri(), assetModel.getPath());
}

log.error(">>>> archive file path: {}", downloadArchiveNamer.getArchiveFilePath(assetModel, assetRendition, target));

downloadFileParameters.put(PARAM_ARCHIVE_PATH, downloadArchiveNamer.getArchiveFilePath(assetModel, assetRendition, target));
downloadFiles.add(apiFactory.createDownloadFile(assetRendition.getSize(),
assetRendition.getBinaryUri(),
Expand All @@ -129,7 +135,7 @@ public Collection<DownloadFile> processTarget(DownloadTarget target, ResourceRes

} else {
if (log.isDebugEnabled()) {
log.debug("assetRenditionDispatcher [ {} ] does not accept AssetModel [ {} ] and renditionName [ {} ]", assetRenditionDispatcher.getClass().getName(), assetModel.getPath(), renditionName);
log.debug("assetRenditionDispatcher [ {} ] does not accept AssetModel [ {} ] and renditionName [ {} ]", assetRenditionDispatcher.getClass().getName(), assetModel.getPath(), renditionNameWithParameters);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ public void dispatch(SlingHttpServletRequest request, SlingHttpServletResponse r

final String expression = mappings.get(parameters.getRenditionName());
// Special case where we use a limited set of expression evaluation since Asset Delivery is limited in its configurations
final String renditionRedirect = getDeliveryURL(evaluateExpression(request, expression), parameters.getAsset());
final String renditionRedirect = getDeliveryURL(evaluateExpression(request, expression, parameters), parameters.getAsset());

if (StringUtils.isNotBlank(renditionRedirect)) {
if (log.isDebugEnabled()) {
Expand Down Expand Up @@ -183,7 +183,7 @@ public void dispatch(SlingHttpServletRequest request, SlingHttpServletResponse r
public AssetRendition getRendition(AssetModel assetModel, AssetRenditionParameters parameters) {
final String expression = mappings.get(parameters.getRenditionName());
// Special case where we use a limited set of expression evaluation since Asset Delivery is limited in its configurations
final String renditionRedirect = getDeliveryURL(evaluateExpression(parameters.getAsset(), expression), parameters.getAsset());
final String renditionRedirect = getDeliveryURL(evaluateExpression(parameters.getAsset(), expression, parameters), parameters.getAsset());

if (StringUtils.isNotBlank(renditionRedirect)) {
try {
Expand Down Expand Up @@ -235,17 +235,17 @@ public boolean accepts(AssetModel assetModel, String renditionName) {
return Arrays.stream(ACCEPTED_MIME_TYPES).anyMatch(regex -> assetFormat.matches(regex));
}

protected String evaluateExpression(final SlingHttpServletRequest request, String expression) {
final
Asset asset = request.getResource().adaptTo(Asset.class);
return evaluateExpression(asset, expression);
protected String evaluateExpression(final SlingHttpServletRequest request, String expression, AssetRenditionParameters assetRenditionParameters) {
final Asset asset = request.getResource().adaptTo(Asset.class);
return evaluateExpression(asset, expression, assetRenditionParameters);
}

protected String evaluateExpression(final Asset asset, String expression) {
protected String evaluateExpression(final Asset asset, String expression, AssetRenditionParameters assetRenditionParameters) {
final AssetModel assetModel = modelFactory.createModel(asset.adaptTo(Resource.class), AssetModel.class);

expression = expressionEvaluator.evaluateAssetExpression(expression, assetModel);
expression = expressionEvaluator.evaluateProperties(expression, assetModel);
expression = expressionEvaluator.evaluateParameterExpression(expression, assetRenditionParameters.getParameters());

return expression;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ public void getAssetRenditionGroups() {
//assertEquals("rendition-2-2", actual.get(1).getItems().get(1).getValue());
}

private class IsSameResourceByPath implements ArgumentMatcher<Resource> {
private static class IsSameResourceByPath implements ArgumentMatcher<Resource> {
private final String path;

public IsSameResourceByPath(String path) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,31 @@ public void getArchiveFilePath() {
assertEquals("test/test (Test Web).png", namer.getArchiveFilePath(assetModel, assetRendition, downloadTarget));
}


@Test
public void getArchiveFilePath_renditionNameWithParameters() {
ctx.registerInjectActivateService(new ExpressionDownloadArchiveNamer());

DownloadArchiveNamer namer = ctx.getService(DownloadArchiveNamer.class);

AssetModel assetModel = modelFactory.getModelFromWrappedRequest(ctx.request(), ctx.resourceResolver().getResource("/content/dam/test.png"), AssetModel.class);
AssetRendition assetRendition = new AssetRendition("/content/dam/test.png/jcr:renditions/cq5dam.web.1280.1280.png", 10l, "image/png");

assertEquals("test/test (Test Web).png", namer.getArchiveFilePath(assetModel, assetRendition, downloadTarget));
}

@Test
public void getArchiveFilePath_withDownloadExtensionResolver() {
ctx.registerService(DownloadExtensionResolver.class, new TestDownloadExtensionResolver());
when(downloadTarget.getParameter(DownloadTargetParameters.RENDITION_NAME.toString(), String.class)).thenReturn("Test web with parameters?param.pattern=.*web.*&width=100px");

ctx.registerInjectActivateService(new ExpressionDownloadArchiveNamer());

DownloadArchiveNamer namer = ctx.getService(DownloadArchiveNamer.class);

AssetModel assetModel = modelFactory.getModelFromWrappedRequest(ctx.request(), ctx.resourceResolver().getResource("/content/dam/test.png"), AssetModel.class);
AssetRendition assetRendition = new AssetRendition("/content/dam/test.png/jcr:renditions/cq5dam.web.1280.1280.png", 10l, "image/png");

assertEquals("test/test (Test Web).custom", namer.getArchiveFilePath(assetModel, assetRendition, downloadTarget));
assertEquals("test/test (Test web with parameters).png", namer.getArchiveFilePath(assetModel, assetRendition, downloadTarget));
}


Expand Down
7 changes: 6 additions & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<parent>
<groupId>com.adobe.aem.commons</groupId>
<artifactId>assetshare</artifactId>
<version>3.8.1-SNAPSHOT</version>
<version>4.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down Expand Up @@ -132,6 +132,11 @@ com.adobe.aem.commons.assetshare.util.impl
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<logback.configurationFile>${project.build.testOutputDirectory}/logback-test.xml</logback.configurationFile>
</systemPropertyVariables>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public final List<String> getAllowedValuesFromQueryParameter(final SlingHttpServ

if (requestParameters != null) {
return Arrays.stream(requestParameters).map(RequestParameter::getString)
.filter(renditionName -> allowedValues.length == 0 || ArrayUtils.contains(allowedValues, renditionName))
.filter(renditionName -> allowedValues.length == 0 || ArrayUtils.contains(allowedValues, StringUtils.substringBefore(renditionName, "?")))
.distinct()
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;

/**
Expand All @@ -47,12 +49,13 @@ public final class AssetRenditionParameters {
public static final String DOWNLOAD = "download";
public static final String CACHE_FILENAME = "asset.rendition";

public static final String PARAMETER_RENDITION_DISPLAY_NAME = "renditionDisplayName";

private final Asset asset;
private final String renditionName;
private final String fileName;
private final List<String> otherParameters;

private final ValueMap otherProperties = new ValueMapDecorator(new HashMap<>());
private final ValueMap otherParameters = new ValueMapDecorator(new HashMap<>());
private final ValueMap otherProperties = new ValueMapDecorator(new HashMap<>());

public AssetRenditionParameters(final SlingHttpServletRequest request) throws IllegalArgumentException {
final String[] segments = PathInfoUtil.getSuffixSegments(request);
Expand All @@ -76,12 +79,17 @@ public AssetRenditionParameters(final SlingHttpServletRequest request) throws Il
// Build the download filename (for Content-Disposition) from the asset node name and rendition name.
this.fileName = buildFileName(asset, renditionName);

// Other parameters are any optional parameters
this.otherParameters = new ArrayList<>();

// Other parameters are any optional parameters in the selector OR in query parameter
for (int i = 1; i < segments.length - 1; i++) {
this.otherParameters.add(segments[i]);
String key = segments[i];
if (StringUtils.equals(key, DOWNLOAD)) {
this.otherParameters.put(key, true);
} else {
this.otherParameters.put(key, null);
}
}

this.otherParameters.putAll(getParameters(request));
}

public AssetRenditionParameters(final @Nonnull AssetModel assetModel, final @Nonnull String renditionName) throws IllegalArgumentException {
Expand All @@ -96,19 +104,25 @@ public AssetRenditionParameters(final @Nonnull AssetModel assetModel, final @Non
this(assetModel, renditionName, download, Arrays.asList(otherParameters));
}

public AssetRenditionParameters(final @Nonnull AssetModel assetModel, final @Nonnull String renditionName, final boolean download, final List<String> otherParameters) throws IllegalArgumentException {
if (StringUtils.isBlank(renditionName)) {
public AssetRenditionParameters(final @Nonnull AssetModel assetModel, final @Nonnull String renditionNameWithParameters, final boolean download, final List<String> otherParameters) throws IllegalArgumentException {
if (StringUtils.isBlank(renditionNameWithParameters)) {
throw new IllegalArgumentException("Am asset is required");
} else if (StringUtils.isBlank(renditionName)) {
} else if (StringUtils.isBlank(renditionNameWithParameters)) {
throw new IllegalArgumentException("A renditionName is required");
}

this.asset = DamUtil.resolveToAsset(assetModel.getResource());
this.renditionName = renditionName;
this.renditionName = StringUtils.substringBefore(renditionNameWithParameters, "?");
this.fileName = buildFileName(asset, renditionName);
this.otherParameters = new ArrayList<>(otherParameters);

for (String otherParameter : otherParameters) {
this.otherParameters.put(otherParameter, null);
}

this.otherParameters.putAll(getParameters(renditionNameWithParameters));

if (download) {
this.otherParameters.add(DOWNLOAD);
this.otherParameters.put(DOWNLOAD, true);
}
}

Expand All @@ -117,7 +131,7 @@ public String getRenditionName() {
}

public boolean isDownload() {
return otherParameters.contains(DOWNLOAD);
return otherParameters.containsKey(DOWNLOAD);
}

public String getFileName() {
Expand All @@ -131,10 +145,10 @@ public Asset getAsset() {
return asset;
}

public List<String> getParameters() {
return new ArrayList<>(otherParameters);
}

public ValueMap getParameters() {
return new ValueMapDecorator(otherParameters);
}

/**
* At this time, only "userId" is set by Asset Share Commons to this ValueMap. Other values can be set by custom implementations as needed.
Expand All @@ -155,6 +169,45 @@ public void setOtherProperty(String key, Object value) {
otherProperties.put(key, value);
}

public static ValueMap getParameters(SlingHttpServletRequest request) {
Map<String, Object> params = new TreeMap<>();

request.getParameterMap().forEach((key, value) -> {
params.put(key, value[0]);
});

return new ValueMapDecorator(params);
}

public static ValueMap getParameters(String input) {
Map<String, Object> params = new TreeMap<>();

input = StringUtils.substringAfter(input, "?");

Arrays.stream(StringUtils.split(input, "&")).spliterator().forEachRemaining(param -> {
final String[] keyValue = StringUtils.split(param, "=");
if (keyValue.length == 2) {
String value = keyValue[1];
try {
value = URLDecoder.decode(value, "UTF-8");
} catch (UnsupportedEncodingException e) {
log.warn("Unable to decode Asset Rendition query parameter value [ {} ]. Using encoded value.", value, e);
}
params.putIfAbsent(keyValue[0], value);
}
});

return new ValueMapDecorator(params);
}

public static String getRenditionName(String input) {
if (StringUtils.contains(input, "?")) {
return StringUtils.substringBefore(input, "?");
} else {
return input;
}
}

protected String buildFileName(final Asset asset, final String renditionName) {
String fileName;

Expand Down
Loading
Loading