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/05/28 21:43:32 UTC
incubator-tinkerpop git commit: Added willAllowId() for features
related to vertex, vertexproperty and edge TINKERPOP3-695
Repository: incubator-tinkerpop
Updated Branches:
refs/heads/master 852627770 -> c1006eeaf
Added willAllowId() for features related to vertex, vertexproperty and edge TINKERPOP3-695
Needed a way to separate what a graph internalizes an id as and what a graph will accept as an id value.
Project: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/commit/c1006eea
Tree: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/tree/c1006eea
Diff: http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/diff/c1006eea
Branch: refs/heads/master
Commit: c1006eeaf0a329a4a0b0d3cd6886fac0c2fac7a5
Parents: 8526277
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu May 28 15:41:27 2015 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu May 28 15:43:24 2015 -0400
----------------------------------------------------------------------
CHANGELOG.asciidoc | 1 +
.../tinkerpop/gremlin/structure/Graph.java | 53 +++++++++
.../structure/io/graphml/GraphMLReader.java | 18 +--
.../structure/io/graphson/GraphSONReader.java | 4 +-
.../io/graphson/LegacyGraphSONReader.java | 21 ++--
.../gremlin/structure/io/gryo/GryoReader.java | 4 +-
.../gremlin/structure/util/Attachable.java | 31 ++++--
.../gremlin/structure/util/star/StarGraph.java | 111 +++++++++++++++++++
.../gremlin/structure/FeatureSupportTest.java | 27 ++++-
.../gremlin/hadoop/structure/HadoopGraph.java | 5 +
.../tinkergraph/structure/TinkerGraph.java | 84 +++++++++++---
11 files changed, 307 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 62e22d5..09760b3 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -25,6 +25,7 @@ image::http://www.tinkerpop.com/docs/current/images/gremlin-hindu.png[width=225]
TinkerPop 3.0.0.GA (NOT OFFICIALLY RELEASED YET)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+* Added `willAllowId` method to features related to vertices, edges and vertex properties to test if an identifier can be use when `supportsUserSuppliedIds` is `true`.
* Fixed a bug in `GraphTraversal.choose(predicate,trueTraversal,falseTraversal)`.
* Removed `MapTraversal`, `MapTraverserTraversal`, `FilterTraversal`, and `FilterTraverserTraversal` as these are simply `__.map(function)` and `__.filter(predicate)`.
* Include `hadoop-gremlin` Hadoop configuration sample files in Gremlin Console distribution.
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
index 10ca2a6..7ef6d1b 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/Graph.java
@@ -44,6 +44,7 @@ import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.Set;
+import java.util.UUID;
import java.util.stream.Collectors;
/**
@@ -602,6 +603,32 @@ public interface Graph extends AutoCloseable, Host {
public default boolean supportsAnyIds() {
return true;
}
+
+ /**
+ * Determines if an identifier will be accepted by the {@link Graph}. This check is different than
+ * what identifier internally supports as defined in methods like {@link #supportsNumericIds()}. Those
+ * refer to internal representation of the identifier. A {@link Graph} may accept an identifier that
+ * is not of those types and internally transform it to a native representation.
+ * <p/>
+ * Note that this method only applies if {@link #supportsUserSuppliedIds()} is {@code true}. Those that
+ * return {@code false} for that method can immediately return false for this one as it allows no ids
+ * of any type (it generates them all).
+ * <p/>
+ * The default implementation will immediately return {@code false} if {@link #supportsUserSuppliedIds()}
+ * is {@code false}. If custom identifiers are supported then it will throw an exception. Those that
+ * return {@code true} for {@link #supportsCustomIds()} should override this method. If
+ * {@link #supportsAnyIds()} is {@code true} then the identifier will immediately be allowed. Finally,
+ * if any of the other types are supported, they will be typed checked against the class of the supplied
+ * identifier.
+ */
+ public default boolean willAllowId(final Object id) {
+ if (!supportsUserSuppliedIds()) return false;
+ if (supportsCustomIds())
+ throw new UnsupportedOperationException("The default implementation is not capable of validating custom ids - please override");
+
+ return supportsAnyIds() || (supportsStringIds() && id instanceof String)
+ || (supportsNumericIds() && id instanceof Number) || (supportsUuidIds() && id instanceof UUID);
+ }
}
/**
@@ -681,6 +708,32 @@ public interface Graph extends AutoCloseable, Host {
public default boolean supportsAnyIds() {
return true;
}
+
+ /**
+ * Determines if an identifier will be accepted by the {@link Graph}. This check is different than
+ * what identifier internally supports as defined in methods like {@link #supportsNumericIds()}. Those
+ * refer to internal representation of the identifier. A {@link Graph} may accept an identifier that
+ * is not of those types and internally transform it to a native representation.
+ * <p/>
+ * Note that this method only applies if {@link #supportsUserSuppliedIds()} is {@code true}. Those that
+ * return {@code false} for that method can immediately return false for this one as it allows no ids
+ * of any type (it generates them all).
+ * <p/>
+ * The default implementation will immediately return {@code false} if {@link #supportsUserSuppliedIds()}
+ * is {@code false}. If custom identifiers are supported then it will throw an exception. Those that
+ * return {@code true} for {@link #supportsCustomIds()} should override this method. If
+ * {@link #supportsAnyIds()} is {@code true} then the identifier will immediately be allowed. Finally,
+ * if any of the other types are supported, they will be typed checked against the class of the supplied
+ * identifier.
+ */
+ public default boolean willAllowId(final Object id) {
+ if (!supportsUserSuppliedIds()) return false;
+ if (supportsCustomIds())
+ throw new UnsupportedOperationException("The default implementation is not capable of validating custom ids - please override");
+
+ return supportsAnyIds() || (supportsStringIds() && id instanceof String)
+ || (supportsNumericIds() && id instanceof Number) || (supportsUuidIds() && id instanceof UUID);
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
index f8d3aee..ca6f76d 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphml/GraphMLReader.java
@@ -74,8 +74,8 @@ public class GraphMLReader implements GraphReader {
final Map<Object,Vertex> cache = new HashMap<>();
final AtomicLong counter = new AtomicLong(0);
final boolean supportsTx = graphToWriteTo.features().graph().supportsTransactions();
- final boolean supportsEdgeIds = graphToWriteTo.features().edge().supportsUserSuppliedIds();
- final boolean supportsVertexIds = graphToWriteTo.features().vertex().supportsUserSuppliedIds();
+ final Graph.Features.EdgeFeatures edgeFeatures = graphToWriteTo.features().edge();
+ final Graph.Features.VertexFeatures vertexFeatures = graphToWriteTo.features().vertex();
try {
final XMLStreamReader reader = inputFactory.createXMLStreamReader(graphInputStream);
@@ -123,8 +123,8 @@ public class GraphMLReader implements GraphReader {
// graphml allows edges and vertices to be mixed in terms of how they are positioned
// in the xml therefore it is possible that an edge is created prior to its definition
// as a vertex.
- edgeOutVertex = findOrCreate(vertexIdOut, graphToWriteTo, supportsVertexIds, cache, false);
- edgeInVertex = findOrCreate(vertexIdIn, graphToWriteTo, supportsVertexIds, cache, false);
+ edgeOutVertex = findOrCreate(vertexIdOut, graphToWriteTo, vertexFeatures, cache, false);
+ edgeInVertex = findOrCreate(vertexIdIn, graphToWriteTo, vertexFeatures, cache, false);
if (supportsTx && counter.incrementAndGet() % batchSize == 0)
graphToWriteTo.tx().commit();
@@ -163,7 +163,8 @@ public class GraphMLReader implements GraphReader {
final String currentVertexLabel = Optional.ofNullable(vertexLabel).orElse(Vertex.DEFAULT_LABEL);
final Object[] propsAsArray = vertexProps.entrySet().stream().flatMap(e -> Stream.of(e.getKey(), e.getValue())).toArray();
- findOrCreate(currentVertexId, graphToWriteTo, supportsVertexIds, cache, true, ElementHelper.upsert(propsAsArray, T.label, currentVertexLabel));
+ findOrCreate(currentVertexId, graphToWriteTo, vertexFeatures, cache,
+ true, ElementHelper.upsert(propsAsArray, T.label, currentVertexLabel));
if (supportsTx && counter.incrementAndGet() % batchSize == 0)
graphToWriteTo.tx().commit();
@@ -174,7 +175,7 @@ public class GraphMLReader implements GraphReader {
isInVertex = false;
} else if (elementName.equals(GraphMLTokens.EDGE)) {
final Object[] propsAsArray = edgeProps.entrySet().stream().flatMap(e -> Stream.of(e.getKey(), e.getValue())).toArray();
- final Object[] propsReady = supportsEdgeIds ? ElementHelper.upsert(propsAsArray, T.id, edgeId) : propsAsArray;
+ final Object[] propsReady = edgeFeatures.willAllowId(edgeId) ? ElementHelper.upsert(propsAsArray, T.id, edgeId) : propsAsArray;
edgeOutVertex.addEdge(edgeLabel, edgeInVertex, propsReady);
if (supportsTx && counter.incrementAndGet() % batchSize == 0)
@@ -277,7 +278,8 @@ public class GraphMLReader implements GraphReader {
throw Io.Exceptions.readerFormatIsForFullGraphSerializationOnly(this.getClass());
}
- private static Vertex findOrCreate(final Object id, final Graph graphToWriteTo, final boolean supportsIds,
+ private static Vertex findOrCreate(final Object id, final Graph graphToWriteTo,
+ final Graph.Features.VertexFeatures features,
final Map<Object,Vertex> cache, final boolean asVertex, final Object... args) {
if (cache.containsKey(id)) {
// if the request to findOrCreate come from a vertex then AND the vertex was already created, that means
@@ -292,7 +294,7 @@ public class GraphMLReader implements GraphReader {
return cache.get(id);
}
} else {
- final Object [] argsReady = supportsIds ? ElementHelper.upsert(args, T.id, id) : args;
+ final Object [] argsReady = features.willAllowId(id) ? ElementHelper.upsert(args, T.id, id) : args;
final Vertex v = graphToWriteTo.addVertex(argsReady);
cache.put(id, v);
return v;
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
index 26b88d6..76594ab 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/GraphSONReader.java
@@ -91,7 +91,7 @@ public class GraphSONReader implements GraphReader {
final AtomicLong counter = new AtomicLong(0);
final boolean supportsTx = graphToWriteTo.features().graph().supportsTransactions();
- final boolean supportsUserSuppliedIdsOnEdge = graphToWriteTo.features().edge().supportsUserSuppliedIds();
+ final Graph.Features.EdgeFeatures edgeFeatures = graphToWriteTo.features().edge();
final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
br.lines().<Vertex>map(FunctionUtils.wrapFunction(line -> readVertex(new ByteArrayInputStream(line.getBytes()), null, null, Direction.OUT))).forEach(vertex -> {
@@ -106,7 +106,7 @@ public class GraphSONReader implements GraphReader {
// StarAdjacentVertex whose equality should match StarVertex.
final Vertex cachedOutV = cache.get(e.outVertex());
final Vertex cachedInV = cache.get(e.inVertex());
- final Edge newEdge = supportsUserSuppliedIdsOnEdge ? cachedOutV.addEdge(e.label(), cachedInV, T.id, e.id()) : cachedOutV.addEdge(e.label(), cachedInV);
+ final Edge newEdge = edgeFeatures.willAllowId(e.id()) ? cachedOutV.addEdge(e.label(), cachedInV, T.id, e.id()) : cachedOutV.addEdge(e.label(), cachedInV);
e.properties().forEachRemaining(p -> newEdge.property(p.key(), p.value()));
if (supportsTx && counter.incrementAndGet() % batchSize == 0)
graphToWriteTo.tx().commit();
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
index 935e2f0..a8d1929 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/graphson/LegacyGraphSONReader.java
@@ -67,11 +67,11 @@ public class LegacyGraphSONReader implements GraphReader {
final Map<Object,Vertex> cache = new HashMap<>();
final AtomicLong counter = new AtomicLong(0);
final boolean supportsTx = graphToWriteTo.features().graph().supportsTransactions();
- final boolean supportsEdgeIds = graphToWriteTo.features().edge().supportsUserSuppliedIds();
- final boolean supportsVertexIds = graphToWriteTo.features().vertex().supportsUserSuppliedIds();
+ final Graph.Features.EdgeFeatures edgeFeatures = graphToWriteTo.features().edge();
+ final Graph.Features.VertexFeatures vertexFeatures = graphToWriteTo.features().vertex();
final JsonFactory factory = mapper.getFactory();
- final LegacyGraphSONUtility graphson = new LegacyGraphSONUtility(graphToWriteTo, supportsVertexIds, supportsEdgeIds, cache);
+ final LegacyGraphSONUtility graphson = new LegacyGraphSONUtility(graphToWriteTo, vertexFeatures, edgeFeatures, cache);
try (JsonParser parser = factory.createParser(inputStream)) {
if (parser.nextToken() != JsonToken.START_OBJECT)
@@ -247,15 +247,16 @@ public class LegacyGraphSONReader implements GraphReader {
static class LegacyGraphSONUtility {
private static final String EMPTY_STRING = "";
private final Graph g;
- private final boolean supportsVertexIds;
- private final boolean supportsEdgeIds;
+ private final Graph.Features.VertexFeatures vertexFeatures;
+ private final Graph.Features.EdgeFeatures edgeFeatures;
private final Map<Object,Vertex> cache;
- public LegacyGraphSONUtility(final Graph g, final boolean supportsVertexIds, final boolean supportsEdgeIds,
+ public LegacyGraphSONUtility(final Graph g, final Graph.Features.VertexFeatures vertexFeatures,
+ final Graph.Features.EdgeFeatures edgeFeatures,
final Map<Object, Vertex> cache) {
this.g = g;
- this.supportsVertexIds = supportsVertexIds;
- this.supportsEdgeIds = supportsEdgeIds;
+ this.vertexFeatures = vertexFeatures;
+ this.edgeFeatures = edgeFeatures;
this.cache = cache;
}
@@ -263,7 +264,7 @@ public class LegacyGraphSONReader implements GraphReader {
final Map<String, Object> props = readProperties(json);
final Object vertexId = getTypedValueFromJsonNode(json.get(GraphSONTokens._ID));
- final Vertex v = supportsVertexIds ? g.addVertex(T.id, vertexId) : g.addVertex();
+ final Vertex v = vertexFeatures.willAllowId(vertexId) ? g.addVertex(T.id, vertexId) : g.addVertex();
cache.put(vertexId, v);
for (Map.Entry<String, Object> entry : props.entrySet()) {
@@ -280,7 +281,7 @@ public class LegacyGraphSONReader implements GraphReader {
final JsonNode nodeLabel = json.get(GraphSONTokens._LABEL);
final String label = nodeLabel == null ? EMPTY_STRING : nodeLabel.textValue();
- final Edge e = supportsEdgeIds ? out.addEdge(label, in, T.id, edgeId) : out.addEdge(label, in) ;
+ final Edge e = edgeFeatures.willAllowId(edgeId) ? out.addEdge(label, in, T.id, edgeId) : out.addEdge(label, in) ;
for (Map.Entry<String, Object> entry : props.entrySet()) {
e.property(entry.getKey(), entry.getValue());
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
index 359fe79..a208e2f 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/io/gryo/GryoReader.java
@@ -84,7 +84,7 @@ public class GryoReader implements GraphReader {
final Map<StarGraph.StarVertex,Vertex> cache = new HashMap<>();
final AtomicLong counter = new AtomicLong(0);
- final boolean supportsUserSuppliedIdsOnEdge = graphToWriteTo.features().edge().supportsUserSuppliedIds();
+ final Graph.Features.EdgeFeatures edgeFeatures = graphToWriteTo.features().edge();
final boolean supportsTx = graphToWriteTo.features().graph().supportsTransactions();
IteratorUtils.iterate(new VertexInputIterator(new Input(inputStream), attachable -> {
@@ -99,7 +99,7 @@ public class GryoReader implements GraphReader {
// StarAdjacentVertex whose equality should match StarVertex.
final Vertex cachedOutV = cache.get(e.outVertex());
final Vertex cachedInV = cache.get(e.inVertex());
- final Edge newEdge = supportsUserSuppliedIdsOnEdge ? cachedOutV.addEdge(e.label(), cachedInV, T.id, e.id()) : cachedOutV.addEdge(e.label(), cachedInV);
+ final Edge newEdge = edgeFeatures.willAllowId(e.id()) ? cachedOutV.addEdge(e.label(), cachedInV, T.id, e.id()) : cachedOutV.addEdge(e.label(), cachedInV);
e.properties().forEachRemaining(p -> newEdge.property(p.key(), p.value()));
if (supportsTx && counter.incrementAndGet() % batchSize == 0)
graphToWriteTo.tx().commit();
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java
index 0049877..4489191 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/Attachable.java
@@ -49,10 +49,25 @@ public interface Attachable<V> {
*/
public V get();
+ /**
+ * Provide a way to attach an {@link Attachable} implementation to a host. Note that the context of the host
+ * is not defined by way of the attachment method itself that is supplied as an argument. It is up to the
+ * implementer to supply that context.
+ *
+ * @param method a {@link Function} that takes an {@link Attachable} and returns the "re-attached" object
+ * @return the return value of the {@code method}
+ * @throws IllegalStateException if the {@link Attachable} is not a "graph" object (i.e. host or
+ * attachable don't work together)
+ */
public default V attach(final Function<Attachable<V>, V> method) throws IllegalStateException {
return method.apply(this);
}
+ /**
+ * A collection of general methods of attachment. Note that more efficient methods of attachment might exist
+ * if the user knows the source data being attached and the features of the graph that the data is being
+ * attached to.
+ */
public static class Method {
public static <V> Function<Attachable<V>, V> get(final Host hostVertexOrGraph) {
return (Attachable<V> attachable) -> {
@@ -272,12 +287,11 @@ public interface Attachable<V> {
public static Vertex createVertex(final Attachable<Vertex> attachableVertex, final Graph hostGraph) {
final Vertex baseVertex = attachableVertex.get();
- final Vertex vertex = hostGraph.features().vertex().supportsUserSuppliedIds() ?
+ final Vertex vertex = hostGraph.features().vertex().willAllowId(baseVertex.id()) ?
hostGraph.addVertex(T.id, baseVertex.id(), T.label, baseVertex.label()) :
hostGraph.addVertex(T.label, baseVertex.label());
- final boolean supportsUserSuppliedIds = hostGraph.features().vertex().properties().supportsUserSuppliedIds();
baseVertex.properties().forEachRemaining(vp -> {
- final VertexProperty vertexProperty = supportsUserSuppliedIds ?
+ final VertexProperty vertexProperty = hostGraph.features().vertex().properties().willAllowId(vp.id()) ?
vertex.property(hostGraph.features().vertex().getCardinality(vp.key()), vp.key(), vp.value(), T.id, vp.id()) :
vertex.property(hostGraph.features().vertex().getCardinality(vp.key()), vp.key(), vp.value());
vp.properties().forEachRemaining(p -> vertexProperty.property(p.key(), p.value()));
@@ -290,12 +304,11 @@ public interface Attachable<V> {
}
public static Edge createEdge(final Attachable<Edge> attachableEdge, final Graph hostGraph) {
- final boolean supportsUserSuppliedIds = hostGraph.features().vertex().supportsUserSuppliedIds();
final Edge baseEdge = attachableEdge.get();
Iterator<Vertex> vertices = hostGraph.vertices(baseEdge.outVertex().id());
- final Vertex outV = vertices.hasNext() ? vertices.next() : supportsUserSuppliedIds ? hostGraph.addVertex(T.id, baseEdge.outVertex().id()) : hostGraph.addVertex();
+ final Vertex outV = vertices.hasNext() ? vertices.next() : hostGraph.features().vertex().willAllowId(baseEdge.outVertex().id()) ? hostGraph.addVertex(T.id, baseEdge.outVertex().id()) : hostGraph.addVertex();
vertices = hostGraph.vertices(baseEdge.inVertex().id());
- final Vertex inV = vertices.hasNext() ? vertices.next() : supportsUserSuppliedIds ? hostGraph.addVertex(T.id, baseEdge.inVertex().id()) : hostGraph.addVertex();
+ final Vertex inV = vertices.hasNext() ? vertices.next() : hostGraph.features().vertex().willAllowId(baseEdge.inVertex().id()) ? hostGraph.addVertex(T.id, baseEdge.inVertex().id()) : hostGraph.addVertex();
if (ElementHelper.areEqual(outV, inV)) {
final Iterator<Edge> itty = outV.edges(Direction.OUT, baseEdge.label());
while (itty.hasNext()) {
@@ -304,7 +317,7 @@ public interface Attachable<V> {
return e;
}
}
- final Edge e = hostGraph.features().edge().supportsUserSuppliedIds() ? outV.addEdge(baseEdge.label(), inV, T.id, baseEdge.id()) : outV.addEdge(baseEdge.label(), inV);
+ final Edge e = hostGraph.features().edge().willAllowId(baseEdge.id()) ? outV.addEdge(baseEdge.label(), inV, T.id, baseEdge.id()) : outV.addEdge(baseEdge.label(), inV);
baseEdge.properties().forEachRemaining(p -> e.property(p.key(), p.value()));
return e;
}
@@ -317,7 +330,7 @@ public interface Attachable<V> {
final VertexProperty<Object> baseVertexProperty = attachableVertexProperty.get();
final Iterator<Vertex> vertexIterator = hostGraph.vertices(baseVertexProperty.element().id());
if (vertexIterator.hasNext()) {
- final VertexProperty vertexProperty = hostGraph.features().vertex().properties().supportsUserSuppliedIds() ?
+ final VertexProperty vertexProperty = hostGraph.features().vertex().properties().willAllowId(baseVertexProperty.id()) ?
vertexIterator.next().property(hostGraph.features().vertex().getCardinality(baseVertexProperty.key()), baseVertexProperty.key(), baseVertexProperty.value(), T.id, baseVertexProperty.id()) :
vertexIterator.next().property(hostGraph.features().vertex().getCardinality(baseVertexProperty.key()), baseVertexProperty.key(), baseVertexProperty.value());
baseVertexProperty.properties().forEachRemaining(p -> vertexProperty.property(p.key(), p.value()));
@@ -328,7 +341,7 @@ public interface Attachable<V> {
public static VertexProperty createVertexProperty(final Attachable<VertexProperty> attachableVertexProperty, final Vertex hostVertex) {
final VertexProperty<Object> baseVertexProperty = attachableVertexProperty.get();
- final VertexProperty vertexProperty = hostVertex.graph().features().vertex().properties().supportsUserSuppliedIds() ?
+ final VertexProperty vertexProperty = hostVertex.graph().features().vertex().properties().willAllowId(baseVertexProperty.id()) ?
hostVertex.property(hostVertex.graph().features().vertex().getCardinality(baseVertexProperty.key()), baseVertexProperty.key(), baseVertexProperty.value(), T.id, baseVertexProperty.id()) :
hostVertex.property(hostVertex.graph().features().vertex().getCardinality(baseVertexProperty.key()), baseVertexProperty.key(), baseVertexProperty.value());
baseVertexProperty.properties().forEachRemaining(p -> vertexProperty.property(p.key(), p.value()));
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraph.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraph.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraph.java
index 50c3a79..9541cdf 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraph.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/structure/util/star/StarGraph.java
@@ -158,6 +158,11 @@ public final class StarGraph implements Graph, Serializable {
}
@Override
+ public Features features() {
+ return StarGraphFeatures.INSTANCE;
+ }
+
+ @Override
public void close() throws Exception {
}
@@ -713,4 +718,110 @@ public final class StarGraph implements Graph, Serializable {
return this;
}
}
+
+ public static class StarGraphFeatures implements Features {
+ public static final StarGraphFeatures INSTANCE = new StarGraphFeatures();
+
+ private StarGraphFeatures() {
+ }
+
+ @Override
+ public GraphFeatures graph() {
+ return StarGraphGraphFeatures.INSTANCE;
+ }
+
+ @Override
+ public EdgeFeatures edge() {
+ return StarGraphEdgeFeatures.INSTANCE;
+ }
+
+ @Override
+ public VertexFeatures vertex() {
+ return StarGraphVertexFeatures.INSTANCE;
+ }
+
+ @Override
+ public String toString() {
+ return StringFactory.featureString(this);
+ }
+ }
+
+ static class StarGraphVertexFeatures implements Features.VertexFeatures {
+ public static final StarGraphVertexFeatures INSTANCE = new StarGraphVertexFeatures();
+
+ private StarGraphVertexFeatures() {
+ }
+
+ @Override
+ public Features.VertexPropertyFeatures properties() {
+ return StarGraphVertexPropertyFeatures.INSTANCE;
+ }
+
+ @Override
+ public boolean supportsCustomIds() {
+ return false;
+ }
+
+ @Override
+ public boolean willAllowId(final Object id) {
+ return true;
+ }
+ }
+
+ static class StarGraphEdgeFeatures implements Features.EdgeFeatures {
+ public static final StarGraphEdgeFeatures INSTANCE = new StarGraphEdgeFeatures();
+
+ private StarGraphEdgeFeatures() {
+ }
+
+ @Override
+ public boolean supportsCustomIds() {
+ return false;
+ }
+
+ @Override
+ public boolean willAllowId(final Object id) {
+ return true;
+ }
+ }
+
+ static class StarGraphGraphFeatures implements Features.GraphFeatures {
+ public static final StarGraphGraphFeatures INSTANCE = new StarGraphGraphFeatures();
+
+ private StarGraphGraphFeatures() {
+ }
+
+ @Override
+ public boolean supportsTransactions() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsPersistence() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsThreadedTransactions() {
+ return false;
+ }
+ }
+
+ static class StarGraphVertexPropertyFeatures implements Features.VertexPropertyFeatures {
+ public static final StarGraphVertexPropertyFeatures INSTANCE = new StarGraphVertexPropertyFeatures();
+
+ private StarGraphVertexPropertyFeatures() {
+ }
+
+ @Override
+ public boolean supportsCustomIds() {
+ return false;
+ }
+
+ @Override
+ public boolean willAllowId(final Object id) {
+ return true;
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java
----------------------------------------------------------------------
diff --git a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java
index ed7190c..40b6694 100644
--- a/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java
+++ b/gremlin-test/src/main/java/org/apache/tinkerpop/gremlin/structure/FeatureSupportTest.java
@@ -22,7 +22,6 @@ import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
import org.apache.tinkerpop.gremlin.ExceptionCoverage;
import org.apache.tinkerpop.gremlin.FeatureRequirement;
import org.apache.tinkerpop.gremlin.FeatureRequirementSet;
-import org.apache.tinkerpop.gremlin.GraphManager;
import org.apache.tinkerpop.gremlin.structure.Graph.Features.EdgeFeatures;
import org.apache.tinkerpop.gremlin.structure.Graph.Features.EdgePropertyFeatures;
import org.apache.tinkerpop.gremlin.structure.Graph.Features.GraphFeatures;
@@ -182,7 +181,7 @@ public class FeatureSupportTest {
@FeatureRequirement(featureClass = VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS, supported = false)
public void shouldSupportUserSuppliedIdsIfAnIdCanBeAssignedToVertex() throws Exception {
try {
- graph.addVertex(T.id, GraphManager.getGraphProvider().convertId(99999943835l, Vertex.class));
+ graph.addVertex(T.id, graphProvider.convertId(99999943835l, Vertex.class));
fail(String.format(INVALID_FEATURE_SPECIFICATION, VertexFeatures.class.getSimpleName(), FEATURE_USER_SUPPLIED_IDS));
} catch (Exception e) {
validateException(Vertex.Exceptions.userSuppliedIdsNotSupported(), e);
@@ -190,6 +189,12 @@ public class FeatureSupportTest {
}
@Test
+ @FeatureRequirement(featureClass = VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS, supported = false)
+ public void shouldNotAllowAnyIdsIfUserSuppliedIdsIsFalse() throws Exception {
+ assertFalse(graph.features().vertex().willAllowId(graphProvider.convertId(99999943835l, Vertex.class)));
+ }
+
+ @Test
@FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
@FeatureRequirement(featureClass = VertexFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
@FeatureRequirement(featureClass = VertexFeatures.class, feature = FEATURE_STRING_IDS, supported = false)
@@ -357,7 +362,7 @@ public class FeatureSupportTest {
public void shouldSupportUserSuppliedIdsIfAnIdCanBeAssignedToEdge() throws Exception {
try {
final Vertex v = graph.addVertex();
- v.addEdge("friend", v, T.id, GraphManager.getGraphProvider().convertId(99999943835l, Edge.class));
+ v.addEdge("friend", v, T.id, graphProvider.convertId(99999943835l, Edge.class));
fail(String.format(INVALID_FEATURE_SPECIFICATION, VertexFeatures.class.getSimpleName(), EdgeFeatures.FEATURE_USER_SUPPLIED_IDS));
} catch (Exception e) {
validateException(Edge.Exceptions.userSuppliedIdsNotSupported(), e);
@@ -365,6 +370,12 @@ public class FeatureSupportTest {
}
@Test
+ @FeatureRequirement(featureClass = EdgeFeatures.class, feature = EdgeFeatures.FEATURE_USER_SUPPLIED_IDS, supported = false)
+ public void shouldNotAllowAnyIdsIfUserSuppliedIdsIsFalse() throws Exception {
+ assertFalse(graph.features().edge().willAllowId(graphProvider.convertId(99999943835l, Edge.class)));
+ }
+
+ @Test
@FeatureRequirement(featureClass = Graph.Features.EdgeFeatures.class, feature = Graph.Features.EdgeFeatures.FEATURE_ADD_EDGES)
@FeatureRequirement(featureClass = Graph.Features.VertexFeatures.class, feature = Graph.Features.VertexFeatures.FEATURE_ADD_VERTICES)
@FeatureRequirement(featureClass = EdgeFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS, supported = false)
@@ -562,7 +573,7 @@ public class FeatureSupportTest {
private Edge createEdgeForPropertyFeatureTests() {
final Vertex vertexA = graph.addVertex();
final Vertex vertexB = graph.addVertex();
- return vertexA.addEdge(GraphManager.getGraphProvider().convertLabel("knows"), vertexB);
+ return vertexA.addEdge(graphProvider.convertLabel("knows"), vertexB);
}
}
@@ -623,7 +634,7 @@ public class FeatureSupportTest {
public void shouldSupportUserSuppliedIdsIfAnIdCanBeAssigned() throws Exception {
try {
final Vertex v = graph.addVertex();
- v.property(VertexProperty.Cardinality.single, "name", "me", T.id, GraphManager.getGraphProvider().convertId(99999943835l, VertexProperty.class));
+ v.property(VertexProperty.Cardinality.single, "name", "me", T.id, graphProvider.convertId(99999943835l, VertexProperty.class));
fail(String.format(INVALID_FEATURE_SPECIFICATION, VertexFeatures.class.getSimpleName(), VertexPropertyFeatures.FEATURE_USER_SUPPLIED_IDS));
} catch (Exception ex) {
validateException(VertexProperty.Exceptions.userSuppliedIdsNotSupported(), ex);
@@ -631,6 +642,12 @@ public class FeatureSupportTest {
}
@Test
+ @FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS, supported = false)
+ public void shouldNotAllowAnyIdsIfUserSuppliedIdsIsFalse() throws Exception {
+ assertFalse(graph.features().vertex().properties().willAllowId(graphProvider.convertId(99999943835l, VertexProperty.class)));
+ }
+
+ @Test
@FeatureRequirementSet(FeatureRequirementSet.Package.VERTICES_ONLY)
@FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_USER_SUPPLIED_IDS)
@FeatureRequirement(featureClass = VertexPropertyFeatures.class, feature = FEATURE_STRING_IDS, supported = false)
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/structure/HadoopGraph.java
----------------------------------------------------------------------
diff --git a/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/structure/HadoopGraph.java b/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/structure/HadoopGraph.java
index 48b6092..469785f 100644
--- a/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/structure/HadoopGraph.java
+++ b/hadoop-gremlin/src/main/java/org/apache/tinkerpop/gremlin/hadoop/structure/HadoopGraph.java
@@ -441,6 +441,11 @@ public final class HadoopGraph implements Graph {
public boolean supportsRemoveProperty() {
return false;
}
+
+ @Override
+ public boolean supportsCustomIds() {
+ return false;
+ }
};
}
};
http://git-wip-us.apache.org/repos/asf/incubator-tinkerpop/blob/c1006eea/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
----------------------------------------------------------------------
diff --git a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
index af9ec79..bb127c4 100644
--- a/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
+++ b/tinkergraph-gremlin/src/main/java/org/apache/tinkerpop/gremlin/tinkergraph/structure/TinkerGraph.java
@@ -77,6 +77,8 @@ public final class TinkerGraph implements Graph {
public static final String CONFIG_EDGE_ID = "gremlin.tinkergraph.edgeIdManager";
public static final String CONFIG_VERTEX_PROPERTY_ID = "gremlin.tinkergraph.vertexPropertyIdManager";
+ private final TinkerGraphFeatures features = new TinkerGraphFeatures();
+
protected AtomicLong currentId = new AtomicLong(-1l);
protected Map<Object, Vertex> vertices = new ConcurrentHashMap<>();
protected Map<Object, Edge> edges = new ConcurrentHashMap<>();
@@ -255,55 +257,62 @@ public final class TinkerGraph implements Graph {
*/
@Override
public Features features() {
- return TinkerGraphFeatures.INSTANCE;
+ return features;
}
- public static class TinkerGraphFeatures implements Features {
+ public class TinkerGraphFeatures implements Features {
- static final TinkerGraphFeatures INSTANCE = new TinkerGraphFeatures();
+ private final TinkerGraphGraphFeatures graphFeatures = new TinkerGraphGraphFeatures();
+ private final TinkerGraphEdgeFeatures edgeFeatures = new TinkerGraphEdgeFeatures();
+ private final TinkerGraphVertexFeatures vertexFeatures = new TinkerGraphVertexFeatures();
private TinkerGraphFeatures() {
}
@Override
public GraphFeatures graph() {
- return TinkerGraphGraphFeatures.INSTANCE;
+ return graphFeatures;
}
@Override
public EdgeFeatures edge() {
- return TinkerGraphEdgeFeatures.INSTANCE;
+ return edgeFeatures;
}
@Override
public VertexFeatures vertex() {
- return TinkerGraphVertexFeatures.INSTANCE;
+ return vertexFeatures;
}
@Override
public String toString() {
return StringFactory.featureString(this);
}
-
}
- public static class TinkerGraphVertexFeatures implements Features.VertexFeatures {
-
- static final TinkerGraphVertexFeatures INSTANCE = new TinkerGraphVertexFeatures();
+ public class TinkerGraphVertexFeatures implements Features.VertexFeatures {
+ private final TinkerGraphVertexPropertyFeatures vertexPropertyFeatures = new TinkerGraphVertexPropertyFeatures();
private TinkerGraphVertexFeatures() {
}
@Override
+ public Features.VertexPropertyFeatures properties() {
+ return vertexPropertyFeatures;
+ }
+
+ @Override
public boolean supportsCustomIds() {
return false;
}
+ @Override
+ public boolean willAllowId(final Object id) {
+ return vertexIdManager.allow(id);
+ }
}
- public static class TinkerGraphEdgeFeatures implements Features.EdgeFeatures {
-
- static final TinkerGraphEdgeFeatures INSTANCE = new TinkerGraphEdgeFeatures();
+ public class TinkerGraphEdgeFeatures implements Features.EdgeFeatures {
private TinkerGraphEdgeFeatures() {
}
@@ -313,11 +322,13 @@ public final class TinkerGraph implements Graph {
return false;
}
+ @Override
+ public boolean willAllowId(final Object id) {
+ return edgeIdManager.allow(id);
+ }
}
- public static class TinkerGraphGraphFeatures implements Features.GraphFeatures {
-
- static final TinkerGraphGraphFeatures INSTANCE = new TinkerGraphGraphFeatures();
+ public class TinkerGraphGraphFeatures implements Features.GraphFeatures {
private TinkerGraphGraphFeatures() {
}
@@ -339,6 +350,22 @@ public final class TinkerGraph implements Graph {
}
+ public class TinkerGraphVertexPropertyFeatures implements Features.VertexPropertyFeatures {
+
+ private TinkerGraphVertexPropertyFeatures() {
+ }
+
+ @Override
+ public boolean supportsCustomIds() {
+ return false;
+ }
+
+ @Override
+ public boolean willAllowId(final Object id) {
+ return vertexIdManager.allow(id);
+ }
+ }
+
///////////// GRAPH SPECIFIC INDEXING METHODS ///////////////
/**
@@ -431,6 +458,11 @@ public final class TinkerGraph implements Graph {
* Convert an identifier to the type required by the manager.
*/
T convert(final Object id);
+
+ /**
+ * Determine if an identifier is allowed by this manager given its type.
+ */
+ boolean allow(final Object id);
}
/**
@@ -460,6 +492,11 @@ public final class TinkerGraph implements Graph {
else
throw new IllegalArgumentException(String.format("Expected an id that is convertible to Long but received %s", id.getClass()));
}
+
+ @Override
+ public boolean allow(final Object id) {
+ return id instanceof Number || id instanceof String;
+ }
},
/**
@@ -485,6 +522,11 @@ public final class TinkerGraph implements Graph {
else
throw new IllegalArgumentException(String.format("Expected an id that is convertible to Integer but received %s", id.getClass()));
}
+
+ @Override
+ public boolean allow(final Object id) {
+ return id instanceof Number || id instanceof String;
+ }
},
/**
@@ -508,6 +550,11 @@ public final class TinkerGraph implements Graph {
else
throw new IllegalArgumentException(String.format("Expected an id that is convertible to UUID but received %s", id.getClass()));
}
+
+ @Override
+ public boolean allow(final Object id) {
+ return id instanceof UUID || id instanceof String;
+ }
},
/**
@@ -526,6 +573,11 @@ public final class TinkerGraph implements Graph {
public Object convert(final Object id) {
return id;
}
+
+ @Override
+ public boolean allow(final Object id) {
+ return true;
+ }
}
}
}