ResourceSource.java 8.2 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.servlet.RequestDispatcher
 *  javax.servlet.ServletException
 *  javax.servlet.ServletOutputStream
 *  javax.servlet.ServletRequest
 *  javax.servlet.ServletResponse
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestDispatcherOptions
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceMetadata
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ResourceUtil
 *  org.apache.sling.api.wrappers.SlingHttpServletResponseWrapper
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.cq.rewriter.xml;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.excalibur.source.Source;
import org.apache.excalibur.source.SourceException;
import org.apache.excalibur.source.SourceNotFoundException;
import org.apache.excalibur.source.SourceUtil;
import org.apache.excalibur.source.SourceValidity;
import org.apache.excalibur.source.impl.AbstractSource;
import org.apache.excalibur.source.validity.TimeStampValidity;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestDispatcherOptions;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceMetadata;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.wrappers.SlingHttpServletResponseWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ResourceSource
extends AbstractSource
implements Source {
    private static final Logger LOGGER = LoggerFactory.getLogger((String)ResourceSource.class.getName());
    private final Resource location;
    private String mimeType;
    private InputStream inputStream;
    private final SlingHttpServletRequest request;
    private final SlingHttpServletResponse response;
    private final String path;
    private static final String BYPASS_ATTR = "com.day.cq.wcm.api.components.ComponentContext/bypass";

    public ResourceSource(ResourceResolver resolver, String systemId, SlingHttpServletRequest request, SlingHttpServletResponse response) throws MalformedURLException {
        int repPos;
        int pos = SourceUtil.indexOfSchemeColon(systemId);
        if (pos == -1 || !systemId.startsWith("://", pos)) {
            throw new MalformedURLException("Invalid format for ResourceSource : " + systemId);
        }
        this.request = request;
        this.response = response;
        while ((repPos = systemId.indexOf("/_x")) != -1) {
            if (repPos + 7 >= systemId.length() || systemId.charAt(repPos + 7) != '_') continue;
            String u = systemId.substring(repPos + 5, repPos + 6);
            String l = systemId.substring(repPos + 6, repPos + 7);
            int c = Integer.valueOf(u) * 16 + Integer.valueOf(l);
            systemId = systemId.substring(0, repPos + 1) + (char)c + systemId.substring(repPos + 8);
        }
        this.path = systemId.substring(pos + 2);
        Resource rsrc = resolver.resolve(this.path);
        this.location = ResourceUtil.isNonExistingResource((Resource)rsrc) ? null : rsrc;
        this.setSystemId(systemId);
        this.setScheme(systemId.substring(0, pos));
    }

    @Override
    public boolean exists() {
        return this.location != null;
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    @Override
    protected void getInfos() {
        super.getInfos();
        this.mimeType = null;
        if (!this.exists()) {
            return;
        }
        this.inputStream = (InputStream)this.location.adaptTo(InputStream.class);
        if (this.inputStream != null) {
            this.mimeType = this.location.getResourceMetadata().getContentType();
            this.setLastModified(this.location.getResourceMetadata().getModificationTime());
            this.setContentLength(this.location.getResourceMetadata().getContentLength());
        } else {
            Object oldValue = this.request.getAttribute("com.day.cq.wcm.api.components.ComponentContext/bypass");
            try {
                this.request.setAttribute("com.day.cq.wcm.api.components.ComponentContext/bypass", (Object)"true");
                RequestDispatcherOptions options = new RequestDispatcherOptions();
                OutputResponse resp = new OutputResponse(this.response);
                this.request.getRequestDispatcher(this.path, options).include((ServletRequest)this.request, (ServletResponse)resp);
                this.inputStream = resp.getInputStream();
                this.mimeType = resp.getContentType();
                this.setContentLength(resp.getContentLength());
            }
            catch (IOException ioe) {
                LOGGER.error("Unable to stream resource " + (Object)this.location, (Throwable)ioe);
            }
            catch (ServletException se) {
                LOGGER.error("Unable to stream resource " + (Object)this.location, (Throwable)se);
            }
            finally {
                if (oldValue == null) {
                    this.request.removeAttribute("com.day.cq.wcm.api.components.ComponentContext/bypass");
                } else {
                    this.request.setAttribute("com.day.cq.wcm.api.components.ComponentContext/bypass", oldValue);
                }
            }
        }
    }

    @Override
    public String getMimeType() {
        this.checkInfos();
        return this.mimeType;
    }

    @Override
    public InputStream getInputStream() throws IOException, SourceException {
        this.checkInfos();
        if (!this.exists() || this.inputStream == null) {
            throw new SourceNotFoundException(this.getURI());
        }
        return this.inputStream;
    }

    @Override
    public SourceValidity getValidity() {
        return new TimeStampValidity(this.getLastModified());
    }

    private static final class OutputResponse
    extends SlingHttpServletResponseWrapper {
        private ByteArrayOutputStream out;
        private String contentType;

        public OutputResponse(SlingHttpServletResponse wrappedResponse) {
            super(wrappedResponse);
        }

        public InputStream getInputStream() {
            if (this.out != null) {
                return new ByteArrayInputStream(this.out.toByteArray());
            }
            return null;
        }

        public int getContentLength() {
            if (this.out != null) {
                return this.out.toByteArray().length;
            }
            return 0;
        }

        public ServletOutputStream getOutputStream() throws IOException {
            if (this.out == null) {
                this.out = new ByteArrayOutputStream();
            }
            return new ServletOutputStream(){

                public void write(byte[] b, int off, int len) throws IOException {
                    OutputResponse.this.out.write(b, off, len);
                }

                public void write(byte[] b) throws IOException {
                    OutputResponse.this.out.write(b);
                }

                public void write(int b) throws IOException {
                    OutputResponse.this.out.write(b);
                }
            };
        }

        public void setCharacterEncoding(String charset) {
        }

        public void setContentLength(int len) {
        }

        public void setContentType(String type) {
            this.contentType = type;
        }

        public String getContentType() {
            return this.contentType;
        }

        public PrintWriter getWriter() throws IOException {
            throw new IOException("Writer not supported.");
        }

        public void flushBuffer() {
        }

        public void reset() {
        }

        public void resetBuffer() {
        }

    }

}