Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.day.cq.dam.core.process.DownloadAssetProcess Maven / Gradle / Ivy
package com.day.cq.dam.core.process;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.day.cq.commons.Externalizer;
import com.day.cq.dam.api.DamConstants;
import com.day.cq.dam.api.jobs.AssetDownloadService;
import com.day.cq.dam.commons.process.AbstractAssetWorkflowProcess;
import com.day.cq.workflow.WorkflowException;
import com.day.cq.workflow.WorkflowSession;
import com.day.cq.workflow.exec.WorkItem;
import com.day.cq.workflow.metadata.MetaDataMap;
import org.apache.commons.httpclient.URI;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.ReferencePolicyOption;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.tenant.Tenant;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
/**
* The DownloadAssetProcess
will invoke the downloadasset service to process asset(s) download.
*/
@Component(metatype = false)
@Service
@Properties({
@Property(name = Constants.SERVICE_DESCRIPTION, value = "Download selected asset(s)."),
@Property(name = "process.label", value = "Download Dam Asset")
})
public class DownloadAssetProcess extends AbstractAssetWorkflowProcess {
/**
* Logger instance for this class.
*/
private static final Logger log = LoggerFactory.getLogger(DownloadAssetProcess.class);
private static final String DOWNLOADASSETS = "downloadAssets";
private static final String DOWNLOADRENDITIONS = "downloadRenditions";
private static final String DOWNLOADSUBASSETS = "downloadSubassets";
private static final String FLATSTRUCTURE = "flatStructure";
private static final String S7EXPORTSETTINGS = "s7exportsettings";
private static final String EMAILTO = "emailTo";
private static final String CONTEXTPATH = "contextPath";
private static final String SERVICE_USER_ID = "assetidhelper";
@Reference(cardinality=ReferenceCardinality.MANDATORY_UNARY, policy=ReferencePolicy.STATIC)
public AssetDownloadService assetDownloadService;
@Reference(policyOption = ReferencePolicyOption.GREEDY)
public Externalizer externalizer;
@Reference
public SlingRepository slingRepository;
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap metaData)
throws WorkflowException {
try {
final Session session = workflowSession.getSession();
final ResourceResolver rr = getResourceResolver(session);
final String payload = workItem.getWorkflowData().getPayload().toString();
final String srcPath = payload.split(".assetdownload.zip")[0];
final MetaDataMap wfMetaDataMap = workItem.getWorkflowData().getMetaDataMap();
final String contextPath = wfMetaDataMap.get(CONTEXTPATH, new String());
// to exclude the "context-path" for "sling" to find and get the resource
Resource resource = rr.getResource(srcPath.substring(contextPath.length()));
// get the download job name and job options
boolean downloadAssets = Boolean.parseBoolean(getValueFromPayload(DOWNLOADASSETS, payload));
boolean downloadRenditions = Boolean.parseBoolean(getValueFromPayload(DOWNLOADRENDITIONS, payload));
boolean downloadSubassets = Boolean.parseBoolean(getValueFromPayload(DOWNLOADSUBASSETS, payload));
String s7exportsettings = getValueFromPayload(S7EXPORTSETTINGS, payload);
if (StringUtils.isNotBlank(s7exportsettings)) {
s7exportsettings = URLDecoder.decode(s7exportsettings, "UTF-8");
}
int idx = payload.indexOf("?");
String downloadName = (idx == -1 ? "" : payload.substring(0, idx));
downloadName = getDownloadName(downloadName);
// get the download assets
ArrayList paths = getAssetPath(payload);
Set downloadSet = new HashSet();
if (paths != null && paths.size() > 0) {
for (String path: paths) {
// no need to decode twice since it is done in getAssetPath(...) already
Resource res = rr.getResource(path);
if (res != null) {
downloadSet.add(res);
}
}
} else {
downloadSet.add(resource);
}
// process download
String emailRecipients = wfMetaDataMap.get(EMAILTO, new String());
boolean flatStructure = Boolean.parseBoolean(getValueFromPayload(FLATSTRUCTURE, payload));
String downloadUrl = assetDownloadService.assetDownload(
new AssetDownloadService.AssetDownloadParams(resource, downloadSet, downloadAssets, downloadRenditions, downloadSubassets, s7exportsettings, null, null, downloadName, emailRecipients, flatStructure, null));
if (!StringUtils.isEmpty(downloadUrl)) {
downloadUrl = getHostPrefix(workItem, rr, resource.getPath()) + downloadUrl;
// store the downloadUrl as a WF metadata
wfMetaDataMap.put(DamConstants.DOWNLOAD_URL, downloadUrl);
} else{
log.debug("downloadUrl is null or empty.");
}
} catch (Exception e) {
log.error("execute: error while processing download asset; work item [{}]: ", workItem.getId(), e);
}
}
private ArrayList getAssetPath(String arg) {
ArrayList paths = new ArrayList();
try {
int beginIdx = arg.indexOf("path=");
while (beginIdx != -1) {
int endIdx = arg.indexOf("&", beginIdx + 1);
endIdx = (endIdx == -1 ? arg.length() : endIdx);
//need to pre-process this, as the '%' character gets encoded, which breaks the loop in execute()
String path = arg.substring(beginIdx + "path+".length(), endIdx);
paths.add(URLDecoder.decode(path, "UTF-8"));
beginIdx = arg.indexOf("path=", endIdx+1);
}
} catch (Exception e) {
log.error("unable to parse asset paths for download: " + arg, e);
}
return paths;
}
private String getValueFromPayload(String key, String argment) {
String value = null;
// There might be s7dam imagepreset nested command settings,
// So not changing argments to an array by spliting "&"
int beginIdx = argment.indexOf(key);
if (beginIdx != -1 && validKeyParameter(key, argment.substring(beginIdx - 1, beginIdx + key.length() + 1))) {
int endIdx = argment.indexOf("&", beginIdx);
endIdx = (endIdx == -1 ? argment.length() : endIdx);
value = (beginIdx == -1 ? "" : argment.substring(beginIdx + (key + "=").length(), endIdx));
}
return value;
}
private boolean validKeyParameter(String key, String argment) {
// we want to make sure the parameter is valid and not an injected one
boolean valid = false;
List params = Arrays.asList(argment.split("&|\\?|="));
for (String param : params) {
if (param.length() != 0) {
valid = (param.equals(key));
}
}
return valid;
}
private String getDownloadName(String pathInfo) {
String name = pathInfo.substring(pathInfo.lastIndexOf("/") + 1, pathInfo.length());
name = name.replaceAll("[\\[\\]\\/ :*|'\"S]", ""); // remove invalid chars to JCR
name = (name.endsWith(".zip") ? name : name + ".zip");
return name;
}
private String getHostPrefix(WorkItem workItem, ResourceResolver resolver, String resourcePath) {
ResourceResolver resolverForExternalizer = getResolverForExternalizer(workItem, resolver);
String externalizerHost = externalizer.externalLink(resolverForExternalizer, Externalizer.AUTHOR, "");
if (externalizerHost != null && externalizerHost.endsWith("/")) {
externalizerHost = externalizerHost.substring(0, externalizerHost.length()-1);
}
String tenantID = getTenantId(resolver, resourcePath);
externalizerHost = adaptTenantIDToHostUrl(externalizerHost, tenantID);
return externalizerHost;
}
private String adaptTenantIDToHostUrl(String hostPrefix, String tenantID) {
try {
URI uri = new URI(hostPrefix, false);
String uriWithTenant = (!StringUtils.isEmpty(tenantID) ? tenantID + "." + uri.getHost() : uri.getHost());
URI hostPrefixUri = new URI(uri.getScheme(), uri.getUserinfo(), uriWithTenant, uri.getPort(), uri.getPath());
hostPrefix = hostPrefixUri.getURIReference();
} catch (URIException e){
log.error("Build uri failed with hostUrl [{}] and tenantID [{}]", new String[]{hostPrefix, tenantID}, e);
}
return hostPrefix;
}
private String getTenantId(ResourceResolver resolver, String downloadAssetsPath) {
Tenant tenant = resolver.getResource(downloadAssetsPath).adaptTo(Tenant.class);
return (tenant == null ? null : tenant.getId());
}
private ResourceResolver getResolverForExternalizer(WorkItem workItem, ResourceResolver workFlowResourceResolver) {
final String initiator = workItem.getWorkflow().getInitiator();
Session initiatorSession = getUserSession(initiator);
ResourceResolver initiatorResolver = getResourceResolver(initiatorSession);
if (initiatorResolver != null) {
return initiatorResolver;
}
return workFlowResourceResolver;
}
private Session getUserSession(String userId) {
final SimpleCredentials credentials = new SimpleCredentials(userId, new char[0]);
try {
return slingRepository.impersonateFromService(SERVICE_USER_ID, credentials, null);
} catch (Exception e) {
log.info("Impersonation of user '{}' failed", userId, e);
return null;
}
}
}