GetServlet.java 8.01 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.servlet.ServletException
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.servlets.SlingSafeMethodsServlet
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.io.JSONWriter
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.socialgraph.impl.rest;

import com.adobe.granite.socialgraph.Direction;
import com.adobe.granite.socialgraph.GraphNode;
import com.adobe.granite.socialgraph.Relationship;
import com.adobe.granite.socialgraph.SocialGraph;
import com.adobe.granite.socialgraph.impl.rest.RequestInfo;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/*
 * This class specifies class file version 49.0 but uses Java 6 signatures.  Assumed Java 6.
 */
public class GetServlet
extends SlingSafeMethodsServlet {
    private static final Logger log = LoggerFactory.getLogger(GetServlet.class);
    private static final String REQUEST_PARAM_INVERSE = "inverse";

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        SocialGraph graph = (SocialGraph)request.getResourceResolver().adaptTo(SocialGraph.class);
        if (graph == null) {
            response.sendError(500, "Social graph not available.");
            return;
        }
        RequestInfo info = new RequestInfo(request);
        if (info.getId() == null) {
            this.sendUsage(request, response);
            return;
        }
        if (!"json".equals(info.getExtension())) {
            // empty if block
        }
        response.setContentType("application/json");
        JSONWriter w = new JSONWriter((Writer)response.getWriter());
        GraphNode node = graph.getNode(info.getId());
        if (node == null) {
            log.warn("No social graph node for user {}", (Object)info.getId());
            response.sendError(404);
            return;
        }
        if (info.getListType() == null) {
            try {
                this.writeGraphNode(w, node);
                return;
            }
            catch (JSONException e) {
                IOException io = new IOException("Error while writing graph node.");
                io.initCause((Throwable)e);
                throw io;
            }
        }
        if (!"relationships".equals(info.getListType())) {
            log.warn("Only 'relationships' collection supported", (Object)info.getListType());
            response.sendError(404);
            return;
        }
        if (info.getRelationshipType() == null) {
            try {
                Direction dir = "true".equals(request.getParameter("inverse")) ? Direction.INCOMING : Direction.OUTGOING;
                this.writeRelationships(w, node, dir);
                return;
            }
            catch (JSONException e) {
                IOException io = new IOException("Error while writing relationships.");
                io.initCause((Throwable)e);
                throw io;
            }
        }
        if (info.getOtherId() == null) {
            try {
                Direction dir = "true".equals(request.getParameter("inverse")) ? Direction.INCOMING : Direction.OUTGOING;
                this.writeRelationships(w, node, dir, info.getRelationshipType());
                return;
            }
            catch (JSONException e) {
                IOException io = new IOException("Error while writing relationships.");
                io.initCause((Throwable)e);
                throw io;
            }
        }
        if (info.getSegments().length == 4) {
            GraphNode other = graph.getNode(info.getOtherId());
            if (other == null) {
                response.sendError(404);
                return;
            }
            Relationship r = node.getRelationship(Direction.OUTGOING, other, info.getRelationshipType());
            if (r == null) {
                response.sendError(404);
                return;
            }
            try {
                this.writeRelationship(w, r);
                return;
            }
            catch (JSONException e) {
                IOException io = new IOException("Error while writing relationship.");
                io.initCause((Throwable)e);
                throw io;
            }
        }
        response.sendError(404);
    }

    private void writeRelationship(JSONWriter w, Relationship r) throws JSONException, IOException {
        w.object();
        this.dumpMap(w, r);
        w.key("isBidirectional").value(r.isBidirectional());
        if (r.isVirtual()) {
            w.key("isVirtual").value(true);
        }
        w.endObject();
    }

    private void writeRelationships(JSONWriter w, GraphNode node, Direction dir) throws IOException, JSONException {
        HashMap<String, HashMap<String, Relationship>> map = new HashMap<String, HashMap<String, Relationship>>();
        for (Relationship r : node.getRelationships(dir, new String[0])) {
            GraphNode other = r.getOtherNode(node);
            if (other == null) continue;
            HashMap<String, Relationship> rels = (HashMap<String, Relationship>)map.get(r.getType());
            if (rels == null) {
                rels = new HashMap<String, Relationship>();
                map.put(r.getType(), rels);
            }
            rels.put(other.getId(), r);
        }
        w.object();
        for (String type : map.keySet()) {
            w.key(type).object();
            Map rels = (Map)map.get(type);
            for (String userid : rels.keySet()) {
                w.key(userid);
                this.writeRelationship(w, (Relationship)rels.get(userid));
            }
            w.endObject();
        }
        w.endObject();
    }

    private void writeRelationships(JSONWriter w, GraphNode node, Direction dir, String type) throws IOException, JSONException {
        w.object();
        for (Relationship r : node.getRelationships(dir, type)) {
            GraphNode other = r.getOtherNode(node);
            if (other == null) continue;
            w.key(other.getId());
            this.writeRelationship(w, r);
        }
        w.endObject();
    }

    private void writeGraphNode(JSONWriter w, GraphNode node) throws IOException, JSONException {
        w.object();
        w.key("id").value((Object)node.getId());
        if (node.isVirtual()) {
            w.key("isVirtual").value(true);
        }
        this.dumpMap(w, node);
        w.endObject();
    }

    private void dumpMap(JSONWriter w, Map<String, Object> map) throws JSONException {
        for (Map.Entry<String, Object> e : map.entrySet()) {
            String name = e.getKey();
            if ("jcr:primaryType".equals(name)) continue;
            w.key(name);
            this.dumpValue(w, e.getValue());
        }
    }

    private void sendUsage(SlingHttpServletRequest request, SlingHttpServletResponse response) throws IOException {
        PrintWriter w = new PrintWriter(response.getWriter());
        w.println("<html><head><title>Social Graph</title></head><body>");
        w.println("<h1>Social Graph Servlet - Usage</h1>");
        w.println("Format: <code>/bin/granite/social.graph/{id}/relationships/{type}/{endid}</code>");
        w.println("</body></html>");
        w.flush();
    }

    private void dumpValue(JSONWriter w, Object v) throws JSONException {
        if (v instanceof Calendar) {
            v = ((Calendar)v).getTimeInMillis();
        }
        w.value(v);
    }
}