
com.adobe.cq.wcm.mobile.qrcode.servlet.QRCodeImageGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
* Copyright 2015 Adobe Systems Incorporated
* All Rights Reserved.
*
* NOTICE: All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any. The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/
package com.adobe.cq.wcm.mobile.qrcode.servlet;
import com.day.cq.commons.Externalizer;
import com.day.cq.wcm.commons.AbstractImageServlet;
import com.day.image.Layer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.google.zxing.qrcode.encoder.Encoder;
import com.google.zxing.qrcode.encoder.QRCode;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.commons.osgi.OsgiUtil;
import org.osgi.framework.Constants;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.servlet.Servlet;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Dictionary;
@Component(metatype=true,
label="AEM WCM QR-Code Generator Servlet",
immediate=true)
@Service(value=Servlet.class)
@Properties( {
@Property(name=Constants.SERVICE_DESCRIPTION,
value="QR Code Image Generator"),
@Property(name="sling.servlet.paths",
value="/libs/wcm/mobile/qrcode",
propertyPrivate=true),
@Property(name="sling.servlet.extensions",
value="png",
propertyPrivate=true),
@Property(name="sling.servlet.methods",
value="GET",
propertyPrivate=true)
} )
@SuppressWarnings("serial")
public class QRCodeImageGenerator extends AbstractImageServlet {
@Reference
private Externalizer externalizer = null;
private static final int QR_MARGIN = 2;
private static final String DATA_NAME_WHITELIST = "cq.wcm.qrcode.servlet.whitelist";
private static final String DATA_WHITELIST_LABEL = "Whitelist URL";
private static final String DATA_WHITELIST_DESC = "List of regular expressions (regex) indicating which URLs are allowed for the creation of QR Codes images. The Author and Publish servers, based on the Externalizer service, are automatically whitelisted.";
private static final String DATA_WHITELIST_VALUE1 = "(https://build.phonegap.com/.*)";
@Property(name=QRCodeImageGenerator.DATA_NAME_WHITELIST,
label=QRCodeImageGenerator.DATA_WHITELIST_LABEL,
value={QRCodeImageGenerator.DATA_WHITELIST_VALUE1},
description=QRCodeImageGenerator.DATA_WHITELIST_DESC,
propertyPrivate=false,
cardinality=1)
private String[] dataNameWhitelist;
private String author;
private String publish;
private String errMessage;
private static final Logger log = LoggerFactory.getLogger(QRCodeImageGenerator.class);
protected void activate(ComponentContext componentContext) {
Dictionary properties = componentContext.getProperties();
dataNameWhitelist = OsgiUtil.toStringArray(properties.get(DATA_NAME_WHITELIST));
if (externalizer != null) {
author = externalizer.authorLink(null, "");
publish = externalizer.publishLink(null, "");
}
}
protected Layer createLayer(ImageContext c) throws RepositoryException, IOException {
Layer layer = null;
// Look for url property in image context
String url = c.properties.get("url", "");
// Look for url property in query string
if (url == null || url.length() == 0) {
url = c.request.getParameter("url");
}
int size = Integer.parseInt(c.properties.get("size", "100"));
if (url != null && !url.isEmpty()) {
boolean matchesWhiteListEntry = (url.startsWith(author) || url.startsWith(publish));
// If not the author or publish servers, check the white list of external servers.
if (!matchesWhiteListEntry) {
for (String filterRegex : dataNameWhitelist) {
if (url.matches(filterRegex)) {
matchesWhiteListEntry = true;
break;
}
}
}
if (matchesWhiteListEntry) {
String selector = c.request.getRequestPathInfo().getSelectorString();
if (selector != null && selector.length() > 0) {
size = Integer.parseInt(selector);
}
// Generate the actual QR Code image
try {
QRCode qrcode = new QRCode();
Encoder.encode(url, ErrorCorrectionLevel.L, qrcode);
int qrBaseSize = qrcode.getMatrixWidth();
int baseSize = qrBaseSize + (2 * QR_MARGIN);
if (size < baseSize) size = baseSize;
int qrActualSize = size / baseSize;
int remainder = size % baseSize;
int startPos = ((remainder > 0) ? remainder / 2 : qrActualSize) + (QR_MARGIN * qrActualSize);
// Make BufferedImage to hold QR code
BufferedImage qrImage = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
qrImage.createGraphics();
Graphics2D graphics = (Graphics2D) qrImage.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, size, size);
// Add QR Code to buffered image
graphics.setColor(Color.BLACK);
for (int i = 0; i < qrBaseSize; i++) {
for (int j = 0; j < qrBaseSize; j++) {
if (qrcode.at(i, j) == 1) {
graphics.fillRect(startPos + i * qrActualSize, startPos + j * qrActualSize, qrActualSize, qrActualSize);
}
}
}
layer = new Layer(qrImage);
} catch (Exception e) {
errMessage = e.getMessage();
layer = null;
}
} else {
errMessage = "The following URL in the QR Code request did not match white list of servers: " + url;
}
} else {
errMessage = "QR Code reguest did not contain an url parameter.";
}
return layer;
}
protected void writeLayer(SlingHttpServletRequest req, SlingHttpServletResponse resp, ImageContext c, Layer layer)
throws IOException, RepositoryException {
if (layer == null) {
if (errMessage != null) {
log.error(errMessage);
resp.sendError(HttpServletResponse.SC_FORBIDDEN, errMessage);
errMessage = null;
} else {
resp.sendError(HttpServletResponse.SC_FORBIDDEN);
}
return;
}
super.writeLayer(req, resp, c, layer);
}
protected boolean checkModifiedSince(SlingHttpServletRequest req, SlingHttpServletResponse resp) {
if (req.getResource().adaptTo(Node.class) != null) {
return super.checkModifiedSince(req, resp);
} else {
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy