From 5ecd123bfde635c7cf40a9ea39bff1d53b0ce3ca Mon Sep 17 00:00:00 2001
From: Mathieu Cloutier <79954947+cloutierMat@users.noreply.github.com>
Date: Thu, 4 Jul 2024 14:28:02 -0600
Subject: [PATCH] Neptune support missing versions (#30)
---
neptune-tinkerpop/3.4.11/pom.xml | 33 +++
.../traversal/step/util/HasContainer.java | 234 +++++++++++++++++
.../traversal/step/filter/HasLabelTest.java | 41 +++
.../tinkergraph/TinkerGraphProvider.java | 206 +++++++++++++++
neptune-tinkerpop/3.5.2/pom.xml | 33 +++
.../traversal/step/util/HasContainer.java | 240 ++++++++++++++++++
.../traversal/step/filter/HasLabelTest.java | 41 +++
.../tinkergraph/TinkerGraphProvider.java | 206 +++++++++++++++
neptune-tinkerpop/3.6.5/pom.xml | 33 +++
.../traversal/step/util/HasContainer.java | 236 +++++++++++++++++
.../traversal/step/filter/HasLabelTest.java | 41 +++
.../tinkergraph/TinkerGraphProvider.java | 206 +++++++++++++++
neptune-tinkerpop/3.7.1/pom.xml | 33 +++
.../traversal/step/util/HasContainer.java | 232 +++++++++++++++++
.../traversal/step/filter/HasLabelTest.java | 41 +++
.../tinkergraph/TinkerGraphProvider.java | 206 +++++++++++++++
neptune-tinkerpop/build.sh | 2 +-
.../gremlin-core-3.4.11-patches.zip | Bin 0 -> 7826 bytes
.../gremlin-core-3.5.2-patches.zip | Bin 0 -> 7855 bytes
.../gremlin-core-3.6.2-patches.zip | Bin 7293 -> 7293 bytes
.../gremlin-core-3.6.5-patches.zip | Bin 0 -> 7372 bytes
.../gremlin-core-3.7.1-patches.zip | Bin 0 -> 7347 bytes
22 files changed, 2063 insertions(+), 1 deletion(-)
create mode 100644 neptune-tinkerpop/3.4.11/pom.xml
create mode 100644 neptune-tinkerpop/3.4.11/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
create mode 100644 neptune-tinkerpop/3.4.11/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
create mode 100644 neptune-tinkerpop/3.4.11/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
create mode 100644 neptune-tinkerpop/3.5.2/pom.xml
create mode 100644 neptune-tinkerpop/3.5.2/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
create mode 100644 neptune-tinkerpop/3.5.2/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
create mode 100644 neptune-tinkerpop/3.5.2/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
create mode 100644 neptune-tinkerpop/3.6.5/pom.xml
create mode 100644 neptune-tinkerpop/3.6.5/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
create mode 100644 neptune-tinkerpop/3.6.5/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
create mode 100644 neptune-tinkerpop/3.6.5/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
create mode 100644 neptune-tinkerpop/3.7.1/pom.xml
create mode 100644 neptune-tinkerpop/3.7.1/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
create mode 100644 neptune-tinkerpop/3.7.1/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
create mode 100644 neptune-tinkerpop/3.7.1/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
create mode 100644 neptune-tinkerpop/gremlin-core-3.4.11-patches.zip
create mode 100644 neptune-tinkerpop/gremlin-core-3.5.2-patches.zip
create mode 100644 neptune-tinkerpop/gremlin-core-3.6.5-patches.zip
create mode 100644 neptune-tinkerpop/gremlin-core-3.7.1-patches.zip
diff --git a/neptune-tinkerpop/3.4.11/pom.xml b/neptune-tinkerpop/3.4.11/pom.xml
new file mode 100644
index 0000000..3a9ba56
--- /dev/null
+++ b/neptune-tinkerpop/3.4.11/pom.xml
@@ -0,0 +1,33 @@
+
+
+ 4.0.0
+
+ cloud.localstack
+ neptune-tinkerpop-gremlin
+ 0.1
+ jar
+
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.tinkerpop
+ gremlin-core
+ 3.4.11
+
+
+ org.apache.tinkerpop
+ tinkergraph-gremlin
+ 3.4.11
+
+
+ org.apache.tinkerpop
+ gremlin-test
+ 3.4.11
+
+
+
diff --git a/neptune-tinkerpop/3.4.11/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java b/neptune-tinkerpop/3.4.11/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
new file mode 100644
index 0000000..3bee398
--- /dev/null
+++ b/neptune-tinkerpop/3.4.11/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
@@ -0,0 +1,234 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package org.apache.tinkerpop.gremlin.process.traversal.step.util;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Compare;
+import org.apache.tinkerpop.gremlin.process.traversal.Contains;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.util.CloseableIterator;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+public class HasContainer implements Serializable, Cloneable, Predicate {
+
+ public static final String LABEL_DELIMITER = "::";
+
+ private String key;
+ private P predicate;
+ private final boolean testingIdString;
+
+ public HasContainer(final String key, final P> predicate) {
+ this.key = key;
+ this.predicate = predicate;
+ if (!this.key.equals(T.id.getAccessor())) {
+ this.testingIdString = false;
+ } else {
+ Object predicateValue = this.predicate.getValue();
+ this.enforceHomogenousCollectionIfPresent(predicateValue);
+ Object valueInstance = this.predicate.getValue() instanceof Collection ? (((Collection)this.predicate.getValue()).isEmpty() ? new Object() : ((Collection)this.predicate.getValue()).toArray()[0]) : this.predicate.getValue();
+ this.testingIdString = this.key.equals(T.id.getAccessor()) && valueInstance instanceof String;
+ if (this.testingIdString) {
+ this.predicate.setValue(this.predicate.getValue() instanceof Collection ? IteratorUtils.set(IteratorUtils.map(((Collection)this.predicate.getValue()).iterator(), Object::toString)) : this.predicate.getValue().toString());
+ }
+ }
+
+ }
+
+ public final boolean test(final Element element) {
+ if (this.key.equals(T.id.getAccessor())) {
+ return this.testingIdString ? this.testIdAsString(element) : this.testId(element);
+ } else if (this.key.equals(T.label.getAccessor())) {
+ return this.testLabel(element);
+ } else {
+ Iterator extends Property> itty = element.properties(new String[]{this.key});
+
+ try {
+ while(itty.hasNext()) {
+ if (this.testValue((Property)itty.next())) {
+ boolean var3 = true;
+ return var3;
+ }
+ }
+ } finally {
+ CloseableIterator.closeIterator(itty);
+ }
+
+ return false;
+ }
+ }
+
+ public final boolean test(final Property property) {
+ if (this.key.equals(T.value.getAccessor())) {
+ return this.testValue(property);
+ } else if (this.key.equals(T.key.getAccessor())) {
+ return this.testKey(property);
+ } else {
+ return property instanceof Element ? this.test((Element)property) : false;
+ }
+ }
+
+ protected boolean testId(Element element) {
+ return this.predicate.test(element.id());
+ }
+
+ protected boolean testIdAsString(Element element) {
+ return this.predicate.test(element.id().toString());
+ }
+
+ protected boolean testLabel(Element element) {
+
+ /* start patch for localstack */
+
+ // add comparison predicates to support the multi-label syntax `label1::label2::label3`
+
+ class LabelEquals implements BiPredicate {
+ public boolean test(String label, String otherLabel) {
+ if (label == null) return false;
+ for (String partialLabel: label.split(LABEL_DELIMITER)) {
+ if (partialLabel.equals(otherLabel)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ class LabelWithin implements BiPredicate> {
+ public boolean test(String label, List labels) {
+ if (label == null) return false;
+ for (String partialLabel: label.split(LABEL_DELIMITER)) {
+ if (labels.contains(partialLabel)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ if (this.predicate.getBiPredicate() == Compare.eq && this.predicate.getValue() instanceof String) {
+ this.predicate = new P(new LabelEquals(), this.predicate.getValue());
+ } else if (this.predicate.getBiPredicate() == Contains.within){
+ if (this.predicate.getValue() instanceof String[]) {
+ // this should catch all hasLabel('LabelX') requests
+ final List labelsList = Arrays.asList((String[])this.predicate.getValue());
+ this.predicate = new P(new LabelWithin(), labelsList);
+ } else if (this.predicate.getValue() instanceof List){
+ // this should handle the traverse logic for hasLabel('LabelX', 'LabelXYZ') e.g. any match from that list
+ boolean validatedAllStrings = true;
+ for (Object s : (List) this.predicate.getValue()){
+ // not sure if we can rely on having only Strings here
+ // verify the content before casting
+ if(! (s instanceof String)){
+ validatedAllStrings = false;
+ break;
+ }
+ }
+ if (validatedAllStrings) this.predicate = new P(new LabelWithin(), this.predicate.getValue());
+ }
+ }
+
+ /* end patch for localstack */
+ return this.predicate.test(element.label());
+ }
+
+ protected boolean testValue(Property property) {
+ return this.predicate.test(property.value());
+ }
+
+ protected boolean testKey(Property property) {
+ return this.predicate.test(property.key());
+ }
+
+ public final String toString() {
+ return this.key + '.' + this.predicate;
+ }
+
+ public HasContainer clone() {
+ try {
+ HasContainer clone = (HasContainer)super.clone();
+ clone.predicate = this.predicate.clone();
+ return clone;
+ } catch (CloneNotSupportedException var2) {
+ CloneNotSupportedException e = var2;
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ public int hashCode() {
+ return (this.key != null ? this.key.hashCode() : 0) ^ (this.predicate != null ? this.predicate.hashCode() : 0);
+ }
+
+ public final String getKey() {
+ return this.key;
+ }
+
+ public final void setKey(final String key) {
+ this.key = key;
+ }
+
+ public final P> getPredicate() {
+ return this.predicate;
+ }
+
+ public final BiPredicate, ?> getBiPredicate() {
+ return this.predicate.getBiPredicate();
+ }
+
+ public final Object getValue() {
+ return this.predicate.getValue();
+ }
+
+ private void enforceHomogenousCollectionIfPresent(final Object predicateValue) {
+ if (predicateValue instanceof Collection) {
+ Collection collection = (Collection)predicateValue;
+ if (!collection.isEmpty()) {
+ Class> first = collection.toArray()[0].getClass();
+ if (!((Collection)predicateValue).stream().map(Object::getClass).allMatch((c) -> {
+ return first.equals(c);
+ })) {
+ throw new IllegalArgumentException("Has comparisons on a collection of ids require ids to all be of the same type");
+ }
+ }
+ }
+
+ }
+
+ public static boolean testAll(final Property property, final List hasContainers) {
+ return internalTestAll(property, hasContainers);
+ }
+
+ public static boolean testAll(final Element element, final List hasContainers) {
+ return internalTestAll(element, hasContainers);
+ }
+
+ private static boolean internalTestAll(final S element, final List hasContainers) {
+ boolean isProperty = element instanceof Property;
+ Iterator var3 = hasContainers.iterator();
+
+ while(var3.hasNext()) {
+ HasContainer hasContainer = (HasContainer)var3.next();
+ if (isProperty) {
+ if (!hasContainer.test((Property)element)) {
+ return false;
+ }
+ } else if (!hasContainer.test((Element)element)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/neptune-tinkerpop/3.4.11/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java b/neptune-tinkerpop/3.4.11/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
new file mode 100644
index 0000000..4e5b385
--- /dev/null
+++ b/neptune-tinkerpop/3.4.11/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
@@ -0,0 +1,41 @@
+package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
+
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.GraphManager;
+import org.apache.tinkerpop.gremlin.tinkergraph.TinkerGraphProvider;
+
+public class HasLabelTest extends AbstractGremlinTest
+{
+ public HasLabelTest() {
+ GraphManager.setGraphProvider(new TinkerGraphProvider());
+ }
+
+ @Test
+ @LoadGraphWith(MODERN)
+ public void testHasLabelMultiValue() {
+ final String label1 = "l" + Math.random();
+ final String label2 = "l" + Math.random();
+ final String label3 = "l" + Math.random();
+
+ // add a couple of vertices with single labels and multi-labels
+ g.addV(label1).iterate();
+ g.addV(label2).iterate();
+ g.addV(label3).iterate();
+ g.addV(label1 + "::" + label2).iterate();
+ g.addV(label1 + "::" + label2 + "::" + label1).iterate();
+
+ // assert that vertices can be selected via single sub-labels
+ assertEquals(g.V().hasLabel(label1).toList().size(), 3);
+ assertEquals(g.V().hasLabel(label1).hasLabel(label2).toList().size(), 2);
+
+ // assert that vertices can be selected via a set of alternative sub-labels
+ assertEquals(g.V().hasLabel(label1, label2).toList().size(), 4);
+ assertEquals(g.V().hasLabel(label1, label2, label3).toList().size(), 5);
+ }
+}
diff --git a/neptune-tinkerpop/3.4.11/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java b/neptune-tinkerpop/3.4.11/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
new file mode 100644
index 0000000..0efd240
--- /dev/null
+++ b/neptune-tinkerpop/3.4.11/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.tinkergraph;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.tinkerpop.gremlin.AbstractGraphProvider;
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.TestHelper;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.GraphTest;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.IoEdgeTest;
+import org.apache.tinkerpop.gremlin.structure.io.IoVertexTest;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedGraphTest;
+import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphTest;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerEdge;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerElement;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraphVariables;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerProperty;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertexProperty;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class TinkerGraphProvider extends AbstractGraphProvider {
+
+ private static final Set IMPLEMENTATION = new HashSet() {{
+ add(TinkerEdge.class);
+ add(TinkerElement.class);
+ add(TinkerGraph.class);
+ add(TinkerGraphVariables.class);
+ add(TinkerProperty.class);
+ add(TinkerVertex.class);
+ add(TinkerVertexProperty.class);
+ }};
+
+ @Override
+ public Map getBaseConfiguration(final String graphName, final Class> test, final String testMethodName,
+ final LoadGraphWith.GraphData loadGraphWith) {
+ final TinkerGraph.DefaultIdManager idManager = selectIdMakerFromGraphData(loadGraphWith);
+ final String idMaker = (idManager.equals(TinkerGraph.DefaultIdManager.ANY) ? selectIdMakerFromTest(test, testMethodName) : idManager).name();
+ return new HashMap() {{
+ put(Graph.GRAPH, TinkerGraph.class.getName());
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_ID_MANAGER, idMaker);
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_EDGE_ID_MANAGER, idMaker);
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_PROPERTY_ID_MANAGER, idMaker);
+ if (requiresListCardinalityAsDefault(loadGraphWith, test, testMethodName))
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_DEFAULT_VERTEX_PROPERTY_CARDINALITY, VertexProperty.Cardinality.list.name());
+ if (requiresPersistence(test, testMethodName)) {
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_FORMAT, "gryo");
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_LOCATION,TestHelper.makeTestDataFile(test, "temp", testMethodName + ".kryo"));
+ }
+ }};
+ }
+
+ @Override
+ public void clear(final Graph graph, final Configuration configuration) throws Exception {
+ if (graph != null)
+ graph.close();
+
+ // in the even the graph is persisted we need to clean up
+ final String graphLocation = null != configuration ? configuration.getString(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_LOCATION, null) : null;
+ if (graphLocation != null) {
+ final File f = new File(graphLocation);
+ f.delete();
+ }
+ }
+
+ @Override
+ public Set getImplementations() {
+ return IMPLEMENTATION;
+ }
+
+ /**
+ * Determines if a test requires TinkerGraph persistence to be configured with graph location and format.
+ */
+ protected static boolean requiresPersistence(final Class> test, final String testMethodName) {
+ return test == GraphTest.class && testMethodName.equals("shouldPersistDataOnClose");
+ }
+
+ /**
+ * Determines if a test requires a different cardinality as the default or not.
+ */
+ protected static boolean requiresListCardinalityAsDefault(final LoadGraphWith.GraphData loadGraphWith,
+ final Class> test, final String testMethodName) {
+ return loadGraphWith == LoadGraphWith.GraphData.CREW
+ || (test == StarGraphTest.class && testMethodName.equals("shouldAttachWithCreateMethod"))
+ || (test == DetachedGraphTest.class && testMethodName.equals("testAttachableCreateMethod"));
+ }
+
+ /**
+ * Some tests require special configuration for TinkerGraph to properly configure the id manager.
+ */
+ protected TinkerGraph.DefaultIdManager selectIdMakerFromTest(final Class> test, final String testMethodName) {
+ if (test.equals(GraphTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldIterateVerticesWithNumericIdSupportUsingDoubleRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingDoubleRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingIntegerRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingIntegerRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingFloatRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingFloatRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingStringRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingStringRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingDoubleRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingDoubleRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingIntegerRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingIntegerRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingFloatRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingFloatRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingStringRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingStringRepresentations");
+ }};
+
+ final Set testsThatNeedUuidIdManager = new HashSet(){{
+ add("shouldIterateVerticesWithUuidIdSupportUsingStringRepresentation");
+ add("shouldIterateVerticesWithUuidIdSupportUsingStringRepresentations");
+ add("shouldIterateEdgesWithUuidIdSupportUsingStringRepresentation");
+ add("shouldIterateEdgesWithUuidIdSupportUsingStringRepresentations");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ else if (testsThatNeedUuidIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.UUID;
+ } else if (test.equals(IoEdgeTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldReadWriteEdge[graphson-v1]");
+ add("shouldReadWriteDetachedEdgeAsReference[graphson-v1]");
+ add("shouldReadWriteDetachedEdge[graphson-v1]");
+ add("shouldReadWriteEdge[graphson-v2]");
+ add("shouldReadWriteDetachedEdgeAsReference[graphson-v2]");
+ add("shouldReadWriteDetachedEdge[graphson-v2]");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ } else if (test.equals(IoVertexTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldReadWriteVertexWithBOTHEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithINEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithOUTEdges[graphson-v1]");
+ add("shouldReadWriteVertexNoEdges[graphson-v1]");
+ add("shouldReadWriteDetachedVertexNoEdges[graphson-v1]");
+ add("shouldReadWriteDetachedVertexAsReferenceNoEdges[graphson-v1]");
+ add("shouldReadWriteVertexMultiPropsNoEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithBOTHEdges[graphson-v2]");
+ add("shouldReadWriteVertexWithINEdges[graphson-v2]");
+ add("shouldReadWriteVertexWithOUTEdges[graphson-v2]");
+ add("shouldReadWriteVertexNoEdges[graphson-v2]");
+ add("shouldReadWriteDetachedVertexNoEdges[graphson-v2]");
+ add("shouldReadWriteDetachedVertexAsReferenceNoEdges[graphson-v2]");
+ add("shouldReadWriteVertexMultiPropsNoEdges[graphson-v2]");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ }
+
+ return TinkerGraph.DefaultIdManager.ANY;
+ }
+
+ /**
+ * Test that load with specific graph data can be configured with a specific id manager as the data type to
+ * be used in the test for that graph is known.
+ */
+ protected TinkerGraph.DefaultIdManager selectIdMakerFromGraphData(final LoadGraphWith.GraphData loadGraphWith) {
+ if (null == loadGraphWith) return TinkerGraph.DefaultIdManager.ANY;
+ if (loadGraphWith.equals(LoadGraphWith.GraphData.CLASSIC))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.MODERN))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.CREW))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.GRATEFUL))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.SINK))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else
+ throw new IllegalStateException(String.format("Need to define a new %s for %s", TinkerGraph.IdManager.class.getName(), loadGraphWith.name()));
+ }
+}
diff --git a/neptune-tinkerpop/3.5.2/pom.xml b/neptune-tinkerpop/3.5.2/pom.xml
new file mode 100644
index 0000000..6500be2
--- /dev/null
+++ b/neptune-tinkerpop/3.5.2/pom.xml
@@ -0,0 +1,33 @@
+
+
+ 4.0.0
+
+ cloud.localstack
+ neptune-tinkerpop-gremlin
+ 0.1
+ jar
+
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.tinkerpop
+ gremlin-core
+ 3.5.2
+
+
+ org.apache.tinkerpop
+ tinkergraph-gremlin
+ 3.5.2
+
+
+ org.apache.tinkerpop
+ gremlin-test
+ 3.5.2
+
+
+
diff --git a/neptune-tinkerpop/3.5.2/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java b/neptune-tinkerpop/3.5.2/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
new file mode 100644
index 0000000..53a0b18
--- /dev/null
+++ b/neptune-tinkerpop/3.5.2/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
@@ -0,0 +1,240 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package org.apache.tinkerpop.gremlin.process.traversal.step.util;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Compare;
+import org.apache.tinkerpop.gremlin.process.traversal.Contains;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.util.CloseableIterator;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
+
+public class HasContainer implements Serializable, Cloneable, Predicate {
+
+ public static final String LABEL_DELIMITER = "::";
+
+ private String key;
+ private P predicate;
+ private final boolean testingIdString;
+
+ public HasContainer(final String key, final P> predicate) {
+ this.key = key;
+ this.predicate = predicate;
+ if (!this.key.equals(T.id.getAccessor())) {
+ this.testingIdString = false;
+ } else {
+ Object predicateValue = this.predicate.getValue();
+ this.enforceHomogenousCollectionIfPresent(predicateValue);
+ Object valueInstance = this.predicate.getValue() instanceof Collection ? (((Collection)this.predicate.getValue()).isEmpty() ? new Object() : ((Collection)this.predicate.getValue()).toArray()[0]) : this.predicate.getValue();
+ this.testingIdString = this.key.equals(T.id.getAccessor()) && valueInstance instanceof String;
+ if (this.testingIdString) {
+ this.predicate.setValue(this.predicate.getValue() instanceof Collection ? IteratorUtils.set(IteratorUtils.map(((Collection)this.predicate.getValue()).iterator(), Object::toString)) : this.predicate.getValue().toString());
+ }
+ }
+
+ }
+
+ public final boolean test(final Element element) {
+ if (this.key.equals(T.id.getAccessor())) {
+ return this.testingIdString ? this.testIdAsString(element) : this.testId(element);
+ } else if (this.key.equals(T.label.getAccessor())) {
+ return this.testLabel(element);
+ } else {
+ Iterator extends Property> itty = element.properties(new String[]{this.key});
+
+ while(true) {
+ boolean var3;
+ try {
+ if (!itty.hasNext()) {
+ return false;
+ }
+
+ if (!this.testValue((Property)itty.next())) {
+ continue;
+ }
+
+ var3 = true;
+ } finally {
+ CloseableIterator.closeIterator(itty);
+ }
+
+ return var3;
+ }
+ }
+ }
+
+ public final boolean test(final Property property) {
+ if (this.key.equals(T.value.getAccessor())) {
+ return this.testValue(property);
+ } else if (this.key.equals(T.key.getAccessor())) {
+ return this.testKey(property);
+ } else {
+ return property instanceof Element ? this.test((Element)property) : false;
+ }
+ }
+
+ protected boolean testId(final Element element) {
+ return this.predicate.test(element.id());
+ }
+
+ protected boolean testIdAsString(final Element element) {
+ return this.predicate.test(element.id().toString());
+ }
+
+ protected boolean testLabel(final Element element) {
+
+ /* start patch for localstack */
+
+ // add comparison predicates to support the multi-label syntax `label1::label2::label3`
+
+ class LabelEquals implements BiPredicate {
+ public boolean test(String label, String otherLabel) {
+ if (label == null) return false;
+ for (String partialLabel: label.split(LABEL_DELIMITER)) {
+ if (partialLabel.equals(otherLabel)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ class LabelWithin implements BiPredicate> {
+ public boolean test(String label, List labels) {
+ if (label == null) return false;
+ for (String partialLabel: label.split(LABEL_DELIMITER)) {
+ if (labels.contains(partialLabel)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ if (this.predicate.getBiPredicate() == Compare.eq && this.predicate.getValue() instanceof String) {
+ this.predicate = new P(new LabelEquals(), this.predicate.getValue());
+ } else if (this.predicate.getBiPredicate() == Contains.within){
+ if (this.predicate.getValue() instanceof String[]) {
+ // this should catch all hasLabel('LabelX') requests
+ final List labelsList = Arrays.asList((String[])this.predicate.getValue());
+ this.predicate = new P(new LabelWithin(), labelsList);
+ } else if (this.predicate.getValue() instanceof List){
+ // this should handle the traverse logic for hasLabel('LabelX', 'LabelXYZ') e.g. any match from that list
+ boolean validatedAllStrings = true;
+ for (Object s : (List) this.predicate.getValue()){
+ // not sure if we can rely on having only Strings here
+ // verify the content before casting
+ if(! (s instanceof String)){
+ validatedAllStrings = false;
+ break;
+ }
+ }
+ if (validatedAllStrings) this.predicate = new P(new LabelWithin(), this.predicate.getValue());
+ }
+ }
+
+ /* end patch for localstack */
+ return this.predicate.test(element.label());
+ }
+
+ protected boolean testValue(final Property property) {
+ return this.predicate.test(property.value());
+ }
+
+ protected boolean testKey(final Property property) {
+ return this.predicate.test(property.key());
+ }
+
+ public final String toString() {
+ return this.key + '.' + this.predicate;
+ }
+
+ public HasContainer clone() {
+ try {
+ HasContainer clone = (HasContainer)super.clone();
+ clone.predicate = this.predicate.clone();
+ return clone;
+ } catch (CloneNotSupportedException var2) {
+ CloneNotSupportedException e = var2;
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ public int hashCode() {
+ return (this.key != null ? this.key.hashCode() : 0) ^ (this.predicate != null ? this.predicate.hashCode() : 0);
+ }
+
+ public final String getKey() {
+ return this.key;
+ }
+
+ public final void setKey(final String key) {
+ this.key = key;
+ }
+
+ public final P> getPredicate() {
+ return this.predicate;
+ }
+
+ public final BiPredicate, ?> getBiPredicate() {
+ return this.predicate.getBiPredicate();
+ }
+
+ public final Object getValue() {
+ return this.predicate.getValue();
+ }
+
+ private void enforceHomogenousCollectionIfPresent(final Object predicateValue) {
+ if (predicateValue instanceof Collection) {
+ Collection collection = (Collection)predicateValue;
+ if (!collection.isEmpty()) {
+ Class> first = collection.toArray()[0].getClass();
+ if (!((Collection)predicateValue).stream().map(Object::getClass).allMatch((c) -> {
+ return first.equals(c);
+ })) {
+ throw new IllegalArgumentException("Has comparisons on a collection of ids require ids to all be of the same type");
+ }
+ }
+ }
+
+ }
+
+ public static boolean testAll(final Property property, final List hasContainers) {
+ return internalTestAll(property, hasContainers);
+ }
+
+ public static boolean testAll(final Element element, final List hasContainers) {
+ return internalTestAll(element, hasContainers);
+ }
+
+ private static boolean internalTestAll(final S element, final List hasContainers) {
+ boolean isProperty = element instanceof Property;
+ Iterator var3 = hasContainers.iterator();
+
+ while(var3.hasNext()) {
+ HasContainer hasContainer = (HasContainer)var3.next();
+ if (isProperty) {
+ if (!hasContainer.test((Property)element)) {
+ return false;
+ }
+ } else if (!hasContainer.test((Element)element)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/neptune-tinkerpop/3.5.2/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java b/neptune-tinkerpop/3.5.2/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
new file mode 100644
index 0000000..4e5b385
--- /dev/null
+++ b/neptune-tinkerpop/3.5.2/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
@@ -0,0 +1,41 @@
+package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
+
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.GraphManager;
+import org.apache.tinkerpop.gremlin.tinkergraph.TinkerGraphProvider;
+
+public class HasLabelTest extends AbstractGremlinTest
+{
+ public HasLabelTest() {
+ GraphManager.setGraphProvider(new TinkerGraphProvider());
+ }
+
+ @Test
+ @LoadGraphWith(MODERN)
+ public void testHasLabelMultiValue() {
+ final String label1 = "l" + Math.random();
+ final String label2 = "l" + Math.random();
+ final String label3 = "l" + Math.random();
+
+ // add a couple of vertices with single labels and multi-labels
+ g.addV(label1).iterate();
+ g.addV(label2).iterate();
+ g.addV(label3).iterate();
+ g.addV(label1 + "::" + label2).iterate();
+ g.addV(label1 + "::" + label2 + "::" + label1).iterate();
+
+ // assert that vertices can be selected via single sub-labels
+ assertEquals(g.V().hasLabel(label1).toList().size(), 3);
+ assertEquals(g.V().hasLabel(label1).hasLabel(label2).toList().size(), 2);
+
+ // assert that vertices can be selected via a set of alternative sub-labels
+ assertEquals(g.V().hasLabel(label1, label2).toList().size(), 4);
+ assertEquals(g.V().hasLabel(label1, label2, label3).toList().size(), 5);
+ }
+}
diff --git a/neptune-tinkerpop/3.5.2/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java b/neptune-tinkerpop/3.5.2/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
new file mode 100644
index 0000000..3254aa1
--- /dev/null
+++ b/neptune-tinkerpop/3.5.2/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.tinkergraph;
+
+import org.apache.commons.configuration2.Configuration;
+import org.apache.tinkerpop.gremlin.AbstractGraphProvider;
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.TestHelper;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.GraphTest;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.IoEdgeTest;
+import org.apache.tinkerpop.gremlin.structure.io.IoVertexTest;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedGraphTest;
+import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphTest;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerEdge;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerElement;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraphVariables;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerProperty;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertexProperty;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class TinkerGraphProvider extends AbstractGraphProvider {
+
+ private static final Set IMPLEMENTATION = new HashSet() {{
+ add(TinkerEdge.class);
+ add(TinkerElement.class);
+ add(TinkerGraph.class);
+ add(TinkerGraphVariables.class);
+ add(TinkerProperty.class);
+ add(TinkerVertex.class);
+ add(TinkerVertexProperty.class);
+ }};
+
+ @Override
+ public Map getBaseConfiguration(final String graphName, final Class> test, final String testMethodName,
+ final LoadGraphWith.GraphData loadGraphWith) {
+ final TinkerGraph.DefaultIdManager idManager = selectIdMakerFromGraphData(loadGraphWith);
+ final String idMaker = (idManager.equals(TinkerGraph.DefaultIdManager.ANY) ? selectIdMakerFromTest(test, testMethodName) : idManager).name();
+ return new HashMap() {{
+ put(Graph.GRAPH, TinkerGraph.class.getName());
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_ID_MANAGER, idMaker);
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_EDGE_ID_MANAGER, idMaker);
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_PROPERTY_ID_MANAGER, idMaker);
+ if (requiresListCardinalityAsDefault(loadGraphWith, test, testMethodName))
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_DEFAULT_VERTEX_PROPERTY_CARDINALITY, VertexProperty.Cardinality.list.name());
+ if (requiresPersistence(test, testMethodName)) {
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_FORMAT, "gryo");
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_LOCATION,TestHelper.makeTestDataFile(test, "temp", testMethodName + ".kryo"));
+ }
+ }};
+ }
+
+ @Override
+ public void clear(final Graph graph, final Configuration configuration) throws Exception {
+ if (graph != null)
+ graph.close();
+
+ // in the even the graph is persisted we need to clean up
+ final String graphLocation = null != configuration ? configuration.getString(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_LOCATION, null) : null;
+ if (graphLocation != null) {
+ final File f = new File(graphLocation);
+ f.delete();
+ }
+ }
+
+ @Override
+ public Set getImplementations() {
+ return IMPLEMENTATION;
+ }
+
+ /**
+ * Determines if a test requires TinkerGraph persistence to be configured with graph location and format.
+ */
+ protected static boolean requiresPersistence(final Class> test, final String testMethodName) {
+ return test == GraphTest.class && testMethodName.equals("shouldPersistDataOnClose");
+ }
+
+ /**
+ * Determines if a test requires a different cardinality as the default or not.
+ */
+ protected static boolean requiresListCardinalityAsDefault(final LoadGraphWith.GraphData loadGraphWith,
+ final Class> test, final String testMethodName) {
+ return loadGraphWith == LoadGraphWith.GraphData.CREW
+ || (test == StarGraphTest.class && testMethodName.equals("shouldAttachWithCreateMethod"))
+ || (test == DetachedGraphTest.class && testMethodName.equals("testAttachableCreateMethod"));
+ }
+
+ /**
+ * Some tests require special configuration for TinkerGraph to properly configure the id manager.
+ */
+ protected TinkerGraph.DefaultIdManager selectIdMakerFromTest(final Class> test, final String testMethodName) {
+ if (test.equals(GraphTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldIterateVerticesWithNumericIdSupportUsingDoubleRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingDoubleRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingIntegerRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingIntegerRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingFloatRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingFloatRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingStringRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingStringRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingDoubleRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingDoubleRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingIntegerRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingIntegerRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingFloatRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingFloatRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingStringRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingStringRepresentations");
+ }};
+
+ final Set testsThatNeedUuidIdManager = new HashSet(){{
+ add("shouldIterateVerticesWithUuidIdSupportUsingStringRepresentation");
+ add("shouldIterateVerticesWithUuidIdSupportUsingStringRepresentations");
+ add("shouldIterateEdgesWithUuidIdSupportUsingStringRepresentation");
+ add("shouldIterateEdgesWithUuidIdSupportUsingStringRepresentations");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ else if (testsThatNeedUuidIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.UUID;
+ } else if (test.equals(IoEdgeTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldReadWriteEdge[graphson-v1]");
+ add("shouldReadWriteDetachedEdgeAsReference[graphson-v1]");
+ add("shouldReadWriteDetachedEdge[graphson-v1]");
+ add("shouldReadWriteEdge[graphson-v2]");
+ add("shouldReadWriteDetachedEdgeAsReference[graphson-v2]");
+ add("shouldReadWriteDetachedEdge[graphson-v2]");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ } else if (test.equals(IoVertexTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldReadWriteVertexWithBOTHEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithINEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithOUTEdges[graphson-v1]");
+ add("shouldReadWriteVertexNoEdges[graphson-v1]");
+ add("shouldReadWriteDetachedVertexNoEdges[graphson-v1]");
+ add("shouldReadWriteDetachedVertexAsReferenceNoEdges[graphson-v1]");
+ add("shouldReadWriteVertexMultiPropsNoEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithBOTHEdges[graphson-v2]");
+ add("shouldReadWriteVertexWithINEdges[graphson-v2]");
+ add("shouldReadWriteVertexWithOUTEdges[graphson-v2]");
+ add("shouldReadWriteVertexNoEdges[graphson-v2]");
+ add("shouldReadWriteDetachedVertexNoEdges[graphson-v2]");
+ add("shouldReadWriteDetachedVertexAsReferenceNoEdges[graphson-v2]");
+ add("shouldReadWriteVertexMultiPropsNoEdges[graphson-v2]");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ }
+
+ return TinkerGraph.DefaultIdManager.ANY;
+ }
+
+ /**
+ * Test that load with specific graph data can be configured with a specific id manager as the data type to
+ * be used in the test for that graph is known.
+ */
+ protected TinkerGraph.DefaultIdManager selectIdMakerFromGraphData(final LoadGraphWith.GraphData loadGraphWith) {
+ if (null == loadGraphWith) return TinkerGraph.DefaultIdManager.ANY;
+ if (loadGraphWith.equals(LoadGraphWith.GraphData.CLASSIC))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.MODERN))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.CREW))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.GRATEFUL))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.SINK))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else
+ throw new IllegalStateException(String.format("Need to define a new %s for %s", TinkerGraph.IdManager.class.getName(), loadGraphWith.name()));
+ }
+}
diff --git a/neptune-tinkerpop/3.6.5/pom.xml b/neptune-tinkerpop/3.6.5/pom.xml
new file mode 100644
index 0000000..19ea25c
--- /dev/null
+++ b/neptune-tinkerpop/3.6.5/pom.xml
@@ -0,0 +1,33 @@
+
+
+ 4.0.0
+
+ cloud.localstack
+ neptune-tinkerpop-gremlin
+ 0.1
+ jar
+
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.tinkerpop
+ gremlin-core
+ 3.6.5
+
+
+ org.apache.tinkerpop
+ tinkergraph-gremlin
+ 3.6.5
+
+
+ org.apache.tinkerpop
+ gremlin-test
+ 3.6.5
+
+
+
diff --git a/neptune-tinkerpop/3.6.5/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java b/neptune-tinkerpop/3.6.5/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
new file mode 100644
index 0000000..42f505c
--- /dev/null
+++ b/neptune-tinkerpop/3.6.5/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
@@ -0,0 +1,236 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package org.apache.tinkerpop.gremlin.process.traversal.step.util;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Compare;
+import org.apache.tinkerpop.gremlin.process.traversal.Contains;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.util.CloseableIterator;
+
+public class HasContainer implements Serializable, Cloneable, Predicate {
+
+ public static final String LABEL_DELIMITER = "::";
+
+ private String key;
+ private P predicate;
+ private final boolean testingIdString;
+
+ public HasContainer(final String key, final P> predicate) {
+ this.key = key;
+ this.predicate = predicate;
+ this.testingIdString = this.isStringTestable();
+ }
+
+ public final boolean test(final Element element) {
+ if (this.key != null) {
+ if (this.key.equals(T.id.getAccessor())) {
+ return this.testingIdString ? this.testIdAsString(element) : this.testId(element);
+ }
+
+ if (this.key.equals(T.label.getAccessor())) {
+ return this.testLabel(element);
+ }
+ }
+
+ Iterator extends Property> itty = element.properties(new String[]{this.key});
+
+ while(true) {
+ boolean var3;
+ try {
+ if (!itty.hasNext()) {
+ return false;
+ }
+
+ if (!this.testValue((Property)itty.next())) {
+ continue;
+ }
+
+ var3 = true;
+ } finally {
+ CloseableIterator.closeIterator(itty);
+ }
+
+ return var3;
+ }
+ }
+
+ public final boolean test(final Property property) {
+ if (this.key != null) {
+ if (this.key.equals(T.value.getAccessor())) {
+ return this.testValue(property);
+ }
+
+ if (this.key.equals(T.key.getAccessor())) {
+ return this.testKey(property);
+ }
+ }
+
+ return property instanceof Element ? this.test((Element)property) : false;
+ }
+
+ protected boolean testId(final Element element) {
+ return this.predicate.test(element.id());
+ }
+
+ protected boolean testIdAsString(final Element element) {
+ return this.predicate.test(element.id().toString());
+ }
+
+ protected boolean testLabel(final Element element) {
+
+ /* start patch for localstack */
+
+ // add comparison predicates to support the multi-label syntax `label1::label2::label3`
+
+ class LabelEquals implements BiPredicate {
+ public boolean test(String label, String otherLabel) {
+ if (label == null) return false;
+ for (String partialLabel: label.split(LABEL_DELIMITER)) {
+ if (partialLabel.equals(otherLabel)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ class LabelWithin implements BiPredicate> {
+ public boolean test(String label, List labels) {
+ if (label == null) return false;
+ for (String partialLabel: label.split(LABEL_DELIMITER)) {
+ if (labels.contains(partialLabel)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ if (this.predicate.getBiPredicate() == Compare.eq && this.predicate.getValue() instanceof String) {
+ this.predicate = new P(new LabelEquals(), this.predicate.getValue());
+ } else if (this.predicate.getBiPredicate() == Contains.within){
+ if (this.predicate.getValue() instanceof String[]) {
+ // this should catch all hasLabel('LabelX') requests
+ final List labelsList = Arrays.asList((String[])this.predicate.getValue());
+ this.predicate = new P(new LabelWithin(), labelsList);
+ } else if (this.predicate.getValue() instanceof List){
+ // this should handle the traverse logic for hasLabel('LabelX', 'LabelXYZ') e.g. any match from that list
+ boolean validatedAllStrings = true;
+ for (Object s : (List) this.predicate.getValue()){
+ // not sure if we can rely on having only Strings here
+ // verify the content before casting
+ if(! (s instanceof String)){
+ validatedAllStrings = false;
+ break;
+ }
+ }
+ if (validatedAllStrings) this.predicate = new P(new LabelWithin(), this.predicate.getValue());
+ }
+ }
+
+ /* end patch for localstack */
+ return this.predicate.test(element.label());
+ }
+
+ protected boolean testValue(final Property property) {
+ return this.predicate.test(property.value());
+ }
+
+ protected boolean testKey(final Property property) {
+ return this.predicate.test(property.key());
+ }
+
+ public final String toString() {
+ return Objects.toString(this.key) + '.' + this.predicate;
+ }
+
+ public HasContainer clone() {
+ try {
+ HasContainer clone = (HasContainer)super.clone();
+ clone.predicate = this.predicate.clone();
+ return clone;
+ } catch (CloneNotSupportedException var2) {
+ CloneNotSupportedException e = var2;
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ public int hashCode() {
+ return (this.key != null ? this.key.hashCode() : 0) ^ (this.predicate != null ? this.predicate.hashCode() : 0);
+ }
+
+ public final String getKey() {
+ return this.key;
+ }
+
+ public final void setKey(final String key) {
+ this.key = key;
+ }
+
+ public final P> getPredicate() {
+ return this.predicate;
+ }
+
+ public final BiPredicate, ?> getBiPredicate() {
+ return this.predicate.getBiPredicate();
+ }
+
+ public final Object getValue() {
+ return this.predicate.getValue();
+ }
+
+ private boolean isStringTestable() {
+ if (this.key != null && this.key.equals(T.id.getAccessor())) {
+ Object predicateValue = null == this.predicate ? null : this.predicate.getValue();
+ if (predicateValue instanceof Collection) {
+ Collection collection = (Collection)predicateValue;
+ if (!collection.isEmpty()) {
+ return ((Collection)predicateValue).stream().allMatch((c) -> {
+ return null == c || c instanceof String;
+ });
+ }
+ }
+
+ return predicateValue instanceof String;
+ } else {
+ return false;
+ }
+ }
+
+ public static boolean testAll(final Property property, final List hasContainers) {
+ return internalTestAll(property, hasContainers);
+ }
+
+ public static boolean testAll(final Element element, final List hasContainers) {
+ return internalTestAll(element, hasContainers);
+ }
+
+ private static boolean internalTestAll(final S element, final List hasContainers) {
+ boolean isProperty = element instanceof Property;
+ Iterator var3 = hasContainers.iterator();
+
+ while(var3.hasNext()) {
+ HasContainer hasContainer = (HasContainer)var3.next();
+ if (isProperty) {
+ if (!hasContainer.test((Property)element)) {
+ return false;
+ }
+ } else if (!hasContainer.test((Element)element)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/neptune-tinkerpop/3.6.5/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java b/neptune-tinkerpop/3.6.5/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
new file mode 100644
index 0000000..4e5b385
--- /dev/null
+++ b/neptune-tinkerpop/3.6.5/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
@@ -0,0 +1,41 @@
+package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
+
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.GraphManager;
+import org.apache.tinkerpop.gremlin.tinkergraph.TinkerGraphProvider;
+
+public class HasLabelTest extends AbstractGremlinTest
+{
+ public HasLabelTest() {
+ GraphManager.setGraphProvider(new TinkerGraphProvider());
+ }
+
+ @Test
+ @LoadGraphWith(MODERN)
+ public void testHasLabelMultiValue() {
+ final String label1 = "l" + Math.random();
+ final String label2 = "l" + Math.random();
+ final String label3 = "l" + Math.random();
+
+ // add a couple of vertices with single labels and multi-labels
+ g.addV(label1).iterate();
+ g.addV(label2).iterate();
+ g.addV(label3).iterate();
+ g.addV(label1 + "::" + label2).iterate();
+ g.addV(label1 + "::" + label2 + "::" + label1).iterate();
+
+ // assert that vertices can be selected via single sub-labels
+ assertEquals(g.V().hasLabel(label1).toList().size(), 3);
+ assertEquals(g.V().hasLabel(label1).hasLabel(label2).toList().size(), 2);
+
+ // assert that vertices can be selected via a set of alternative sub-labels
+ assertEquals(g.V().hasLabel(label1, label2).toList().size(), 4);
+ assertEquals(g.V().hasLabel(label1, label2, label3).toList().size(), 5);
+ }
+}
diff --git a/neptune-tinkerpop/3.6.5/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java b/neptune-tinkerpop/3.6.5/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
new file mode 100644
index 0000000..3254aa1
--- /dev/null
+++ b/neptune-tinkerpop/3.6.5/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.tinkergraph;
+
+import org.apache.commons.configuration2.Configuration;
+import org.apache.tinkerpop.gremlin.AbstractGraphProvider;
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.TestHelper;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.GraphTest;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.IoEdgeTest;
+import org.apache.tinkerpop.gremlin.structure.io.IoVertexTest;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedGraphTest;
+import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphTest;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerEdge;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerElement;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraphVariables;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerProperty;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertexProperty;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class TinkerGraphProvider extends AbstractGraphProvider {
+
+ private static final Set IMPLEMENTATION = new HashSet() {{
+ add(TinkerEdge.class);
+ add(TinkerElement.class);
+ add(TinkerGraph.class);
+ add(TinkerGraphVariables.class);
+ add(TinkerProperty.class);
+ add(TinkerVertex.class);
+ add(TinkerVertexProperty.class);
+ }};
+
+ @Override
+ public Map getBaseConfiguration(final String graphName, final Class> test, final String testMethodName,
+ final LoadGraphWith.GraphData loadGraphWith) {
+ final TinkerGraph.DefaultIdManager idManager = selectIdMakerFromGraphData(loadGraphWith);
+ final String idMaker = (idManager.equals(TinkerGraph.DefaultIdManager.ANY) ? selectIdMakerFromTest(test, testMethodName) : idManager).name();
+ return new HashMap() {{
+ put(Graph.GRAPH, TinkerGraph.class.getName());
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_ID_MANAGER, idMaker);
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_EDGE_ID_MANAGER, idMaker);
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_PROPERTY_ID_MANAGER, idMaker);
+ if (requiresListCardinalityAsDefault(loadGraphWith, test, testMethodName))
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_DEFAULT_VERTEX_PROPERTY_CARDINALITY, VertexProperty.Cardinality.list.name());
+ if (requiresPersistence(test, testMethodName)) {
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_FORMAT, "gryo");
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_LOCATION,TestHelper.makeTestDataFile(test, "temp", testMethodName + ".kryo"));
+ }
+ }};
+ }
+
+ @Override
+ public void clear(final Graph graph, final Configuration configuration) throws Exception {
+ if (graph != null)
+ graph.close();
+
+ // in the even the graph is persisted we need to clean up
+ final String graphLocation = null != configuration ? configuration.getString(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_LOCATION, null) : null;
+ if (graphLocation != null) {
+ final File f = new File(graphLocation);
+ f.delete();
+ }
+ }
+
+ @Override
+ public Set getImplementations() {
+ return IMPLEMENTATION;
+ }
+
+ /**
+ * Determines if a test requires TinkerGraph persistence to be configured with graph location and format.
+ */
+ protected static boolean requiresPersistence(final Class> test, final String testMethodName) {
+ return test == GraphTest.class && testMethodName.equals("shouldPersistDataOnClose");
+ }
+
+ /**
+ * Determines if a test requires a different cardinality as the default or not.
+ */
+ protected static boolean requiresListCardinalityAsDefault(final LoadGraphWith.GraphData loadGraphWith,
+ final Class> test, final String testMethodName) {
+ return loadGraphWith == LoadGraphWith.GraphData.CREW
+ || (test == StarGraphTest.class && testMethodName.equals("shouldAttachWithCreateMethod"))
+ || (test == DetachedGraphTest.class && testMethodName.equals("testAttachableCreateMethod"));
+ }
+
+ /**
+ * Some tests require special configuration for TinkerGraph to properly configure the id manager.
+ */
+ protected TinkerGraph.DefaultIdManager selectIdMakerFromTest(final Class> test, final String testMethodName) {
+ if (test.equals(GraphTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldIterateVerticesWithNumericIdSupportUsingDoubleRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingDoubleRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingIntegerRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingIntegerRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingFloatRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingFloatRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingStringRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingStringRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingDoubleRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingDoubleRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingIntegerRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingIntegerRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingFloatRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingFloatRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingStringRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingStringRepresentations");
+ }};
+
+ final Set testsThatNeedUuidIdManager = new HashSet(){{
+ add("shouldIterateVerticesWithUuidIdSupportUsingStringRepresentation");
+ add("shouldIterateVerticesWithUuidIdSupportUsingStringRepresentations");
+ add("shouldIterateEdgesWithUuidIdSupportUsingStringRepresentation");
+ add("shouldIterateEdgesWithUuidIdSupportUsingStringRepresentations");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ else if (testsThatNeedUuidIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.UUID;
+ } else if (test.equals(IoEdgeTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldReadWriteEdge[graphson-v1]");
+ add("shouldReadWriteDetachedEdgeAsReference[graphson-v1]");
+ add("shouldReadWriteDetachedEdge[graphson-v1]");
+ add("shouldReadWriteEdge[graphson-v2]");
+ add("shouldReadWriteDetachedEdgeAsReference[graphson-v2]");
+ add("shouldReadWriteDetachedEdge[graphson-v2]");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ } else if (test.equals(IoVertexTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldReadWriteVertexWithBOTHEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithINEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithOUTEdges[graphson-v1]");
+ add("shouldReadWriteVertexNoEdges[graphson-v1]");
+ add("shouldReadWriteDetachedVertexNoEdges[graphson-v1]");
+ add("shouldReadWriteDetachedVertexAsReferenceNoEdges[graphson-v1]");
+ add("shouldReadWriteVertexMultiPropsNoEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithBOTHEdges[graphson-v2]");
+ add("shouldReadWriteVertexWithINEdges[graphson-v2]");
+ add("shouldReadWriteVertexWithOUTEdges[graphson-v2]");
+ add("shouldReadWriteVertexNoEdges[graphson-v2]");
+ add("shouldReadWriteDetachedVertexNoEdges[graphson-v2]");
+ add("shouldReadWriteDetachedVertexAsReferenceNoEdges[graphson-v2]");
+ add("shouldReadWriteVertexMultiPropsNoEdges[graphson-v2]");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ }
+
+ return TinkerGraph.DefaultIdManager.ANY;
+ }
+
+ /**
+ * Test that load with specific graph data can be configured with a specific id manager as the data type to
+ * be used in the test for that graph is known.
+ */
+ protected TinkerGraph.DefaultIdManager selectIdMakerFromGraphData(final LoadGraphWith.GraphData loadGraphWith) {
+ if (null == loadGraphWith) return TinkerGraph.DefaultIdManager.ANY;
+ if (loadGraphWith.equals(LoadGraphWith.GraphData.CLASSIC))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.MODERN))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.CREW))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.GRATEFUL))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.SINK))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else
+ throw new IllegalStateException(String.format("Need to define a new %s for %s", TinkerGraph.IdManager.class.getName(), loadGraphWith.name()));
+ }
+}
diff --git a/neptune-tinkerpop/3.7.1/pom.xml b/neptune-tinkerpop/3.7.1/pom.xml
new file mode 100644
index 0000000..865e0ee
--- /dev/null
+++ b/neptune-tinkerpop/3.7.1/pom.xml
@@ -0,0 +1,33 @@
+
+
+ 4.0.0
+
+ cloud.localstack
+ neptune-tinkerpop-gremlin
+ 0.1
+ jar
+
+
+ 1.8
+ 1.8
+
+
+
+
+ org.apache.tinkerpop
+ gremlin-core
+ 3.7.1
+
+
+ org.apache.tinkerpop
+ tinkergraph-gremlin
+ 3.7.1
+
+
+ org.apache.tinkerpop
+ gremlin-test
+ 3.7.1
+
+
+
diff --git a/neptune-tinkerpop/3.7.1/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java b/neptune-tinkerpop/3.7.1/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
new file mode 100644
index 0000000..81d1dab
--- /dev/null
+++ b/neptune-tinkerpop/3.7.1/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/step/util/HasContainer.java
@@ -0,0 +1,232 @@
+//
+// Source code recreated from a .class file by IntelliJ IDEA
+// (powered by FernFlower decompiler)
+//
+
+package org.apache.tinkerpop.gremlin.process.traversal.step.util;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.function.BiPredicate;
+import java.util.function.Predicate;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Compare;
+import org.apache.tinkerpop.gremlin.process.traversal.Contains;
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.PBiPredicate;
+import org.apache.tinkerpop.gremlin.structure.Element;
+import org.apache.tinkerpop.gremlin.structure.Property;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.util.CloseableIterator;
+
+
+public class HasContainer implements Serializable, Cloneable, Predicate {
+
+ public static final String LABEL_DELIMITER = "::";
+
+ private String key;
+ private P predicate;
+ private final boolean testingIdString;
+
+ public HasContainer(final String key, final P> predicate) {
+ this.key = key;
+ this.predicate = predicate;
+ this.testingIdString = this.isStringTestable();
+ }
+
+ public final boolean test(final Element element) {
+ if (this.key != null) {
+ if (this.key.equals(T.id.getAccessor())) {
+ return this.testingIdString ? this.testIdAsString(element) : this.testId(element);
+ }
+ if (this.key.equals(T.label.getAccessor())) {
+ return this.testLabel(element);
+ }
+ }
+
+ Iterator extends Property> itty = element.properties(new String[]{this.key});
+
+ try {
+ while(itty.hasNext()) {
+ if (this.testValue((Property)itty.next())) {
+ boolean var3 = true;
+ return var3;
+ }
+ }
+ } finally {
+ CloseableIterator.closeIterator(itty);
+ }
+
+ return false;
+ }
+
+ public final boolean test(final Property property) {
+ if (this.key != null) {
+ if (this.key.equals(T.value.getAccessor())) {
+ return this.testValue(property);
+ }
+
+ if (this.key.equals(T.key.getAccessor())) {
+ return this.testKey(property);
+ }
+ }
+
+ return property instanceof Element ? this.test((Element)property) : false;
+ }
+
+ protected boolean testId(final Element element) {
+ return this.predicate.test(element.id());
+ }
+
+ protected boolean testIdAsString(final Element element) {
+ return this.predicate.test(element.id().toString());
+ }
+
+ protected boolean testLabel(final Element element) {
+
+ /* start patch for localstack */
+
+ // add comparison predicates to support the multi-label syntax `label1::label2::label3`
+
+ class LabelEquals implements PBiPredicate {
+ public boolean test(String label, String otherLabel) {
+ if (label == null) return false;
+ for (String partialLabel: label.split(LABEL_DELIMITER)) {
+ if (partialLabel.equals(otherLabel)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ class LabelWithin implements PBiPredicate> {
+ public boolean test(String label, List labels) {
+ if (label == null) return false;
+ for (String partialLabel: label.split(LABEL_DELIMITER)) {
+ if (labels.contains(partialLabel)) {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ if (this.predicate.getBiPredicate() == Compare.eq && this.predicate.getValue() instanceof String) {
+ this.predicate = new P(new LabelEquals(), this.predicate.getValue());
+ } else if (this.predicate.getBiPredicate() == Contains.within){
+ if (this.predicate.getValue() instanceof String[]) {
+ // this should catch all hasLabel('LabelX') requests
+ final List labelsList = Arrays.asList((String[])this.predicate.getValue());
+ this.predicate = new P(new LabelWithin(), labelsList);
+ } else if (this.predicate.getValue() instanceof List){
+ // this should handle the traverse logic for hasLabel('LabelX', 'LabelXYZ') e.g. any match from that list
+ boolean validatedAllStrings = true;
+ for (Object s : (List) this.predicate.getValue()){
+ // not sure if we can rely on having only Strings here
+ // verify the content before casting
+ if(! (s instanceof String)){
+ validatedAllStrings = false;
+ break;
+ }
+ }
+ if (validatedAllStrings) this.predicate = new P(new LabelWithin(), this.predicate.getValue());
+ }
+ }
+
+ /* end patch for localstack */
+
+ return this.predicate.test(element.label());
+ }
+
+ protected boolean testValue(final Property property) {
+ return this.predicate.test(property.value());
+ }
+
+ protected boolean testKey(final Property property) {
+ return this.predicate.test(property.key());
+ }
+
+ public final String toString() {
+ return Objects.toString(this.key) + '.' + this.predicate;
+ }
+
+ public HasContainer clone() {
+ try {
+ HasContainer clone = (HasContainer)super.clone();
+ clone.predicate = this.predicate.clone();
+ return clone;
+ } catch (CloneNotSupportedException var2) {
+ CloneNotSupportedException e = var2;
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ public int hashCode() {
+ return (this.key != null ? this.key.hashCode() : 0) ^ (this.predicate != null ? this.predicate.hashCode() : 0);
+ }
+
+ public final String getKey() {
+ return this.key;
+ }
+
+ public final void setKey(final String key) {
+ this.key = key;
+ }
+
+ public final P> getPredicate() {
+ return this.predicate;
+ }
+
+ public final BiPredicate, ?> getBiPredicate() {
+ return this.predicate.getBiPredicate();
+ }
+
+ public final Object getValue() {
+ return this.predicate.getValue();
+ }
+
+ private boolean isStringTestable() {
+ if (this.key != null && this.key.equals(T.id.getAccessor())) {
+ Object predicateValue = null == this.predicate ? null : this.predicate.getValue();
+ if (predicateValue instanceof Collection) {
+ Collection collection = (Collection)predicateValue;
+ if (!collection.isEmpty()) {
+ return ((Collection)predicateValue).stream().allMatch((c) -> {
+ return null == c || c instanceof String;
+ });
+ }
+ }
+
+ return predicateValue instanceof String;
+ } else {
+ return false;
+ }
+ }
+
+ public static boolean testAll(final Property property, final List hasContainers) {
+ return internalTestAll(property, hasContainers);
+ }
+
+ public static boolean testAll(final Element element, final List hasContainers) {
+ return internalTestAll(element, hasContainers);
+ }
+
+ private static boolean internalTestAll(final S element, final List hasContainers) {
+ boolean isProperty = element instanceof Property;
+ Iterator var3 = hasContainers.iterator();
+
+ while(var3.hasNext()) {
+ HasContainer hasContainer = (HasContainer)var3.next();
+ if (isProperty) {
+ if (!hasContainer.test((Property)element)) {
+ return false;
+ }
+ } else if (!hasContainer.test((Element)element)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/neptune-tinkerpop/3.7.1/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java b/neptune-tinkerpop/3.7.1/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
new file mode 100644
index 0000000..4e5b385
--- /dev/null
+++ b/neptune-tinkerpop/3.7.1/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/step/filter/HasLabelTest.java
@@ -0,0 +1,41 @@
+package org.apache.tinkerpop.gremlin.process.traversal.step.filter;
+
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.apache.tinkerpop.gremlin.LoadGraphWith.GraphData.MODERN;
+
+import org.apache.tinkerpop.gremlin.AbstractGremlinTest;
+import org.apache.tinkerpop.gremlin.GraphManager;
+import org.apache.tinkerpop.gremlin.tinkergraph.TinkerGraphProvider;
+
+public class HasLabelTest extends AbstractGremlinTest
+{
+ public HasLabelTest() {
+ GraphManager.setGraphProvider(new TinkerGraphProvider());
+ }
+
+ @Test
+ @LoadGraphWith(MODERN)
+ public void testHasLabelMultiValue() {
+ final String label1 = "l" + Math.random();
+ final String label2 = "l" + Math.random();
+ final String label3 = "l" + Math.random();
+
+ // add a couple of vertices with single labels and multi-labels
+ g.addV(label1).iterate();
+ g.addV(label2).iterate();
+ g.addV(label3).iterate();
+ g.addV(label1 + "::" + label2).iterate();
+ g.addV(label1 + "::" + label2 + "::" + label1).iterate();
+
+ // assert that vertices can be selected via single sub-labels
+ assertEquals(g.V().hasLabel(label1).toList().size(), 3);
+ assertEquals(g.V().hasLabel(label1).hasLabel(label2).toList().size(), 2);
+
+ // assert that vertices can be selected via a set of alternative sub-labels
+ assertEquals(g.V().hasLabel(label1, label2).toList().size(), 4);
+ assertEquals(g.V().hasLabel(label1, label2, label3).toList().size(), 5);
+ }
+}
diff --git a/neptune-tinkerpop/3.7.1/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java b/neptune-tinkerpop/3.7.1/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
new file mode 100644
index 0000000..3254aa1
--- /dev/null
+++ b/neptune-tinkerpop/3.7.1/src/test/java/org/apache/tinkerpop/gremlin/tinkergraph/TinkerGraphProvider.java
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tinkerpop.gremlin.tinkergraph;
+
+import org.apache.commons.configuration2.Configuration;
+import org.apache.tinkerpop.gremlin.AbstractGraphProvider;
+import org.apache.tinkerpop.gremlin.LoadGraphWith;
+import org.apache.tinkerpop.gremlin.TestHelper;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.GraphTest;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
+import org.apache.tinkerpop.gremlin.structure.io.IoEdgeTest;
+import org.apache.tinkerpop.gremlin.structure.io.IoVertexTest;
+import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedGraphTest;
+import org.apache.tinkerpop.gremlin.structure.util.star.StarGraphTest;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerEdge;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerElement;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraphVariables;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerProperty;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertexProperty;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Stephen Mallette (http://stephen.genoprime.com)
+ */
+public class TinkerGraphProvider extends AbstractGraphProvider {
+
+ private static final Set IMPLEMENTATION = new HashSet() {{
+ add(TinkerEdge.class);
+ add(TinkerElement.class);
+ add(TinkerGraph.class);
+ add(TinkerGraphVariables.class);
+ add(TinkerProperty.class);
+ add(TinkerVertex.class);
+ add(TinkerVertexProperty.class);
+ }};
+
+ @Override
+ public Map getBaseConfiguration(final String graphName, final Class> test, final String testMethodName,
+ final LoadGraphWith.GraphData loadGraphWith) {
+ final TinkerGraph.DefaultIdManager idManager = selectIdMakerFromGraphData(loadGraphWith);
+ final String idMaker = (idManager.equals(TinkerGraph.DefaultIdManager.ANY) ? selectIdMakerFromTest(test, testMethodName) : idManager).name();
+ return new HashMap() {{
+ put(Graph.GRAPH, TinkerGraph.class.getName());
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_ID_MANAGER, idMaker);
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_EDGE_ID_MANAGER, idMaker);
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_VERTEX_PROPERTY_ID_MANAGER, idMaker);
+ if (requiresListCardinalityAsDefault(loadGraphWith, test, testMethodName))
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_DEFAULT_VERTEX_PROPERTY_CARDINALITY, VertexProperty.Cardinality.list.name());
+ if (requiresPersistence(test, testMethodName)) {
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_FORMAT, "gryo");
+ put(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_LOCATION,TestHelper.makeTestDataFile(test, "temp", testMethodName + ".kryo"));
+ }
+ }};
+ }
+
+ @Override
+ public void clear(final Graph graph, final Configuration configuration) throws Exception {
+ if (graph != null)
+ graph.close();
+
+ // in the even the graph is persisted we need to clean up
+ final String graphLocation = null != configuration ? configuration.getString(TinkerGraph.GREMLIN_TINKERGRAPH_GRAPH_LOCATION, null) : null;
+ if (graphLocation != null) {
+ final File f = new File(graphLocation);
+ f.delete();
+ }
+ }
+
+ @Override
+ public Set getImplementations() {
+ return IMPLEMENTATION;
+ }
+
+ /**
+ * Determines if a test requires TinkerGraph persistence to be configured with graph location and format.
+ */
+ protected static boolean requiresPersistence(final Class> test, final String testMethodName) {
+ return test == GraphTest.class && testMethodName.equals("shouldPersistDataOnClose");
+ }
+
+ /**
+ * Determines if a test requires a different cardinality as the default or not.
+ */
+ protected static boolean requiresListCardinalityAsDefault(final LoadGraphWith.GraphData loadGraphWith,
+ final Class> test, final String testMethodName) {
+ return loadGraphWith == LoadGraphWith.GraphData.CREW
+ || (test == StarGraphTest.class && testMethodName.equals("shouldAttachWithCreateMethod"))
+ || (test == DetachedGraphTest.class && testMethodName.equals("testAttachableCreateMethod"));
+ }
+
+ /**
+ * Some tests require special configuration for TinkerGraph to properly configure the id manager.
+ */
+ protected TinkerGraph.DefaultIdManager selectIdMakerFromTest(final Class> test, final String testMethodName) {
+ if (test.equals(GraphTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldIterateVerticesWithNumericIdSupportUsingDoubleRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingDoubleRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingIntegerRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingIntegerRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingFloatRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingFloatRepresentations");
+ add("shouldIterateVerticesWithNumericIdSupportUsingStringRepresentation");
+ add("shouldIterateVerticesWithNumericIdSupportUsingStringRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingDoubleRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingDoubleRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingIntegerRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingIntegerRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingFloatRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingFloatRepresentations");
+ add("shouldIterateEdgesWithNumericIdSupportUsingStringRepresentation");
+ add("shouldIterateEdgesWithNumericIdSupportUsingStringRepresentations");
+ }};
+
+ final Set testsThatNeedUuidIdManager = new HashSet(){{
+ add("shouldIterateVerticesWithUuidIdSupportUsingStringRepresentation");
+ add("shouldIterateVerticesWithUuidIdSupportUsingStringRepresentations");
+ add("shouldIterateEdgesWithUuidIdSupportUsingStringRepresentation");
+ add("shouldIterateEdgesWithUuidIdSupportUsingStringRepresentations");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ else if (testsThatNeedUuidIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.UUID;
+ } else if (test.equals(IoEdgeTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldReadWriteEdge[graphson-v1]");
+ add("shouldReadWriteDetachedEdgeAsReference[graphson-v1]");
+ add("shouldReadWriteDetachedEdge[graphson-v1]");
+ add("shouldReadWriteEdge[graphson-v2]");
+ add("shouldReadWriteDetachedEdgeAsReference[graphson-v2]");
+ add("shouldReadWriteDetachedEdge[graphson-v2]");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ } else if (test.equals(IoVertexTest.class)) {
+ final Set testsThatNeedLongIdManager = new HashSet(){{
+ add("shouldReadWriteVertexWithBOTHEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithINEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithOUTEdges[graphson-v1]");
+ add("shouldReadWriteVertexNoEdges[graphson-v1]");
+ add("shouldReadWriteDetachedVertexNoEdges[graphson-v1]");
+ add("shouldReadWriteDetachedVertexAsReferenceNoEdges[graphson-v1]");
+ add("shouldReadWriteVertexMultiPropsNoEdges[graphson-v1]");
+ add("shouldReadWriteVertexWithBOTHEdges[graphson-v2]");
+ add("shouldReadWriteVertexWithINEdges[graphson-v2]");
+ add("shouldReadWriteVertexWithOUTEdges[graphson-v2]");
+ add("shouldReadWriteVertexNoEdges[graphson-v2]");
+ add("shouldReadWriteDetachedVertexNoEdges[graphson-v2]");
+ add("shouldReadWriteDetachedVertexAsReferenceNoEdges[graphson-v2]");
+ add("shouldReadWriteVertexMultiPropsNoEdges[graphson-v2]");
+ }};
+
+ if (testsThatNeedLongIdManager.contains(testMethodName))
+ return TinkerGraph.DefaultIdManager.LONG;
+ }
+
+ return TinkerGraph.DefaultIdManager.ANY;
+ }
+
+ /**
+ * Test that load with specific graph data can be configured with a specific id manager as the data type to
+ * be used in the test for that graph is known.
+ */
+ protected TinkerGraph.DefaultIdManager selectIdMakerFromGraphData(final LoadGraphWith.GraphData loadGraphWith) {
+ if (null == loadGraphWith) return TinkerGraph.DefaultIdManager.ANY;
+ if (loadGraphWith.equals(LoadGraphWith.GraphData.CLASSIC))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.MODERN))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.CREW))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.GRATEFUL))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else if (loadGraphWith.equals(LoadGraphWith.GraphData.SINK))
+ return TinkerGraph.DefaultIdManager.INTEGER;
+ else
+ throw new IllegalStateException(String.format("Need to define a new %s for %s", TinkerGraph.IdManager.class.getName(), loadGraphWith.name()));
+ }
+}
diff --git a/neptune-tinkerpop/build.sh b/neptune-tinkerpop/build.sh
index f92c0fd..f1f0661 100755
--- a/neptune-tinkerpop/build.sh
+++ b/neptune-tinkerpop/build.sh
@@ -2,7 +2,7 @@
runDir=$(pwd)
-versions=("3.6.2" "3.7.2")
+versions=("3.4.11" "3.5.2" "3.6.2" "3.6.5" "3.7.1" "3.7.2")
for version in "${versions[@]}"; do
(
cd $version
diff --git a/neptune-tinkerpop/gremlin-core-3.4.11-patches.zip b/neptune-tinkerpop/gremlin-core-3.4.11-patches.zip
new file mode 100644
index 0000000000000000000000000000000000000000..634f3c9adfcf7a2c6c968bfc7b694ec33c4f0c59
GIT binary patch
literal 7826
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%0AKmk-NYqbZ}m1w+p{->`0lEh
zSBUG9@7~&+eGjoPlxDu}ER=Vq`=^;CN0
zLkRfN4PTOIh=Y1zXiuBop;MP$h@;1_jMO@BSQjl&KhuT{Xjw6mF46VfM=~
zM2FJ^_q(@ZV?8EnV1TjIKQ6EyV#&`wVJEE#V#u*cBmjMWO1U466btxJW}JwcwrMzghi=8oZX?1OcQ4V#-*^?#Q8>0;
z^?^4=z~b4kB^&L!5V4Ni$gMbM;^d_M*-C@ZxA;|h4~pNKfOgcWTcmyD`dZjG2=QgZ
zSE1=&fs@jc4?48!rgXt3UyrauEWHKTR?$tsa8x*x5jE6z7tHu3GD?F_kv`3$3bOHv
z71j}9spFcPazYR|UWLdR%D}3san1)dy&q1dQm38*j{W+QlHwOGFs}qw}g+Mw+Ug(
zCw<^_$oO>oy)OA(Rt