LinkTransformer.java
6.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
* 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("<%") && link.indexOf("%>") > 0) {
return false;
}
if (link.startsWith("http://") || link.startsWith("https://")) {
return false;
}
return true;
}
}