LinkTransformer.java 6.49 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.Externalizer
 *  org.apache.cocoon.xml.sax.AttributesImpl
 *  org.apache.commons.lang.StringEscapeUtils
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.rewriter.DefaultTransformer
 *  org.apache.sling.rewriter.ProcessingComponentConfiguration
 *  org.apache.sling.rewriter.ProcessingContext
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.cq.mcm.campaign.impl;

import com.day.cq.commons.Externalizer;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.cocoon.xml.sax.AttributesImpl;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.rewriter.DefaultTransformer;
import org.apache.sling.rewriter.ProcessingComponentConfiguration;
import org.apache.sling.rewriter.ProcessingContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

public class LinkTransformer
extends DefaultTransformer {
    private static final String[] TAGS = new String[]{"img", "a", "td", "th"};
    private static final String[] ATTRIBS = new String[]{"src", "href", "background", "background"};
    private static final Pattern pattern = Pattern.compile("(<%[=@].*?%>)");
    private final Logger log;
    private Externalizer externalizer;
    private ResourceResolver resourceResolver;
    private boolean isEnabled;

    public LinkTransformer(Externalizer externalizer) {
        this.log = LoggerFactory.getLogger(this.getClass());
        this.externalizer = externalizer;
        this.isEnabled = false;
    }

    private String getAttrib(Attributes atts, String name) {
        String value = null;
        int index = atts.getIndex(name);
        if (index >= 0) {
            value = atts.getValue(index);
        }
        return value;
    }

    private AttributesImpl createOrGetMutableAttribs(AttributesImpl current, Attributes readOnly) {
        if (current != null) {
            return current;
        }
        return new AttributesImpl(readOnly);
    }

    public void init(ProcessingContext context, ProcessingComponentConfiguration config) throws IOException {
        super.init(context, config);
        SlingHttpServletRequest request = context.getRequest();
        this.resourceResolver = request.getResourceResolver();
        RequestPathInfo pathInfo = request.getRequestPathInfo();
        String[] selectors = pathInfo.getSelectors();
        if (selectors != null && selectors.length >= 2 && selectors[0].equals("campaign") && selectors[1].equals("content")) {
            this.isEnabled = true;
        }
        Object[] arrobject = new String[2];
        arrobject[0] = this.isEnabled ? "enabled" : "disabled";
        arrobject[1] = request.getRequestURI();
        this.log.debug("LinkTransformer {} for URL {}", arrobject);
        if (this.isEnabled) {
            this.log.debug("Rewriting links to publish instance.");
        }
    }

    private String createPlaceholder(String link, int counter) {
        StringBuilder placeholder = new StringBuilder("_" + counter);
        while (link.contains(placeholder)) {
            placeholder.insert(0, '_');
        }
        return placeholder.toString();
    }

    private String externalizeLink(String link) {
        link = StringEscapeUtils.unescapeHtml((String)link);
        int counter = 0;
        HashMap<String, String> replacements = new HashMap<String, String>();
        Matcher matcher = pattern.matcher(link);
        while (matcher.find()) {
            String acExpression = matcher.group(1);
            String placeholder = this.createPlaceholder(link, counter++);
            link = link.replaceFirst(Pattern.quote(acExpression), placeholder);
            replacements.put(placeholder, acExpression);
        }
        String path = link;
        String fragQuery = "";
        int queryPos = link.indexOf("?");
        if (queryPos > 0) {
            path = link.substring(0, queryPos);
            fragQuery = link.substring(queryPos);
        } else {
            int fragPos = link.indexOf("#");
            if (fragPos > 0) {
                path = link.substring(0, fragPos);
                fragQuery = link.substring(fragPos);
            }
        }
        try {
            path = URLDecoder.decode(path, "UTF-8");
        }
        catch (UnsupportedEncodingException uee) {
            // empty catch block
        }
        link = this.externalizer.publishLink(this.resourceResolver, path) + fragQuery;
        for (Map.Entry replacement : replacements.entrySet()) {
            String placeholder = (String)replacement.getKey();
            String acExpression = (String)replacement.getValue();
            link = link.replaceFirst(placeholder, acExpression);
        }
        link = StringEscapeUtils.escapeHtml((String)link);
        return link;
    }

    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
        Attributes mutableAttribs = null;
        if (this.isEnabled) {
            int pos = 0;
            for (String tag : TAGS) {
                String link;
                String attrib = ATTRIBS[pos++];
                if (!tag.equals(localName) || !this.shouldRewriteLink(link = this.getAttrib(atts, attrib))) continue;
                mutableAttribs = this.createOrGetMutableAttribs((AttributesImpl)mutableAttribs, atts);
                String rewrittenLink = this.externalizeLink(link);
                mutableAttribs.updateCDATAAttribute(attrib, rewrittenLink);
            }
        }
        super.startElement(uri, localName, qName, mutableAttribs != null ? mutableAttribs : atts);
    }

    private boolean shouldRewriteLink(String link) {
        if (link == null) {
            return false;
        }
        if (link.startsWith("<%") && link.indexOf("%>") > 0) {
            return false;
        }
        if (link.startsWith("&lt;%") && link.indexOf("%&gt;") > 0) {
            return false;
        }
        if (link.startsWith("http://") || link.startsWith("https://")) {
            return false;
        }
        return true;
    }
}