OriginalPageEditorServlet.java 11.7 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.jcr.JcrUtil
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.servlet.Servlet
 *  javax.servlet.ServletException
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.ReferencePolicy
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.commons.html.HtmlParser
 *  org.osgi.service.component.ComponentContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.wcm.siteimporter.internal.servlet;

import com.day.cq.commons.jcr.JcrUtil;
import com.day.cq.wcm.siteimporter.ProgressTracker;
import com.day.cq.wcm.siteimporter.internal.servlet.SiteImporterServletBase;
import com.day.cq.wcm.siteimporter.internal.util.Utils;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.html.HtmlParser;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

@Component(metatype=0, label="Original Page Editor", description="Edits original page")
@Service(value={Servlet.class})
@Properties(value={@org.apache.felix.scr.annotations.Property(name="sling.servlet.paths", propertyPrivate=1, value={"/libs/wcm/bin/siteimporter/editorigpage"}), @org.apache.felix.scr.annotations.Property(name="sling.servlet.methods", propertyPrivate=1, value={"POST"}), @org.apache.felix.scr.annotations.Property(name="service.description", value={"Original Page Editor"})})
public class OriginalPageEditorServlet
extends SiteImporterServletBase {
    private static final long serialVersionUID = 9112167990766136591L;
    private static final Logger log = LoggerFactory.getLogger(OriginalPageEditorServlet.class);
    @Reference(policy=ReferencePolicy.STATIC)
    private HtmlParser parser;

    protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");
        ResourceResolver resolver = request.getResourceResolver();
        String path = request.getParameter("path");
        String id = request.getParameter("id");
        String newid = request.getParameter("newid");
        String content = request.getParameter("content");
        String operation = request.getParameter("operation");
        if ("insert".equalsIgnoreCase(operation) && id != null && newid != null && content != null) {
            Resource resource = resolver.getResource(path);
            if (resource == null) {
                throw new ServletException("path " + path + " not found");
            }
            this.makeBackup(resource);
            this.insertElementAfterID(resolver, path, id, newid, content);
        } else if ("remove".equalsIgnoreCase(operation) && id != null) {
            Resource resource = resolver.getResource(path);
            if (resource == null) {
                throw new ServletException("path " + path + " not found");
            }
            this.makeBackup(resource);
            this.removeElementID(resolver, path, id);
        } else if ("restore".equalsIgnoreCase(operation)) {
            Resource resource = resolver.getResource(path + ".bk");
            if (resource != null) {
                this.restoreBackup(resource);
            }
        } else {
            throw new ServletException("invalid parameters");
        }
    }

    protected void makeBackup(Resource res) throws ServletException {
        if (res.getResourceResolver().getResource(res.getPath() + ".bk") != null) {
            return;
        }
        Node node = (Node)res.adaptTo(Node.class);
        try {
            JcrUtil.copy((Node)node, (Node)node.getParent(), (String)(node.getName() + ".bk"));
            node.getParent().getSession().save();
        }
        catch (Exception ex) {
            log.error("error while making backup of " + (Object)res, (Throwable)ex);
            throw new ServletException((Throwable)ex);
        }
    }

    protected void restoreBackup(Resource res) throws ServletException {
        Node node = (Node)res.adaptTo(Node.class);
        try {
            JcrUtil.copy((Node)node, (Node)node.getParent(), (String)node.getName().replaceAll("\\.bk$", ""));
            node.getParent().getSession().save();
        }
        catch (Exception ex) {
            log.error("error while restoring backup of " + (Object)res, (Throwable)ex);
            throw new ServletException((Throwable)ex);
        }
    }

    protected void insertElementAfterID(ResourceResolver resolver, String path, String id, String newid, String content) throws ServletException {
        Resource resource = resolver.getResource(path);
        if (resource == null) {
            throw new ServletException("path " + path + " not found");
        }
        Resource res = resolver.getResource(path + "/jcr:content");
        if (res == null) {
            throw new ServletException("path " + path + "/jcr:content not found");
        }
        Node data = (Node)res.adaptTo(Node.class);
        String html = null;
        try {
            html = data.getProperty("jcr:data").getString();
        }
        catch (Exception ex) {
            log.error("unable to get jcr:data from " + path);
            return;
        }
        String charset = this.getCharSet(resource);
        ProgressTracker out = this.getOutput();
        Document doc = Utils.parse(html, charset, this.parser, out);
        XPath xpath = XPathFactory.newInstance().newXPath();
        Element el = null;
        try {
            el = (Element)xpath.evaluate("//*[@componentinsertid='" + id + "']", doc, XPathConstants.NODE);
        }
        catch (XPathExpressionException e) {
            out.error("Couldn't get element: " + e.getMessage(), e);
        }
        if (el == null) {
            out.error("element " + id + " not found");
            return;
        }
        Element newElement = doc.createElement("div");
        newElement.setAttribute("componentinsertid", newid);
        newElement.setTextContent(content);
        el.getParentNode().insertBefore(newElement, el.getNextSibling());
        String newhtml = this.makeHTML(doc, charset);
        try {
            data.getProperty("jcr:data").setValue(newhtml);
            data.getProperty("jcr:lastModified").setValue((Calendar)new GregorianCalendar());
            data.getSession().save();
        }
        catch (Exception ex) {
            out.error("unable to set jcr:data to " + path);
        }
    }

    protected String getCharSet(Resource resource) throws ServletException {
        try {
            Node node = (Node)resource.adaptTo(Node.class);
            Node parent = node.getParent();
            return parent.getProperty("cqProjectCharset").getString();
        }
        catch (Exception ex) {
            log.error("unable to extract charset " + (Object)resource, (Throwable)ex);
            return "UTF-8";
        }
    }

    protected String makeHTML(Document doc, String charset) {
        ProgressTracker out = this.getOutput();
        DOMSource source = new DOMSource(doc);
        ByteArrayOutputStream transContent = new ByteArrayOutputStream();
        try {
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer xformer = tf.newTransformer();
            if (charset != null) {
                xformer.setOutputProperty("encoding", charset);
            }
            xformer.setOutputProperty("omit-xml-declaration", "yes");
            xformer.transform(source, new StreamResult(transContent));
        }
        catch (Exception e) {
            out.error("Couldn't parse original HTML: " + e.getMessage(), e);
            return null;
        }
        if (charset != null) {
            try {
                return new String(transContent.toByteArray(), charset);
            }
            catch (UnsupportedEncodingException e) {
                return new String(transContent.toByteArray());
            }
        }
        return new String(transContent.toByteArray());
    }

    protected void removeElementID(ResourceResolver resolver, String path, String id) throws ServletException {
        Resource resource = resolver.getResource(path);
        if (resource == null) {
            throw new ServletException("path " + path + " not found");
        }
        Resource res = resolver.getResource(path + "/jcr:content");
        if (res == null) {
            throw new ServletException("path " + path + "/jcr:content not found");
        }
        Node data = (Node)res.adaptTo(Node.class);
        String html = null;
        try {
            html = data.getProperty("jcr:data").getString();
        }
        catch (Exception ex) {
            log.error("unable to get jcr:data from " + path);
            return;
        }
        String charset = this.getCharSet(resource);
        ProgressTracker out = this.getOutput();
        Document doc = Utils.parse(html, charset, this.parser, out);
        XPath xpath = XPathFactory.newInstance().newXPath();
        Element el = null;
        try {
            el = (Element)xpath.evaluate("//*[@componentinsertid='" + id + "']", doc, XPathConstants.NODE);
        }
        catch (XPathExpressionException e) {
            out.error("Couldn't get element: " + e.getMessage(), e);
        }
        if (el == null) {
            out.error("element " + id + " not found");
            return;
        }
        el.getParentNode().removeChild(el);
        String newhtml = this.makeHTML(doc, charset);
        try {
            data.getProperty("jcr:data").setValue(newhtml);
            data.getProperty("jcr:lastModified").setValue((Calendar)new GregorianCalendar());
            data.getSession().save();
        }
        catch (Exception ex) {
            out.error("unable to set jcr:data to " + path);
        }
    }

    protected void activate(ComponentContext context) throws RepositoryException {
    }

    protected void bindParser(HtmlParser htmlParser) {
        this.parser = htmlParser;
    }

    protected void unbindParser(HtmlParser htmlParser) {
        if (this.parser == htmlParser) {
            this.parser = null;
        }
    }
}