AbstractImageServlet.java 12 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.day.cq.commons.DiffInfo
 *  com.day.cq.commons.DiffInfo$TYPE
 *  com.day.cq.commons.ImageResource
 *  com.day.cq.commons.SlingRepositoryException
 *  com.day.cq.wcm.api.Page
 *  com.day.cq.wcm.api.PageManager
 *  com.day.cq.wcm.api.components.Component
 *  com.day.cq.wcm.api.designer.Style
 *  com.day.image.Layer
 *  javax.jcr.Node
 *  javax.jcr.RepositoryException
 *  javax.servlet.ServletException
 *  javax.servlet.ServletOutputStream
 *  javax.servlet.http.HttpServletRequest
 *  javax.servlet.http.HttpServletResponse
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.apache.sling.api.servlets.SlingSafeMethodsServlet
 */
package com.day.cq.wcm.commons;

import com.day.cq.commons.DiffInfo;
import com.day.cq.commons.ImageResource;
import com.day.cq.commons.SlingRepositoryException;
import com.day.cq.wcm.api.Page;
import com.day.cq.wcm.api.PageManager;
import com.day.cq.wcm.api.components.Component;
import com.day.cq.wcm.api.designer.Style;
import com.day.cq.wcm.commons.RequestHelper;
import com.day.cq.wcm.commons.WCMUtils;
import com.day.image.Layer;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.Stroke;
import java.awt.geom.Rectangle2D;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Calendar;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;

