All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tinkerpop.frames.annotations.gremlin.GremlinGroovyAnnotationHandler Maven / Gradle / Ivy

Go to download

Frames is a framework for exposing the elements of a Blueprints graph as Java objects. Instead of writing software in terms of vertices and edges, with Frames, software is written in terms of domain objects and their relationships to each other.

The newest version!
package com.tinkerpop.frames.annotations.gremlin;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.logging.Logger;

import javax.script.Bindings;
import javax.script.CompiledScript;
import javax.script.ScriptException;

import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Element;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.frames.ClassUtilities;
import com.tinkerpop.frames.FramedGraph;
import com.tinkerpop.frames.annotations.AnnotationHandler;
import com.tinkerpop.frames.modules.MethodHandler;
import com.tinkerpop.frames.structures.FramedVertexIterable;
import com.tinkerpop.frames.structures.FramedVertexMap;
import com.tinkerpop.frames.util.ExceptionUtils;
import com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine;
import com.tinkerpop.pipes.Pipe;
import com.tinkerpop.pipes.util.iterators.SingleIterator;

/**
 * @author Marko A. Rodriguez (http://markorodriguez.com)
 * @author Bryn Cooke
 */
public class GremlinGroovyAnnotationHandler implements AnnotationHandler, MethodHandler {
    private static final String PIPE = "_()";
    private final GremlinGroovyScriptEngine engine = new GremlinGroovyScriptEngine();
    private static final String IT = "it";
    private static final String G = "g";

    private static final Logger LOGGER = Logger.getLogger(GremlinGroovyAnnotationHandler.class.getName());

    public GremlinGroovyScriptEngine getGremlinScriptEngine() {
        return this.engine;
    }

    @Override
    public Class getAnnotationType() {
        return GremlinGroovy.class;
    }

    @Override
    public Object processElement(final GremlinGroovy annotation, final Method method, final Object[] arguments, final FramedGraph framedGraph,
                                 final Element element, final Direction direction) {
        if (element instanceof Vertex) {
            return processVertex(annotation, method, arguments, framedGraph, (Vertex) element);
        } else {
            throw new UnsupportedOperationException("This method only works for vertices");
        }
    }

    public Object processVertex(final GremlinGroovy annotation, final Method method, final Object[] arguments, final FramedGraph framedGraph,
                                final Vertex vertex) {
        try {
            final CompiledScript script = this.engine.compile(annotation.value());
            final Bindings bindings = getBindings(method, arguments);
            bindings.put(IT, vertex);
            bindings.put(G, framedGraph);
            final Object result = script.eval(bindings);

            // TODO: Deprecate the use of _() and replace with it
            if (result instanceof Pipe & annotation.value().startsWith(PIPE)) {
                LOGGER.warning("_() is deprecated in favor of using 'it' to represent the framed vertex");
                ((Pipe) result).setStarts(new SingleIterator(vertex));
            }

            if (annotation.frame()) {
                if (result instanceof Iterable) {
                    final FramedVertexIterable r = new FramedVertexIterable(framedGraph, (Iterable) result, ClassUtilities.getGenericClass(method));
                    return (ClassUtilities.returnsIterable(method)) ? r : r.iterator().hasNext() ? r.iterator().next() : null;
                } else if (ClassUtilities.returnsMap(method)) {
                    return new FramedVertexMap(framedGraph, (Map) result, ClassUtilities.getGenericClass(method));
                } else if (result instanceof Vertex) {
                    return framedGraph.frame((Vertex) result, ClassUtilities.getGenericClass(method));
                } else {
                    throw new IllegalStateException("The returned object can not be framed: " + result.getClass());
                }
            } else {
                return result;
            }

        } catch (ScriptException e) {
        	ExceptionUtils.sneakyThrow(e); //Preserve original exception functionality.
            return null;
        }
    }

    private Bindings getBindings(final Method method, final Object[] arguments) {
        Bindings bindings = engine.createBindings();
        Annotation[][] allParameterAnnotations = method.getParameterAnnotations();
        for (int pCount = 0; pCount < allParameterAnnotations.length; pCount++) {
            Annotation parameterAnnotations[] = allParameterAnnotations[pCount];
            for (int aCount = 0; aCount < parameterAnnotations.length; aCount++) {
                Annotation paramAnnotation = parameterAnnotations[aCount];
                if (paramAnnotation instanceof GremlinParam) {
                    bindings.put(((GremlinParam) paramAnnotation).value(), arguments[pCount]);
                    break;
                }
            }
        }
        return bindings;
    }

	@Override
	public Object processElement(Object framedElement, Method method,
			Object[] arguments, GremlinGroovy annotation,
			FramedGraph framedGraph, Element element) {
		if (element instanceof Vertex) {
            return processVertex(annotation, method, arguments, framedGraph, (Vertex) element);
        } else {
            throw new UnsupportedOperationException("This method only works for vertices");
        }
	}


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy