All Downloads are FREE. Search and download functionalities are using the official Maven repository.
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.MetadataProcessorProcess Maven / Gradle / Ivy
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2014 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.day.cq.dam.core.process;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import com.day.cq.dam.commons.util.AssetCache;
import com.day.cq.dam.commons.util.AssetUpdate;
import com.day.cq.dam.commons.util.AssetUpdateMonitor;
import com.day.cq.dam.commons.util.DamUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyUnbounded;
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.ModifiableValueMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.contentdetection.ContentAwareMimeTypeService;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.granite.xss.XSSAPI;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.dam.api.Asset;
import com.day.cq.dam.api.AssetManager;
import com.day.cq.dam.api.DamConstants;
import com.day.cq.dam.api.handler.AssetHandler;
import com.day.cq.dam.commons.metadata.SimpleXmpToJcrMetadataBuilder;
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;
/**
* The MetadataProcessorProcess
is called in a workflow process step.
* This process will import metadata, create references and apply processing profile if the
* paylod of the step is an
* {@link com.day.cq.dam.api.Asset Asset} or a part of an
* {@link com.day.cq.dam.api.Asset Asset}.
*
* @see AbstractAssetWorkflowProcess
*/
@Component(metatype = true)
@Service
@Property(name = "process.label", value = "Metadata Processor")
public class MetadataProcessorProcess extends AbstractAssetWorkflowProcess {
private static final String METADATA_EXTRACED = "com.day.cq.dam.core.process.meta.extraced";
private boolean sha1Enabled = false;
private ProcessingProfileApplier processingProfileApplier = new ProcessingProfileApplier();
@Reference(
policy = ReferencePolicy.DYNAMIC,
cardinality = ReferenceCardinality.OPTIONAL_UNARY,
policyOption = ReferencePolicyOption.GREEDY // ensures service-resolution to the one ranked highest
)
protected ContentAwareMimeTypeService contentAwareMimeTypeService;
@Property(boolValue = true)
public static final String ENABLE_SHA1_GEN = "cq.dam.enable.sha1";
@Property(value = { "adobe_dam:restrictions" }, unbounded = PropertyUnbounded.ARRAY, label = "XSS protected properties", description = "These properties will be passed through xss api before saving")
public static final String XSS_PROTECTED_PROPERTIES = "cq.dam.metadata.xssprotected.properties";
private String[] xssProtectedProperties;
private static final String[] DEFAULT_XSS_PROTECTED_PROPERTIES = new String[] { "adobe_dam:restrictions" };
private static final String ATTRIBUTE_EXTRACT_METADATA = "dam:extractMetadata";
@Reference
private XSSAPI xssApi;
@Reference
private SimpleXmpToJcrMetadataBuilder metadataBuilder;
@Reference
private AssetUpdateMonitor monitor;
/**
* Logger instance for this class.
*/
private static final Logger log = LoggerFactory.getLogger(MetadataProcessorProcess.class);
public void execute(final WorkItem workItem, WorkflowSession workflowSession,
MetaDataMap args) throws WorkflowException {
if (workItem.getWorkflow().getMetaDataMap().get(METADATA_EXTRACED, Boolean.FALSE)) {
/* already run in this workflow */
log.debug("already executed in workflow {}", workItem.getWorkflow().getId());
return;
}
final AssetCache cache = DamUtil.getAssetCache();
final AssetUpdate update = monitor.startUpdate(workItem, getResourceResolver(workflowSession.getSession()), this);
try {
final Session session = workflowSession.getSession();
final Asset asset = update.getAsset(new AssetUpdate.Check() {
@Override
public boolean isNullAcceptable() throws WorkflowException {
String wfPayload = workItem.getWorkflowData().getPayload().toString();
String message = "execute: cannot extract metadata, create references and apply processing profile, asset [{"
+ wfPayload + "}] in payload doesn't exist for workflow [{"
+ workItem.getId() + "}].";
throw new WorkflowException(message);
}
});
if (null != asset) {
asset.setBatchMode(true);
try {
asset.adaptTo(AssetManager.class).assignAssetID(asset);
} catch (RepositoryException e) {
update.error(e);
log.error("Couldn't assign Asset ID to asset at {}."
+ "Please see if sufficient privileges are available", asset.getPath(), e);
}
final AssetHandler assetHandler = getAssetHandler(asset.getMimeType());
if (null != assetHandler) {
Node assetNode = asset.adaptTo(Node.class);
if(extractMetadataRequired(assetNode)) {
MetadataExtractor metadataExtractor = new MetadataExtractor(metadataBuilder);
metadataExtractor.extractMetadata(session, asset, assetHandler, sha1Enabled,
(null != contentAwareMimeTypeService)
? contentAwareMimeTypeService
: mimeTypeService);
assetHandler.processRelated(asset);
} else {
log.debug("execute: Metadata not extracted on Asset : {}. Property dam:extractMetadata is " +
"found to be false", asset.getPath());
update.ignore();
}
removeExtractMetadataProperty(assetNode);
} else {
log.error("execute: cannot extract metadata, no handler found for asset [{}] with mime type [{}]",
asset.getPath(), asset.getMimeType());
update.ignore();
}
processingProfileApplier.applyProcessingProfile(session, asset);
processXSSProtectedProperties(asset, getResourceResolver(session));
//workItem.getWorkflow().getMetaDataMap().put(METADATA_EXTRACED, Boolean.TRUE);
log.debug("remembering execution in workflow {}", workItem.getWorkflow().getId());
}
} catch (Exception e) {
update.error(e);
log.warn("unexpected error occurred during metadata extraction. Cause: {}",
e.getMessage(), e);
}
finally {
cache.release();
update.done();
}
}
/**
* applies xss protection to all the properties in asset's metdata that
* matches with xssProtectedProperties
*
* @param asset
* @param resourceResolver
*/
private void processXSSProtectedProperties(Asset asset,
ResourceResolver resourceResolver) {
try {
Resource assetResource = resourceResolver.getResource(asset.getPath());
Resource metadataResource = assetResource.getChild(JcrConstants.JCR_CONTENT
+ "/" + DamConstants.METADATA_FOLDER);
ModifiableValueMap metadataVM = metadataResource.adaptTo(ModifiableValueMap.class);
for (String prop : xssProtectedProperties) {
String propValue = asset.getMetadataValue(prop);
if (StringUtils.isNotBlank(propValue)) {
metadataVM.put(prop, xssApi.encodeForHTML(propValue));
}
}
} catch (Exception e) {
log.error(
"Exception occured while applying for xss to xss protected properties",
e.getMessage());
}
}
@Activate
@SuppressWarnings("unused")
protected void Actiate(final ComponentContext context) throws RepositoryException {
sha1Enabled = OsgiUtil.toBoolean(context.getProperties().get(ENABLE_SHA1_GEN), true);
xssProtectedProperties = OsgiUtil.toStringArray(
context.getProperties().get(XSS_PROTECTED_PROPERTIES),
DEFAULT_XSS_PROTECTED_PROPERTIES);
}
private static boolean extractMetadataRequired(Node assetNode){
boolean retVal = true;
try {
if (assetNode.hasNode(JcrConstants.JCR_CONTENT)) {
Node contentNode = assetNode.getNode(JcrConstants.JCR_CONTENT);
if(contentNode.hasProperty(ATTRIBUTE_EXTRACT_METADATA)) {
retVal = contentNode.getProperty(ATTRIBUTE_EXTRACT_METADATA).getBoolean();
}
}
} catch (RepositoryException e) {}
return retVal;
}
private static void removeExtractMetadataProperty(Node assetNode) throws RepositoryException {
try {
if (assetNode.hasNode(JcrConstants.JCR_CONTENT)) {
Node contentNode = assetNode.getNode(JcrConstants.JCR_CONTENT);
if(contentNode.hasProperty(ATTRIBUTE_EXTRACT_METADATA)) {
contentNode.getProperty(ATTRIBUTE_EXTRACT_METADATA).remove();
}
}
} catch (RepositoryException e) {}
}
}