PageGenerator.java 13.8 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  org.apache.commons.lang.StringUtils
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.commons.html.HtmlParser
 */
package com.day.cq.wcm.siteimporter.internal.util;

import com.day.cq.wcm.siteimporter.ImporterContext;
import com.day.cq.wcm.siteimporter.ProgressTracker;
import com.day.cq.wcm.siteimporter.ResourcesBoard;
import com.day.cq.wcm.siteimporter.internal.resource.ImporterResource;
import com.day.cq.wcm.siteimporter.internal.resource.ReferenceLocation;
import com.day.cq.wcm.siteimporter.internal.util.MappingDefinition;
import com.day.cq.wcm.siteimporter.internal.util.Utils;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
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.commons.lang.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.commons.html.HtmlParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class PageGenerator {
    private static final String TEXT_PLAIN = "text/plain";
    private static final String NAVIMAGE_TPL = "/libs/wcm/siteimporter/resources/navimage.png.java.tpl";
    private static final String BODY_TPL = "/libs/wcm/siteimporter/resources/body.tpl";
    private static final String HEADER_TPL = "/libs/wcm/siteimporter/resources/head.tpl";
    private static final String CONTENTPAGE_TPL = "/libs/wcm/siteimporter/resources/contentpage.tpl";
    private ResourceResolver resolver;
    private HtmlParser parser;
    private ProgressTracker out;

    public PageGenerator(ResourceResolver resolver, HtmlParser parser, ProgressTracker out) {
        this.resolver = resolver;
        this.parser = parser;
        this.out = out;
    }

    public String rewriteLinks(ImporterResource resource, String content, boolean useDesigner) {
        ImporterContext ctx = resource.getContext();
        ArrayList<ReferenceLocation> refs = resource.getExternalReferences();
        Object[] refsArr = new ReferenceLocation[refs.size()];
        refs.toArray(refsArr);
        Arrays.sort(refsArr);
        String contextPath = ctx.getContextPath();
        for (Object next : refsArr) {
            String path;
            if (next.getType() == 0) {
                content = content.substring(0, next.getStart()) + "#" + content.substring(next.getEnd());
                continue;
            }
            String designPath = "/etc/designs/" + ctx.getProjectName() + "/" + "resources";
            ImporterResource ress = ctx.getBoard().getResource(next.getLink(), ctx);
            if (useDesigner) {
                path = next.getLink().getPath();
                if (ress.isDownloaded() && (path = ress.getDownloadLocation()).startsWith(designPath)) {
                    path = path.substring(designPath.length());
                }
                content = content.substring(0, next.getStart()) + contextPath + "<%= designer.getDesignPath(currentPage) %>/" + "resources" + path + content.substring(next.getEnd());
                continue;
            }
            path = designPath + next.getLink().getPath();
            if (ress.isDownloaded()) {
                path = ress.getDownloadLocation();
            }
            content = content.substring(0, next.getStart()) + contextPath + path + content.substring(next.getEnd());
        }
        return content;
    }

    public String replace(String name, String content, String charset, Map<String, MappingDefinition> mappings) {
        Resource tplContent = this.resolver.getResource("/apps/" + name + "/" + "templates" + "/" + "contentpage/" + "jcr:content");
        if (tplContent == null) {
            this.out.error("Could not locate templates folder.");
            return null;
        }
        javax.jcr.Node tpl = (javax.jcr.Node)tplContent.adaptTo(javax.jcr.Node.class);
        if (tpl == null) {
            this.out.error("Template content is not in repository.");
            return null;
        }
        try {
            NodeIterator kidz = tpl.getNodes();
            while (kidz.hasNext()) {
                kidz.nextNode().remove();
                tpl.getSession().save();
            }
        }
        catch (RepositoryException e) {
            this.out.error("Error while removing childs from template content.", (Exception)e);
            return null;
        }
        XPath xpath = XPathFactory.newInstance().newXPath();
        Document doc = Utils.parse(content, charset, this.parser, this.out);
        for (String id : mappings.keySet()) {
            MappingDefinition def = mappings.get(id);
            Element el = null;
            try {
                el = (Element)xpath.evaluate("//*[@componentinsertid='" + id + "']", doc, XPathConstants.NODE);
            }
            catch (XPathExpressionException e) {
                this.out.error("Couldn't execute XPath: " + e.getMessage(), e);
                return null;
            }
            if (el != null) {
                Element include = doc.createElement("cq:include");
                include.setAttribute("path", def.getPath());
                include.setAttribute("resourceType", def.getResourceType());
                if (id.startsWith("new_")) {
                    Element div = doc.createElement("div");
                    div.appendChild(include);
                    include = div;
                }
                try {
                    tpl.addNode(def.getPath());
                }
                catch (RepositoryException e) {
                    this.out.error("Couldn't add child to template content: " + e.getMessage(), (Exception)e);
                    return null;
                }
                while (el.hasChildNodes()) {
                    el.removeChild(el.getLastChild());
                }
                el.appendChild(include);
                continue;
            }
            this.out.error("Couldn't find element with insert ID " + id);
        }
        try {
            tpl.getSession().save();
        }
        catch (RepositoryException e) {
            this.out.error("Couldn't save changes in template content: " + e.getMessage(), (Exception)e);
            return null;
        }
        try {
            NodeList toBeRemoved = (NodeList)xpath.evaluate("//*[@cqsiteimporter='removeFromFinal']", doc, XPathConstants.NODESET);
            for (int i = 0; i < toBeRemoved.getLength(); ++i) {
                Node child = toBeRemoved.item(i);
                child.getParentNode().removeChild(child);
            }
        }
        catch (XPathExpressionException e) {
            this.out.error("Couldn't execute XPath: " + e.getMessage(), e);
            return null;
        }
        try {
            NodeList comps = (NodeList)xpath.evaluate("//*[@componentinsertid]", doc, XPathConstants.NODESET);
            Utils.removeInsertIds(comps);
        }
        catch (XPathExpressionException e) {
            this.out.error("Couldn't execute XPath: " + e.getMessage(), e);
            return null;
        }
        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) {
            this.out.error("Couldn't transform 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());
    }

    public boolean generate(String name, String title, String content, String resourceSuperType, String charset, boolean overwrite) {
        javax.jcr.Node compNode;
        block10 : {
            Resource compFolder = this.resolver.getResource("/apps/" + name + "/components");
            if (compFolder == null) {
                this.out.error("Couldn't access component folder: /apps/" + name + "/components");
                return false;
            }
            compNode = (javax.jcr.Node)compFolder.adaptTo(javax.jcr.Node.class);
            try {
                if (!compNode.hasNode("contentpage")) break block10;
                if (overwrite) {
                    compNode.getNode("contentpage").remove();
                    compNode.getSession().save();
                    break block10;
                }
                this.out.error("Component already exists, maybe tick overwrite option");
                return false;
            }
            catch (RepositoryException e) {
                this.out.error("Repository failure: " + e.getMessage(), (Exception)e);
                return false;
            }
        }
        try {
            resourceSuperType = StringUtils.defaultIfEmpty((String)resourceSuperType, (String)"foundation/components/page");
            Hashtable<String, Object> properties = new Hashtable<String, Object>();
            properties.put("sling:resourceSuperType", resourceSuperType);
            properties.put("jcr:title", title + " Content Page");
            properties.put("jcr:description", "The " + title + " Content Page Component");
            javax.jcr.Node comp = Utils.createNode(compNode, "contentpage", "cq:Component", properties, this.out);
            this.out.output("Created contentpage component");
            String pageEncoding = "";
            String contentType = "\"text/html";
            if (charset != null) {
                pageEncoding = "pageEncoding=\"" + charset + "\"";
                contentType = contentType + "; charset=" + charset + "\"";
            } else {
                contentType = contentType + "\"";
            }
            String doctype = "";
            if (content.substring(content.indexOf("<")).toUpperCase().startsWith("<!DOCTYPE")) {
                doctype = content.substring(0, content.indexOf(">")) + ">\n";
            }
            String code = Utils.readFileNode("/libs/wcm/siteimporter/resources/contentpage.tpl", this.resolver, this.out);
            code = code.replace("$PAGEENCODING", pageEncoding);
            code = code.replace("$CONTENTTYPE", "contentType=" + contentType);
            code = code.replace("$DOCTYPE", doctype);
            Utils.createFile(comp, "contentpage.jsp", code, "text/plain", charset, this.out);
            this.out.output("Created contentpage script");
            int headStart = content.toUpperCase().indexOf("<HEAD");
            if (headStart != -1) {
                int headClose = content.indexOf(">", headStart);
                int headEnd = content.toUpperCase().indexOf("</HEAD>");
                String head = content.substring(headClose + 1, headEnd);
                head = Utils.stripTag(head, "title", true, "");
                head = Utils.stripTag(head, "base", false, "href");
                head = Utils.stripTag(head, "meta", false, "content-type");
                head = Utils.stripTag(head, "meta", false, "keywords");
                code = Utils.readFileNode("/libs/wcm/siteimporter/resources/head.tpl", this.resolver, this.out);
                code = code.replace("$PAGEENCODING", pageEncoding);
                code = code.replace("$CONTENTTYPE", contentType);
                code = code.replace("$CONTENT", head);
                Utils.createFile(comp, "head.jsp", code, "text/plain", charset, this.out);
                this.out.output("Created head script");
            }
            int bodyStart = content.toUpperCase().indexOf("<BODY");
            int bodyEnd = content.indexOf(">", bodyStart) + 1;
            String bodyTag = content.substring(bodyStart, bodyEnd);
            int endBodyStart = content.toUpperCase().indexOf("</BODY>");
            String body = content.substring(bodyEnd, endBodyStart);
            code = Utils.readFileNode("/libs/wcm/siteimporter/resources/body.tpl", this.resolver, this.out);
            code = code.replace("$PAGEENCODING", pageEncoding);
            code = code.replace("$BODYTAG", bodyTag);
            code = code.replace("$CONTENT", body);
            Utils.createFile(comp, "body.jsp", code, "text/plain", charset, this.out);
            this.out.output("Created body script");
            code = Utils.readFileNode("/libs/wcm/siteimporter/resources/navimage.png.java.tpl", this.resolver, this.out);
            code = code.replace("$PROJECTNAME", name);
            Utils.createFile(comp, "navimage.png.java", code, "text/plain", charset, this.out);
        }
        catch (RepositoryException e) {
            this.out.error("Repository Exception during creation of component: " + e.getMessage(), (Exception)e);
            return false;
        }
        return true;
    }
}