com.tinkerpop.frames.annotations.gremlin.GremlinGroovyAnnotationHandler Maven / Gradle / Ivy
Go to download
Windup Frames is an extension of the upstream Frames project, with tools to ease debugging and integration within windup.
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