CreateComponentStep.java 11.1 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Service
 *  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.steps;

import com.day.cq.wcm.siteimporter.ImporterContext;
import com.day.cq.wcm.siteimporter.ImporterStep;
import com.day.cq.wcm.siteimporter.ProgressTracker;
import com.day.cq.wcm.siteimporter.ResourcesBoard;
import com.day.cq.wcm.siteimporter.internal.resource.BinaryImporterResource;
import com.day.cq.wcm.siteimporter.internal.resource.CssImporterResource;
import com.day.cq.wcm.siteimporter.internal.resource.HtmlImporterResource;
import com.day.cq.wcm.siteimporter.internal.resource.ImporterResource;
import com.day.cq.wcm.siteimporter.internal.resource.ImporterResourceVisitor;
import com.day.cq.wcm.siteimporter.internal.resource.JsImporterResource;
import com.day.cq.wcm.siteimporter.internal.steps.AbstractImporterStep;
import com.day.cq.wcm.siteimporter.internal.util.PageGenerator;
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.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Service;
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.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

@Component(metatype=0)
@Service(value={ImporterStep.class})
@Properties(value={@org.apache.felix.scr.annotations.Property(name="importerstep.order", intValue={400})})
public class CreateComponentStep
extends AbstractImporterStep
implements ImporterResourceVisitor {
    private static final Pattern LANG_PATTERN = Pattern.compile("(?:<html.*\\s*lang\\s*=\\s*)(?:\"|')([a-zA-Z_]{2,5})(\"|')", 10);

    @Override
    public boolean execute(ImporterContext ctx) {
        ctx.output("Creating contentpage component", "heading");
        ctx.doIndent();
        ImporterResource original = ctx.getBoard().getResource(ctx.getOriginal(), 0, ctx);
        Object object = original.triggerAction(this);
        ctx.undoIndent();
        return object instanceof Boolean && (Boolean)object != false;
    }

    @Override
    public Object performBinary(BinaryImporterResource resource) {
        return null;
    }

    @Override
    public Object performCss(CssImporterResource resource) {
        return null;
    }

    @Override
    public Object performHtml(HtmlImporterResource resource) {
        ImporterContext ctx = resource.getContext();
        if (ctx.getOriginal().equals(resource.getLocation())) {
            String content;
            String charset;
            try {
                content = resource.reload(new ImporterResource.LineProcessor(){

                    @Override
                    public String onLine(String line) {
                        if (line.contains("window.")) {
                            return "//" + line;
                        }
                        return line;
                    }
                });
            }
            catch (IOException e) {
                ctx.error("Could not obtain remote resource " + ctx.getOriginal().toString(), e);
                return false;
            }
            PageGenerator pg = new PageGenerator(ctx.getResolver(), ctx.getService(HtmlParser.class), ctx);
            String originalHtml = pg.rewriteLinks(resource, content, false);
            content = pg.rewriteLinks(resource, content, true);
            ctx.output("Rewrote links to references");
            try {
                charset = resource.getCharset();
            }
            catch (IOException e) {
                charset = null;
            }
            return this.storeOriginalHtml(resource, ctx, originalHtml) && pg.generate(ctx.getProjectName(), ctx.getTitle(), content, ctx.getResourceSuperType(), charset, ctx.isOverwrite());
        }
        return null;
    }

    @Override
    public Object performJs(JsImporterResource resource) {
        return null;
    }

    private boolean storeOriginalHtml(HtmlImporterResource resource, ImporterContext ctx, String html) throws TransformerFactoryConfigurationError {
        Resource designs;
        Matcher matcher = LANG_PATTERN.matcher(html);
        if (matcher.find() && matcher.groupCount() > 1) {
            String langString = matcher.group(1);
            ctx.setDefaultLanguage(langString.substring(0, 2));
        }
        if ((designs = ctx.getResolver().getResource("/etc/designs")) == null) {
            ctx.error("Design folder not found");
            return false;
        }
        String origName = ctx.getProjectName() + "-original.html";
        Node folder = Utils.createPath(designs, "/" + ctx.getProjectName() + "/" + "dev" + "/" + origName, ctx, false);
        if (folder == null) {
            ctx.error("Repository Exception during creation of folder for dev resources");
            return false;
        }
        try {
            String charset;
            String transContent;
            try {
                charset = resource.getCharset();
            }
            catch (IOException e) {
                charset = null;
            }
            folder.setProperty("cqProjectName", ctx.getProjectName());
            folder.setProperty("cqProjectTitle", ctx.getTitle());
            folder.setProperty("cqProjectOriginalUrl", ctx.getOriginal().toExternalForm());
            folder.setProperty("cqResourceSupertype", ctx.getResourceSuperType());
            if (charset != null) {
                folder.setProperty("cqProjectCharset", charset);
            }
            Node download = (transContent = this.injectMarkup(html, charset, ctx)) != null ? Utils.createFile(folder, origName, transContent, "text/html", charset, false, (ProgressTracker)ctx) : Utils.createFile(folder, origName, html, "text/html", charset, false, (ProgressTracker)ctx);
            download.addMixin("cq:ComponentExtractorSource");
            resource.setDownloadLocation(download.getPath());
        }
        catch (Exception e) {
            ctx.error("Exception during storage of original HTML: " + e.getMessage(), e);
            return false;
        }
        return true;
    }

    private String injectMarkup(String content, String charset, ImporterContext ctx) throws TransformerFactoryConfigurationError {
        Document doc = Utils.parse(content, charset, ctx.getService(HtmlParser.class), (ProgressTracker)ctx);
        if (doc == null) {
            return null;
        }
        NodeList head = doc.getElementsByTagName("head");
        if (head.getLength() > 0) {
            org.w3c.dom.Node first = head.item(0).getFirstChild();
            String ctxPath = ctx.getContextPath();
            Element jquery = doc.createElement("script");
            jquery.setAttribute("src", ctxPath + "/etc/clientlibs/granite/jquery.js");
            jquery.setAttribute("type", "text/javascript");
            jquery.setAttribute("cqSiteImporter", "removeFromFinal");
            head.item(0).insertBefore(jquery, first);
            Element granite = doc.createElement("script");
            granite.setAttribute("src", ctxPath + "/etc/clientlibs/granite/utils.js");
            granite.setAttribute("type", "text/javascript");
            granite.setAttribute("cqSiteImporter", "removeFromFinal");
            head.item(0).insertBefore(granite, first);
            Element shared = doc.createElement("script");
            shared.setAttribute("src", ctxPath + "/etc/clientlibs/foundation/shared.js");
            shared.setAttribute("type", "text/javascript");
            shared.setAttribute("cqSiteImporter", "removeFromFinal");
            head.item(0).insertBefore(shared, first);
            Element extjs = doc.createElement("script");
            extjs.setAttribute("src", ctxPath + "/libs/cq/ui/widgets.js");
            extjs.setAttribute("type", "text/javascript");
            extjs.setAttribute("cqSiteImporter", "removeFromFinal");
            head.item(0).insertBefore(extjs, first);
            Element theme = doc.createElement("script");
            theme.setAttribute("src", ctxPath + "/libs/cq/ui/widgets/themes/default.js");
            theme.setAttribute("type", "text/javascript");
            theme.setAttribute("cqSiteImporter", "removeFromFinal");
            head.item(0).insertBefore(theme, first);
        }
        NodeList body = doc.getElementsByTagName("body");
        Utils.injectInsertIds(body);
        NodeList scriptTags = doc.getElementsByTagName("script");
        for (int i = 0; i < scriptTags.getLength(); ++i) {
            org.w3c.dom.Node node = scriptTags.item(i);
            String text = node.getTextContent();
            if (StringUtils.isBlank((String)text)) {
                node.appendChild(doc.createComment(""));
                continue;
            }
            node.setTextContent("\n" + text + "\n");
        }
        NodeList divTags = doc.getElementsByTagName("div");
        for (int i2 = 0; i2 < divTags.getLength(); ++i2) {
            org.w3c.dom.Node node = divTags.item(i2);
            if (node.getChildNodes().getLength() != 0 || !StringUtils.isBlank((String)node.getTextContent())) continue;
            node.appendChild(doc.createComment(""));
        }
        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("cdata-section-elements", "script");
            xformer.setOutputProperty("omit-xml-declaration", "yes");
            xformer.transform(source, new StreamResult(transContent));
        }
        catch (Exception e) {
            ctx.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());
    }

}