Js GLV: Use Groovy templates for generation
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/7491f9d4 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/7491f9d4 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/7491f9d4 Branch: refs/heads/TINKERPOP-1489 Commit: 7491f9d4909ccfd81417e2a50f520fd06901b34f Parents: 396fbde Author: Jorge Bay Gondra <jorgebaygon...@gmail.com> Authored: Thu Aug 17 17:28:32 2017 +0200 Committer: Jorge Bay Gondra <jorgebaygon...@gmail.com> Committed: Wed Nov 22 15:13:18 2017 +0100 ---------------------------------------------------------------------- .../glv/GraphTraversalSource.template | 127 ++++++++++ gremlin-javascript/glv/PackageJson.template | 55 +++++ gremlin-javascript/glv/TraversalSource.template | 171 +++++++++++++ gremlin-javascript/pom.xml | 131 ++++++++-- .../javascript/GenerateGremlinJavascript.groovy | 36 --- .../GraphTraversalSourceGenerator.groovy | 231 ------------------ .../javascript/PackageJsonGenerator.groovy | 72 ------ .../gremlin/javascript/SymbolHelper.groovy | 50 ---- .../javascript/TraversalSourceGenerator.groovy | 237 ------------------- .../lib/process/graph-traversal.js | 42 +--- .../gremlin-javascript/lib/process/traversal.js | 6 +- .../javascript/gremlin-javascript/package.json | 2 +- 12 files changed, 475 insertions(+), 685 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7491f9d4/gremlin-javascript/glv/GraphTraversalSource.template ---------------------------------------------------------------------- diff --git a/gremlin-javascript/glv/GraphTraversalSource.template b/gremlin-javascript/glv/GraphTraversalSource.template new file mode 100644 index 0000000..e0fb453 --- /dev/null +++ b/gremlin-javascript/glv/GraphTraversalSource.template @@ -0,0 +1,127 @@ +/* + * 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 + */ +'use strict'; + +var t = require('./traversal.js'); +var remote = require('../driver/remote-connection'); +var utils = require('../utils'); +var Bytecode = require('./bytecode'); +var TraversalStrategies = require('./traversal-strategy').TraversalStrategies; +var inherits = utils.inherits; +var parseArgs = utils.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 {GraphTraversalSource} + */ +GraphTraversalSource.prototype.withRemote = function (remoteConnection) { + var traversalStrategy = new TraversalStrategies(this.traversalStrategies); + traversalStrategy.addStrategy(new remote.RemoteStrategy(remoteConnection)); + return new GraphTraversalSource(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() + ']'; +}; +<% sourceStepMethods.each{ method -> %> +/** + * Graph Traversal Source <%= method %> method. + * @param {...Object} args + * @returns {GraphTraversalSource} + */ +GraphTraversalSource.prototype.<%= toJs.call(method) %> = function (args) { + var b = new Bytecode(this.bytecode).addSource('<%= method %>', parseArgs.apply(null, arguments)); + return new GraphTraversalSource(this.graph, new TraversalStrategies(this.traversalStrategies), b); +}; +<% +} +sourceSpawnMethods.each{ method -> %> +/** + * <%= method %> GraphTraversalSource step method. + * @param {...Object} args + * @returns {GraphTraversal} + */ +GraphTraversalSource.prototype.<%= toJs.call(method) %> = function (args) { + var b = new Bytecode(this.bytecode).addStep('<%= method %>', parseArgs.apply(null, arguments)); + return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b); +}; +<% } %> +/** + * Represents a graph traversal. + * @extends Traversal + * @constructor + */ +function GraphTraversal(graph, traversalStrategies, bytecode) { + t.Traversal.call(this, graph, traversalStrategies, bytecode); +} + +inherits(GraphTraversal, t.Traversal); +<% graphStepMethods.each{ method -> %> +/** + * Graph traversal <%= method %> method. + * @param {...Object} args + * @returns {GraphTraversal} + */ +GraphTraversal.prototype.<%= toJs.call(method) %> = function (args) { + this.bytecode.addStep('<%= method %>', parseArgs.apply(null, arguments)); + return this; +}; +<% } %> +/** + * Contains the static method definitions + * @type {Object} + */ +var statics = {}; +<% anonStepMethods.each{ method -> %> +/** + * <%= method %>() static method + * @param {...Object} args + * @returns {GraphTraversal} + */ +statics.<%= toJs.call(method) %> = function (args) { + var g = new GraphTraversal(null, null, new Bytecode()); + return g.<%= toJs.call(method) %>.apply(g, arguments); +}; +<% } %> +module.exports = { + GraphTraversal: GraphTraversal, + GraphTraversalSource: GraphTraversalSource, + statics: statics +}; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7491f9d4/gremlin-javascript/glv/PackageJson.template ---------------------------------------------------------------------- diff --git a/gremlin-javascript/glv/PackageJson.template b/gremlin-javascript/glv/PackageJson.template new file mode 100644 index 0000000..f61913f --- /dev/null +++ b/gremlin-javascript/glv/PackageJson.template @@ -0,0 +1,55 @@ +<% +/* + 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. +*/ +%>{ + "name": "gremlin-javascript", + "version": "<%= version %>", + "description": "JavaScript Gremlin Language Variant", + "author": "Apache TinkerPop team", + "keywords": [ + "graph", + "gremlin", + "tinkerpop", + "connection", + "glv", + "driver", + "graphdb" + ], + "license": "Apache-2.0", + "dependencies": { + "ws": "^3.0.0" + }, + "devDependencies": { + "mocha": ">= 1.14.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/apache/tinkerpop.git" + }, + "bugs": { + "url": "https://issues.apache.org/jira/browse/TINKERPOP" + }, + "scripts": { + "test": "./node_modules/.bin/mocha test --recursive -t 5000", + "unit-test": "./node_modules/.bin/mocha test/unit" + }, + "engines": { + "node": ">=4" + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7491f9d4/gremlin-javascript/glv/TraversalSource.template ---------------------------------------------------------------------- diff --git a/gremlin-javascript/glv/TraversalSource.template b/gremlin-javascript/glv/TraversalSource.template new file mode 100644 index 0000000..dbb7bc4 --- /dev/null +++ b/gremlin-javascript/glv/TraversalSource.template @@ -0,0 +1,171 @@ +/* + * 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 + */ +'use strict'; + +var utils = require('../utils'); +var parseArgs = utils.parseArgs; +var itemDone = Object.freeze({ value: null, done: true }); +var emptyArray = Object.freeze([]); + +function Traversal(graph, traversalStrategies, bytecode) { + this.graph = graph; + this.traversalStrategies = traversalStrategies; + this.bytecode = bytecode; + this.traversers = null; + this.sideEffects = null; + this._traversalStrategiesPromise = null; + this._traversersIteratorIndex = 0; +} + +/** @returns {Bytecode} */ +Traversal.prototype.getBytecode = function () { + return this.bytecode; +}; + +/** + * Returns an Array containing the traverser objects. + * @returns {Promise.<Array>} + */ +Traversal.prototype.toList = function () { + var self = this; + return this._applyStrategies().then(function () { + if (!self.traversers || self._traversersIteratorIndex === self.traversers.length) { + return emptyArray; + } + var arr = new Array(self.traversers.length - self._traversersIteratorIndex); + for (var i = self._traversersIteratorIndex; i < self.traversers.length; i++) { + arr[i] = self.traversers[i].object; + } + self._traversersIteratorIndex = self.traversers.length; + return arr; + }); +}; + +/** + * Async iterator method implementation. + * Returns a promise containing an iterator item. + * @returns {Promise.<{value, done}>} + */ +Traversal.prototype.next = function () { + var self = this; + return this._applyStrategies().then(function () { + if (!self.traversers || self._traversersIteratorIndex === self.traversers.length) { + return itemDone; + } + return { value: self.traversers[self._traversersIteratorIndex++].object, done: false }; + }); +}; + +Traversal.prototype._applyStrategies = function () { + if (this._traversalStrategiesPromise) { + // Apply strategies only once + return this._traversalStrategiesPromise; + } + return this._traversalStrategiesPromise = this.traversalStrategies.applyStrategies(this); +}; + +/** + * Returns the Bytecode JSON representation of the traversal + * @returns {String} + */ +Traversal.prototype.toString = function () { + return this.bytecode.toString(); +}; + +/** + * 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)); +} +<% pmethods.each{ method -> %> +/** @param {...Object} args */ +P.<%= toJs.call(method) %> = function (args) { + return createP('<%= method %>', parseArgs.apply(null, arguments)); +}; +<% } %> +P.prototype.and = function (arg) { + return new P('and', this, arg); +}; + +P.prototype.or = function (arg) { + return new P('or', this, arg); +}; + +function Traverser(object, bulk) { + this.object = object; + this.bulk = bulk == undefined ? 1 : bulk; +} + +function TraversalSideEffects() { + +} + +function toEnum(typeName, keys) { + var result = {}; + keys.split(' ').forEach(function (k) { + var jsKey = k; + if (jsKey === jsKey.toUpperCase()) { + jsKey = jsKey.toLowerCase(); + } + result[jsKey] = new EnumValue(typeName, k); + }); + return result; +} + +function EnumValue(typeName, elementName) { + this.typeName = typeName; + this.elementName = elementName; +} + +module.exports = { + EnumValue: EnumValue, + P: P, + Traversal: Traversal, + TraversalSideEffects: TraversalSideEffects, + Traverser: Traverser<% +enums.each{ enumClass -> + out.print ",\n " + decapitalize.call(enumClass.simpleName) + ": toEnum('" + enumClass.simpleName + "', '" + + enumClass.getEnumConstants().sort { a, b -> a.name() <=> b.name() }.collect { toJs.call(it.name()) }.join(' ') + "')" +} +%> +}; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7491f9d4/gremlin-javascript/pom.xml ---------------------------------------------------------------------- diff --git a/gremlin-javascript/pom.xml b/gremlin-javascript/pom.xml index 452e183..203e59e 100644 --- a/gremlin-javascript/pom.xml +++ b/gremlin-javascript/pom.xml @@ -31,12 +31,6 @@ limitations under the License. <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> <!-- TESTING --> <dependency> <groupId>org.apache.tinkerpop</groupId> @@ -72,27 +66,18 @@ limitations under the License. <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>${project.version}</argument> - <argument>${basedir}</argument> - </arguments> - </configuration> - </execution> - </executions> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-install-plugin</artifactId> + <configuration> + <skip>true</skip> + </configuration> </plugin> <plugin> + <!-- + Use gmavenplus-plugin to: + - Generate js sources + - Start and stop gremlin server for integration tests + --> <groupId>org.codehaus.gmavenplus</groupId> <artifactId>gmavenplus-plugin</artifactId> <dependencies> @@ -116,6 +101,102 @@ limitations under the License. </dependencies> <executions> <execution> + <id>generate-javascript</id> + <phase>generate-sources</phase> + <goals> + <goal>execute</goal> + </goals> + <configuration> + <scripts> + <script><![CDATA[ +import org.apache.tinkerpop.gremlin.jsr223.CoreImports +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.P +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__ +import java.lang.reflect.Modifier + +def toJsMap = ["in": "in_", + "from": "from_"] + +def toJs = { symbol -> toJsMap.getOrDefault(symbol, symbol) } + +def decapitalize = { + String string = it; + if (string == null || string.length() == 0) { + return string; + } + def c = string.toCharArray(); + c[0] = Character.toLowerCase(c[0]); + return new String(c); +} + +def determineVersion = { + def env = System.getenv() + def mavenVersion = env.containsKey("TP_RELEASE_VERSION") ? env.get("JS_RELEASE_VERSION") : '${project.version}' + return mavenVersion.replace("-SNAPSHOT", "-alpha1") +} + +def binding = ["enums": CoreImports.getClassImports() + .findAll { Enum.class.isAssignableFrom(it) } + .sort { a, b -> a.getSimpleName() <=> b.getSimpleName() }, + "pmethods": P.class.getMethods(). + findAll { Modifier.isStatic(it.getModifiers()) }. + findAll { P.class.isAssignableFrom(it.returnType) }. + collect { it.name }. + unique(). + sort { a, b -> a <=> b }, + "sourceStepMethods": 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) && + !it.name.equals(TraversalSource.Symbols.withComputer) + }. + collect { it.name }. + unique(). + sort { a, b -> a <=> b }, + "sourceSpawnMethods": GraphTraversalSource.getMethods(). // SPAWN STEPS + findAll { GraphTraversal.class.equals(it.returnType) }. + collect { it.name }. + unique(). + sort { a, b -> a <=> b }, + "graphStepMethods": GraphTraversal.getMethods(). + findAll { GraphTraversal.class.equals(it.returnType) }. + findAll { !it.name.equals("clone") && !it.name.equals("iterate") }. + collect { it.name }. + unique(). + sort { a, b -> a <=> b }, + "anonStepMethods": __.class.getMethods(). + findAll { GraphTraversal.class.equals(it.returnType) }. + findAll { Modifier.isStatic(it.getModifiers()) }. + findAll { !it.name.equals("__") && !it.name.equals("start") }. + collect { it.name }. + unique(). + sort { a, b -> a <=> b }, + "toJs": toJs, + "version": determineVersion(), + "decapitalize": decapitalize] + +def engine = new groovy.text.GStringTemplateEngine() +def graphTraversalTemplate = engine.createTemplate(new File('${project.basedir}/glv/GraphTraversalSource.template')).make(binding) +def graphTraversalFile = new File('${project.basedir}/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js') +graphTraversalFile.newWriter().withWriter{ it << graphTraversalTemplate } + +def traversalTemplate = engine.createTemplate(new File('${project.basedir}/glv/TraversalSource.template')).make(binding) +def traversalFile = new File('${project.basedir}/src/main/javascript/gremlin-javascript/lib/process/traversal.js') +traversalFile.newWriter().withWriter{ it << traversalTemplate } + +def packageJsonTemplate = engine.createTemplate(new File('${project.basedir}/glv/PackageJson.template')).make(binding) +def packageJsonFile = new File('${project.basedir}/src/main/javascript/gremlin-javascript/package.json') +packageJsonFile.newWriter().withWriter{ it << packageJsonTemplate } +]]> </script> + </scripts> + </configuration> + </execution> + <execution> <id>gremlin-server-start</id> <phase>pre-integration-test</phase> <goals> http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7491f9d4/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.groovy ---------------------------------------------------------------------- diff --git a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.groovy b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.groovy deleted file mode 100644 index ab9eaf1..0000000 --- a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GenerateGremlinJavascript.groovy +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 { - public static void main(String[] args) { - String projectVersion = args[0]; - final String baseDir = args[1]; - final String jsModuleDir = "${baseDir}/src/main/javascript/gremlin-javascript"; - Integer versionSnapshotIndex = projectVersion.indexOf("-SNAPSHOT"); - if (versionSnapshotIndex > 0) { - // Use a alpha version x.y.z-alpha1 - projectVersion = projectVersion.substring(0, versionSnapshotIndex) + "-alpha1"; - } - TraversalSourceGenerator.create("$jsModuleDir/lib/process/traversal.js"); - GraphTraversalSourceGenerator.create("$jsModuleDir/lib/process/graph-traversal.js"); - PackageJsonGenerator.create("$jsModuleDir/package.json", projectVersion); - } -} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7491f9d4/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 deleted file mode 100644 index 3227f2c..0000000 --- a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/GraphTraversalSourceGenerator.groovy +++ /dev/null @@ -1,231 +0,0 @@ -/* - * 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.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 - */ -'use strict'; - -var t = require('./traversal.js'); -var remote = require('../driver/remote-connection'); -var utils = require('../utils'); -var Bytecode = require('./bytecode'); -var TraversalStrategies = require('./traversal-strategy').TraversalStrategies; -var inherits = utils.inherits; -var parseArgs = utils.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 {GraphTraversalSource} - */ -GraphTraversalSource.prototype.withRemote = function (remoteConnection) { - var traversalStrategy = new TraversalStrategies(this.traversalStrategies); - traversalStrategy.addStrategy(new remote.RemoteStrategy(remoteConnection)); - return new GraphTraversalSource(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 { it.name }. - unique(). - sort { a, b -> a <=> b }. - forEach { methodName -> - moduleOutput.append( - """ -/** - * Graph Traversal Source ${methodName} method. - * @param {...Object} args - * @returns {GraphTraversalSource} - */ -GraphTraversalSource.prototype.${SymbolHelper.toJs(methodName)} = function (args) { - var b = new Bytecode(this.bytecode).addSource('$methodName', parseArgs.apply(null, arguments)); - return new GraphTraversalSource(this.graph, new TraversalStrategies(this.traversalStrategies), b); -}; -""") - } - GraphTraversalSource.getMethods(). - findAll { GraphTraversal.class.equals(it.returnType) }. - collect { it.name }. - unique(). - sort { a, b -> a <=> b }. - forEach { methodName -> - moduleOutput.append( - """ -/** - * $methodName GraphTraversalSource step method. - * @param {...Object} args - * @returns {GraphTraversal} - */ -GraphTraversalSource.prototype.${SymbolHelper.toJs(methodName)} = function (args) { - var b = new Bytecode(this.bytecode).addStep('$methodName', parseArgs.apply(null, arguments)); - return new GraphTraversal(this.graph, new TraversalStrategies(this.traversalStrategies), b); -}; -""") - } -//////////////////// -// GraphTraversal // -//////////////////// - moduleOutput.append( - """ -/** - * Represents a graph traversal. - * @extends 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 { it.name }. - unique(). - sort { a, b -> a <=> b }. - forEach { methodName -> - moduleOutput.append( - """ -/** - * Graph traversal $methodName method. - * @param {...Object} args - * @returns {GraphTraversal} - */ -GraphTraversal.prototype.${SymbolHelper.toJs(methodName)} = function (args) { - this.bytecode.addStep('$methodName', 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()) }. - findAll { !it.name.equals("__") }. - 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(""" -module.exports = { - GraphTraversal: GraphTraversal, - GraphTraversalSource: GraphTraversalSource, - statics: statics -};"""); - - // 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/7491f9d4/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/PackageJsonGenerator.groovy ---------------------------------------------------------------------- diff --git a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/PackageJsonGenerator.groovy b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/PackageJsonGenerator.groovy deleted file mode 100644 index 4b4d012..0000000 --- a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/PackageJsonGenerator.groovy +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 - -/** - * @author Jorge Bay Gondra - */ -class PackageJsonGenerator { - - public static void create(final String traversalSourceFile, final String version) { - - final StringBuilder moduleOutput = new StringBuilder(); - moduleOutput.append("""{ - "name": "gremlin-javascript", - "version": "${version}", - "description": "JavaScript Gremlin Language Variant", - "author": "Apache TinkerPop team", - "keywords": [ - "graph", - "gremlin", - "tinkerpop", - "connection", - "glv", - "driver", - "graphdb" - ], - "license": "Apache-2.0", - "dependencies": { - "ws": "^3.0.0" - }, - "devDependencies": { - "mocha": ">= 1.14.0" - }, - "repository": { - "type": "git", - "url": "https://github.com/apache/tinkerpop.git" - }, - "bugs": { - "url": "https://issues.apache.org/jira/browse/TINKERPOP" - }, - "scripts": { - "test": "./node_modules/.bin/mocha test --recursive -t 5000", - "unit-test": "./node_modules/.bin/mocha test/unit" - }, - "engines": { - "node": ">=4" - } -}""" ); - - // 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/7491f9d4/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/SymbolHelper.groovy ---------------------------------------------------------------------- diff --git a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/SymbolHelper.groovy b/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/SymbolHelper.groovy deleted file mode 100644 index ed45cdb..0000000 --- a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/SymbolHelper.groovy +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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 - -/** - * @author Jorge Bay Gondra - */ -public final class SymbolHelper { - - private final static Map<String, String> TO_JS_MAP = new HashMap<>(); - - static { - TO_JS_MAP.put("in", "in_"); - TO_JS_MAP.put("from", "from_"); - } - - 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 decapitalize(String string) { - if (string == null || string.length() == 0) { - return string; - } - def c = string.toCharArray(); - c[0] = Character.toLowerCase(c[0]); - return new String(c); - } -} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7491f9d4/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 deleted file mode 100644 index f3405c3..0000000 --- a/gremlin-javascript/src/main/groovy/org/apache/tinkerpop/gremlin/javascript/TraversalSourceGenerator.groovy +++ /dev/null @@ -1,237 +0,0 @@ -/* - * 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 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 - */ -'use strict'; - -var utils = require('../utils'); -var parseArgs = utils.parseArgs; -var itemDone = Object.freeze({ value: null, done: true }); -var emptyArray = Object.freeze([]); - -function Traversal(graph, traversalStrategies, bytecode) { - this.graph = graph; - this.traversalStrategies = traversalStrategies; - this.bytecode = bytecode; - this.traversers = null; - this.sideEffects = null; - this._traversalStrategiesPromise = null; - this._traversersIteratorIndex = 0; -} - -/** @returns {Bytecode} */ -Traversal.prototype.getBytecode = function () { - return this.bytecode; -}; - -/** - * Returns an Array containing the traverser objects. - * @returns {Promise.<Array>} - */ -Traversal.prototype.toList = function () { - var self = this; - return this._applyStrategies().then(function () { - if (!self.traversers || self._traversersIteratorIndex === self.traversers.length) { - return emptyArray; - } - var arr = new Array(self.traversers.length - self._traversersIteratorIndex); - for (var i = self._traversersIteratorIndex; i < self.traversers.length; i++) { - arr[i] = self.traversers[i].object; - } - self._traversersIteratorIndex = self.traversers.length; - return arr; - }); -}; - -/** - * Async iterator method implementation. - * Returns a promise containing an iterator item. - * @returns {Promise.<{value, done}>} - */ -Traversal.prototype.next = function () { - var self = this; - return this._applyStrategies().then(function () { - if (!self.traversers || self._traversersIteratorIndex === self.traversers.length) { - return itemDone; - } - return { value: self.traversers[self._traversersIteratorIndex++].object, done: false }; - }); -}; - -Traversal.prototype._applyStrategies = function () { - if (this._traversalStrategiesPromise) { - // Apply strategies only once - return this._traversalStrategiesPromise; - } - return this._traversalStrategiesPromise = this.traversalStrategies.applyStrategies(this); -}; - -/** - * 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 { it.name }. - unique(). - sort { a, b -> a <=> b }. - each { methodName -> - moduleOutput.append( - """ -/** @param {...Object} args */ -P.${SymbolHelper.toJs(methodName)} = function (args) { - return createP('$methodName', 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() { - -} - -function toEnum(typeName, keys) { - var result = {}; - keys.split(' ').forEach(function (k) { - var jsKey = k; - if (jsKey === jsKey.toUpperCase()) { - jsKey = jsKey.toLowerCase(); - } - result[jsKey] = new EnumValue(typeName, k); - }); - return result; -} - -function EnumValue(typeName, elementName) { - this.typeName = typeName; - this.elementName = elementName; -} - -module.exports = { - EnumValue: EnumValue, - P: P, - Traversal: Traversal, - TraversalSideEffects: TraversalSideEffects, - Traverser: Traverser""") - for (final Class<? extends Enum> enumClass : CoreImports.getClassImports(). - findAll { Enum.class.isAssignableFrom(it) }. - sort { a, b -> a.simpleName <=> b.simpleName }) { - moduleOutput.append(",\n ${SymbolHelper.decapitalize(enumClass.simpleName)}: " + - "toEnum('${SymbolHelper.toJs(enumClass.simpleName)}', '"); - moduleOutput.append( - enumClass.getEnumConstants(). - sort { a, b -> a.name() <=> b.name() }. - collect { SymbolHelper.toJs(it.name()) }. - join(' ')); - moduleOutput.append("\')"); - } - - moduleOutput.append("""\n};"""); - - // 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/7491f9d4/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js ---------------------------------------------------------------------- diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js index 5ee734a1..f6a0de1 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/graph-traversal.js @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ - + /** * @author Jorge Bay Gondra */ @@ -72,16 +72,6 @@ GraphTraversalSource.prototype.withBulk = function (args) { }; /** - * Graph Traversal Source withComputer method. - * @param {...Object} args - * @returns {GraphTraversalSource} - */ -GraphTraversalSource.prototype.withComputer = function (args) { - var b = new Bytecode(this.bytecode).addSource('withComputer', parseArgs.apply(null, arguments)); - return new GraphTraversalSource(this.graph, new TraversalStrategies(this.traversalStrategies), b); -}; - -/** * Graph Traversal Source withPath method. * @param {...Object} args * @returns {GraphTraversalSource} @@ -1539,33 +1529,33 @@ statics.identity = function (args) { }; /** - * inE() static method + * in() static method * @param {...Object} args * @returns {GraphTraversal} */ -statics.inE = function (args) { +statics.in_ = function (args) { var g = new GraphTraversal(null, null, new Bytecode()); - return g.inE.apply(g, arguments); + return g.in_.apply(g, arguments); }; /** - * inV() static method + * inE() static method * @param {...Object} args * @returns {GraphTraversal} */ -statics.inV = function (args) { +statics.inE = function (args) { var g = new GraphTraversal(null, null, new Bytecode()); - return g.inV.apply(g, arguments); + return g.inE.apply(g, arguments); }; /** - * in_() static method + * inV() static method * @param {...Object} args * @returns {GraphTraversal} */ -statics.in_ = function (args) { +statics.inV = function (args) { var g = new GraphTraversal(null, null, new Bytecode()); - return g.in_.apply(g, arguments); + return g.inV.apply(g, arguments); }; /** @@ -1909,16 +1899,6 @@ statics.simplePath = function (args) { }; /** - * start() static method - * @param {...Object} args - * @returns {GraphTraversal} - */ -statics.start = function (args) { - var g = new GraphTraversal(null, null, new Bytecode()); - return g.start.apply(g, arguments); -}; - -/** * store() static method * @param {...Object} args * @returns {GraphTraversal} @@ -2092,4 +2072,4 @@ module.exports = { GraphTraversal: GraphTraversal, GraphTraversalSource: GraphTraversalSource, statics: statics -}; +}; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7491f9d4/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js ---------------------------------------------------------------------- diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js index 1cd6b53..49c6aef 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal.js @@ -91,7 +91,7 @@ Traversal.prototype._applyStrategies = function () { Traversal.prototype.toString = function () { return this.bytecode.toString(); }; - + /** * Represents an operation. * @constructor @@ -227,10 +227,12 @@ module.exports = { cardinality: toEnum('Cardinality', 'list set single'), column: toEnum('Column', 'keys values'), direction: toEnum('Direction', 'BOTH IN OUT'), + graphSONVersion: toEnum('GraphSONVersion', 'V1_0 V2_0'), + gryoVersion: toEnum('GryoVersion', 'V1_0'), operator: toEnum('Operator', 'addAll and assign div max min minus mult or sum sumLong'), order: toEnum('Order', 'decr incr keyDecr keyIncr shuffle valueDecr valueIncr'), pick: toEnum('Pick', 'any none'), pop: toEnum('Pop', 'all first last'), scope: toEnum('Scope', 'global local'), t: toEnum('T', 'id key label value') -}; +}; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/7491f9d4/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json ---------------------------------------------------------------------- diff --git a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json index db6d3fe..514663b 100644 --- a/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json +++ b/gremlin-javascript/src/main/javascript/gremlin-javascript/package.json @@ -33,4 +33,4 @@ "engines": { "node": ">=4" } -} +} \ No newline at end of file