com.day.cq.contentsync.handler.AbstractSlingResourceUpdateHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*
* Copyright 1997-2011 Day Management AG
* Barfuesserplatz 6, 4001 Basel, Switzerland
* All Rights Reserved.
*
* This software is the confidential and proprietary information of
* Day Management AG, ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Day.
*/
package com.day.cq.contentsync.handler;
import com.day.cq.commons.jcr.JcrConstants;
import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.contentsync.handler.util.RequestResponseFactory;
import com.day.cq.contentsync.impl.handler.util.RequestResponseFactoryImpl;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.engine.SlingRequestProcessor;
import org.apache.sling.jcr.resource.JcrResourceConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Collections;
import org.apache.commons.io.output.DeferredFileOutputStream;
/**
* The {@code AbstractSlingResourceUpdateHandler} is an abstract base class
* for cache update handlers that would like to use the Sling request processing.
*/
@Component(metatype = false, componentAbstract = true)
public abstract class AbstractSlingResourceUpdateHandler extends AbstractDefaultContentUpdateHandler implements ContentUpdateHandler {
private static final Logger log = LoggerFactory.getLogger(AbstractSlingResourceUpdateHandler.class);
@Reference
protected SlingRequestProcessor slingServlet;
@Reference
protected ResourceResolverFactory resourceResolverFactory;
@Reference
protected RequestResponseFactory requestResponseFactory;
/**
* This method renders the given request URI using the Sling request processing
* and stores the result at the request's location relative to the cache root
* folder. The request is processed in the context of the given user's session.
*
* @param uri The request URI including selectors and extensions
* @param configCacheRoot The cache root folder
* @param admin The admin session used to store the result in the cache
* @param session The user's session
* @return {@code true} if the cache was updated
* @throws IOException if an I/O error occurrs.
* @throws RepositoryException if an error accessing the repository occurrs.
* @throws ServletException if a generic servlet error occurrs.
* @throws NoSuchAlgorithmException
*/
protected boolean renderResource(String uri, String configCacheRoot, Session admin, Session session) throws RepositoryException, ServletException, IOException, NoSuchAlgorithmException {
String cachePath = configCacheRoot + getTargetPath(uri);
DeferredFileOutputStream out = new DeferredFileOutputStream(1024 * 64, "content-sync", ".tmp", null);
boolean isHashMatched = false;
try {
ResourceResolver resolver = resourceResolverFactory.getResourceResolver(Collections.singletonMap("user.jcr.session", (Object) session));
// render resource
HttpServletRequest request = createRequest(uri);
HttpServletResponse response = ((RequestResponseFactoryImpl) requestResponseFactory).createBufferedResponse(out);
slingServlet.processRequest(request, response, resolver);
response.getWriter().flush();
InputStream inputStream = null;
String hash;
try {
if (out.isInMemory()) {
// Data is in memory, create ByteArrayInputStream from the byte array
inputStream = new ByteArrayInputStream(out.getData());
} else {
// Data spilled to a temporary file, create FileInputStream from the file
inputStream = new FileInputStream(out.getFile());
}
hash = DigestUtils.sha256Hex(inputStream);
} finally {
IOUtils.closeQuietly(inputStream);
}
isHashMatched = hashMatches(session, cachePath, hash);
if (!isHashMatched) {
log.debug("Hash missing or not equal, updating content sync cache: {}", cachePath);
JcrUtil.createPath(cachePath, JcrResourceConstants.NT_SLING_FOLDER, JcrConstants.NT_FILE, admin, false);
Node cacheContentNode = JcrUtil.createPath(cachePath + "/" + JcrConstants.JCR_CONTENT, JcrConstants.NT_RESOURCE, admin);
if(out.isInMemory()){
cacheContentNode.setProperty(JcrConstants.JCR_DATA, admin.getValueFactory().createBinary(new ByteArrayInputStream(out.getData())));
}
else {
cacheContentNode.setProperty(JcrConstants.JCR_DATA, admin.getValueFactory().createBinary(new FileInputStream(out.getFile())));
}
cacheContentNode.setProperty(JcrConstants.JCR_LASTMODIFIED, Calendar.getInstance());
if (response.getContentType() != null) {
cacheContentNode.setProperty(JcrConstants.JCR_MIMETYPE, response.getContentType());
}
if (response.getCharacterEncoding() != null) {
cacheContentNode.setProperty(JcrConstants.JCR_ENCODING, response.getCharacterEncoding());
}
writeHash(cacheContentNode, hash);
admin.save();
return true;
} else {
log.debug("Skipping update of content sync cache: {}", uri);
return false;
}
} catch (LoginException e) {
log.error("Creating resource resolver for resource rendering failed: ", e);
return false;
} finally {
IOUtils.closeQuietly(out);
if (!isHashMatched && admin.hasPendingChanges()) {
admin.refresh(false);
}
}
}
/**
* Creates a GET request for the given uri. This method can
* be overridden to provide a customized request object,
* e.g. with added parameters.
*
* @param uri The uri
* @return The request object
* @see com.day.cq.contentsync.handler.util.RequestResponseFactory
*/
protected HttpServletRequest createRequest(String uri) {
return requestResponseFactory.createRequest("GET", uri);
}
/**
* Returns the target path of a rendered resource relative
* to the cache root. This method can be overridden to
* adjust the output path in the zip file. The default
* implementation simply returns the input path.
*
* @param path The initial path
* @return The adjusted path
*/
protected String getTargetPath(String path) {
return path;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy