CommandServlet.java 7.63 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Session
 *  javax.servlet.Servlet
 *  javax.servlet.ServletException
 *  javax.servlet.http.HttpServletResponse
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  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.ResourceResolver
 *  org.apache.sling.api.servlets.HtmlResponse
 *  org.apache.sling.api.servlets.SlingAllMethodsServlet
 *  org.osgi.service.event.Event
 *  org.osgi.service.event.EventAdmin
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.replication.impl.servlets;

import com.day.cq.replication.AccessDeniedException;
import com.day.cq.replication.PathNotFoundException;
import com.day.cq.replication.ReplicationActionType;
import com.day.cq.replication.ReplicationOptions;
import com.day.cq.replication.Replicator;
import java.io.IOException;
import java.util.Dictionary;
import java.util.Hashtable;
import javax.jcr.Session;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
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.ResourceResolver;
import org.apache.sling.api.servlets.HtmlResponse;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(metatype=0)
@Property(name="sling.servlet.paths", value={"/bin/replicate"})
@Service(value={Servlet.class})
public class CommandServlet
extends SlingAllMethodsServlet {
    private static final long serialVersionUID = -647584595694478227L;
    private final transient Logger logger;
    @Reference
    private transient Replicator replicator;
    @Reference
    private transient EventAdmin eventAdmin;
    private static final String PATH_PARAMETER = "path";
    private static final String ACTION_PARAMETER = "cmd";
    private static final String VERSION_PARAMETER = "version";

    public CommandServlet() {
        this.logger = LoggerFactory.getLogger(this.getClass());
    }

    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        if (this.isJson(request)) {
            response.setContentType("application/json");
        } else {
            response.setContentType("text/plain");
        }
        String[] paths = request.getParameterValues("path");
        if (paths == null || paths.length == 0) {
            this.writeStatus((HttpServletResponse)response, "Error: path parameter is missing", 400, paths, this.isJson(request));
            return;
        }
        String actionParam = request.getParameter("cmd");
        ReplicationActionType action = ReplicationActionType.fromName(actionParam);
        if (action == null) {
            this.writeStatus((HttpServletResponse)response, "Error: cmd contains unknown value: " + actionParam, 400, paths, this.isJson(request));
            return;
        }
        Replicator localReplicator = this.replicator;
        if (localReplicator == null) {
            this.writeStatus((HttpServletResponse)response, "Error: Replicator service is not available", 400, paths, this.isJson(request));
            return;
        }
        ReplicationOptions opts = new ReplicationOptions();
        opts.setRevision(request.getParameter("version"));
        String[] msgs = new String[paths.length];
        Session session = (Session)request.getResourceResolver().adaptTo(Session.class);
        int status = 200;
        int index = 0;
        for (String path : paths) {
            block16 : {
                try {
                    localReplicator.replicate(session, action, path, opts);
                    msgs[index] = "Replication started for " + path;
                }
                catch (PathNotFoundException pnfe) {
                    msgs[index] = "Error: Path not found: " + path;
                    if (status == 200) {
                        status = 404;
                    }
                }
                catch (AccessDeniedException ade) {
                    if (action.equals((Object)ReplicationActionType.ACTIVATE) || action.equals((Object)ReplicationActionType.DEACTIVATE)) {
                        this.logger.debug(request.getRemoteUser() + " is not allowed to replicate " + "this resource " + path + ". Issuing request for 'replication");
                        Hashtable<String, Object> properties = new Hashtable<String, Object>();
                        properties.put("path", path);
                        properties.put("replicationType", (Object)action);
                        properties.put("userId", session.getUserID());
                        Event event = new Event("com/day/cq/wcm/workflow/req/for/activation", properties);
                        this.eventAdmin.sendEvent(event);
                        msgs[index] = "Warn: No rights to replicate. Request for de/activation got issued for " + path;
                        if (status == 200) {
                            status = 403;
                        }
                    } else {
                        msgs[index] = "Error: No rights to replicate " + path;
                        if (status == 200) {
                            status = 403;
                        }
                    }
                }
                catch (Throwable e) {
                    this.logger.error("Error during replication: " + e.getMessage(), e);
                    msgs[index] = "Error: " + e.getLocalizedMessage() + " for path " + path;
                    if (status != 200) break block16;
                    status = 400;
                }
            }
            ++index;
        }
        StringBuilder msg = new StringBuilder();
        for (String m : msgs) {
            msg.append(m).append("\n");
        }
        this.writeStatus((HttpServletResponse)response, msg.toString(), status, paths, this.isJson(request));
    }

    private boolean isJson(SlingHttpServletRequest request) {
        return "json".equals(request.getRequestPathInfo().getExtension());
    }

    private void writeStatus(HttpServletResponse response, String message, int status, String[] paths, boolean isJson) throws IOException {
        this.createStatusResponse(status, message, paths).send(response, true);
    }

    private HtmlResponse createStatusResponse(int status, String message, String[] paths) {
        HtmlResponse res = new HtmlResponse();
        res.setStatus(status, message);
        if (paths != null && paths.length > 0) {
            res.setPath(paths[0]);
        }
        return res;
    }

    protected void bindReplicator(Replicator replicator) {
        this.replicator = replicator;
    }

    protected void unbindReplicator(Replicator replicator) {
        if (this.replicator == replicator) {
            this.replicator = null;
        }
    }

    protected void bindEventAdmin(EventAdmin eventAdmin) {
        this.eventAdmin = eventAdmin;
    }

    protected void unbindEventAdmin(EventAdmin eventAdmin) {
        if (this.eventAdmin == eventAdmin) {
            this.eventAdmin = null;
        }
    }
}