public abstract class AbstractImageServlet
extends SlingSafeMethodsServlet {
    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        try {
            if (this.checkModifiedSince(request, response)) {
                return;
            }
            String type = this.getImageType(request.getRequestPathInfo().getExtension());
            if (type == null) {
                response.sendError(404, "Image type not supported");
                return;
            }
            ImageContext context = new ImageContext(request, type);
            Layer layer = this.createLayer(context);
            if (layer != null) {
                this.applyDiff(layer, context);
            }
            this.writeLayer(request, response, context, layer);
        }
        catch (RepositoryException e) {
            throw new SlingRepositoryException(e);
        }
    }

    protected void writeLayer(SlingHttpServletRequest request, SlingHttpServletResponse response, ImageContext context, Layer layer) throws IOException, RepositoryException {
        this.writeLayer(request, response, context, layer, this.getImageQuality());
    }

    protected void writeLayer(SlingHttpServletRequest request, SlingHttpServletResponse response, ImageContext context, Layer layer, double quality) throws IOException, RepositoryException {
        String imageType = this.getImageType();
        if (context != null && context.requestImageType != null && context.requestImageType.startsWith("image/")) {
            imageType = context.requestImageType;
        }
        response.setContentType(imageType);
        int size = layer.getHeight() * layer.getWidth();
        if (size < 1048576) {
            ByteArrayOutputStream out = new ByteArrayOutputStream(size);
            layer.write(imageType, quality, (OutputStream)out);
            byte[] bytes = out.toByteArray();
            response.setContentLength(bytes.length);
            response.getOutputStream().write(bytes);
        } else {
            layer.write(imageType, quality, (OutputStream)response.getOutputStream());
        }
    }

    protected String getImageType() {
        return "image/png";
    }

    protected String getImageType(String ext) {
        if (ext != null) {
            ext = ext.toLowerCase();
        }
        if ("png".equals(ext)) {
            return "image/png";
        }
        if ("gif".equals(ext)) {
            return "image/gif";
        }
        if ("jpg".equals(ext) || "jpeg".equals(ext)) {
            return "image/jpeg";
        }
        return null;
    }

    protected double getImageQuality() {
        return 1.0;
    }

    protected boolean checkModifiedSince(SlingHttpServletRequest req, SlingHttpServletResponse resp) {
        Resource resource = req.getResource();
        Node node = (Node)resource.adaptTo(Node.class);
        if (node != null) {
            return RequestHelper.handleIfModifiedSince((HttpServletRequest)req, (HttpServletResponse)resp, node);
        }
        ValueMap properties = (ValueMap)resource.adaptTo(ValueMap.class);
        if (properties != null) {
            return RequestHelper.handleIfModifiedSince((HttpServletRequest)req, (HttpServletResponse)resp, properties);
        }
        return false;
    }

    protected abstract Layer createLayer(ImageContext var1) throws RepositoryException, IOException;

    protected boolean applyDiff(Layer layer, ImageContext c) {
        if (layer == null || c.diffInfo == null) {
            return false;
        }
        if (this.isRemovedDiff(c)) {
            layer.setPaint((Paint)Color.RED);
            layer.setStroke((Stroke)new BasicStroke(2.0f));
            layer.drawLine(0.0f, 0.0f, (float)layer.getWidth(), (float)layer.getHeight());
            layer.drawLine((float)layer.getWidth(), 0.0f, 0.0f, (float)layer.getHeight());
            return true;
        }
        if (this.isAddedDiff(c)) {
            layer.setPaint((Paint)Color.GREEN);
            layer.setStroke((Stroke)new BasicStroke(3.0f));
            layer.drawRect((Rectangle2D)new Rectangle(layer.getWidth(), layer.getHeight()));
            return true;
        }
        if (this.isModifiedDiff(c)) {
            layer.setPaint((Paint)Color.RED);
            layer.setStroke((Stroke)new BasicStroke(3.0f));
            layer.drawRect((Rectangle2D)new Rectangle(layer.getWidth(), layer.getHeight()));
            return true;
        }
        return false;
    }

    protected ImageResource createImageResource(Resource resource) {
        return new ImageResource(resource);
    }

    protected boolean isModifiedDiff(ImageContext c) {
        Rectangle r0;
        Dimension d1;
        Rectangle r1;
        if (c.diffInfo == null || c.diffInfo.getContent() == null) {
            return false;
        }
        ImageResource img0 = this.createImageResource(c.resource);
        if (!img0.hasContent()) {
            return false;
        }
        ImageResource img1 = this.createImageResource(c.diffInfo.getContent());
        if (!img1.hasContent()) {
            return false;
        }
        try {
            Calendar c0 = img0.getLastModified();
            Calendar c1 = img1.getLastModified();
            if (!(c0 == c1 || c0 != null && c0.equals(c1))) {
                return true;
            }
        }
        catch (RepositoryException e) {
            // empty catch block
        }
        if (!((r0 = img0.getCropRect()) == (r1 = img1.getCropRect()) || r0 != null && r0.equals(r1))) {
            return true;
        }
        if (img0.getRotation() != img1.getRotation()) {
            return true;
        }
        Dimension d0 = new Dimension(img0.get(img0.getItemName("width"), 0), img0.get(img0.getItemName("height"), 0));
        return !d0.equals(d1 = new Dimension(img1.get(img1.getItemName("width"), 0), img1.get(img1.getItemName("height"), 0)));
    }

    protected boolean isAddedDiff(ImageContext c) {
        if (c.diffInfo == null) {
            return false;
        }
        ImageResource img0 = this.createImageResource(c.resource);
        if (!img0.hasContent()) {
            return false;
        }
        if (c.diffInfo.getType() == DiffInfo.TYPE.ADDED) {
            return true;
        }
        if (c.resource.getPath().contains("jcr:frozenNode")) {
            return false;
        }
        Resource diffContent = c.diffInfo.getContent();
        if (diffContent == null) {
            return true;
        }
        ImageResource img1 = this.createImageResource(diffContent);
        if (!img1.hasContent()) {
            return true;
        }
        return false;
    }

    protected boolean isRemovedDiff(ImageContext c) {
        if (c.diffInfo == null) {
            return false;
        }
        Resource diffContent = c.diffInfo.getContent();
        if (diffContent == null) {
            return false;
        }
        ImageResource img1 = this.createImageResource(diffContent);
        if (!img1.hasContent()) {
            return false;
        }
        if (c.diffInfo.getType() == DiffInfo.TYPE.REMOVED) {
            return true;
        }
        ImageResource img0 = this.createImageResource(c.resource);
        if (!img0.hasContent()) {
            return true;
        }
        return false;
    }

    public static class ImageContext {
        public final SlingHttpServletRequest request;
        public final Resource resource;
        public final Resource defaultResource;
        public final ResourceResolver resolver;
        public final Node node;
        public final ValueMap properties;
        public final Style style;
        public final Page currentPage;
        public final ValueMap pageProperties;
        public final Component component;
        public final String requestImageType;
        public final DiffInfo diffInfo;

        public ImageContext(SlingHttpServletRequest request, String type) {
            String vLabel;
            this.request = request;
            this.resource = request.getResource();
            this.resolver = request.getResourceResolver();
            this.node = (Node)this.resource.adaptTo(Node.class);
            ValueMap props = (ValueMap)this.resource.adaptTo(ValueMap.class);
            this.properties = props == null ? ValueMap.EMPTY : props;
            this.style = WCMUtils.getStyle(request);
            PageManager pageManager = (PageManager)this.resolver.adaptTo(PageManager.class);
            this.currentPage = pageManager.getContainingPage(this.resource);
            this.pageProperties = this.currentPage == null ? ValueMap.EMPTY : this.currentPage.getProperties();
            this.component = WCMUtils.getComponent(this.resource);
            this.requestImageType = type;
            Resource vRes = null;
            DiffInfo.TYPE diffType = null;
            String vType = request.getParameter("cq_diffType");
            if (vType != null) {
                try {
                    diffType = DiffInfo.TYPE.valueOf((String)vType);
                }
                catch (IllegalArgumentException e) {
                    // empty catch block
                }
            }
            if ((vLabel = request.getParameter("cq_diffTo")) != null && (vRes = DiffInfo.getVersionedResource((Resource)this.resource, (String)vLabel)) == null && diffType == null && !this.resource.getPath().contains("jcr:frozenNode")) {
                diffType = DiffInfo.TYPE.ADDED;
            }
            String defaultResourcePath = request.getParameter("defaultImagePath");
            Resource defRes = null;
            if (defaultResourcePath != null) {
                defRes = this.resolver.resolve(defaultResourcePath);
            }
            this.defaultResource = defRes;
            this.diffInfo = vRes != null || diffType != null ? new DiffInfo(vRes, diffType == null ? DiffInfo.TYPE.SAME : diffType) : null;
        }
    }

}