wip
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/6a40535c Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/6a40535c Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/6a40535c Branch: refs/heads/shortest-path-wip Commit: 6a40535c69c88ae62887375a6eb0fa75496c15ae Parents: 4d1b391 Author: Stephen Mallette <sp...@genoprime.com> Authored: Fri May 25 13:38:32 2018 -0400 Committer: Daniel Kuppitz <daniel_kupp...@hotmail.com> Committed: Thu May 31 12:46:10 2018 -0700 ---------------------------------------------------------------------- .../gremlin/jsr223/JavaTranslator.java | 37 ++++++++++++++ .../gremlin/process/traversal/Bytecode.java | 16 +++++- .../traversal/step/StepConfiguration.java | 51 ++++++++++++++++++++ .../process/traversal/step/WithModulating.java | 26 ---------- .../process/traversal/step/WithModulation.java | 26 ---------- .../structure/io/graphson/GraphSONModule.java | 10 +++- .../io/graphson/TraversalSerializersV2d0.java | 37 ++++++++++++-- .../io/graphson/TraversalSerializersV3d0.java | 34 ++++++++++++- .../structure/io/gryo/GryoSerializersV1d0.java | 32 ++++++++++++ .../structure/io/gryo/GryoSerializersV3d0.java | 2 +- .../gremlin/structure/io/gryo/GryoVersion.java | 7 ++- .../process/traversal/step/StepTest.java | 2 +- .../GraphSONMapperPartialEmbeddedTypeTest.java | 10 ++++ .../structure/io/gryo/GryoMapperTest.java | 7 +++ gremlin-dotnet/glv/generate.groovy | 1 + .../gremlin/groovy/jsr223/GroovyTranslator.java | 9 +++- gremlin-python/glv/generate.groovy | 1 + 17 files changed, 244 insertions(+), 64 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java index 7480974..4813fab 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java @@ -25,7 +25,10 @@ import org.apache.tinkerpop.gremlin.process.traversal.Bytecode; import org.apache.tinkerpop.gremlin.process.traversal.Translator; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.step.StepConfiguration; import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.DefaultStepConfiguration; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.StepConfigurationProxy; import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy; import org.apache.tinkerpop.gremlin.structure.util.StringFactory; @@ -119,6 +122,16 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal final Configuration configuration = ((TraversalStrategyProxy) object).getConfiguration(); configuration.getKeys().forEachRemaining(key -> map.put(key, translateObject(configuration.getProperty(key)))); return invokeStrategyCreationMethod(object, map); + } else if (object instanceof DefaultStepConfiguration) { + final Map<String, Object> map = new LinkedHashMap<>(); + final Configuration configuration = ((DefaultStepConfiguration) object).getConfiguration(); + configuration.getKeys().forEachRemaining(key -> map.put(key, translateObject(configuration.getProperty(key)))); + return invokeStepConfigurationCreationMethod(object, map); + }else if (object instanceof StepConfigurationProxy) { + final Map<String, Object> map = new LinkedHashMap<>(); + final Configuration configuration = ((StepConfigurationProxy) object).getConfiguration(); + configuration.getKeys().forEachRemaining(key -> map.put(key, translateObject(configuration.getProperty(key)))); + return invokeStepConfigurationCreationMethod(object, map); } else if (object instanceof Map) { final Map<Object, Object> map = object instanceof Tree ? new Tree() : @@ -184,6 +197,30 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal } } + private Object invokeStepConfigurationCreationMethod(final Object delegate, final Map<String, Object> map) { + final Class<?> stepConfigurationClass = delegate instanceof DefaultStepConfiguration ? delegate.getClass() : ((StepConfigurationProxy) delegate).getStepConfigurationClass(); + final Map<String, Method> methodCache = localMethodCache.computeIfAbsent(stepConfigurationClass, k -> { + final Map<String, Method> cacheEntry = new HashMap<>(); + + try { + cacheEntry.put("create", stepConfigurationClass.getMethod("create", Configuration.class)); + } catch (NoSuchMethodException ignored) { + // nothing - the StepConfiguration may not be constructed this way + } + + if (cacheEntry.isEmpty()) + throw new IllegalStateException(String.format("%s does can only be constructed with create(Configuration)", stepConfigurationClass.getSimpleName())); + + return cacheEntry; + }); + + try { + return methodCache.get("create").invoke(null, new MapConfiguration(map)); + } catch (final InvocationTargetException | IllegalAccessException e) { + throw new IllegalStateException(e.getMessage(), e); + } + } + private Object invokeMethod(final Object delegate, final Class<?> returnType, final String methodName, final Object... arguments) { // populate method cache for fast access to methods in subsequent calls final Map<String, List<Method>> methodCache = GLOBAL_METHOD_CACHE.getOrDefault(delegate.getClass(), new HashMap<>()); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java index a3ba9f0..ad50c5c 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/Bytecode.java @@ -19,6 +19,8 @@ package org.apache.tinkerpop.gremlin.process.traversal; +import org.apache.tinkerpop.gremlin.process.traversal.step.StepConfiguration; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.DefaultStepConfiguration; import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy; import org.apache.tinkerpop.gremlin.structure.util.StringFactory; import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; @@ -276,7 +278,19 @@ public final class Bytecode implements Cloneable, Serializable { // if (argument instanceof Traversal) return ((Traversal) argument).asAdmin().getBytecode(); - else if (argument instanceof Map) { + else if (argument instanceof StepConfiguration) { + final StepConfiguration stepConfig = (StepConfiguration) argument; + final LinkedHashMap<String,List<Object>> m = new LinkedHashMap<>(); + final org.apache.commons.configuration.Configuration conf = stepConfig.getConfiguration(); + final java.util.Iterator<String> keys = conf.getKeys(); + while (keys.hasNext()) { + final String key = keys.next(); + final List<Object> args = new ArrayList<>(); + conf.getList(key).forEach(x -> args.add(convertArgument(x, true))); + m.put(key, args); + } + return new DefaultStepConfiguration(m); + } else if (argument instanceof Map) { final Map<Object, Object> map = new LinkedHashMap<>(((Map) argument).size()); for (final Map.Entry<?, ?> entry : ((Map<?, ?>) argument).entrySet()) { map.put(convertArgument(entry.getKey(), true), convertArgument(entry.getValue(), true)); http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/StepConfiguration.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/StepConfiguration.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/StepConfiguration.java new file mode 100644 index 0000000..3a9d4a7 --- /dev/null +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/StepConfiguration.java @@ -0,0 +1,51 @@ +/* + * 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.process.traversal.step; + +import org.apache.commons.configuration.BaseConfiguration; +import org.apache.commons.configuration.Configuration; +import org.apache.tinkerpop.gremlin.process.traversal.Step; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.DefaultStepConfiguration; + +import java.util.function.Consumer; + +/** + * A {@code WithOption} can be supplied to {@link GraphTraversal#with(StepConfiguration)} and is designed to modulate a + * {@link Step} in some way. As {@code WithStep} is a {@code Consumer} that accepts a {@link Step}, the implementation + * can modify that step in any way it deems necessary. Typical usage for those adding to the Gremlin language in some + * way would be to provide an expression that returns a {@link DefaultStepConfiguration}. + * <p/> + * To work properly with TinkerPop serialization, implementations should provide a static + * {@code StepConfiguration create(Configuration)} method. + * + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +public interface StepConfiguration<S extends Step> extends Consumer<S> { + + /** + * Get the configuration representation of this strategy. This is useful for converting a strategy into a + * serialized form. + * + * @return the configuration used to create this strategy + */ + public default Configuration getConfiguration() { + return new BaseConfiguration(); + } +} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/WithModulating.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/WithModulating.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/WithModulating.java deleted file mode 100644 index 2a81c45..0000000 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/WithModulating.java +++ /dev/null @@ -1,26 +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.process.traversal.step; - -/** - * @author Stephen Mallette (http://stephen.genoprime.com) - */ -public interface WithModulating { - public void modulateWith(final WithModulation configuration); -} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/WithModulation.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/WithModulation.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/WithModulation.java deleted file mode 100644 index 404b02f..0000000 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/WithModulation.java +++ /dev/null @@ -1,26 +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.process.traversal.step; - -/** - * @author Stephen Mallette (http://stephen.genoprime.com) - */ -public interface WithModulation { - public Object[] -} http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java index 2e795a5..4253c15 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONModule.java @@ -31,7 +31,9 @@ import org.apache.tinkerpop.gremlin.process.traversal.Scope; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; import org.apache.tinkerpop.gremlin.process.traversal.Traverser; +import org.apache.tinkerpop.gremlin.process.traversal.step.StepConfiguration; import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.DefaultStepConfiguration; import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ConnectiveStrategy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ElementIdStrategy; @@ -129,7 +131,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { put(List.class, "List"); put(Set.class, "Set"); - // Tinkerpop Graph objects + // TinkerPop Graph objects put(Lambda.class, "Lambda"); put(Vertex.class, "Vertex"); put(Edge.class, "Edge"); @@ -184,6 +186,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { GraphFilterStrategy.class, VertexProgramStrategy.class ).forEach(strategy -> put(strategy, strategy.getSimpleName())); + Arrays.asList(DefaultStepConfiguration.class).forEach(stepConfiguration-> put(stepConfiguration, stepConfiguration.getSimpleName())); }}); /** @@ -234,6 +237,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { addSerializer(Bytecode.Binding.class, new TraversalSerializersV3d0.BindingJacksonSerializer()); addSerializer(Traverser.class, new TraversalSerializersV3d0.TraverserJacksonSerializer()); addSerializer(TraversalStrategy.class, new TraversalSerializersV3d0.TraversalStrategyJacksonSerializer()); + addSerializer(StepConfiguration.class, new TraversalSerializersV3d0.StepConfigurationJacksonSerializer()); /////////////////////// DESERIALIZERS //////////////////////////// @@ -300,6 +304,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { GraphFilterStrategy.class, VertexProgramStrategy.class ).forEach(strategy -> addDeserializer(strategy, new TraversalSerializersV3d0.TraversalStrategyProxyJacksonDeserializer(strategy))); + Arrays.asList(DefaultStepConfiguration.class).forEach(stepConf -> addDeserializer(stepConf, new TraversalSerializersV3d0.StepConfigurationProxyJacksonDeserializer(stepConf))); } public static Builder build() { @@ -398,6 +403,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { GraphFilterStrategy.class, VertexProgramStrategy.class ).forEach(strategy -> put(strategy, strategy.getSimpleName())); + Arrays.asList(DefaultStepConfiguration.class).forEach(stepConfiguration-> put(stepConfiguration, stepConfiguration.getSimpleName())); }}); /** @@ -445,6 +451,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { addSerializer(Bytecode.Binding.class, new TraversalSerializersV2d0.BindingJacksonSerializer()); addSerializer(Traverser.class, new TraversalSerializersV2d0.TraverserJacksonSerializer()); addSerializer(TraversalStrategy.class, new TraversalSerializersV2d0.TraversalStrategyJacksonSerializer()); + addSerializer(StepConfiguration.class, new TraversalSerializersV2d0.StepConfigurationJacksonSerializer()); /////////////////////// DESERIALIZERS //////////////////////////// @@ -506,6 +513,7 @@ abstract class GraphSONModule extends TinkerPopJacksonModule { GraphFilterStrategy.class, VertexProgramStrategy.class ).forEach(strategy -> addDeserializer(strategy, new TraversalSerializersV2d0.TraversalStrategyProxyJacksonDeserializer(strategy))); + Arrays.asList(DefaultStepConfiguration.class).forEach(stepConf -> addDeserializer(stepConf, new TraversalSerializersV2d0.StepConfigurationProxyJacksonDeserializer(stepConf))); } public static Builder build() { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java index 040fd1d..bc105e6 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV2d0.java @@ -27,6 +27,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; import org.apache.tinkerpop.gremlin.process.traversal.Traverser; +import org.apache.tinkerpop.gremlin.process.traversal.step.StepConfiguration; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.StepConfigurationProxy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy; import org.apache.tinkerpop.gremlin.process.traversal.util.AndP; import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP; @@ -37,18 +39,14 @@ import org.apache.tinkerpop.shaded.jackson.core.JsonParser; import org.apache.tinkerpop.shaded.jackson.core.JsonProcessingException; import org.apache.tinkerpop.shaded.jackson.core.JsonToken; import org.apache.tinkerpop.shaded.jackson.databind.DeserializationContext; -import org.apache.tinkerpop.shaded.jackson.databind.JavaType; -import org.apache.tinkerpop.shaded.jackson.databind.JsonNode; import org.apache.tinkerpop.shaded.jackson.databind.SerializerProvider; import org.apache.tinkerpop.shaded.jackson.databind.deser.std.StdDeserializer; import org.apache.tinkerpop.shaded.jackson.databind.jsontype.TypeSerializer; import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdScalarSerializer; import org.apache.tinkerpop.shaded.jackson.databind.ser.std.StdSerializer; -import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; @@ -243,6 +241,23 @@ final class TraversalSerializersV2d0 { } } + final static class StepConfigurationJacksonSerializer extends StdScalarSerializer<StepConfiguration> { + + public StepConfigurationJacksonSerializer() { + super(StepConfiguration.class); + } + + @Override + public void serialize(final StepConfiguration stepConfiguration, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) + throws IOException { + jsonGenerator.writeStartObject(); + for (final Map.Entry<Object, Object> entry : ConfigurationConverter.getMap(stepConfiguration.getConfiguration()).entrySet()) { + jsonGenerator.writeObjectField((String) entry.getKey(), entry.getValue()); + } + jsonGenerator.writeEndObject(); + } + } + /////////////////// // DESERIALIZERS // ////////////////// @@ -490,4 +505,18 @@ final class TraversalSerializersV2d0 { return new TraversalStrategyProxy<>(this.clazz, new MapConfiguration(data)); } } + + final static class StepConfigurationProxyJacksonDeserializer<T extends StepConfiguration> extends AbstractObjectDeserializer<StepConfigurationProxy> { + private final Class<T> clazz; + + public StepConfigurationProxyJacksonDeserializer(final Class<T> clazz) { + super(StepConfigurationProxy.class); + this.clazz = clazz; + } + + @Override + public StepConfigurationProxy<T> createObject(final Map<String, Object> data) { + return new StepConfigurationProxy<>(this.clazz, new MapConfiguration(data)); + } + } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java index eaa7b0f..59ba4a0 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/TraversalSerializersV3d0.java @@ -27,6 +27,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; import org.apache.tinkerpop.gremlin.process.traversal.Traverser; +import org.apache.tinkerpop.gremlin.process.traversal.step.StepConfiguration; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.StepConfigurationProxy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy; import org.apache.tinkerpop.gremlin.process.traversal.util.AndP; import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP; @@ -47,7 +49,6 @@ import org.apache.tinkerpop.shaded.jackson.databind.type.TypeFactory; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; @@ -235,6 +236,23 @@ final class TraversalSerializersV3d0 { } } + final static class StepConfigurationJacksonSerializer extends StdScalarSerializer<StepConfiguration> { + + public StepConfigurationJacksonSerializer() { + super(StepConfiguration.class); + } + + @Override + public void serialize(final StepConfiguration stepConfiguration, final JsonGenerator jsonGenerator, final SerializerProvider serializerProvider) + throws IOException { + jsonGenerator.writeStartObject(); + for (final Map.Entry<Object, Object> entry : ConfigurationConverter.getMap(stepConfiguration.getConfiguration()).entrySet()) { + jsonGenerator.writeObjectField((String) entry.getKey(), entry.getValue()); + } + jsonGenerator.writeEndObject(); + } + } + /////////////////// // DESERIALIZERS // ////////////////// @@ -484,4 +502,18 @@ final class TraversalSerializersV3d0 { return new TraversalStrategyProxy<>(this.clazz, new MapConfiguration(data)); } } + + final static class StepConfigurationProxyJacksonDeserializer<T extends StepConfiguration> extends AbstractObjectDeserializer<StepConfigurationProxy> { + private final Class<T> clazz; + + public StepConfigurationProxyJacksonDeserializer(final Class<T> clazz) { + super(StepConfigurationProxy.class); + this.clazz = clazz; + } + + @Override + public StepConfigurationProxy<T> createObject(final Map<String, Object> data) { + return new StepConfigurationProxy<>(this.clazz, new MapConfiguration(data)); + } + } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV1d0.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV1d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV1d0.java index ca7c241..9fdfd4e 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV1d0.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV1d0.java @@ -18,11 +18,14 @@ */ package org.apache.tinkerpop.gremlin.structure.io.gryo; +import org.apache.commons.configuration.Configuration; import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser; import org.apache.tinkerpop.gremlin.process.traversal.Bytecode; import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.Path; +import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.DefaultStepConfiguration; import org.apache.tinkerpop.gremlin.process.traversal.util.AndP; import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP; import org.apache.tinkerpop.gremlin.process.traversal.util.OrP; @@ -44,7 +47,10 @@ import org.apache.tinkerpop.gremlin.util.function.Lambda; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; /** * This class holds serializers for graph-based objects such as vertices, edges, properties, and paths. These objects @@ -281,4 +287,30 @@ public final class GryoSerializersV1d0 { return new DefaultRemoteTraverser<>(o, input.readLong()); } } + +// public final static class DefaultStepConfigurationSerializer implements SerializerShim<DefaultStepConfiguration> { +// @Override +// public <O extends OutputShim> void write(final KryoShim<?, O> kryo, final O output, final DefaultStepConfiguration stepConfig) { +// final LinkedHashMap<String,List<Object>> m = new LinkedHashMap<>(); +// final Configuration conf = stepConfig.getConfiguration(); +// final Iterator<String> keys = conf.getKeys(); +// while (keys.hasNext()) { +// final String key = keys.next(); +// final List<Object> args = new ArrayList<>(); +// +// // gryo doesn't (for whatever reason that i can't remember) coerce traversals to bytecode so if a +// // step configuration has a traversal it needs to be coerced here. not sure........ +// conf.getList(key).forEach(x -> args.add(x instanceof Traversal ? ((Traversal) x).asAdmin().getBytecode() : x)); +// m.put(key, args); +// } +// +// kryo.writeObject(output, m); +// } +// +// @Override +// public <I extends InputShim> DefaultStepConfiguration read(final KryoShim<I, ?> kryo, final I input, final Class<DefaultStepConfiguration> clazz) { +// final LinkedHashMap<String,List<Object>> m = kryo.readObject(input, LinkedHashMap.class); +// return DefaultStepConfiguration. +// } +// } } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV3d0.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV3d0.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV3d0.java index 8a57a06..da91e42 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV3d0.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoSerializersV3d0.java @@ -46,12 +46,12 @@ import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedProperty; import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex; import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertexProperty; import org.apache.tinkerpop.gremlin.util.function.Lambda; -import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java index 6bb7b34..5d4b30b 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoVersion.java @@ -43,6 +43,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.map.MeanGlobalStep; import org.apache.tinkerpop.gremlin.process.traversal.step.map.OrderGlobalStep; import org.apache.tinkerpop.gremlin.process.traversal.step.map.TreeStep; import org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.DefaultStepConfiguration; import org.apache.tinkerpop.gremlin.process.traversal.step.util.ProfileStep; import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree; import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.ConnectiveStrategy; @@ -310,6 +311,7 @@ public enum GryoVersion { add(GryoTypeReg.of(TraversalOptionParent.Pick.class, 137)); add(GryoTypeReg.of(HashSetSupplier.class, 136, new UtilSerializers.HashSetSupplierSerializer())); add(GryoTypeReg.of(MultiComparator.class, 165)); + add(GryoTypeReg.of(DefaultStepConfiguration.class, 174)); // ***LAST ID*** add(GryoTypeReg.of(ConnectiveStrategy.class, 138)); add(GryoTypeReg.of(HaltedTraverserStrategy.class, 139)); @@ -373,7 +375,7 @@ public enum GryoVersion { add(GryoTypeReg.of(RangeGlobalStep.RangeBiOperator.class, 114)); add(GryoTypeReg.of(OrderGlobalStep.OrderBiOperator.class, 118)); add(GryoTypeReg.of(ProfileStep.ProfileBiOperator.class, 119)); - add(GryoTypeReg.of(IndexedTraverserSet.VertexIndexedTraverserSet.class, 173)); // ***LAST ID*** + add(GryoTypeReg.of(IndexedTraverserSet.VertexIndexedTraverserSet.class, 173)); // placeholder serializers for classes that don't live here in core. this will allow them to be used if // present or ignored if the class isn't available. either way the registration numbers are held as @@ -486,6 +488,7 @@ public enum GryoVersion { add(GryoTypeReg.of(TraversalOptionParent.Pick.class, 137)); add(GryoTypeReg.of(HashSetSupplier.class, 136, new UtilSerializers.HashSetSupplierSerializer())); add(GryoTypeReg.of(MultiComparator.class, 165)); + add(GryoTypeReg.of(DefaultStepConfiguration.class, 174)); // ***LAST ID*** add(GryoTypeReg.of(TraverserSet.class, 58)); @@ -552,7 +555,7 @@ public enum GryoVersion { add(GryoTypeReg.of(MatchStep.CountMatchAlgorithm.class, 160)); add(GryoTypeReg.of(MatchStep.GreedyMatchAlgorithm.class, 167)); // skip 171, 172 to sync with tp33 - add(GryoTypeReg.of(IndexedTraverserSet.VertexIndexedTraverserSet.class, 173)); // ***LAST ID*** + add(GryoTypeReg.of(IndexedTraverserSet.VertexIndexedTraverserSet.class, 173)); }}; } http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/StepTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/StepTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/StepTest.java index cfdb08b..e2f4ae0 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/StepTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/StepTest.java @@ -47,7 +47,7 @@ public abstract class StepTest { } @Test - public void testEquality() { + public void shouldValidateEqualityExpectations() { final List<Step> instances1 = this.getStepInstances(); final List<Step> instances2 = this.getStepInstances(); for (int i = 0; i < instances1.size(); i++) { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java index 4e86ebd..de4dded 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONMapperPartialEmbeddedTypeTest.java @@ -22,6 +22,8 @@ import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraver import org.apache.tinkerpop.gremlin.process.traversal.Bytecode; import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.Traverser; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.DefaultStepConfiguration; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.StepConfigurationProxy; import org.apache.tinkerpop.shaded.jackson.databind.JsonMappingException; import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper; import org.junit.Test; @@ -334,6 +336,14 @@ public class GraphSONMapperPartialEmbeddedTypeTest extends AbstractGraphSONTest } } + @Test + public void shouldHandleWithDefaultStepConfiguration() throws Exception { + final DefaultStepConfiguration stepConfig = new DefaultStepConfiguration("setInterval", 1000); + final StepConfigurationProxy deserStepConfig = serializeDeserializeAuto(mapper, stepConfig); + assertEquals(1000, deserStepConfig.getConfiguration().getInt("setInterval")); + assertEquals(DefaultStepConfiguration.class, deserStepConfig.getStepConfigurationClass()); + } + // Class needs to be defined as statics as it's a nested class. public static class FunObject { private String val; http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java index fcb040a..3013098 100644 --- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java +++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoMapperTest.java @@ -20,6 +20,7 @@ package org.apache.tinkerpop.gremlin.structure.io.gryo; import org.apache.tinkerpop.gremlin.process.remote.traversal.DefaultRemoteTraverser; import org.apache.tinkerpop.gremlin.process.traversal.Bytecode; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.DefaultStepConfiguration; import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalExplanation; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.io.IoX; @@ -377,6 +378,12 @@ public class GryoMapperTest { assertThat(Arrays.equals(bb.array(), serializeDeserialize(bb, ByteBuffer.class).array()), is(true)); } + @Test + public void shouldHandleDefaultStepConfiguration() throws Exception { + final DefaultStepConfiguration stepConf = new DefaultStepConfiguration("pageRankProperty", "xxx"); + assertEquals(stepConf, serializeDeserialize(stepConf, DefaultStepConfiguration.class)); + } + public <T> T serializeDeserialize(final Object o, final Class<T> clazz) throws Exception { final Kryo kryo = builder.get().create().createMapper(); try (final ByteArrayOutputStream stream = new ByteArrayOutputStream()) { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-dotnet/glv/generate.groovy ---------------------------------------------------------------------- diff --git a/gremlin-dotnet/glv/generate.groovy b/gremlin-dotnet/glv/generate.groovy index 91f9b94..6121483 100644 --- a/gremlin-dotnet/glv/generate.groovy +++ b/gremlin-dotnet/glv/generate.groovy @@ -53,6 +53,7 @@ def toCSharpTypeMap = ["Long": "long", "Traversal[]": "ITraversal[]", "Predicate": "IPredicate", "P": "P", + "StepConfiguration": "IStepConfiguration", "TraversalStrategy": "ITraversalStrategy", "TraversalStrategy[]": "ITraversalStrategy[]", "Function": "IFunction", http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java ---------------------------------------------------------------------- diff --git a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java index 48ba882..ee8b0c3 100644 --- a/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java +++ b/gremlin-groovy/src/main/java/org/apache/tinkerpop/gremlin/groovy/jsr223/GroovyTranslator.java @@ -28,6 +28,8 @@ import org.apache.tinkerpop.gremlin.process.traversal.Traversal; import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource; import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy; import org.apache.tinkerpop.gremlin.process.traversal.step.TraversalOptionParent; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.DefaultStepConfiguration; +import org.apache.tinkerpop.gremlin.process.traversal.step.util.StepConfigurationProxy; import org.apache.tinkerpop.gremlin.process.traversal.strategy.TraversalStrategyProxy; import org.apache.tinkerpop.gremlin.process.traversal.util.ConnectiveP; import org.apache.tinkerpop.gremlin.process.traversal.util.OrP; @@ -182,7 +184,12 @@ public final class GroovyTranslator implements Translator.ScriptTranslator { "Collections.emptyMap()," + convertToString(vertexProperty.element()) + ")"; } - } else if (object instanceof Lambda) { + } else if (object instanceof DefaultStepConfiguration) { + return DefaultStepConfiguration.class.getName() + ".create(new org.apache.commons.configuration.MapConfiguration(" + convertToString(ConfigurationConverter.getMap(((DefaultStepConfiguration) object).getConfiguration())) + "))"; + } else if (object instanceof StepConfigurationProxy) { + final StepConfigurationProxy proxy = (StepConfigurationProxy) object; + return proxy.getStepConfigurationClass().getCanonicalName() + ".create(new org.apache.commons.configuration.MapConfiguration(" + convertToString(ConfigurationConverter.getMap(proxy.getConfiguration())) + "))"; + }else if (object instanceof Lambda) { final String lambdaString = ((Lambda) object).getLambdaScript().trim(); return lambdaString.startsWith("{") ? lambdaString : "{" + lambdaString + "}"; } else if (object instanceof TraversalStrategyProxy) { http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/6a40535c/gremlin-python/glv/generate.groovy ---------------------------------------------------------------------- diff --git a/gremlin-python/glv/generate.groovy b/gremlin-python/glv/generate.groovy index 57cc9c9..5ea2fa5 100644 --- a/gremlin-python/glv/generate.groovy +++ b/gremlin-python/glv/generate.groovy @@ -29,6 +29,7 @@ import java.lang.reflect.Modifier def toPythonMap = ["global": "global_", "as": "as_", "in": "in_", + "with": "with_", "and": "and_", "with": "with_", "or": "or_",