PermalinkServlet.java 6.43 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.PathInfo
 *  com.day.cq.commons.servlets.NonExistingResourceServlet
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Value
 *  javax.jcr.ValueFactory
 *  javax.jcr.Workspace
 *  javax.jcr.query.Query
 *  javax.jcr.query.QueryManager
 *  javax.jcr.query.QueryResult
 *  javax.servlet.ServletException
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.apache.sling.api.servlets.SlingSafeMethodsServlet
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.JSONObject
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.mcm.campaign.servlets;

import com.adobe.cq.mcm.campaign.NewsletterException;
import com.day.cq.commons.PathInfo;
import com.day.cq.commons.servlets.NonExistingResourceServlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.servlet.ServletException;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestPathInfo;
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.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component
@Service(value={NonExistingResourceServlet.class})
public class PermalinkServlet
extends SlingSafeMethodsServlet
implements NonExistingResourceServlet {
    private static final int CACHE_SIZE = 1000;
    private static final String SEARCH_SQL = "SELECT * FROM [nt:base] WHERE [cq:acUUID] = $uuid AND NOT [jcr:primaryType] = 'nt:frozenNode'";
    private final Logger log;
    private Map<String, String> cache;

    public PermalinkServlet() {
        this.log = LoggerFactory.getLogger(this.getClass());
        this.cache = new LinkedHashMap<String, String>(1002, 1.0f){

            @Override
            protected boolean removeEldestEntry(Map.Entry<String, String> stringStringEntry) {
                return this.size() > 1000;
            }
        };
    }

    public boolean accepts(SlingHttpServletRequest request) {
        String path = request.getRequestPathInfo().getResourcePath();
        return path != null && path.startsWith("/libs/mcm/campaign/content/newsletters/");
    }

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/json");
        response.setCharacterEncoding("utf-8");
        try {
            JSONObject result = this.handleGet(request, response);
            if (result != null) {
                response.getWriter().write(result.toString());
            }
        }
        catch (Exception e) {
            this.log.error("Caught exception while serving permalink request", (Throwable)e);
            response.setStatus(500);
            response.getWriter().write("{\"message\":" + JSONObject.quote((String)e.getMessage()) + "}");
        }
    }

    private JSONObject handleGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws RepositoryException, IOException, JSONException, NewsletterException {
        PathInfo pathInfo = new PathInfo(request.getPathInfo());
        String uuid = pathInfo.getResourcePath().substring("/libs/mcm/campaign/content/newsletters".length() + 1);
        String path = null;
        if (this.cache.containsKey(uuid)) {
            path = this.cache.get(uuid);
            Resource page = request.getResourceResolver().getResource(path);
            Resource content = request.getResourceResolver().getResource(path + "/" + "jcr:content");
            if (page == null || content == null) {
                path = null;
            } else {
                ValueMap properties = (ValueMap)content.adaptTo(ValueMap.class);
                if (!uuid.equals(properties.get("cq:acUUID", (Object)""))) {
                    path = null;
                }
            }
        }
        if (path == null) {
            Session session = (Session)request.getResourceResolver().adaptTo(Session.class);
            QueryManager queryManager = session.getWorkspace().getQueryManager();
            Query query = queryManager.createQuery("SELECT * FROM [nt:base] WHERE [cq:acUUID] = $uuid AND NOT [jcr:primaryType] = 'nt:frozenNode'", "JCR-SQL2");
            query.bindValue("uuid", session.getValueFactory().createValue(uuid));
            NodeIterator iterator = query.execute().getNodes();
            if (!iterator.hasNext()) {
                String msg = "No newsletter found with uuid " + uuid;
                this.log.warn(msg);
                response.setStatus(404);
                return new JSONObject().put("message", (Object)msg);
            }
            Node node = iterator.nextNode();
            if (iterator.hasNext()) {
                String msg = "More than one newsletter found with uuid " + uuid;
                throw new NewsletterException(msg);
            }
            path = node.getParent().getPath();
            this.cache.put(uuid, path);
        }
        String selectors = pathInfo.getSelectorString() == null ? "" : "." + pathInfo.getSelectorString();
        String extension = pathInfo.getExtension() == null ? "" : "." + pathInfo.getExtension();
        String redirectPath = path + selectors + extension;
        response.setStatus(302);
        response.addHeader("Cache-Control", "no-cache");
        response.addHeader("Location", redirectPath);
        return null;
    }

}