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 2015/02/12 14:01:33 UTC
[07/77] [partial] incubator-tinkerpop git commit: moved com/tinkerpop
directories to org/apache/tinkerpop
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/PartitionStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/PartitionStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/PartitionStrategy.java
new file mode 100644
index 0000000..7538c84
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/PartitionStrategy.java
@@ -0,0 +1,322 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.process.Step;
+import com.tinkerpop.gremlin.process.Traverser;
+import com.tinkerpop.gremlin.process.graph.traversal.GraphTraversal;
+import com.tinkerpop.gremlin.process.graph.traversal.step.filter.HasStep;
+import com.tinkerpop.gremlin.process.graph.traversal.DefaultGraphTraversal;
+import com.tinkerpop.gremlin.process.graph.util.HasContainer;
+import com.tinkerpop.gremlin.process.traverser.util.DefaultTraverserGeneratorFactory;
+import com.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
+import com.tinkerpop.gremlin.structure.Contains;
+import com.tinkerpop.gremlin.structure.Direction;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Element;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.structure.util.ElementHelper;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.util.StreamFactory;
+import com.tinkerpop.gremlin.util.function.TriFunction;
+import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+/**
+ * A {@link GraphStrategy} which enables support for logical graph partitioning where the Graph can be blinded to
+ * different parts of the total {@link com.tinkerpop.gremlin.structure.Graph}. Note that the {@code partitionKey}
+ * is hidden by this strategy. Use the base {@link com.tinkerpop.gremlin.structure.Graph} to access that.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Joshua Shinavier (http://fortytwo.net)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class PartitionStrategy implements GraphStrategy {
+
+ private String writePartition;
+ private final String partitionKey;
+ private final Set<String> readPartitions = new HashSet<>();
+
+ private PartitionStrategy(final String partitionKey, final String partition) {
+ this.writePartition = partition;
+ this.addReadPartition(partition);
+ this.partitionKey = partitionKey;
+ }
+
+ public String getWritePartition() {
+ return this.writePartition;
+ }
+
+ public void setWritePartition(final String writePartition) {
+ this.writePartition = writePartition;
+ }
+
+ public String getPartitionKey() {
+ return this.partitionKey;
+ }
+
+ public Set<String> getReadPartitions() {
+ return Collections.unmodifiableSet(this.readPartitions);
+ }
+
+ public void removeReadPartition(final String readPartition) {
+ this.readPartitions.remove(readPartition);
+ }
+
+ public void addReadPartition(final String readPartition) {
+ this.readPartitions.add(readPartition);
+ }
+
+ public void clearReadPartitions() {
+ this.readPartitions.clear();
+ }
+
+ ///////////// old subgraph strategy methods
+ @Override
+ public UnaryOperator<BiFunction<Direction, String[], Iterator<Vertex>>> getVertexIteratorsVertexIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (direction, labels) -> StreamFactory
+ .stream(ctx.getCurrent().getBaseVertex().iterators().edgeIterator(direction, labels))
+ .filter(this::testEdge)
+ .map(edge -> otherVertex(direction, ctx.getCurrent(), edge)).iterator();
+ // TODO: Note that we are not doing f.apply() like the other methods. Is this bad?
+ // by not calling f.apply() to get the iterator, we're possibly bypassing strategy methods that
+ // could have been sequenced
+ }
+
+ @Override
+ public UnaryOperator<BiFunction<Direction, String[], Iterator<Edge>>> getVertexIteratorsEdgeIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (direction, labels) -> IteratorUtils.filter(f.apply(direction, labels), this::testEdge);
+ }
+
+ @Override
+ public UnaryOperator<Function<Direction, Iterator<Vertex>>> getEdgeIteratorsVertexIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> direction -> IteratorUtils.filter(f.apply(direction), this::testVertex);
+ }
+
+ @Override
+ public UnaryOperator<Function<Object[], GraphTraversal<Vertex, Vertex>>> getGraphVStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> ids -> {
+ final GraphTraversal<Vertex, Vertex> traversal = this.generateTraversal(ctx.getStrategyGraph().getBaseGraph().getClass());
+ traversal.asAdmin().getStrategies().setTraverserGeneratorFactory(DefaultTraverserGeneratorFactory.instance());
+ TraversalHelper.insertTraversal(0, f.apply(ids).has(this.partitionKey, Contains.within, getReadPartitions()).asAdmin(), traversal.asAdmin());
+ return traversal.filter(vertex -> testVertex(vertex.get()));
+ };
+ }
+
+ @Override
+ public UnaryOperator<Function<Object[], GraphTraversal<Edge, Edge>>> getGraphEStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> ids -> {
+ final GraphTraversal<Edge, Edge> traversal = this.generateTraversal(ctx.getStrategyGraph().getBaseGraph().getClass());
+ traversal.asAdmin().getStrategies().setTraverserGeneratorFactory(DefaultTraverserGeneratorFactory.instance());
+ TraversalHelper.insertTraversal(0, f.apply(ids).has(this.partitionKey, Contains.within, getReadPartitions()).asAdmin(), traversal.asAdmin());
+ return traversal.filter(edge -> testEdge(edge.get()));
+ };
+ }
+
+ private boolean testElement(final Element element) {
+ final Property<String> property = element instanceof StrategyElement ?
+ ((StrategyElement) element).getBaseElement().property(this.partitionKey) :
+ element.property(this.partitionKey);
+ return property.isPresent() && this.readPartitions.contains(property.value());
+ }
+
+ private boolean testVertex(final Vertex vertex) {
+ return testElement(vertex);
+ }
+
+ private boolean testEdge(final Edge edge) {
+ // the edge must pass the edge predicate, and both of its incident vertices must also pass the vertex predicate
+ // inV() and/or outV() will be empty if they do not. it is sometimes the case that an edge is unwrapped
+ // in which case it may not be filtered. in such cases, the vertices on such edges should be tested.
+ return testElement(edge)
+ && (edge instanceof StrategyWrapped ? edge.iterators().vertexIterator(Direction.IN).hasNext() && edge.iterators().vertexIterator(Direction.OUT).hasNext()
+ : testVertex(edge.iterators().vertexIterator(Direction.IN).next()) && testVertex(edge.iterators().vertexIterator(Direction.OUT).next()));
+ }
+
+ private static final Vertex otherVertex(final Direction direction, final Vertex start, final Edge edge) {
+ if (direction.equals(Direction.BOTH)) {
+ final Vertex inVertex = edge.iterators().vertexIterator(Direction.IN).next();
+ return ElementHelper.areEqual(start, inVertex) ?
+ edge.iterators().vertexIterator(Direction.OUT).next() :
+ inVertex;
+ } else {
+ return edge.iterators().vertexIterator(direction.opposite()).next();
+ }
+ }
+
+ private final <S, E> GraphTraversal<S, E> generateTraversal(final Class emanatingClass) {
+ return new DefaultGraphTraversal<S, E>(emanatingClass) {
+ @Override
+ public GraphTraversal<S, Vertex> to(final Direction direction, final String... edgeLabels) {
+ return direction.equals(Direction.BOTH) ?
+ this.toE(direction, edgeLabels).otherV() :
+ this.toE(direction, edgeLabels).toV(direction.opposite());
+ }
+
+ @Override
+ public GraphTraversal<S, Edge> toE(final Direction direction, final String... edgeLabels) {
+ return super.toE(direction, edgeLabels).has(getPartitionKey(), Contains.within, getReadPartitions()).filter(edge -> testEdge(edge.get()));
+ }
+
+ @Override
+ public GraphTraversal<S, Vertex> toV(final Direction direction) {
+ return super.toV(direction).has(getPartitionKey(), Contains.within, getReadPartitions());
+ }
+
+ @Override
+ public GraphTraversal<S, Vertex> otherV() {
+ return super.otherV().has(getPartitionKey(), Contains.within, getReadPartitions());
+ }
+
+ @Override
+ public GraphTraversal<S, E> has(final String key, final BiPredicate predicate, final Object value) {
+ final HasContainer hasContainer = new HasContainer(key, predicate, value);
+ final HasStep<Element> hasStep = new HasStep(this, hasContainer) {
+ @Override
+ protected boolean filter(final Traverser.Admin traverser) {
+ return hasContainer.test(((StrategyElement) traverser.get()).getBaseElement());
+ }
+ };
+ return this.asAdmin().addStep((Step) hasStep);
+ }
+ };
+ }
+
+ ///////////////////////////
+
+ @Override
+ public <V> UnaryOperator<Function<String[], Iterator<VertexProperty<V>>>> getVertexIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (keys) -> IteratorUtils.filter(f.apply(keys), property -> {
+ return !this.partitionKey.equals(property.key());
+ });
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String[], Iterator<V>>> getVertexIteratorsValueIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (keys) -> IteratorUtils.map(ctx.getCurrent().iterators().<V>propertyIterator(keys), vertexProperty -> vertexProperty.value());
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Set<String>>> getVertexKeysStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> () -> IteratorUtils.fill(IteratorUtils.filter(f.get().iterator(), key -> {
+ return !this.partitionKey.equals(key);
+ }), new HashSet<>());
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String, VertexProperty<V>>> getVertexGetPropertyStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> k -> {
+ return k.equals(this.partitionKey) ? VertexProperty.<V>empty() : f.apply(k);
+ };
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String, Property<V>>> getEdgeGetPropertyStrategy(StrategyContext<StrategyEdge> ctx, GraphStrategy composingStrategy) {
+ return (f) -> k -> {
+ return k.equals(this.partitionKey) ? Property.<V>empty() : f.apply(k);
+ };
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String[], Iterator<Property<V>>>> getEdgeIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (keys) -> IteratorUtils.filter(f.apply(keys), property -> {
+ return !this.partitionKey.equals(property.key());
+ });
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String[], Iterator<V>>> getEdgeIteratorsValueIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (keys) -> IteratorUtils.map(ctx.getCurrent().iterators().<V>propertyIterator(keys), property -> property.value());
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Set<String>>> getEdgeKeysStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> () -> IteratorUtils.fill(IteratorUtils.filter(f.get().iterator(), key -> {
+ return !this.partitionKey.equals(key);
+ }), new HashSet<>());
+ }
+
+ @Override
+ public UnaryOperator<Function<Object[], Vertex>> getAddVertexStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (keyValues) -> f.apply(this.addKeyValues(keyValues));
+ }
+
+ @Override
+ public UnaryOperator<TriFunction<String, Vertex, Object[], Edge>> getAddEdgeStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (label, v, keyValues) -> f.apply(label, v, this.addKeyValues(keyValues));
+ }
+
+ private final Object[] addKeyValues(final Object[] keyValues) {
+ final Object[] keyValuesExtended = Arrays.copyOf(keyValues, keyValues.length + 2);
+ keyValuesExtended[keyValues.length] = this.partitionKey;
+ keyValuesExtended[keyValues.length + 1] = this.writePartition;
+ return keyValuesExtended;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.graphStrategyString(this);
+ }
+
+ public static Builder build() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private String startPartition = "default";
+ private String partitionKey = "_partition";
+
+ private Builder() {
+ }
+
+ /**
+ * The initial partition to filter by. If this value is not set, it will be defaulted to "default".
+ */
+ public Builder startPartition(final String startPartition) {
+ if (null == startPartition) throw new IllegalArgumentException("The startPartition cannot be null");
+ this.startPartition = startPartition;
+ return this;
+ }
+
+ /**
+ * The name of the partition key. If this is not set, then the value is defaulted to "_partition".
+ */
+ public Builder partitionKey(final String partitionKey) {
+ if (null == partitionKey) throw new IllegalArgumentException("The partitionKey cannot be null");
+ this.partitionKey = partitionKey;
+ return this;
+ }
+
+ public PartitionStrategy create() {
+ return new PartitionStrategy(partitionKey, startPartition);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/ReadOnlyStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/ReadOnlyStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/ReadOnlyStrategy.java
new file mode 100644
index 0000000..d76085d
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/ReadOnlyStrategy.java
@@ -0,0 +1,143 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.util.function.TriFunction;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+
+/**
+ * This {@link GraphStrategy} prevents the graph from being modified and will throw a
+ * {@link UnsupportedOperationException} if an attempt is made to do so.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public final class ReadOnlyStrategy implements GraphStrategy {
+ private static final ReadOnlyStrategy instance = new ReadOnlyStrategy();
+
+ private ReadOnlyStrategy() {
+ }
+
+ public static final ReadOnlyStrategy instance() {
+ return instance;
+ }
+
+ @Override
+ public UnaryOperator<Function<Object[], Vertex>> getAddVertexStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return readOnlyFunction();
+ }
+
+ @Override
+ public UnaryOperator<TriFunction<String, Vertex, Object[], Edge>> getAddEdgeStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return readOnlyTriFunction();
+ }
+
+ @Override
+ public <V> UnaryOperator<BiFunction<String, V, Property<V>>> getEdgePropertyStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (t, u) -> {
+ throw Exceptions.graphUsesReadOnlyStrategy();
+ };
+ }
+
+ @Override
+ public <V> UnaryOperator<BiFunction<String, V, VertexProperty<V>>> getVertexPropertyStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (t, u) -> {
+ throw Exceptions.graphUsesReadOnlyStrategy();
+ };
+ }
+
+ @Override
+ public <V, U> UnaryOperator<BiFunction<String, V, Property<V>>> getVertexPropertyPropertyStrategy(final StrategyContext<StrategyVertexProperty<U>> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (t, u) -> {
+ throw Exceptions.graphUsesReadOnlyStrategy();
+ };
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Void>> getRemoveEdgeStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return readOnlySupplier();
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Void>> getRemoveVertexStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return readOnlySupplier();
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<Void>> getRemovePropertyStrategy(final StrategyContext<StrategyProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return readOnlySupplier();
+ }
+
+ @Override
+ public UnaryOperator<BiConsumer<String, Object>> getVariableSetStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> (k, v) -> {
+ throw Exceptions.graphUsesReadOnlyStrategy();
+ };
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Map<String, Object>>> getVariableAsMapStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+ return (f) -> () -> Collections.unmodifiableMap(f.get());
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<Void>> getRemoveVertexPropertyStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return readOnlySupplier();
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.graphStrategyString(this);
+ }
+
+ public static <T> UnaryOperator<Supplier<T>> readOnlySupplier() {
+ return (f) -> () -> {
+ throw Exceptions.graphUsesReadOnlyStrategy();
+ };
+ }
+
+ public static <T, U> UnaryOperator<Function<T, U>> readOnlyFunction() {
+ return (f) -> (t) -> {
+ throw Exceptions.graphUsesReadOnlyStrategy();
+ };
+ }
+
+ public static <T, U, V, W> UnaryOperator<TriFunction<T, U, V, W>> readOnlyTriFunction() {
+ return (f) -> (t, u, v) -> {
+ throw Exceptions.graphUsesReadOnlyStrategy();
+ };
+ }
+
+ public static class Exceptions {
+ public static UnsupportedOperationException graphUsesReadOnlyStrategy() {
+ return new UnsupportedOperationException(String.format("Graph uses %s and is therefore unmodifiable", ReadOnlyStrategy.class));
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/SequenceStrategy.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/SequenceStrategy.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/SequenceStrategy.java
new file mode 100644
index 0000000..64f472f
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/SequenceStrategy.java
@@ -0,0 +1,366 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.process.graph.traversal.GraphTraversal;
+import com.tinkerpop.gremlin.structure.Direction;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.util.function.TriFunction;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
+import java.util.stream.Collectors;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public final class SequenceStrategy implements GraphStrategy {
+ private final List<GraphStrategy> graphStrategySequence;
+
+ private SequenceStrategy(final List<GraphStrategy> strategies) {
+ this.graphStrategySequence = strategies;
+ }
+
+ public List<GraphStrategy> getGraphStrategySequence() {
+ return Collections.unmodifiableList(graphStrategySequence);
+ }
+
+ @Override
+ public UnaryOperator<Function<Object[], Iterator<Vertex>>> getGraphIteratorsVertexIteratorStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getGraphIteratorsVertexIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Function<Object[], Iterator<Edge>>> getGraphIteratorsEdgeIteratorStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getGraphIteratorsEdgeIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Function<Object[], Vertex>> getAddVertexStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getAddVertexStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<TriFunction<String, Vertex, Object[], Edge>> getAddEdgeStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getAddEdgeStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Void>> getRemoveEdgeStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getRemoveEdgeStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Void>> getRemoveVertexStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getRemoveVertexStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<Void>> getRemovePropertyStrategy(final StrategyContext<StrategyProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getRemovePropertyStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String, VertexProperty<V>>> getVertexGetPropertyStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexGetPropertyStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String, Property<V>>> getEdgeGetPropertyStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgeGetPropertyStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<BiFunction<String, V, VertexProperty<V>>> getVertexPropertyStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<BiFunction<String, V, Property<V>>> getEdgePropertyStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgePropertyStrategy(ctx, this));
+ }
+
+ @Override
+ public <V, U> UnaryOperator<BiFunction<String, V, Property<V>>> getVertexPropertyPropertyStrategy(final StrategyContext<StrategyVertexProperty<U>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyPropertyStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Object>> getVertexIdStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexIdStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Graph>> getVertexGraphStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexGraphStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<Object>> getVertexPropertyIdStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyIdStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<Graph>> getVertexPropertyGraphStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyGraphStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Object>> getEdgeIdStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgeIdStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Graph>> getEdgeGraphStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgeGraphStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<String>> getVertexLabelStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexLabelStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<String>> getEdgeLabelStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgeLabelStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<String>> getVertexPropertyLabelStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyLabelStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String[], Iterator<VertexProperty<V>>>> getVertexIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexIteratorsPropertyIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String[], Iterator<Property<V>>>> getEdgeIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgeIteratorsPropertyIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public <V, U> UnaryOperator<Function<String[], Iterator<Property<V>>>> getVertexPropertyIteratorsPropertyIteratorStrategy(final StrategyContext<StrategyVertexProperty<U>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyIteratorsPropertyIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Set<String>>> getVertexKeysStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexKeysStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Set<String>>> getEdgeKeysStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgeKeysStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<Set<String>>> getVertexPropertyKeysStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyKeysStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String[], Iterator<V>>> getVertexIteratorsValueIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexIteratorsValueIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String[], Iterator<V>>> getEdgeIteratorsValueIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgeIteratorsValueIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public <V, U> UnaryOperator<Function<String[], Iterator<V>>> getVertexPropertyIteratorsValueIteratorStrategy(final StrategyContext<StrategyVertexProperty<U>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyIteratorsValueIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Function<Direction, Iterator<Vertex>>> getEdgeIteratorsVertexIteratorStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgeIteratorsVertexIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<BiFunction<Direction, String[], Iterator<Vertex>>> getVertexIteratorsVertexIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexIteratorsVertexIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<BiFunction<Direction, String[], Iterator<Edge>>> getVertexIteratorsEdgeIteratorStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexIteratorsEdgeIteratorStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String, V>> getVertexValueStrategy(final StrategyContext<StrategyVertex> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexValueStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Function<String, V>> getEdgeValueStrategy(final StrategyContext<StrategyEdge> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getEdgeValueStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Set<String>>> getVariableKeysStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVariableKeysStrategy(ctx, this));
+ }
+
+ @Override
+ public <R> UnaryOperator<Function<String, Optional<R>>> getVariableGetStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVariableGetStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Consumer<String>> getVariableRemoveStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVariableRemoveStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<BiConsumer<String, Object>> getVariableSetStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVariableSetStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Map<String, Object>>> getVariableAsMapStrategy(final StrategyContext<StrategyVariables> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVariableAsMapStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Supplier<Void>> getGraphCloseStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getGraphCloseStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<Void>> getRemoveVertexPropertyStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getRemoveVertexPropertyStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<Vertex>> getVertexPropertyGetElementStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyGetElementStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Function<Object[], GraphTraversal<Vertex, Vertex>>> getGraphVStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getGraphVStrategy(ctx, this));
+ }
+
+ @Override
+ public UnaryOperator<Function<Object[], GraphTraversal<Edge, Edge>>> getGraphEStrategy(final StrategyContext<StrategyGraph> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getGraphEStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<V>> getVertexPropertyValueStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyValueStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<V>> getPropertyValueStrategy(final StrategyContext<StrategyProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getPropertyValueStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<String>> getVertexPropertyKeyStrategy(final StrategyContext<StrategyVertexProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getVertexPropertyKeyStrategy(ctx, this));
+ }
+
+ @Override
+ public <V> UnaryOperator<Supplier<String>> getPropertyKeyStrategy(final StrategyContext<StrategyProperty<V>> ctx, final GraphStrategy composingStrategy) {
+ return this.composeStrategyUnaryOperator(s -> s.getPropertyKeyStrategy(ctx, this));
+ }
+
+ @Override
+ public String toString() {
+ return String.join("->", this.graphStrategySequence.stream().map(Object::toString)
+ .map(String::toLowerCase).collect(Collectors.<String>toList()));
+ }
+
+ /**
+ * Compute a new strategy function from the sequence of supplied {@link GraphStrategy} objects.
+ *
+ * @param f a {@link java.util.function.Function} that extracts a particular strategy implementation from a {@link GraphStrategy}
+ * @return a newly constructed {@link java.util.function.UnaryOperator} that applies each extracted strategy implementation in
+ * the order supplied
+ */
+ private UnaryOperator composeStrategyUnaryOperator(final Function<GraphStrategy, UnaryOperator> f) {
+ return this.graphStrategySequence.stream().map(f).reduce(null,
+ (acc, next) -> acc == null ? next : toUnaryOp(acc.compose(next)));
+ }
+
+ /**
+ * Converts a {@link java.util.function.Function} to a {@link java.util.function.UnaryOperator} since the call to
+ * {@link java.util.function.UnaryOperator#andThen(java.util.function.Function)} doesn't return {@link java.util.function.UnaryOperator} and can't
+ * be casted to one.
+ *
+ * @param f a {@link java.util.function.Function} that has the same argument and return type
+ * @return a {@link java.util.function.UnaryOperator} of the supplied {@code f}
+ */
+ private static <T> UnaryOperator<T> toUnaryOp(final Function<T, T> f) {
+ return new UnaryOperator<T>() {
+ @Override
+ public T apply(T t) {
+ return f.apply(t);
+ }
+ };
+ }
+
+ public static Builder build() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private List<GraphStrategy> strategies = new ArrayList<>();
+
+ private Builder() {
+ strategies.add(IdentityStrategy.instance());
+ }
+
+ /**
+ * Provide the sequence of {@link GraphStrategy} implementations to execute. If this value is not set,
+ * then a {@code SequenceStrategy} is initialized with a single
+ * {@link com.tinkerpop.gremlin.structure.strategy.IdentityStrategy} instance.
+ */
+ public Builder sequence(final GraphStrategy... strategies) {
+ this.strategies = new ArrayList<>(Arrays.asList(strategies));
+ return this;
+ }
+
+ public SequenceStrategy create() {
+ return new SequenceStrategy(strategies);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyContext.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyContext.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyContext.java
new file mode 100644
index 0000000..ce78df1
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyContext.java
@@ -0,0 +1,54 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Graph;
+
+/**
+ * The {@link StrategyContext} object is provided to the methods of {@link GraphStrategy} so that the strategy functions
+ * it constructs have some knowledge of the environment.
+ *
+ * @param <T> represents the object that is triggering the strategy (i.e. the vertex on which addEdge was called).
+ */
+public final class StrategyContext<T extends StrategyWrapped> {
+ private final StrategyGraph g;
+ private final T current;
+
+ public StrategyContext(final StrategyGraph g, final T current) {
+ if (null == g) throw Graph.Exceptions.argumentCanNotBeNull("g");
+ if (null == current) throw Graph.Exceptions.argumentCanNotBeNull("current");
+
+ this.g = g;
+ this.current = current;
+ }
+
+ /**
+ * Gets the {@link StrategyWrapped} instance that is triggering the {@link GraphStrategy} method.
+ */
+ public T getCurrent() {
+ return current;
+ }
+
+ /**
+ * Gets the current {@link com.tinkerpop.gremlin.structure.strategy.StrategyGraph} instance.
+ */
+ public StrategyGraph getStrategyGraph() {
+ return g;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyEdge.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyEdge.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyEdge.java
new file mode 100644
index 0000000..9517498
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyEdge.java
@@ -0,0 +1,164 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Direction;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedEdge;
+import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StrategyEdge extends StrategyElement implements Edge, Edge.Iterators, StrategyWrapped, WrappedEdge<Edge> {
+
+ private final StrategyContext<StrategyEdge> strategyContext;
+
+ public StrategyEdge(final Edge baseEdge, final StrategyGraph strategyGraph) {
+ super(baseEdge, strategyGraph);
+ this.strategyContext = new StrategyContext<>(strategyGraph, this);
+ }
+
+ @Override
+ public Edge.Iterators iterators() {
+ return this;
+ }
+
+ @Override
+ public Graph graph() {
+ return this.strategyGraph.compose(
+ s -> s.getEdgeGraphStrategy(this.strategyContext, strategy),
+ () -> this.strategyGraph).get();
+ }
+
+ @Override
+ public Object id() {
+ return this.strategyGraph.compose(
+ s -> s.getEdgeIdStrategy(this.strategyContext, strategy),
+ this.getBaseEdge()::id).get();
+ }
+
+ @Override
+ public String label() {
+ return this.strategyGraph.compose(
+ s -> s.getEdgeLabelStrategy(this.strategyContext, strategy),
+ this.getBaseEdge()::label).get();
+ }
+
+ @Override
+ public <V> V value(final String key) throws NoSuchElementException {
+ return this.strategyGraph.compose(
+ s -> s.<V>getEdgeValueStrategy(this.strategyContext, strategy),
+ this.getBaseEdge()::value).apply(key);
+ }
+
+ @Override
+ public Set<String> keys() {
+ return this.strategyGraph.compose(
+ s -> s.getEdgeKeysStrategy(this.strategyContext, strategy),
+ this.getBaseEdge()::keys).get();
+ }
+
+ @Override
+ public Edge getBaseEdge() {
+ return (Edge) this.baseElement;
+ }
+
+ @Override
+ public <V> Property<V> property(final String key) {
+ return new StrategyProperty<>(this.strategyGraph.compose(
+ s -> s.<V>getEdgeGetPropertyStrategy(this.strategyContext, strategy),
+ this.getBaseEdge()::property).apply(key), this.strategyGraph);
+ }
+
+ @Override
+ public <V> Property<V> property(final String key, final V value) {
+ return new StrategyProperty<>(this.strategyGraph.compose(
+ s -> s.<V>getEdgePropertyStrategy(this.strategyContext, strategy),
+ this.getBaseEdge()::property).apply(key, value), this.strategyGraph);
+ }
+
+ @Override
+ public void remove() {
+ this.strategyGraph.compose(
+ s -> s.getRemoveEdgeStrategy(this.strategyContext, strategy),
+ () -> {
+ this.getBaseEdge().remove();
+ return null;
+ }).get();
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.graphStrategyElementString(this);
+ }
+
+
+ @Override
+ public Iterator<Vertex> vertexIterator(final Direction direction) {
+ return new StrategyVertex.StrategyVertexIterator(this.strategyGraph.compose(
+ s -> s.getEdgeIteratorsVertexIteratorStrategy(this.strategyContext, strategy),
+ (Direction d) -> this.getBaseEdge().iterators().vertexIterator(d)).apply(direction), this.strategyGraph);
+ }
+
+ @Override
+ public <V> Iterator<V> valueIterator(final String... propertyKeys) {
+ return this.strategyGraph.compose(
+ s -> s.<V>getEdgeIteratorsValueIteratorStrategy(this.strategyContext, strategy),
+ (String[] pks) -> this.getBaseEdge().iterators().valueIterator(pks)).apply(propertyKeys);
+ }
+
+ @Override
+ public <V> Iterator<Property<V>> propertyIterator(final String... propertyKeys) {
+ return IteratorUtils.map(this.strategyGraph.compose(
+ s -> s.<V>getEdgeIteratorsPropertyIteratorStrategy(this.strategyContext, strategy),
+ (String[] pks) -> this.getBaseEdge().iterators().propertyIterator(pks)).apply(propertyKeys),
+ property -> new StrategyProperty<>(property, this.strategyGraph));
+ }
+
+
+ public static class StrategyEdgeIterator implements Iterator<Edge> {
+ private final Iterator<Edge> edges;
+ private final StrategyGraph strategyGraph;
+
+ public StrategyEdgeIterator(final Iterator<Edge> itty,
+ final StrategyGraph strategyGraph) {
+ this.edges = itty;
+ this.strategyGraph = strategyGraph;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.edges.hasNext();
+ }
+
+ @Override
+ public Edge next() {
+ return new StrategyEdge(this.edges.next(), this.strategyGraph);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyElement.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyElement.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyElement.java
new file mode 100644
index 0000000..46d8fed
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyElement.java
@@ -0,0 +1,57 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Element;
+import com.tinkerpop.gremlin.structure.util.ElementHelper;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public abstract class StrategyElement implements Element, StrategyWrapped {
+ protected final StrategyGraph strategyGraph;
+ protected final GraphStrategy strategy;
+ protected final Element baseElement;
+ protected final StrategyContext<StrategyElement> elementStrategyContext;
+
+ protected StrategyElement(final Element baseElement, final StrategyGraph strategyGraph) {
+ if (baseElement instanceof StrategyWrapped) throw new IllegalArgumentException(
+ String.format("The element %s is already StrategyWrapped and must be a base Element", baseElement));
+ this.strategyGraph = strategyGraph;
+ this.strategy = strategyGraph.getStrategy();
+ this.baseElement = baseElement;
+ this.elementStrategyContext = new StrategyContext<>(strategyGraph, this);
+ }
+
+ public Element getBaseElement() {
+ return this.baseElement;
+ }
+
+ @Override
+ public int hashCode() {
+ return this.baseElement.hashCode();
+ }
+
+ @SuppressWarnings("EqualsWhichDoesntCheckParameterClass")
+ @Override
+ public boolean equals(final Object object) {
+ return ElementHelper.areEqual(this, object);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyGraph.java
new file mode 100644
index 0000000..d80391e
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyGraph.java
@@ -0,0 +1,187 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.process.Traversal;
+import com.tinkerpop.gremlin.process.computer.GraphComputer;
+import com.tinkerpop.gremlin.process.graph.traversal.GraphTraversal;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Transaction;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedGraph;
+import com.tinkerpop.gremlin.util.function.FunctionUtils;
+import org.apache.commons.configuration.Configuration;
+
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
+
+/**
+ * A wrapper class for {@link Graph} instances that host and apply a {@link GraphStrategy}. The wrapper implements
+ * {@link Graph} itself and intercepts calls made to the hosted instance and then applies the strategy. Methods
+ * that return an extension of {@link com.tinkerpop.gremlin.structure.Element} or a
+ * {@link com.tinkerpop.gremlin.structure.Property} will be automatically wrapped in a {@link StrategyWrapped}
+ * implementation.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class StrategyGraph implements Graph, Graph.Iterators, StrategyWrapped, WrappedGraph<Graph> {
+ private final Graph baseGraph;
+ private final GraphStrategy strategy;
+ private final StrategyContext<StrategyGraph> graphContext;
+
+ public StrategyGraph(final Graph baseGraph) {
+ this(baseGraph, IdentityStrategy.instance());
+ }
+
+ public StrategyGraph(final Graph baseGraph, final GraphStrategy strategy) {
+ if (baseGraph instanceof StrategyWrapped) throw new IllegalArgumentException(
+ String.format("The graph %s is already StrategyWrapped and must be a base Graph", baseGraph));
+ if (null == strategy) throw new IllegalArgumentException("Strategy cannot be null");
+
+ this.strategy = strategy;
+ this.baseGraph = baseGraph;
+ this.graphContext = new StrategyContext<>(this, this);
+ }
+
+ /**
+ * Gets the underlying base {@link Graph} that is being hosted within this wrapper.
+ */
+ @Override
+ public Graph getBaseGraph() {
+ return this.baseGraph;
+ }
+
+ /**
+ * Gets the {@link com.tinkerpop.gremlin.structure.strategy.GraphStrategy} for the {@link com.tinkerpop.gremlin.structure.Graph}.
+ */
+ public GraphStrategy getStrategy() {
+ return this.strategy;
+ }
+
+ /**
+ * Return a {@link GraphStrategy} function that takes the base function of the form denoted by {@code T} as
+ * an argument and returns back a function with {@code T}.
+ *
+ * @param f a function to execute if a {@link com.tinkerpop.gremlin.structure.strategy.GraphStrategy}.
+ * @param impl the base implementation of an operation.
+ * @return a function that will be applied in the Gremlin Structure implementation
+ */
+ public <T> T compose(final Function<GraphStrategy, UnaryOperator<T>> f, final T impl) {
+ return f.apply(this.strategy).apply(impl);
+ }
+
+ @Override
+ public Vertex addVertex(final Object... keyValues) {
+ final Optional<Vertex> v = Optional.ofNullable(compose(
+ s -> s.getAddVertexStrategy(this.graphContext, strategy),
+ this.baseGraph::addVertex).apply(keyValues));
+ return v.isPresent() ? new StrategyVertex(v.get(), this) : null;
+ }
+
+ @Override
+ public GraphTraversal<Vertex, Vertex> V(final Object... vertexIds) {
+ return this.compose(s -> s.getGraphVStrategy(this.graphContext, this.strategy), this.baseGraph::V).apply(vertexIds).map(vertex -> new StrategyVertex(vertex.get(), this));
+ /* final GraphTraversal<Vertex, Vertex> traversal = new DefaultGraphTraversal<>(this.getClass());
+ return traversal.asAdmin().addStep(new StrategyGraphStep<>(traversal, this, Vertex.class, this.compose(
+ s -> s.getGraphVStrategy(this.graphContext, strategy),
+ this.baseGraph::V).apply(vertexIds))); */
+ }
+
+ @Override
+ public GraphTraversal<Edge, Edge> E(final Object... edgeIds) {
+ return this.compose(s -> s.getGraphEStrategy(this.graphContext, this.strategy), this.baseGraph::E).apply(edgeIds).map(edge -> new StrategyEdge(edge.get(), this));
+ /*final GraphTraversal<Edge, Edge> traversal = new DefaultGraphTraversal<>(this.getClass());
+ return traversal.asAdmin().addStep(new StrategyGraphStep<>(traversal, this, Edge.class, this.compose(
+ s -> s.getGraphEStrategy(this.graphContext, strategy),
+ this.baseGraph::E).apply(edgeIds)));*/
+ }
+
+ @Override
+ public <T extends Traversal<S, S>, S> T of(final Class<T> traversalClass) {
+ return this.baseGraph.of(traversalClass); // TODO: wrap the users traversal in StrategyWrappedTraversal
+ }
+
+ @Override
+ public GraphComputer compute(final Class... graphComputerClass) {
+ return this.baseGraph.compute(graphComputerClass);
+ }
+
+ @Override
+ public Transaction tx() {
+ return this.baseGraph.tx();
+ }
+
+ @Override
+ public Variables variables() {
+ return new StrategyVariables(this.baseGraph.variables(), this);
+ }
+
+ @Override
+ public Configuration configuration() {
+ return this.baseGraph.configuration();
+ }
+
+ @Override
+ public Features features() {
+ return this.baseGraph.features();
+ }
+
+ @Override
+ public Iterators iterators() {
+ return this;
+ }
+
+ @Override
+ public Iterator<Vertex> vertexIterator(final Object... vertexIds) {
+ return new StrategyVertex.StrategyVertexIterator(compose(s -> s.getGraphIteratorsVertexIteratorStrategy(this.graphContext, strategy), this.baseGraph.iterators()::vertexIterator).apply(vertexIds), this);
+ }
+
+ @Override
+ public Iterator<Edge> edgeIterator(final Object... edgeIds) {
+ return new StrategyEdge.StrategyEdgeIterator(compose(s -> s.getGraphIteratorsEdgeIteratorStrategy(this.graphContext, strategy), this.baseGraph.iterators()::edgeIterator).apply(edgeIds), this);
+ }
+
+ @Override
+ public void close() throws Exception {
+ // compose function doesn't seem to want to work here even though it works with other Supplier<Void>
+ // strategy functions. maybe the "throws Exception" is hosing it up.......
+ this.strategy.getGraphCloseStrategy(this.graphContext, strategy).apply(FunctionUtils.wrapSupplier(() -> {
+ baseGraph.close();
+ return null;
+ })).get();
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.graphStrategyString(strategy, this.baseGraph);
+ }
+
+ public static class Exceptions {
+ public static IllegalStateException strategyGraphIsSafe() {
+ return new IllegalStateException("StrategyGraph is in safe mode - its elements cannot be unwrapped.");
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyProperty.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyProperty.java
new file mode 100644
index 0000000..09d0c10
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyProperty.java
@@ -0,0 +1,114 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Element;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedProperty;
+
+import java.util.NoSuchElementException;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StrategyProperty<V> implements Property<V>, StrategyWrapped, WrappedProperty<Property<V>> {
+
+ private final Property<V> baseProperty;
+ private final StrategyContext<StrategyProperty<V>> strategyContext;
+ private final StrategyGraph strategyGraph;
+ private final GraphStrategy strategy;
+
+ public StrategyProperty(final Property<V> baseProperty, final StrategyGraph strategyGraph) {
+ if (baseProperty instanceof StrategyWrapped) throw new IllegalArgumentException(
+ String.format("The property %s is already StrategyWrapped and must be a base Property", baseProperty));
+ this.baseProperty = baseProperty;
+ this.strategyContext = new StrategyContext<>(strategyGraph, this);
+ this.strategyGraph = strategyGraph;
+ this.strategy = strategyGraph.getStrategy();
+ }
+
+ @Override
+ public String key() {
+ return this.strategyGraph.compose(
+ s -> s.getPropertyKeyStrategy(this.strategyContext, strategy), this.baseProperty::key).get();
+ }
+
+ @Override
+ public V value() throws NoSuchElementException {
+ return this.strategyGraph.compose(
+ s -> s.getPropertyValueStrategy(this.strategyContext, strategy), this.baseProperty::value).get();
+ }
+
+ @Override
+ public boolean isPresent() {
+ return this.baseProperty.isPresent();
+ }
+
+ @Override
+ public Element element() {
+ final Element baseElement = this.baseProperty.element();
+ return (baseElement instanceof Vertex ? new StrategyVertex((Vertex) baseElement, this.strategyGraph) :
+ new StrategyEdge((Edge) baseElement, this.strategyGraph));
+ }
+
+ @Override
+ public <E extends Throwable> V orElseThrow(final Supplier<? extends E> exceptionSupplier) throws E {
+ return this.baseProperty.orElseThrow(exceptionSupplier);
+ }
+
+ @Override
+ public V orElseGet(final Supplier<? extends V> valueSupplier) {
+ return this.baseProperty.orElseGet(valueSupplier);
+ }
+
+ @Override
+ public V orElse(final V otherValue) {
+ return this.baseProperty.orElse(otherValue);
+ }
+
+ @Override
+ public void ifPresent(final Consumer<? super V> consumer) {
+ this.baseProperty.ifPresent(consumer);
+ }
+
+ @Override
+ public void remove() {
+ this.strategyGraph.compose(
+ s -> s.getRemovePropertyStrategy(strategyContext, strategy),
+ () -> {
+ this.baseProperty.remove();
+ return null;
+ }).get();
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.graphStrategyPropertyString(this);
+ }
+
+ @Override
+ public Property<V> getBaseProperty() {
+ return this.baseProperty;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVariables.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVariables.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVariables.java
new file mode 100644
index 0000000..f492389
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVariables.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedVariables;
+
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class StrategyVariables implements StrategyWrapped, Graph.Variables, WrappedVariables<Graph.Variables> {
+
+ protected final StrategyGraph strategyGraph;
+ private final Graph.Variables baseVariables;
+ private final StrategyContext<StrategyVariables> variableStrategyContext;
+ private final GraphStrategy strategy;
+
+ public StrategyVariables(final Graph.Variables variables, final StrategyGraph strategyGraph) {
+ if (variables instanceof StrategyWrapped) throw new IllegalArgumentException(
+ String.format("The variables %s is already StrategyWrapped and must be a base Variables", variables));
+ this.baseVariables = variables;
+ this.strategyGraph = strategyGraph;
+ this.variableStrategyContext = new StrategyContext<>(strategyGraph, this);
+ this.strategy = strategyGraph.getStrategy();
+ }
+
+ @Override
+ public Set<String> keys() {
+ return this.strategyGraph.compose(
+ s -> s.getVariableKeysStrategy(this.variableStrategyContext, strategy),
+ this.baseVariables::keys).get();
+ }
+
+ @Override
+ public <R> Optional<R> get(final String key) {
+ return this.strategyGraph.compose(
+ s -> s.<R>getVariableGetStrategy(this.variableStrategyContext, strategy),
+ this.baseVariables::get).apply(key);
+ }
+
+ @Override
+ public void set(final String key, final Object value) {
+ this.strategyGraph.compose(
+ s -> s.getVariableSetStrategy(this.variableStrategyContext, strategy),
+ this.baseVariables::set).accept(key, value);
+ }
+
+ @Override
+ public void remove(final String key) {
+ this.strategyGraph.compose(
+ s -> s.getVariableRemoveStrategy(this.variableStrategyContext, strategy),
+ this.baseVariables::remove).accept(key);
+ }
+
+ @Override
+ public Map<String, Object> asMap() {
+ return this.strategyGraph.compose(
+ s -> s.getVariableAsMapStrategy(this.variableStrategyContext, strategy),
+ this.baseVariables::asMap).get();
+ }
+
+ @Override
+ public Graph.Variables getBaseVariables() {
+ return this.baseVariables;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.graphStrategyVariables(this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertex.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertex.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertex.java
new file mode 100644
index 0000000..7276b10
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertex.java
@@ -0,0 +1,178 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Direction;
+import com.tinkerpop.gremlin.structure.Edge;
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedVertex;
+import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class StrategyVertex extends StrategyElement implements Vertex, StrategyWrapped, WrappedVertex<Vertex>, Vertex.Iterators {
+
+ private final StrategyContext<StrategyVertex> strategyContext;
+
+ public StrategyVertex(final Vertex baseVertex, final StrategyGraph strategyGraph) {
+ super(baseVertex, strategyGraph);
+ this.strategyContext = new StrategyContext<>(strategyGraph, this);
+ }
+
+ @Override
+ public Graph graph() {
+ return this.strategyGraph.compose(
+ s -> s.getVertexGraphStrategy(this.strategyContext, strategy),
+ () -> this.strategyGraph).get();
+ }
+
+ @Override
+ public Object id() {
+ return this.strategyGraph.compose(
+ s -> s.getVertexIdStrategy(this.strategyContext, strategy),
+ this.getBaseVertex()::id).get();
+ }
+
+ @Override
+ public String label() {
+ return this.strategyGraph.compose(
+ s -> s.getVertexLabelStrategy(this.strategyContext, strategy),
+ this.getBaseVertex()::label).get();
+ }
+
+ @Override
+ public Set<String> keys() {
+ return this.strategyGraph.compose(
+ s -> s.getVertexKeysStrategy(this.strategyContext, strategy),
+ this.getBaseVertex()::keys).get();
+ }
+
+ @Override
+ public Vertex.Iterators iterators() {
+ return this;
+ }
+
+ @Override
+ public <V> V value(final String key) throws NoSuchElementException {
+ return this.strategyGraph.compose(
+ s -> s.<V>getVertexValueStrategy(this.strategyContext, strategy),
+ this.getBaseVertex()::value).apply(key);
+ }
+
+ @Override
+ public void remove() {
+ this.strategyGraph.compose(
+ s -> s.getRemoveVertexStrategy(this.strategyContext, strategy),
+ () -> {
+ this.getBaseVertex().remove();
+ return null;
+ }).get();
+ }
+
+ @Override
+ public Vertex getBaseVertex() {
+ return (Vertex) this.baseElement;
+ }
+
+ @Override
+ public Edge addEdge(final String label, final Vertex inVertex, final Object... keyValues) {
+ final Vertex baseInVertex = (inVertex instanceof StrategyVertex) ? ((StrategyVertex) inVertex).getBaseVertex() : inVertex;
+ return new StrategyEdge(this.strategyGraph.compose(
+ s -> s.getAddEdgeStrategy(this.strategyContext, strategy),
+ this.getBaseVertex()::addEdge)
+ .apply(label, baseInVertex, keyValues), this.strategyGraph);
+ }
+
+ @Override
+ public <V> VertexProperty<V> property(final String key, final V value) {
+ return new StrategyVertexProperty<>(this.strategyGraph.compose(
+ s -> s.<V>getVertexPropertyStrategy(this.strategyContext, strategy),
+ this.getBaseVertex()::property).apply(key, value), this.strategyGraph);
+ }
+
+ @Override
+ public <V> VertexProperty<V> property(final String key) {
+ return new StrategyVertexProperty<>(this.strategyGraph.compose(
+ s -> s.<V>getVertexGetPropertyStrategy(this.strategyContext, strategy),
+ this.getBaseVertex()::property).apply(key), this.strategyGraph);
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.graphStrategyElementString(this);
+ }
+
+ @Override
+ public Iterator<Edge> edgeIterator(final Direction direction, final String... edgeLabels) {
+ return new StrategyEdge.StrategyEdgeIterator(this.strategyGraph.compose(
+ s -> s.getVertexIteratorsEdgeIteratorStrategy(this.strategyContext, strategy),
+ (Direction d, String[] l) -> this.getBaseVertex().iterators().edgeIterator(d, l)).apply(direction, edgeLabels), this.strategyGraph);
+ }
+
+ @Override
+ public Iterator<Vertex> vertexIterator(final Direction direction, final String... labels) {
+ return new StrategyVertexIterator(this.strategyGraph.compose(
+ s -> s.getVertexIteratorsVertexIteratorStrategy(strategyContext, strategy),
+ (Direction d, String[] l) -> this.getBaseVertex().iterators().vertexIterator(d, l)).apply(direction, labels), this.strategyGraph);
+ }
+
+ @Override
+ public <V> Iterator<V> valueIterator(final String... propertyKeys) {
+ return this.strategyGraph.compose(
+ s -> s.<V>getVertexIteratorsValueIteratorStrategy(strategyContext, strategy),
+ (String[] pks) -> this.getBaseVertex().iterators().valueIterator(pks)).apply(propertyKeys);
+ }
+
+ @Override
+ public <V> Iterator<VertexProperty<V>> propertyIterator(final String... propertyKeys) {
+ return IteratorUtils.map(this.strategyGraph.compose(
+ s -> s.<V>getVertexIteratorsPropertyIteratorStrategy(this.strategyContext, strategy),
+ (String[] pks) -> this.getBaseVertex().iterators().propertyIterator(pks)).apply(propertyKeys),
+ property -> new StrategyVertexProperty<>(property, this.strategyGraph));
+ }
+
+ public static class StrategyVertexIterator implements Iterator<Vertex> {
+ private final Iterator<Vertex> vertices;
+ private final StrategyGraph strategyGraph;
+
+ public StrategyVertexIterator(final Iterator<Vertex> iterator, final StrategyGraph strategyGraph) {
+ this.vertices = iterator;
+ this.strategyGraph = strategyGraph;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return this.vertices.hasNext();
+ }
+
+ @Override
+ public Vertex next() {
+ return new StrategyVertex(this.vertices.next(), this.strategyGraph);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertexProperty.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertexProperty.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertexProperty.java
new file mode 100644
index 0000000..cf88a50
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyVertexProperty.java
@@ -0,0 +1,145 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+import com.tinkerpop.gremlin.structure.Graph;
+import com.tinkerpop.gremlin.structure.Property;
+import com.tinkerpop.gremlin.structure.Vertex;
+import com.tinkerpop.gremlin.structure.VertexProperty;
+import com.tinkerpop.gremlin.structure.util.StringFactory;
+import com.tinkerpop.gremlin.structure.util.wrapped.WrappedVertexProperty;
+import com.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ * @author Marko A. Rodriguez (http://markorodriguez.com)
+ */
+public class StrategyVertexProperty<V> extends StrategyElement implements VertexProperty<V>, StrategyWrapped, WrappedVertexProperty<VertexProperty<V>>, VertexProperty.Iterators {
+
+ private final StrategyContext<StrategyVertexProperty<V>> strategyContext;
+
+ public StrategyVertexProperty(final VertexProperty<V> baseVertexProperty, final StrategyGraph strategyGraph) {
+ super(baseVertexProperty, strategyGraph);
+ this.strategyContext = new StrategyContext<>(strategyGraph, this);
+ }
+
+ @Override
+ public Graph graph() {
+ return this.strategyGraph.compose(
+ s -> s.getVertexPropertyGraphStrategy(strategyContext, strategy),
+ () -> this.strategyGraph).get();
+ }
+
+ @Override
+ public Object id() {
+ return this.strategyGraph.compose(
+ s -> s.getVertexPropertyIdStrategy(strategyContext, strategy),
+ this.getBaseVertexProperty()::id).get();
+ }
+
+ @Override
+ public String label() {
+ return this.strategyGraph.compose(
+ s -> s.getVertexPropertyLabelStrategy(strategyContext, strategy),
+ this.getBaseVertexProperty()::label).get();
+ }
+
+ @Override
+ public Set<String> keys() {
+ return this.strategyGraph.compose(
+ s -> s.getVertexPropertyKeysStrategy(strategyContext, strategy),
+ this.getBaseVertexProperty()::keys).get();
+ }
+
+ @Override
+ public Vertex element() {
+ return new StrategyVertex(this.strategyGraph.compose(
+ s -> s.getVertexPropertyGetElementStrategy(strategyContext, strategy),
+ this.getBaseVertexProperty()::element).get(), strategyGraph);
+ }
+
+ @Override
+ public VertexProperty.Iterators iterators() {
+ return this;
+ }
+
+ @Override
+ public <U> Property<U> property(final String key, final U value) {
+ return new StrategyProperty<>(this.strategyGraph.compose(
+ s -> s.<U, V>getVertexPropertyPropertyStrategy(strategyContext, strategy),
+ this.getBaseVertexProperty()::property).<String, U>apply(key, value), this.strategyGraph);
+ }
+
+ @Override
+ public String key() {
+ return this.strategyGraph.compose(
+ s -> s.getVertexPropertyKeyStrategy(this.strategyContext, strategy), this.getBaseVertexProperty()::key).get();
+ }
+
+ @Override
+ public V value() throws NoSuchElementException {
+ return this.strategyGraph.compose(
+ s -> s.getVertexPropertyValueStrategy(this.strategyContext, strategy), this.getBaseVertexProperty()::value).get();
+ }
+
+ @Override
+ public boolean isPresent() {
+ return this.getBaseVertexProperty().isPresent();
+ }
+
+ @Override
+ public void remove() {
+ this.strategyGraph.compose(
+ s -> s.getRemoveVertexPropertyStrategy(this.strategyContext, strategy),
+ () -> {
+ this.getBaseVertexProperty().remove();
+ return null;
+ }).get();
+ }
+
+ @Override
+ public VertexProperty<V> getBaseVertexProperty() {
+ return (VertexProperty<V>) this.baseElement;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.graphStrategyElementString(this);
+ }
+
+
+ @Override
+ public <U> Iterator<Property<U>> propertyIterator(final String... propertyKeys) {
+ return IteratorUtils.map(this.strategyGraph.compose(
+ s -> s.<U, V>getVertexPropertyIteratorsPropertyIteratorStrategy(this.strategyContext, strategy),
+ (String[] pks) -> this.getBaseVertexProperty().iterators().propertyIterator(pks)).apply(propertyKeys),
+ property -> new StrategyProperty<>(property, this.strategyGraph));
+ }
+
+ @Override
+ public <U> Iterator<U> valueIterator(final String... propertyKeys) {
+ return this.strategyGraph.compose(
+ s -> s.<U, V>getVertexPropertyIteratorsValueIteratorStrategy(this.strategyContext, strategy),
+ (String[] pks) -> this.getBaseVertexProperty().iterators().valueIterator(pks)).apply(propertyKeys);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/1545201f/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyWrapped.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyWrapped.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyWrapped.java
new file mode 100644
index 0000000..f967385
--- /dev/null
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/strategy/StrategyWrapped.java
@@ -0,0 +1,28 @@
+/*
+ * 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 com.tinkerpop.gremlin.structure.strategy;
+
+/**
+ * A marker interface for the graph wrapper classes. Classes that are strategy wrappers should implement this
+ * interface.
+ *
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public interface StrategyWrapped {
+}