From ce9e7d0f878a291a1e58cd6b1900293563a30001 Mon Sep 17 00:00:00 2001
From: Jess Sightler <jesse.sightler@gmail.com>
Date: Mon, 8 Jan 2018 13:09:42 -0500
Subject: [PATCH] Fixed a bug that caused exceptions in the case of a vertex
 property with a cardinality other than single

---
 .../syncleus/ferma/AbstractVertexFrame.java   | 38 +++++++++++++++++--
 .../ferma/AbstractElementFrameTest.java       | 29 ++++++++++++++
 2 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/src/main/java/com/syncleus/ferma/AbstractVertexFrame.java b/src/main/java/com/syncleus/ferma/AbstractVertexFrame.java
index 8da3df5b..2be66f8e 100644
--- a/src/main/java/com/syncleus/ferma/AbstractVertexFrame.java
+++ b/src/main/java/com/syncleus/ferma/AbstractVertexFrame.java
@@ -23,9 +23,12 @@
  */
 package com.syncleus.ferma;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.function.Function;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.structure.*;
@@ -232,6 +235,23 @@ public abstract class AbstractVertexFrame extends AbstractElementFrame implement
         return this.setLinkBothExplicit(new DefaultClassInitializer<>(kind), labels);
     }
 
+    private Object getPropertySupportingMultiproperty(final String name) {
+        final Iterator<VertexProperty<Object>> propertyIterator = getElement().properties(name);
+        List<Object> results = new ArrayList<>();
+        while (propertyIterator.hasNext()) {
+            Property<Object> property = propertyIterator.next();
+            if (property.isPresent()) {
+                results.add(property.value());
+            }
+        }
+
+        if (results.size() == 1) {
+            return results.get(0);
+        } else {
+            return results;
+        }
+    }
+
     @Override
     public JsonObject toJson() {
         final JsonObject json = new JsonObject();
@@ -241,15 +261,27 @@ public abstract class AbstractVertexFrame extends AbstractElementFrame implement
             json.addProperty("id", getId(String.class));
         json.addProperty("elementClass", "vertex");
         for (final String key : getPropertyKeys()) {
-
-            final Object value = getProperty(key);
+            Object value = getPropertySupportingMultiproperty(key);
             if (value instanceof Number)
                 json.addProperty(key, (Number) value);
             else if(value instanceof Boolean)
                 json.addProperty(key, (Boolean) value);
             else if(value instanceof Character)
                 json.addProperty(key, (Character) value);
-            else
+            else if (value instanceof List) {
+                JsonArray jsonArray = new JsonArray();
+                ((List) value).forEach(item -> {
+                    if (item instanceof Number)
+                        jsonArray.add((Number) item);
+                    else if(item instanceof Boolean)
+                        jsonArray.add((Boolean) item);
+                    else if(item instanceof Character)
+                        jsonArray.add((Character) item);
+                    else
+                        jsonArray.add(item.toString());
+                });
+                json.add(key, jsonArray);
+            } else
                 json.addProperty(key, value.toString());
         }
         return json;
diff --git a/src/test/java/com/syncleus/ferma/AbstractElementFrameTest.java b/src/test/java/com/syncleus/ferma/AbstractElementFrameTest.java
index a3355dd0..fda8706f 100644
--- a/src/test/java/com/syncleus/ferma/AbstractElementFrameTest.java
+++ b/src/test/java/com/syncleus/ferma/AbstractElementFrameTest.java
@@ -17,6 +17,8 @@ package com.syncleus.ferma;
 
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
 import org.junit.Assert;
 import org.junit.Before;
@@ -26,6 +28,8 @@ import com.google.common.collect.Sets;
 import com.google.gson.JsonObject;
 import com.syncleus.ferma.graphtypes.javaclass.JavaAccessModifier;
 import java.io.IOException;
+import java.util.Iterator;
+
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.junit.After;
 
@@ -211,6 +215,31 @@ public class AbstractElementFrameTest {
         Assert.assertEquals(expected.getProperty(charPropName), (Character) actual.get(charPropName).getAsCharacter());
     }
 
+    @Test
+    public void testVtoJSonMultiproperty() {
+        String stringPropName = "custom-string-property";
+        String stringPropValue = "custom-string-value";
+        String charPropName = "custom-char-property";
+        Character charPropValue = 'D';
+        String intPropName = "custom-int-property";
+        int intPropValue = 1234;
+        Person expected = fg.addFramedVertex(Person.DEFAULT_INITIALIZER,
+            T.id, "some-id",
+            stringPropName, stringPropValue,
+            charPropName, charPropValue,
+            intPropName, intPropValue);
+        Vertex vertex = expected.getElement();
+
+        String key = "multiproperty";
+        vertex.property(VertexProperty.Cardinality.list, key, "value1");
+        vertex.property(VertexProperty.Cardinality.list, key, "value2");
+        vertex.property(VertexProperty.Cardinality.list, key, "value3");
+        vertex.property(VertexProperty.Cardinality.list, key, "value4");
+
+        JsonObject actual = expected.toJson();
+        Assert.assertNotNull(actual);
+    }
+
     @Test
     public void testEtoJson() {
         JsonObject actual = e1.toJson();
-- 
GitLab