Package com.tinkerpop.rexster.kibbles.frames

Source Code of com.tinkerpop.rexster.kibbles.frames.FramesExtension

package com.tinkerpop.rexster.kibbles.frames;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Graph;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.frames.FramedGraph;
import com.tinkerpop.frames.FramedGraphFactory;
import com.tinkerpop.frames.Property;
import com.tinkerpop.frames.modules.gremlingroovy.GremlinGroovyModule;
import com.tinkerpop.rexster.RexsterResourceContext;
import com.tinkerpop.rexster.extension.AbstractRexsterExtension;
import com.tinkerpop.rexster.extension.ExtensionConfiguration;
import com.tinkerpop.rexster.extension.ExtensionDefinition;
import com.tinkerpop.rexster.extension.ExtensionDescriptor;
import com.tinkerpop.rexster.extension.ExtensionMethod;
import com.tinkerpop.rexster.extension.ExtensionNaming;
import com.tinkerpop.rexster.extension.ExtensionPoint;
import com.tinkerpop.rexster.extension.ExtensionRequestParameter;
import com.tinkerpop.rexster.extension.ExtensionResponse;
import com.tinkerpop.rexster.extension.RexsterContext;

import org.apache.log4j.Logger;

import javax.ws.rs.core.PathSegment;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* An extension that exposes Tinkerpop Frames via Rexster.  Configuration in rexster.xml looks like:
* <p/>
* <configuration>
* <person>com.tinkerpop.frames.domain.classes.Person</person>
* <project>com.tinkerpop.frames.domain.classes.Project</project>
* </configuration>
*/
@ExtensionNaming(name = FramesExtension.EXTENSION_NAME, namespace = FramesExtension.EXTENSION_NAMESPACE)
public class FramesExtension extends AbstractRexsterExtension {
    protected static Logger logger = Logger.getLogger(FramesExtension.class);

    public static final String EXTENSION_NAME = "frames";
    public static final String EXTENSION_NAMESPACE = "tp";

    public static final String TOKEN_BOTH = "both";
    public static final String TOKEN_IN = "in";
    public static final String TOKEN_OUT = "out";
   
    private FramedGraphFactory factory = new FramedGraphFactory(new GremlinGroovyModule());

    @ExtensionDefinition(extensionPoint = ExtensionPoint.EDGE)
    @ExtensionDescriptor(description = "Frames extension for an edge.")
    public ExtensionResponse doFramesWorkOnEdge(@RexsterContext RexsterResourceContext rexsterResourceContext,
                                                @RexsterContext Graph graph,
                                                @RexsterContext Edge edge,

                                                @ExtensionRequestParameter(name = "direction", description = "the direction of the edge (must be \"" + TOKEN_BOTH + "\", \"" + TOKEN_IN + "\", or \"" + TOKEN_OUT + "\" with the default being \"" + TOKEN_BOTH + "\"") String directionString) {
        Direction direction = Direction.BOTH;
        if (directionString != null && !directionString.isEmpty()) {
            if (directionString.equals(TOKEN_IN)) {
                direction = Direction.IN;
            } else if (directionString.equals(TOKEN_OUT)) {
                direction = Direction.OUT;
            } else {
                ExtensionMethod extMethod = rexsterResourceContext.getExtensionMethod();
                return ExtensionResponse.error(
                        "the direction parameter must be \"" + TOKEN_BOTH + "\", \"" + TOKEN_IN + "\", or \"" + TOKEN_OUT + "\"",
                        null,
                        Response.Status.BAD_REQUEST.getStatusCode(),
                        null,
                        generateErrorJson(extMethod.getExtensionApiAsJson()));
            }
        }

        return this.frameItUp(rexsterResourceContext, graph, edge, direction);
    }

