Skip to content

Commit

Permalink
Brought back some changes from gvalue branch bound to master
Browse files Browse the repository at this point in the history
  • Loading branch information
spmallette committed Aug 15, 2024
1 parent 1390738 commit f70d0d5
Show file tree
Hide file tree
Showing 11 changed files with 236 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public Object apply(final Object a, final Object b) {

if (a instanceof Map && b instanceof Map)
((Map<?,?>) a).putAll((Map) b);
else if (a instanceof Collection && a instanceof Collection)
else if (a instanceof Collection && b instanceof Collection)
((Collection<?>) a).addAll((Collection) b);
else
throw new IllegalArgumentException(String.format("Objects must be both of Map or Collection: a=%s b=%s",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
* Predefined {@code Predicate} values that can be used to define filters to {@code has()} and {@code where()}.
Expand Down Expand Up @@ -75,10 +77,22 @@ public void setValue(final V value) {

@Override
public boolean test(final V testValue) {
if (this.value instanceof GValue)
if (this.value instanceof GValue) {
return this.biPredicate.test(testValue, ((GValue<V>) this.value).get());
else
return this.biPredicate.test(testValue, this.value);
} else {
// this might be a bunch of GValue that need to be resolved. zomg
if (this.value instanceof List) {
return this.biPredicate.test(testValue, (V) ((List) this.value).stream().map(o -> {
if (o instanceof GValue) {
return ((GValue) o).get();
} else {
return o;
}
}).collect(Collectors.toList()));
} else {
return this.biPredicate.test(testValue, this.value);
}
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,30 @@ public default GraphTraversal<S, E> hasLabel(final Object label, final Object...
return TraversalHelper.addHasContainer(this.asAdmin(), new HasContainer(T.label.getAccessor(), labels.length == 1 ? P.eq(labels[0]) : P.within(labels)));
}

/**
* This is a step modulator to a {@link TraversalOptionParent} like {@code choose()} or {@code mergeV()} where the
* provided argument associated to the {@code token} is applied according to the semantics of the step. Please see
* the documentation of such steps to understand the usage context.
*
* @param token the token that would trigger this option which may be a {@link Pick}, {@link Merge},
* a {@link Traversal}, {@link Predicate}, or object depending on the step being modulated.
* @param traversalOption the option as a traversal
* @return the traversal with the modulated step
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#choose-step" target="_blank">Reference Documentation - Choose Step</a>
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergev-step" target="_blank">Reference Documentation - MergeV Step</a>
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#mergee-step" target="_blank">Reference Documentation - MergeE Step</a>
* @since 3.0.0-incubating
*/
public default <M, E2> GraphTraversal<S, E> option(final GValue<M> token, final Traversal<?, E2> traversalOption) {
this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.option, token, traversalOption);

// handle null similar to how option() with Map handles it, otherwise we get a NPE if this one gets used
final Traversal.Admin<E,E2> t = null == traversalOption ?
new ConstantTraversal<>(null) : (Traversal.Admin<E, E2>) traversalOption.asAdmin();
((TraversalOptionParent<M, E, E2>) this.asAdmin().getEndStep()).addChildOption(token.get(), t);
return this;
}

/**
* This is a step modulator to a {@link TraversalOptionParent} like {@code choose()} or {@code mergeV()} where the
* provided argument associated to the {@code token} is applied according to the semantics of the step. Please see
Expand Down Expand Up @@ -501,6 +525,46 @@ public default <M, E2> GraphTraversal<S, E> option(final Merge merge, final GVal
return this;
}

/**
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
* incoming vertex of the newly added {@link Edge}.
*
* @param toVertex the vertex for selecting the incoming vertex
* @return the traversal with the modified {@link AddEdgeStep}
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
* @since 4.0.0
*/
public default GraphTraversal<S, E> to(final GValue<Vertex> toVertex) {
final Step<?,?> prev = this.asAdmin().getEndStep();
if (!(prev instanceof FromToModulating))
throw new IllegalArgumentException(String.format(
"The to() step cannot follow %s", prev.getClass().getSimpleName()));

this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.to, toVertex);
((FromToModulating) prev).addTo(__.constant(toVertex).asAdmin());
return this;
}

/**
* When used as a modifier to {@link #addE(String)} this method specifies the traversal to use for selecting the
* outgoing vertex of the newly added {@link Edge}.
*
* @param fromVertex the vertex for selecting the outgoing vertex
* @return the traversal with the modified {@link AddEdgeStep}
* @see <a href="http://tinkerpop.apache.org/docs/${project.version}/reference/#addedge-step" target="_blank">Reference Documentation - From Step</a>
* @since 4.0.0
*/
public default GraphTraversal<S, E> from(final GValue<Vertex> fromVertex) {
final Step<?,?> prev = this.asAdmin().getEndStep();
if (!(prev instanceof FromToModulating))
throw new IllegalArgumentException(String.format(
"The from() step cannot follow %s", prev.getClass().getSimpleName()));

this.asAdmin().getBytecode().addStep(GraphTraversal.Symbols.from, fromVertex);
((FromToModulating) prev).addFrom(__.constant(fromVertex).asAdmin());
return this;
}

@Override
public default <E2> GraphTraversal.Admin<S, E2> addStep(final Step<?, E2> step) {
return (GraphTraversal.Admin<S, E2>) Traversal.Admin.super.addStep((Step) step);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.apache.tinkerpop.gremlin.process.traversal.TraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategies;
import org.apache.tinkerpop.gremlin.process.traversal.TraversalStrategy;
import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import org.apache.tinkerpop.gremlin.process.traversal.step.branch.UnionStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddEdgeStartStep;
import org.apache.tinkerpop.gremlin.process.traversal.step.map.AddVertexStartStep;
Expand Down Expand Up @@ -68,6 +69,7 @@ public class GraphTraversalSource implements TraversalSource {
protected final Graph graph;
protected TraversalStrategies strategies;
protected Bytecode bytecode = new Bytecode();
protected Admin admin;

////////////////

Expand Down Expand Up @@ -100,6 +102,12 @@ public GraphTraversalSource(final RemoteConnection connection) {
this.strategies.addStrategies(new RemoteStrategy(connection));
}

public GraphTraversalSource.Admin asAdmin() {
if (null == this.admin)
this.admin = new Admin();
return this.admin;
}

@Override
public Optional<Class<?>> getAnonymousTraversalClass() {
return Optional.of(__.class);
Expand Down Expand Up @@ -624,4 +632,39 @@ public String toString() {
return StringFactory.traversalSourceString(this);
}

/**
* This class masks spawn steps that are more reserved for advanced usage.
*/
public class Admin {

/**
* Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Vertex} using a
* {@code Map} as an argument. The {@code Map} represents search criteria and will match each of the supplied
* key/value pairs where the keys may be {@code String} property values or a value of {@link T}. If a match is not
* made it will use that search criteria to create the new {@link Vertex}.
*
* @param searchCreate This {@code Map} can have a key of {@link T} or a {@code String}.
* @since 4.0.0
*/
public GraphTraversal<Vertex, Vertex> mergeV(final GValue<Map<Object, Object>> searchCreate) {
final GraphTraversalSource clone = GraphTraversalSource.this.clone();
clone.bytecode.addStep(GraphTraversal.Symbols.mergeV, searchCreate);
final GraphTraversal.Admin<Vertex, Vertex> traversal = new DefaultGraphTraversal<>(clone);
return traversal.addStep(new MergeVertexStep(traversal, true, searchCreate));
}

/**
* Spawns a {@link GraphTraversal} by doing a merge (i.e. upsert) style operation for an {@link Edge} using a
* {@code Map} as an argument.
*
* @param searchCreate This {@code Map} can have a key of {@link T} {@link Direction} or a {@code String}.
* @since 4.0.0
*/
public GraphTraversal<Edge, Edge> mergeE(final GValue<Map<?, Object>> searchCreate) {
final GraphTraversalSource clone = GraphTraversalSource.this.clone();
clone.bytecode.addStep(GraphTraversal.Symbols.mergeE, searchCreate);
final GraphTraversal.Admin<Edge, Edge> traversal = new DefaultGraphTraversal<>(clone);
return traversal.addStep(new MergeEdgeStep(traversal, true, searchCreate));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,26 @@ public enum GType {
GType() {}

/**
* Returns true if the type is a number.
* Returns {@code true} if the type is a number.
*/
public boolean isNumeric() {
return this == INTEGER || this == DOUBLE || this == LONG || this == BIG_INTEGER || this == BIG_DECIMAL;
}

/**
* Returns {@code true} if the type is a collection.v
*/
public boolean isCollection() {
return this == LIST || this == SET;
}

/**
* Returns {@code true} if the type is an element.
*/
public boolean isElement() {
return this == VERTEX || this == EDGE;
}

/**
* Convert an object to a matching {@link GType} and if not matched return {@link GType#UNKNOWN}.
*/
Expand All @@ -78,4 +92,4 @@ public static GType getType(final Object object) {
else if (object instanceof BigDecimal) return BIG_DECIMAL;
else return UNKNOWN;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ public boolean isVariable() {
/**
* Gets the name of the variable if it was defined as such and returns empty if the value was a literal.
*/
public Optional<String> getName() {
return Optional.ofNullable(this.name);
public String getName() {
return this.name;
}

/**
Expand All @@ -79,6 +79,13 @@ public GType getType() {
return this.type;
}

/**
* Determines if the value held is of a {@code null} value.
*/
public boolean isNull() {
return this.value == null;
}

/**
* Gets the value.
*/
Expand All @@ -96,7 +103,7 @@ public String toString() {
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
GValue<?> gValue = (GValue<?>) o;
final GValue<?> gValue = (GValue<?>) o;
return Objects.equals(name, gValue.name) && type == gValue.type && Objects.equals(value, gValue.value);
}

Expand All @@ -123,6 +130,7 @@ public static <V> GValue<V> of(final V value) {
public static <V> GValue<V> of(final String name, final V value) {
return new GValue<>(name, GType.getType(value), value);
}

/**
* Create a new {@code GValue} for a string value.
*/
Expand Down Expand Up @@ -238,14 +246,14 @@ public static GValue<Map> ofMap(final String name, final Map value) {
/**
* Create a new {@code GValue} for a list value.
*/
public static GValue<List> ofList(final List value) {
public static <T> GValue<List<T>> ofList(final List<T> value) {
return new GValue<>(GType.LIST, value);
}

/**
* Create a new {@code GValue} for a list value with a specified name.
*/
public static GValue<List> ofList(final String name, final List value) {
public static <T> GValue<List<T>> ofList(final String name, final List<T> value) {
return new GValue<>(name, GType.LIST, value);
}

Expand Down Expand Up @@ -318,4 +326,4 @@ public static GValue<Property> ofProperty(final Property value) {
public static GValue<Property> ofProperty(final String name, final Property value) {
return new GValue<>(name, GType.PROPERTY, value);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,40 @@
package org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect;

import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
import org.apache.tinkerpop.gremlin.process.traversal.step.GValue;
import org.apache.tinkerpop.gremlin.util.iterator.ArrayIterator;

/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
public final class InjectStep<S> extends StartStep<S> {

private final S[] injections;
private final GValue<S>[] injections;

@SafeVarargs
public InjectStep(final Traversal.Admin traversal, final S... injections) {
super(traversal);
this.injections = injections;
this.start = new ArrayIterator<>(this.injections);
this.injections = convertToGValues(injections);
this.start = new ArrayIterator<>(resolveToValues(this.injections));
}

@Override
public InjectStep<S> clone() {
final InjectStep<S> clone = (InjectStep<S>) super.clone();
clone.start = new ArrayIterator<>(clone.injections);
clone.start = new ArrayIterator<>(resolveToValues(clone.injections));
return clone;
}

@Override
public void reset() {
super.reset();
this.start = new ArrayIterator<>(this.injections);
this.start = new ArrayIterator<>(resolveToValues(this.injections));
}

public S[] getInjections() {
/**
* Get the injections of the step.
*/
public GValue<S>[] getInjections() {
return this.injections;
}
}
}
Loading

0 comments on commit f70d0d5

Please sign in to comment.