Amp.java
package sk.iway.iwcm.doc.ninja;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Attribute;
import org.jsoup.nodes.Attributes;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Tag;
import org.jsoup.select.Elements;
import sk.iway.iwcm.Cache;
import sk.iway.iwcm.Constants;
import sk.iway.iwcm.Logger;
import sk.iway.iwcm.Tools;
import sk.iway.iwcm.doc.TemplateDetails;
import sk.iway.iwcm.helpers.RequestHelper;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Amp {
private final HttpServletRequest request;
public Amp(HttpServletRequest request) {
this.request = request;
request.setAttribute("jQueryInserted", "true");
}
private void replaceInObject(String object) {
String html = (String) request.getAttribute(object);
if (Tools.isNotEmpty(html)) {
html = replaceInString(html);
request.setAttribute(object, html);
}
}
public void replaceInRequest() {
String[] objects = Tools.getTokens(Constants.getString("ampObjects","doc_data"), ",");
for (String object : objects) {
replaceInObject(object);
}
}
public String replaceInString(String html) {
if (Tools.isNotEmpty(html)) {
Document document = Jsoup.parseBodyFragment(html);
replaceImages(document);
removeScripts(document);
removeIncludes(document);
return document.body().html();
}
return "";
}
private void replaceImages(Document document) {
Elements elements = document.select("img");
boolean ampImageRealDimensions = Constants.getBoolean("ampImageRealDimensions");
int ampImageRealDimensionsCache = Constants.getInt("ampImageRealDimensionsCache", 0);
Attributes attributes = getAttributes();
for (Element element : elements) {
Element ampImg = new Element(Tag.valueOf("amp-img"), "", attributes.clone());
int width = 0;
int height = 0;
String src = "";
for (Attribute attribute : element.attributes()) {
if ("width".equalsIgnoreCase(attribute.getKey())) {
width = Tools.getIntValue(attribute.getValue(), 0);
continue;
}
if ("height".equalsIgnoreCase(attribute.getKey())) {
height = Tools.getIntValue(attribute.getValue(), 0);
continue;
}
if ("src".equalsIgnoreCase(attribute.getKey())) {
src = attribute.getValue();
}
if ("style".equalsIgnoreCase(attribute.getKey())) {
continue;
}
ampImg.attr(attribute.getKey(), attribute.getValue());
}
if (ampImageRealDimensions && Tools.isNotEmpty(src)) {
if (ampImageRealDimensionsCache > 0) {
Cache c = Cache.getInstance();
String dimensions = c.getObject("ampImageCache-" + src, String.class);
if (Tools.isNotEmpty(dimensions) && dimensions.contains("x")) {
String[] dimesnionsTokens = Tools.getTokens(dimensions, "x");
width = Tools.getIntValue(dimesnionsTokens[0], 0);
height = Tools.getIntValue(dimesnionsTokens[1], 0);
}
}
if (width == 0 || height == 0) {
try {
BufferedImage bimg = ImageIO.read(new File(Tools.getRealPath(src)));
if (bimg != null) {
width = bimg.getWidth();
height = bimg.getHeight();
if (ampImageRealDimensionsCache > 0) {
Cache c = Cache.getInstance();
c.setObject("ampImageCache-" + src, width + "x" + height, ampImageRealDimensionsCache);
}
}
} catch (IOException e) {
sk.iway.iwcm.Logger.error(e);
}
}
}
if (width > 0) {
ampImg.attr("width", "" + width);
}
if (height > 0) {
ampImg.attr("height", "" + height);
}
element.replaceWith(ampImg);
}
}
private void removeScripts(Document document) {
document.select("script").remove();
}
private void removeIncludes(Document document) {
List<String> allowedIncludes = Tools.getStringListValue(Tools.getTokens(Constants.getString("ampAllowedIncludes", "/components/news/news-velocity.jsp"), ","));
String html = document.body().html();
final String regex = "\\!INCLUDE.*\\)!";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(html);
outerloop: while (matcher.find()) {
String match = matcher.group(0);
if (!allowedIncludes.isEmpty()) {
for (String allowedInclude : allowedIncludes) {
if (match.contains(allowedInclude)) {
Logger.debug(Amp.class, String.format("Nechavam include: %s", match));
continue outerloop;
}
}
}
Logger.debug(Amp.class, String.format("Odstranujem include: %s", match));
html = Tools.replace(html, match, "");
}
document.body().html(html);
}
private Attributes getAttributes() {
Attributes attributes = new Attributes();
RequestHelper requestHelper = new RequestHelper(request);
TemplateDetails template = requestHelper.getTemplate();
if (template == null) {
return attributes;
}
int templateId = template.getTempId();
if (templateId < 1) {
return attributes;
}
String constantKey = "ampImgAttributes";
String[] attributesArray = getAttributesArray(Constants.getString(constantKey + templateId, ""));
if (attributesArray.length == 0) {
attributesArray = getAttributesArray(Constants.getString(constantKey, ""));
}
if (attributesArray.length > 0) {
for (String s : attributesArray) {
String[] tokens = Tools.getTokens(s, "=");
attributes.put(tokens[0], Tools.replace(tokens[1], "\"", ""));
}
}
return attributes;
}
private String[] getAttributesArray(String att) {
String attPmd = att;
if (attPmd.contains("\n")) {
attPmd = Tools.replace(attPmd, "\n", " ");
}
return Tools.getTokens(attPmd, " ");
}
}