    @ExtensionDefinition(extensionPoint = ExtensionPoint.VERTEX)
    @ExtensionDescriptor(description = "Frames extension for a vertex.")
    public ExtensionResponse doFramesWorkOnVertex(@RexsterContext RexsterResourceContext rexsterResourceContext,
                                                  @RexsterContext Graph graph,
                                                  @RexsterContext Vertex vertex) {
        return this.frameItUp(rexsterResourceContext, graph, vertex, null);
    }

    /**
     * Frames up a graph element.
     *
     * @param rexsterResourceContext The Rexster context.
     * @param graph                  The graph from which the element is framed.
     * @param element                A vertex or an edge.
     * @param direction              The direction of the edge.  Only relevant for frame edges and should be
     *                               set to null for vertices.
     * @return The response.
     */
    private ExtensionResponse frameItUp(RexsterResourceContext rexsterResourceContext, Graph graph, Element element, Direction direction) {

        if (element instanceof Edge && direction == null) {
            throw new IllegalArgumentException("Direction cannot be null");
        }

        ExtensionResponse extensionResponse;
        FramedGraph framedGraph = factory.create(graph);

        ExtensionConfiguration extensionConfig = rexsterResourceContext.getRexsterApplicationGraph()
                .findExtensionConfiguration(EXTENSION_NAMESPACE, EXTENSION_NAME);
        Map<String, String> mapFrames = extensionConfig.tryGetMapFromConfiguration();

        if (mapFrames != null && !mapFrames.isEmpty()) {
            UriInfo uriInfo = rexsterResourceContext.getUriInfo();
            List<PathSegment> pathSegmentList = uriInfo.getPathSegments();

            String domainObjectMappingName = "";
            if (pathSegmentList.size() > 6) {
                domainObjectMappingName = pathSegmentList.get(6).getPath();
            }

            if (domainObjectMappingName.isEmpty()) {
                return ExtensionResponse.error(
                        "A Frames class was not specified in the URI", generateErrorJson());
            }

            String frameClassName = mapFrames.get(domainObjectMappingName);
            if (frameClassName == null || frameClassName.isEmpty()) {
                return ExtensionResponse.error(
                        "Frames configuration does not contain a Frames class for " + domainObjectMappingName, generateErrorJson());
            }

            try {
                Class clazz = Class.forName(frameClassName);
                Object obj = null;

                if (element instanceof Vertex) {
                    obj = framedGraph.frame((Vertex) element, clazz);
                } else if (element instanceof Edge) {
                    obj = framedGraph.frame((Edge) element, Direction.BOTH, clazz);
                }

                Map map = new HashMap();

                Method[] methods = clazz.getMethods();
                for (Method method : methods) {
                    // assumes that the properties are unique within a frame
                    Property property = method.getAnnotation(Property.class);
                    if (property != null && method.getName().startsWith("get")) {
                        map.put(property.value(), method.invoke(obj, null));
                    }
                }

                extensionResponse = ExtensionResponse.ok(map);
            } catch (Exception x) {
                logger.error("Frames encountered a problem with " + frameClassName, x);
                extensionResponse = ExtensionResponse.error(
                        "Frames encountered a problem with " + frameClassName, generateErrorJson());
            }
        } else {
            // bad configuration
            extensionResponse = ExtensionResponse.error(
                    "Frames configuration is not valid.  Please check rexster.xml", generateErrorJson());
        }

        return extensionResponse;
    }

    /**
     * By default this returns true.  Overriding classes should evaluate the configuration to determine
     * if it is correct.
     */
    @Override
    public boolean isConfigurationValid(ExtensionConfiguration extensionConfiguration) {
        boolean valid = false;

        if (extensionConfiguration != null) {
            Map<String, String> mapFrames = extensionConfiguration.tryGetMapFromConfiguration();
            valid = mapFrames != null && !mapFrames.isEmpty() && mapFrames.size() > 0;
        }

        return valid;
    }
}
TOP

Related Classes of com.tinkerpop.rexster.kibbles.frames.FramesExtension

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.