You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2017/07/18 21:04:18 UTC
[45/50] [abbrv] tinkerpop git commit: Javascript GLV
Javascript GLV
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/66bd5fa4
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/66bd5fa4
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/66bd5fa4
Branch: refs/heads/TINKERPOP-1489
Commit: 66bd5fa408746d3ccc3cc0b74598836bb0019b70
Parents: 2704245
Author: Jorge Bay Gondra <jo...@gmail.com>
Authored: Wed Oct 5 16:14:46 2016 +0200
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue Jul 18 17:01:43 2017 -0400
----------------------------------------------------------------------
gremlin-javascript/pom.xml | 132 ++
.../GraphTraversalSourceGenerator.groovy | 247 +++
.../javascript/TraversalSourceGenerator.groovy | 398 ++++
.../javascript/GenerateGremlinJavascript.java | 32 +
.../gremlin/javascript/jsr223/SymbolHelper.java | 59 +
.../driver/remote-connection.js | 107 +
.../main/javascript/gremlin-javascript/index.js | 85 +
.../process/graph-traversal.js | 2025 ++++++++++++++++++
.../gremlin-javascript/process/traversal.js | 395 ++++
.../gremlin-javascript/structure/graph.js | 146 ++
.../structure/io/graph-serializer.js | 406 ++++
.../javascript/gremlin-javascript/helper.js | 84 +
.../gremlin-javascript/test-exports.js | 78 +
.../gremlin-javascript/test-graphson.js | 108 +
.../gremlin-javascript/test-traversal.js | 54 +
pom.xml | 1 +
16 files changed, 4357 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/gremlin-javascript/pom.xml
----------------------------------------------------------------------
diff --git a/gremlin-javascript/pom.xml b/gremlin-javascript/pom.xml
new file mode 100644
index 0000000..387e628
--- /dev/null
+++ b/gremlin-javascript/pom.xml
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>tinkerpop</artifactId>
+ <version>3.2.3-SNAPSHOT</version>
+ </parent>
+ <artifactId>gremlin-javascript</artifactId>
+ <name>Apache TinkerPop :: Gremlin Javascript</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.groovy</groupId>
+ <artifactId>groovy</artifactId>
+ <version>${groovy.version}</version>
+ <classifier>indy</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>tinkergraph-gremlin</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-test</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tinkerpop</groupId>
+ <artifactId>gremlin-server</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>${slf4j.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ <properties>
+ <!-- provides a way to convert maven.test.skip value to skipTests for use in skipping python tests -->
+ <maven.test.skip>false</maven.test.skip>
+ <skipTests>${maven.test.skip}</skipTests>
+ <gremlin.server.dir>${project.parent.basedir}/gremlin-server</gremlin.server.dir>
+ </properties>
+ <build>
+ <directory>${basedir}/target</directory>
+ <finalName>${project.artifactId}-${project.version}</finalName>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2.1</version>
+ <executions>
+ <execution>
+ <id>generate-javascript</id>
+ <phase>generate-test-resources</phase>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ <configuration>
+ <mainClass>org.apache.tinkerpop.gremlin.javascript.GenerateGremlinJavascript</mainClass>
+ <arguments>
+ <argument>${basedir}/src/main/javascript/gremlin-javascript/process/traversal.js</argument>
+ <argument>${basedir}/src/main/javascript/gremlin-javascript/process/graph-traversal.js</argument>
+ </arguments>
+ </configuration>
+ </execution>
+ <execution>
+ <id>js-tests</id>
+ <phase>test</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ <configuration>
+ <executable>jjs</executable>
+ <arguments>
+ <argument>${basedir}/src/test/javascript/gremlin-javascript/test-exports.js</argument>
+ <argument>${basedir}/src/test/javascript/gremlin-javascript/test-graphson.js</argument>
+ <argument>${basedir}/src/test/javascript/gremlin-javascript/test-traversal.js</argument>
+ </arguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.gmavenplus</groupId>
+ <artifactId>gmavenplus-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-clean-plugin</artifactId>
+ <version>3.0.0</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>clean</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy
new file mode 100644
index 0000000..81c38dc
--- /dev/null
+++ b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.javascript
+
+import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__
+import org.apache.tinkerpop.gremlin.javascript.jsr223.SymbolHelper
+
+import java.lang.reflect.Modifier
+
+/**
+ * @author Jorge Bay Gondra
+ */
+class GraphTraversalSourceGenerator {
+
+ public static void create(final String graphTraversalSourceFile) {
+
+ final StringBuilder moduleOutput = new StringBuilder()
+
+ moduleOutput.append("""/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+ """)
+
+//////////////////////////
+// GraphTraversalSource //
+//////////////////////////
+ moduleOutput.append("""
+/**
+ * @author Jorge Bay Gondra
+ */
+(function defineGraphTraversalModule() {
+ "use strict";
+
+ var t = loadModule.call(this, './traversal.js');
+ var remote = loadModule.call(this, '../driver/remote-connection.js');
+ var Bytecode = t.Bytecode;
+ var inherits = t.inherits;
+ var parseArgs = t.parseArgs;
+
+ /**
+ *
+ * @param {Graph} graph
+ * @param {TraversalStrategies} traversalStrategies
+ * @param {Bytecode} [bytecode]
+ * @constructor
+ */
+ function GraphTraversalSource(graph, traversalStrategies, bytecode) {
+ this._graph = graph;
+ this._traversalStrategies = traversalStrategies;
+ this._bytecode = bytecode || new Bytecode();
+ }
+
+ /**
+ * @param remoteConnection
+ * @returns {GraphTraversal}
+ */
+ GraphTraversalSource.prototype.withRemote = function (remoteConnection) {
+ var traversalStrategy = new t.TraversalStrategies(this._traversalStrategies);
+ traversalStrategy.addStrategy(new remote.RemoteStrategy(remoteConnection));
+ return new GraphTraversal(this._graph, traversalStrategy, new Bytecode(this._bytecode));
+ };
+
+ /**
+ * Returns the string representation of the GraphTraversalSource.
+ * @returns {string}
+ */
+ GraphTraversalSource.prototype.toString = function () {
+ return 'graphtraversalsource[' + this._graph.toString() + ']';
+ };
+""")
+ GraphTraversalSource.getMethods(). // SOURCE STEPS
+ findAll { GraphTraversalSource.class.equals(it.returnType) }.
+ findAll {
+ !it.name.equals("clone") &&
+ !it.name.equals(TraversalSource.Symbols.withBindings) &&
+ !it.name.equals(TraversalSource.Symbols.withRemote)
+ }.
+ collect { SymbolHelper.toJs(it.name) }.
+ unique().
+ sort { a, b -> a <=> b }.
+ forEach { method ->
+ moduleOutput.append(
+ """
+ /**
+ * ${method} GraphTraversalSource method.
+ * @param {...Object} args
+ * @returns {GraphTraversalSource}
+ */
+ GraphTraversalSource.prototype.${method} = function (args) {
+ var b = new Bytecode(this._bytecode).addSource('${SymbolHelper.toJava(method)}', parseArgs.apply(null, arguments));
+ return new GraphTraversalSource(this._graph, new t.TraversalStrategies(this._traversalStrategies), b);
+ };
+""")
+ }
+ GraphTraversalSource.getMethods(). // SPAWN STEPS
+ findAll { GraphTraversal.class.equals(it.returnType) }.
+ collect { SymbolHelper.toJs(it.name) }.
+ unique().
+ sort { a, b -> a <=> b }.
+ forEach { method ->
+ moduleOutput.append(
+ """
+ /**
+ * ${method} GraphTraversalSource step method.
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+ GraphTraversalSource.prototype.${method} = function (args) {
+ var b = new Bytecode(this._bytecode).addStep('${SymbolHelper.toJava(method)}', parseArgs.apply(null, arguments));
+ return new GraphTraversal(this._graph, new t.TraversalStrategies(this._traversalStrategies), b);
+ };
+""")
+ }
+////////////////////
+// GraphTraversal //
+////////////////////
+ moduleOutput.append(
+ """
+ /**
+ * Represents a graph traversal.
+ * @constructor
+ */
+ function GraphTraversal(graph, traversalStrategies, bytecode) {
+ t.Traversal.call(this, graph, traversalStrategies, bytecode);
+ }
+
+ inherits(GraphTraversal, t.Traversal);
+""")
+ GraphTraversal.getMethods().
+ findAll { GraphTraversal.class.equals(it.returnType) }.
+ findAll { !it.name.equals("clone") && !it.name.equals("iterate") }.
+ collect { SymbolHelper.toJs(it.name) }.
+ unique().
+ sort { a, b -> a <=> b }.
+ forEach { method ->
+ moduleOutput.append(
+ """
+ /**
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+ GraphTraversal.prototype.${method} = function (args) {
+ this._bytecode.addStep('${SymbolHelper.toJava(method)}', parseArgs.apply(null, arguments));
+ return this;
+ };
+""")
+ };
+
+////////////////////////
+// AnonymousTraversal //
+////////////////////////
+ moduleOutput.append("""
+ /**
+ * Contains the static method definitions
+ * @type {Object}
+ */
+ var statics = {};
+""");
+ __.class.getMethods().
+ findAll { GraphTraversal.class.equals(it.returnType) }.
+ findAll { Modifier.isStatic(it.getModifiers()) }.
+ collect { SymbolHelper.toJs(it.name) }.
+ unique().
+ sort { a, b -> a <=> b }.
+ forEach { method ->
+ moduleOutput.append(
+ """
+ /**
+ * ${method}() static method
+ * @param {...Object} args
+ * @returns {GraphTraversal}
+ */
+ statics.${method} = function (args) {
+ var g = new GraphTraversal(null, null, new Bytecode());
+ return g.${method}.apply(g, arguments);
+ };
+""")
+ };
+
+ moduleOutput.append("""
+ function loadModule(moduleName) {
+ if (typeof require !== 'undefined') {
+ return require(moduleName);
+ }
+ if (typeof load !== 'undefined') {
+ var path = new java.io.File(__DIR__ + moduleName).getCanonicalPath();
+ this.__dependencies = this.__dependencies || {};
+ return this.__dependencies[path] = (this.__dependencies[path] || load(path));
+ }
+ throw new Error('No module loader was found');
+ }
+
+ var toExport = {
+ GraphTraversal: GraphTraversal,
+ GraphTraversalSource: GraphTraversalSource,
+ statics: statics
+ };
+ if (typeof module !== 'undefined') {
+ // CommonJS
+ module.exports = toExport;
+ return;
+ }
+ // Nashorn and rest
+ return toExport;
+}).call(this);""")
+
+ // save to file
+ final File file = new File(graphTraversalSourceFile);
+ file.delete()
+ moduleOutput.eachLine { file.append(it + "\n") }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy
new file mode 100644
index 0000000..efcb826
--- /dev/null
+++ b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy
@@ -0,0 +1,398 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.javascript
+
+import org.apache.tinkerpop.gremlin.process.traversal.P
+import org.apache.tinkerpop.gremlin.util.CoreImports
+import org.apache.tinkerpop.gremlin.javascript.jsr223.SymbolHelper
+
+import java.lang.reflect.Modifier
+
+/**
+ * @author Jorge Bay Gondra
+ */
+class TraversalSourceGenerator {
+
+ public static void create(final String traversalSourceFile) {
+
+ final StringBuilder moduleOutput = new StringBuilder()
+
+ moduleOutput.append("""/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+""")
+ moduleOutput.append("""
+/**
+ * @author Jorge Bay Gondra
+ */
+(function defineTraversalModule() {
+ "use strict";
+
+ function Traversal(graph, traversalStrategies, bytecode) {
+ this._graph = graph;
+ this._traversalStrategies = traversalStrategies;
+ this._bytecode = bytecode;
+ this.traversers = null;
+ this.sideEffects = null;
+ }
+
+ /** @returns {Bytecode} */
+ Traversal.prototype.getBytecode = function () {
+ return this._bytecode;
+ };
+
+ /** @param {Function} callback */
+ Traversal.prototype.list = function (callback) {
+ var self = this;
+ this._traversalStrategies.applyStrategies(this, function (err) {
+ if (err) {
+ return callback(err);
+ }
+ callback(err, self.traversers);
+ });
+ };
+
+ /** @param {Function} callback */
+ Traversal.prototype.one = function (callback) {
+ this.list(function (err, result) {
+ callback(err, result ? result[0] : null);
+ });
+ };
+
+ /**
+ * Returns the Bytecode JSON representation of the traversal
+ * @returns {String}
+ */
+ Traversal.prototype.toString = function () {
+ return this._bytecode.toString();
+ };
+ """);
+
+ moduleOutput.append("""
+ /**
+ * Represents an operation.
+ * @constructor
+ */
+ function P(operator, value, other) {
+ this.operator = operator;
+ this.value = value;
+ this.other = other;
+ }
+
+ /**
+ * Returns the string representation of the instance.
+ * @returns {string}
+ */
+ P.prototype.toString = function () {
+ if (this.other === undefined) {
+ return this.operator + '(' + this.value + ')';
+ }
+ return this.operator + '(' + this.value + ', ' + this.other + ')';
+ };
+
+ function createP(operator, args) {
+ args.unshift(null, operator);
+ return new (Function.prototype.bind.apply(P, args));
+ }
+""")
+ P.class.getMethods().
+ findAll { Modifier.isStatic(it.getModifiers()) }.
+ findAll { P.class.isAssignableFrom(it.returnType) }.
+ collect { SymbolHelper.toJs(it.name) }.
+ unique().
+ sort { a, b -> a <=> b }.
+ each { method ->
+ moduleOutput.append(
+ """
+ /** @param {...Object} args */
+ P.${method} = function (args) {
+ return createP('${SymbolHelper.toJava(method)}', parseArgs.apply(null, arguments));
+ };
+""")
+ };
+ moduleOutput.append("""
+ P.prototype.and = function (arg) {
+ return new P('and', this, arg);
+ };
+
+ P.prototype.or = function (arg) {
+ return new P('or', this, arg);
+ };
+""")
+
+ moduleOutput.append("""
+ function Traverser(object, bulk) {
+ this.object = object;
+ this.bulk = bulk == undefined ? 1 : bulk;
+ }
+
+ function TraversalSideEffects() {
+
+ }
+
+ /**
+ * Creates a new instance of TraversalStrategies.
+ * @param {TraversalStrategies} [traversalStrategies]
+ * @constructor
+ */
+ function TraversalStrategies(traversalStrategies) {
+ /** @type {Array<TraversalStrategy>} */
+ this.strategies = traversalStrategies ? traversalStrategies.strategies : [];
+ }
+
+ /** @param {TraversalStrategy} strategy */
+ TraversalStrategies.prototype.addStrategy = function (strategy) {
+ this.strategies.push(strategy);
+ };
+
+ /** @param {Traversal} traversal */
+ TraversalStrategies.prototype.applyStrategies = function (traversal) {
+ this.strategies.forEach(function eachStrategy(s) {
+ s.apply(traversal);
+ });
+ };
+
+ /**
+ * @abstract
+ * @constructor
+ */
+ function TraversalStrategy() {
+
+ }
+
+ /**
+ * @abstract
+ * @param {Traversal} traversal
+ */
+ TraversalStrategy.prototype.apply = function (traversal) {
+
+ };
+
+ /**
+ * Creates a new instance of Bytecode
+ * @param {Bytecode} [toClone]
+ * @constructor
+ */
+ function Bytecode(toClone) {
+ this._bindings = {};
+ if (!toClone) {
+ this.sourceInstructions = [];
+ this.stepInstructions = [];
+ }
+ else {
+ this.sourceInstructions = toClone.sourceInstructions.slice(0);
+ this.stepInstructions = toClone.sourceInstructions.slice(0);
+ }
+ }
+
+ /**
+ * Adds a new source instructions
+ * @param {String} name
+ * @param {Array} values
+ * @returns {Bytecode}
+ */
+ Bytecode.prototype.addSource = function (name, values) {
+ if (name === undefined) {
+ throw new Error('Name is not defined');
+ }
+ var instruction = new Array(values.length + 1);
+ instruction[0] = name;
+ for (var i = 0; i < values.length; ++i) {
+ instruction[i + 1] = this._convertToArgument(values[i]);
+ }
+ this.sourceInstructions.push(this._generateInstruction(name, values));
+ return this;
+ };
+
+ /**
+ * Adds a new step instructions
+ * @param {String} name
+ * @param {Array} values
+ * @returns {Bytecode}
+ */
+ Bytecode.prototype.addStep = function (name, values) {
+ if (name === undefined) {
+ throw new Error('Name is not defined');
+ }
+ this.stepInstructions.push(this._generateInstruction(name, values));
+ return this;
+ };
+
+ Bytecode.prototype._generateInstruction = function (name, values) {
+ var instruction = new Array(values.length + 1);
+ instruction[0] = name;
+ for (var i = 0; i < values.length; ++i) {
+ instruction[i + 1] = this._convertToArgument(values[i]);
+ }
+ return instruction;
+ };
+
+ /**
+ * Returns the JSON representation of the source and step instructions
+ * @returns {String}
+ */
+ Bytecode.prototype.toString = function () {
+ return (
+ (this.sourceInstructions.length > 0 ? JSON.stringify(this.sourceInstructions) : '') +
+ (this.stepInstructions.length > 0 ? JSON.stringify(this.stepInstructions) : '')
+ );
+ };
+
+ Bytecode.prototype._convertToArgument = function (value) {
+ return value;
+ };
+
+ function toEnum(typeName, keys) {
+ var result = {};
+ keys.split(' ').forEach(function (k) {
+ if (k === k.toUpperCase()) {
+ k = k.toLowerCase();
+ }
+ result[k] = new EnumValue(typeName, k);
+ });
+ return result;
+ }
+
+ function EnumValue(typeName, elementName) {
+ this.typeName = typeName;
+ this.elementName = elementName;
+ }
+
+ /**
+ * @type {{barrier, cardinality, column, direction, operator, order, pop, scope, t}}
+ */
+ var enums = {};\n""")
+
+ for (final Class<? extends Enum> enumClass : CoreImports.getClassImports()
+ .findAll { Enum.class.isAssignableFrom(it) }
+ .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }
+ .collect()) {
+ moduleOutput.append(" enums.${SymbolHelper.decapitalize(enumClass.getSimpleName())} = " +
+ "toEnum('${SymbolHelper.toJs(enumClass.getSimpleName())}', '");
+ enumClass.getEnumConstants()
+ .sort { a, b -> a.name() <=> b.name() }
+ .each { value -> moduleOutput.append("${SymbolHelper.toJs(value.name())} "); }
+ moduleOutput.deleteCharAt(moduleOutput.length() - 1).append("');\n")
+ }
+
+ moduleOutput.append("""
+ // Utility functions
+ /** @returns {Array} */
+ function parseArgs() {
+ return (arguments.length === 1 ? [ arguments[0] ] : Array.apply(null, arguments));
+ }
+
+ /**
+ * @param {Array} arr
+ * @param {Function} fn
+ * @param {Function} [callback]
+ */
+ function eachSeries(arr, fn, callback) {
+ if (!Array.isArray(arr)) {
+ throw new TypeError('First parameter is not an Array');
+ }
+ callback = callback || noop;
+ var length = arr.length;
+ if (length === 0) {
+ return callback();
+ }
+ var sync;
+ var index = 1;
+ fn(arr[0], next);
+ if (sync === undefined) {
+ sync = false;
+ }
+
+ function next(err) {
+ if (err) {
+ return callback(err);
+ }
+ if (index >= length) {
+ return callback();
+ }
+ if (sync === undefined) {
+ sync = true;
+ }
+ if (sync) {
+ return process.nextTick(function () {
+ fn(arr[index++], next);
+ });
+ }
+ fn(arr[index++], next);
+ }
+ }
+
+ function inherits(ctor, superCtor) {
+ ctor.super_ = superCtor;
+ ctor.prototype = Object.create(superCtor.prototype, {
+ constructor: {
+ value: ctor,
+ enumerable: false,
+ writable: true,
+ configurable: true
+ }
+ });
+ }
+
+ var toExport = {
+ Bytecode: Bytecode,
+ EnumValue: EnumValue,
+ inherits: inherits,
+ P: P,
+ parseArgs: parseArgs,
+ Traversal: Traversal,
+ TraversalSideEffects: TraversalSideEffects,
+ TraversalStrategies: TraversalStrategies,
+ TraversalStrategy: TraversalStrategy,
+ Traverser: Traverser
+ };
+ Object.keys(enums).forEach(function (k) {
+ toExport[k] = enums[k];
+ });
+ if (typeof module !== 'undefined') {
+ // CommonJS
+ module.exports = toExport;
+ return;
+ }
+ // Nashorn and rest
+ return toExport;
+}).call(this);""")
+
+ // save to a file
+ final File file = new File(traversalSourceFile);
+ file.delete()
+ moduleOutput.eachLine { file.append(it + "\n") }
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.java
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.java b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.java
new file mode 100644
index 0000000..1656db4
--- /dev/null
+++ b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.javascript;
+
+public class GenerateGremlinJavascript {
+
+ private GenerateGremlinJavascript() {
+ // just need the main method
+ }
+
+ public static void main(String[] args) {
+ TraversalSourceGenerator.create(args[0]);
+ GraphTraversalSourceGenerator.create(args[1]);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/jsr223/SymbolHelper.java
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/jsr223/SymbolHelper.java b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/jsr223/SymbolHelper.java
new file mode 100644
index 0000000..535de44
--- /dev/null
+++ b/gremlin-javascript/src/main/java/org/apache/tinkerpop/gremlin/javascript/jsr223/SymbolHelper.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tinkerpop.gremlin.javascript.jsr223;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Jorge Bay Gondra
+ */
+public final class SymbolHelper {
+
+ private final static Map<String, String> TO_JS_MAP = new HashMap<>();
+ private final static Map<String, String> FROM_JS_MAP = new HashMap<>();
+
+ static {
+ TO_JS_MAP.put("in", "in_");
+ TO_JS_MAP.put("from", "from_");
+ TO_JS_MAP.forEach((k, v) -> FROM_JS_MAP.put(v, k));
+ }
+
+ private SymbolHelper() {
+ // static methods only, do not instantiate
+ }
+
+ public static String toJs(final String symbol) {
+ return TO_JS_MAP.getOrDefault(symbol, symbol);
+ }
+
+ public static String toJava(final String symbol) {
+ return FROM_JS_MAP.getOrDefault(symbol, symbol);
+ }
+
+ public static String decapitalize(String string) {
+ if (string == null || string.length() == 0) {
+ return string;
+ }
+ char c[] = string.toCharArray();
+ c[0] = Character.toLowerCase(c[0]);
+ return new String(c);
+ }
+}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/gremlin-javascript/src/main/javascript/gremlin-javascript/driver/remote-connection.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/driver/remote-connection.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/driver/remote-connection.js
new file mode 100644
index 0000000..99b177f
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/driver/remote-connection.js
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Jorge Bay Gondra
+ */
+(function defineRemoteConnectionModule() {
+ "use strict";
+
+ var t = loadModule.call(this, '../process/traversal.js');
+ var inherits = t.inherits;
+
+ function RemoteConnection(url, traversalSource) {
+ this.url = url;
+ this.traversalSource = traversalSource;
+ }
+
+ /**
+ * @abstract
+ * @param {Bytecode} bytecode
+ * @param {Function} callback
+ */
+ RemoteConnection.prototype.submit = function (bytecode, callback) {
+ throw new Error('submit() needs to be implemented');
+ };
+
+ /**
+ * @extends {Traversal}
+ * @constructor
+ */
+ function RemoteTraversal(traversers, sideEffects) {
+ t.Traversal.call(this, null, null, null);
+ this.traversers = traversers;
+ this.sideEffects = sideEffects;
+ }
+
+ inherits(RemoteTraversal, t.Traversal);
+
+ /**
+ *
+ * @param {RemoteConnection} connection
+ * @extends {TraversalStrategy}
+ * @constructor
+ */
+ function RemoteStrategy(connection) {
+ t.TraversalStrategy.call(this);
+ this.connection = connection;
+ }
+
+ inherits(RemoteStrategy, t.TraversalStrategy);
+
+ /** @override */
+ RemoteStrategy.prototype.apply = function (traversal, callback) {
+ if (traversal.traversers) {
+ return;
+ }
+ this.connection.submit(traversal.getBytecode(), function (err, remoteTraversal) {
+ if (err) {
+ return callback(err);
+ }
+ traversal.sideEffects = remoteTraversal.sideEffects;
+ traversal.traversers = remoteTraversal.traversers;
+ callback();
+ });
+ };
+
+ function loadModule(moduleName) {
+ if (typeof require !== 'undefined') {
+ return require(moduleName);
+ }
+ if (typeof load !== 'undefined') {
+ var path = new java.io.File(__DIR__ + moduleName).getCanonicalPath();
+ this.__dependencies = this.__dependencies || {};
+ return this.__dependencies[path] = (this.__dependencies[path] || load(path));
+ }
+ throw new Error('No module loader was found');
+ }
+
+ var toExport = {
+ RemoteConnection: RemoteConnection,
+ RemoteStrategy: RemoteStrategy,
+ RemoteTraversal: RemoteTraversal
+ };
+ if (typeof module !== 'undefined') {
+ // CommonJS
+ module.exports = toExport;
+ return;
+ }
+ // Nashorn and rest
+ return toExport;
+}).call(this);
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/66bd5fa4/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
----------------------------------------------------------------------
diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
new file mode 100644
index 0000000..cda8200
--- /dev/null
+++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/index.js
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * @author Jorge Bay Gondra
+ */
+(function exportModule() {
+ "use strict";
+
+ function loadModule(moduleName) {
+ if (typeof require !== 'undefined') {
+ return require(moduleName);
+ }
+ if (typeof load !== 'undefined') {
+ var path = new java.io.File(__DIR__ + moduleName).getCanonicalPath();
+ this.__dependencies = this.__dependencies || {};
+ return this.__dependencies[path] = (this.__dependencies[path] || load(path));
+ }
+ throw new Error('No module loader was found');
+ }
+
+ var t = loadModule.call(this, './process/traversal.js');
+ var gt = loadModule.call(this, './process/graph-traversal.js');
+ var graph = loadModule.call(this, './structure/graph.js');
+ var gs = loadModule.call(this, './structure/io/graph-serializer.js');
+ var rc = loadModule.call(this, './driver/remote-connection.js');
+ var toExport = {
+ driver: {
+ RemoteConnection: rc.RemoteConnection,
+ RemoteStrategy: rc.RemoteStrategy,
+ RemoteTraversal: rc.RemoteTraversal
+ },
+ process: {
+ Bytecode: t.Bytecode,
+ EnumValue: t.EnumValue,
+ inherits: t.inherits,
+ P: t.P,
+ parseArgs: t.parseArgs,
+ Traversal: t.Traversal,
+ TraversalSideEffects: t.TraversalSideEffects,
+ TraversalStrategies: t.TraversalStrategies,
+ TraversalStrategy: t.TraversalStrategy,
+ Traverser: t.Traverser,
+ GraphTraversal: gt.GraphTraversal,
+ GraphTraversalSource: gt.GraphTraversalSource,
+ statics: gt.statics
+ },
+ structure: {
+ io: {
+ GraphSONReader: gs.GraphSONReader,
+ GraphSONWriter: gs.GraphSONWriter
+ },
+ Edge: graph.Edge,
+ Graph: graph.Graph,
+ Path: graph.Path,
+ Property: graph.Property,
+ Vertex: graph.Vertex,
+ VertexProperty: graph.VertexProperty
+ }
+ };
+
+
+ if (typeof module !== 'undefined') {
+ // CommonJS
+ module.exports = toExport;
+ return;
+ }
+ return toExport;
+}).call(this);
\ No newline at end of file