TreeServlet.java 8.19 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.jcr.Node
 *  javax.jcr.NodeIterator
 *  javax.jcr.Property
 *  javax.jcr.RepositoryException
 *  javax.jcr.Session
 *  javax.jcr.Workspace
 *  javax.jcr.nodetype.NodeType
 *  javax.jcr.nodetype.NodeTypeManager
 *  javax.jcr.query.InvalidQueryException
 *  javax.jcr.query.Query
 *  javax.jcr.query.QueryManager
 *  javax.jcr.query.QueryResult
 *  javax.servlet.ServletException
 *  javax.servlet.http.HttpServletRequest
 *  javax.servlet.http.HttpServletResponse
 *  org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter
 *  org.apache.jackrabbit.util.ISO9075
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.io.JSONWriter
 *  org.osgi.framework.BundleContext
 *  org.slf4j.Logger
 */
package com.day.crx.delite.impl.servlets;

import com.day.crx.delite.impl.AbstractServlet;
import com.day.crx.delite.impl.support.RequestData;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Workspace;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter;
import org.apache.jackrabbit.util.ISO9075;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;

public class TreeServlet
extends AbstractServlet {
    public TreeServlet(BundleContext bc) {
        super(bc);
    }

    private void writeNode(JSONWriter out, Node parent, String filterType, String filterName) throws JSONException, RepositoryException {
        NodeIterator nodes;
        out.array();
        boolean orderable = parent.getPrimaryNodeType().hasOrderableChildNodes();
        NodeIterator nodeIterator = nodes = orderable ? parent.getNodes() : this.orderNodesByName(parent.getNodes());
        while (nodes.hasNext()) {
            Node node = nodes.nextNode();
            boolean typeMatch = this.isType(node, filterType) && this.isName(node, filterName);
            boolean descendantsTypeMatch = this.hasDescendantsOfType(node, filterType, filterName);
            if (!typeMatch && !descendantsTypeMatch) continue;
            out.object();
            out.key("name").value((Object)node.getName());
            String title = node.getName();
            if (node.hasProperty("jcr:title")) {
                title = node.getProperty("jcr:title").getString();
            }
            if (title != null) {
                title = title.replaceAll("<", "&lt;");
            }
            out.key("title").value((Object)title);
            out.key("text").value((Object)title);
            if (node.hasProperty("jcr:description")) {
                String desc = node.getProperty("jcr:description").getString();
                if (desc != null) {
                    desc = desc.replaceAll("<", "&lt;");
                }
                out.key("description").value((Object)desc);
            }
            out.key("type").value((Object)node.getPrimaryNodeType().getName());
            if (node.hasProperty("sling:resourceType")) {
                out.key("restype").value((Object)node.getProperty("sling:resourceType").getString());
            }
            if (filterType == null && filterName == null) {
                boolean leaf = !node.getNodes().hasNext();
                out.key("leaf").value(leaf);
                out.key("cls").value((Object)(leaf ? "file" : "folder"));
            } else {
                out.key("leaf").value(!descendantsTypeMatch);
                out.key("cls").value((Object)(typeMatch ? "match" : "folder"));
            }
            out.endObject();
        }
        out.endArray();
    }

    private boolean isName(Node node, String name) throws RepositoryException {
        if (name == null) {
            return true;
        }
        return node.getName().equals(name);
    }

    private boolean isType(Node node, String type) throws RepositoryException {
        if (type == null) {
            return true;
        }
        if (node.getPrimaryNodeType().getName().equals(type)) {
            return true;
        }
        if (node.hasProperty("sling:resourceType") && node.getProperty("sling:resourceType").getString().equals(type)) {
            return true;
        }
        if (node.hasProperty("sling:superResourceType") && node.getProperty("sling:superResourceType").getString().equals(type)) {
            return true;
        }
        return false;
    }

    private boolean hasDescendantsOfType(Node node, String type, String name) {
        if (type == null && name == null) {
            return true;
        }
        try {
            String query = "/jcr:root" + ISO9075.encodePath((String)node.getPath()) + "//";
            if (type == null) {
                query = query + name;
            } else if (type.contains(":")) {
                try {
                    if (!node.getSession().getWorkspace().getNodeTypeManager().hasNodeType(type)) {
                        return false;
                    }
                }
                catch (RepositoryException e) {
                    return false;
                }
                query = query + "element(" + (name == null ? "*" : name) + ", " + type + ")";
            } else {
                query = query + (name == null ? "*" : name) + "[@sling:resourceType='" + type + "' or @sling:superResourceType='" + type + "']";
            }
            try {
                QueryManager qm = node.getSession().getWorkspace().getQueryManager();
                NodeIterator nodes = qm.createQuery(query, "xpath").execute().getNodes();
                return nodes.hasNext();
            }
            catch (InvalidQueryException iqe) {
                this.logger.error("Could not run invalid query '" + query + "'.");
                return true;
            }
        }
        catch (RepositoryException e) {
            this.logger.error("Could not run query", (Throwable)e);
            return true;
        }
    }

    private NodeIterator orderNodesByName(NodeIterator nodeIter) throws RepositoryException {
        ArrayList<Node> nodeList = new ArrayList<Node>((int)nodeIter.getSize());
        while (nodeIter.hasNext()) {
            nodeList.add(nodeIter.nextNode());
        }
        Collections.sort(nodeList, new Comparator<Node>(){

            @Override
            public int compare(Node a, Node b) {
                try {
                    return a.getName().compareToIgnoreCase(b.getName());
                }
                catch (RepositoryException e) {
                    return 0;
                }
            }
        });
        return new NodeIteratorAdapter(nodeList.iterator());
    }

    protected void doService(HttpServletRequest request, HttpServletResponse res, Session session) throws ServletException, IOException {
        res.setContentType("application/json");
        res.setCharacterEncoding("UTF-8");
        PrintWriter pw = res.getWriter();
        JSONWriter writer = new JSONWriter((Writer)pw);
        try {
            RequestData req = new RequestData(request);
            String path = req.getParameter("path");
            if (path == null) {
                res.sendError(400, "Path parameter is missing");
                return;
            }
            String type = req.getParameter("type");
            String name = req.getParameter("name");
            if (!session.nodeExists(path)) {
                res.sendError(404);
            }
            Node node = session.getNode(path);
            this.writeNode(writer, node, type, name);
        }
        catch (Exception re) {
            this.logger.error("Unable to search", (Throwable)re);
            res.sendError(500);
        }
    }

}