ResourceServlet.java 11 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Item
 *  javax.jcr.ItemNotFoundException
 *  javax.jcr.Node
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Value
 *  javax.jcr.Workspace
 *  javax.jcr.nodetype.PropertyDefinition
 *  javax.servlet.RequestDispatcher
 *  javax.servlet.Servlet
 *  javax.servlet.ServletConfig
 *  javax.servlet.ServletContext
 *  javax.servlet.ServletException
 *  javax.servlet.ServletOutputStream
 *  javax.servlet.ServletRequest
 *  javax.servlet.ServletResponse
 *  javax.servlet.http.HttpServlet
 *  javax.servlet.http.HttpServletRequest
 *  javax.servlet.http.HttpServletResponse
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Properties
 *  org.apache.felix.scr.annotations.Property
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.jackrabbit.util.Text
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.day.crx.explorer.impl.j2ee;

import com.day.crx.explorer.impl.j2ee.CRXContext;
import com.day.crx.explorer.impl.j2ee.CRXSessionProvider;
import com.day.crx.explorer.impl.j2ee.JCRExplorerServlet;
import com.day.crx.explorer.impl.j2ee.LoginServlet;
import com.day.crx.explorer.impl.j2ee.mapping.Mapping;
import com.day.crx.explorer.impl.j2ee.mapping.RequestMapper;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.jcr.Item;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.Workspace;
import javax.jcr.nodetype.PropertyDefinition;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.Service;
import org.apache.jackrabbit.util.Text;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(immediate=1)
@Service(value={Servlet.class})
@Properties(value={@Property(name="alias", value={"/crx/explorer/repository"})})
public class ResourceServlet
extends HttpServlet {
    public static SimpleDateFormat modificationDateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
    public static SimpleDateFormat creationDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    private static final String PROP_LASTMODIFIED = "jcr:lastModified";
    private static final String PROP_MIMETYPE = "jcr:mimeType";
    private static final Logger log = LoggerFactory.getLogger(ResourceServlet.class);
    private final Map<String, RequestMapper> requestMappers = new HashMap<String, RequestMapper>();
    private CRXSessionProvider sessionProvider = null;

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.spoolResource(request, response, true);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    private boolean spoolResource(HttpServletRequest request, HttpServletResponse response, boolean sendContent) throws IOException {
        int index;
        String resourceHref = Text.escape((String)JCRExplorerServlet.getServletPath(request), (char)'%', (boolean)true);
        String prefix = (String)this.getServletContext().getAttribute("jackrabbit.webdav.simple.resourcepath");
        String pathInfo = request.getPathInfo();
        if (pathInfo == null || pathInfo.length() == 0) {
            log.error("Path info is empty {}", (Object)pathInfo);
            response.sendError(404);
            return false;
        }
        int idx = pathInfo.indexOf(47, 1);
        if (idx < 0) {
            log.error("No workspace in path {}", (Object)pathInfo);
            response.sendError(404);
            return false;
        }
        String path = pathInfo.substring(idx);
        String workspace = pathInfo.substring(1, idx);
        boolean ownSession = false;
        Session repSession = JCRExplorerServlet.getSession(request);
        if (repSession == null) {
            try {
                repSession = LoginServlet.login(CRXContext.getInstance(this.getServletConfig().getServletContext(), request), response);
                ownSession = true;
                if (repSession == null) {
                    return true;
                }
            }
            catch (RepositoryException e) {
                log.error("Error while login: {0}", (Object)e.getMessage());
                return true;
            }
            catch (ServletException e) {
                log.error("Error while login: {0}", (Object)e.getMessage());
                return true;
            }
        }
        if (!repSession.getWorkspace().getName().equals(workspace)) {
            log.info("Illegal cache session. Workspace of session=" + repSession.getWorkspace().getName() + ", but workspace in path=" + workspace);
            response.sendError(404);
            return false;
        }
        try {
            long contentLength;
            InputStream in;
            RequestMapper reqMapper;
            int lastSlash;
            RequestDispatcher rd2;
            String contentType;
            String uri = request.getRequestURI();
            index = 0;
            int pos = uri.lastIndexOf(59);
            if (pos > 0) {
                try {
                    index = Integer.parseInt(uri.substring(pos + 1));
                }
                catch (NumberFormatException e) {
                    // empty catch block
                }
            }
            Item item = null;
            String[] selectors = new String[]{};
            if (repSession.itemExists(path)) {
                item = repSession.getItem(path);
            } else {
                int dot;
                lastSlash = path.lastIndexOf(47);
                if (lastSlash >= 0 && (dot = path.indexOf(46, lastSlash)) > 0) {
                    String handle = path.substring(0, dot);
                    item = repSession.getItem(handle);
                    selectors = Text.explode((String)path.substring(dot), (int)46);
                }
            }
            if (item == null) {
                log.info("Could not resolve property for " + path);
                response.sendError(404);
                lastSlash = 1;
                return (boolean)lastSlash;
            }
            Map<String, RequestMapper> dot = this.requestMappers;
            synchronized (dot) {
                reqMapper = this.requestMappers.get(workspace);
                if (reqMapper == null) {
                    reqMapper = new RequestMapper(repSession);
                    this.requestMappers.put(workspace, reqMapper);
                }
            }
            Mapping map = reqMapper.getMapping(item);
            if (map != null && (rd2 = request.getRequestDispatcher(map.getPath())) != null) {
                try {
                    request.setAttribute("com.day.crx.include.selectors", (Object)selectors);
                    request.setAttribute("com.day.crx.include.item", (Object)item);
                    rd2.include((ServletRequest)request, (ServletResponse)response);
                }
                catch (ServletException e2) {
                    log.error("Error while forwarding.", (Throwable)e2);
                }
                boolean e2 = true;
                return e2;
            }
            if (item.isNode()) {
                boolean rd2 = false;
                return rd2;
            }
            log.debug("Found property at " + item.getPath());
            javax.jcr.Property prop = (javax.jcr.Property)item;
            Node parent = prop.getParent();
            long modificationTime = 0;
            if (parent.hasProperty("jcr:lastModified")) {
                modificationTime = parent.getProperty("jcr:lastModified").getLong();
            }
            if (parent.hasProperty("jcr:mimeType")) {
                contentType = parent.getProperty("jcr:mimeType").getString();
            } else if (prop.getType() == 2) {
                contentType = "application/octet-stream";
            } else {
                String ext = selectors.length > 0 ? selectors[selectors.length - 1] : "txt";
                contentType = this.getServletContext().getMimeType("dummy." + ext);
                if (contentType == null) {
                    contentType = "text/plain";
                }
            }
            if (prop.getDefinition().isMultiple()) {
                Value[] values = prop.getValues();
                if (values == null || index >= values.length) {
                    throw new ItemNotFoundException("Property has no value at index " + index);
                }
                in = values[index].getStream();
                contentLength = prop.getLengths()[index];
            } else {
                contentLength = prop.getLength();
                in = prop.getValue().getStream();
            }
            if (modificationTime <= request.getDateHeader("If-Modified-Since")) {
                log.debug("sending NOT_MODIFIED");
                response.setStatus(304);
                boolean values = true;
                return values;
            }
            if (modificationTime > 0) {
                response.setHeader("Last-Modified", modificationDateFormat.format(new Date(modificationTime)));
            }
            response.setHeader("ETag", "W/\"" + contentLength + "-" + modificationTime + "\"");
            response.setHeader("Content-Type", contentType);
            response.setIntHeader("Content-Length", (int)contentLength);
            if (sendContent) {
                log.debug("spooling data...");
                if (in != null) {
                    int read;
                    ServletOutputStream out = response.getOutputStream();
                    byte[] buffer = new byte[8192];
                    while ((read = in.read(buffer)) >= 0) {
                        out.write(buffer, 0, read);
                    }
                    in.close();
                }
            }
            response.flushBuffer();
            boolean out = true;
            return out;
        }
        catch (ItemNotFoundException e) {
            log.info("Could not resolve property for " + path);
            response.sendError(404);
            index = 1;
            return (boolean)index;
        }
        catch (RepositoryException e) {
            response.sendError(404, e.toString());
            index = 1;
            return (boolean)index;
        }
        finally {
            if (ownSession && repSession != null) {
                repSession.logout();
            }
        }
    }
}