Skip to content

Commit 720ec3c

Browse files
committed
added BaseDocument and tests to provide an Object that can contain unknown attribute structures
1 parent 01d1f14 commit 720ec3c

File tree

9 files changed

+509
-32
lines changed

9 files changed

+509
-32
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
/.project
33
/.settings
44
/target
5+
/.idea
6+
/*.iml

src/main/java/com/arangodb/ArangoDriver.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,6 +1645,9 @@ public <T> DocumentEntity<T> getDocument(String collectionName, String documentK
16451645
* @throws ArangoException
16461646
*/
16471647
public <T> DocumentEntity<T> getDocument(String documentHandle, Class<?> clazz) throws ArangoException {
1648+
if (clazz.getName() == BaseDocument.class.getName()) {
1649+
return documentDriver.getDocument(getDefaultDatabase(), documentHandle, clazz, null, null);
1650+
}
16481651
return documentDriver.getDocument(getDefaultDatabase(), documentHandle, clazz, null, null);
16491652
}
16501653

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
package com.arangodb.entity;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
import java.util.HashMap;
6+
import java.util.Map;
7+
8+
/**
9+
* Created by gschwab on 1/14/15.
10+
*/
11+
public class BaseDocument extends BaseEntity implements DocumentHolder {
12+
13+
public static final String REV = "_rev";
14+
15+
public static final String KEY = "_key";
16+
17+
/**
18+
* the documents revision number
19+
*/
20+
@SerializedName("_rev")
21+
long documentRevision;
22+
23+
/**
24+
* the document handle
25+
*/
26+
@SerializedName("_id")
27+
String documentHandle;
28+
29+
/**
30+
* the document key
31+
*/
32+
@SerializedName("_key")
33+
String documentKey;
34+
35+
/**
36+
* the map containing the key value pairs
37+
*/
38+
Map<String, Object> properties = new HashMap<String, Object>();
39+
40+
/**
41+
* create an empty BaseDocument
42+
*/
43+
public BaseDocument() {
44+
this.init();
45+
}
46+
47+
/**
48+
* create an empty BaseDocument with a given key
49+
*
50+
* @param documentKey the unique key of the document
51+
*/
52+
public BaseDocument(String documentKey) {
53+
this.init();
54+
this.documentKey = documentKey;
55+
}
56+
57+
// /**
58+
// * @param keyValues a set of key/value pairs containing the attributes for the document.
59+
// * The length has to be even and each even entry has to be of type String.
60+
// * If not an empty document will be created
61+
// */
62+
// public BaseDocument(Object ...keyValues) {
63+
// this(null, keyValues);
64+
// }
65+
//
66+
// /**
67+
// * create a BaseDocument with a given key and attributes defined in keyValues
68+
// *
69+
// * @param documentKey the unique key of the document
70+
// * @param keyValues a set of key/value pairs containing the attributes for the document.
71+
// * The length has to be even and each even entry has to be of type String.
72+
// * If not an empty document will be created
73+
// */
74+
// public BaseDocument(String documentKey, Object ...keyValues) {
75+
// this.init();
76+
// if (documentKey != null) {
77+
// this.documentKey = documentKey;
78+
// }
79+
// if (checkKeyValues(keyValues)) {
80+
// for (int i = 0; i < keyValues.length; i = i+2) {
81+
// if (keyValues[i] == REV) {
82+
// this.documentRevision = (Long) keyValues[i+1];
83+
// } else if (keyValues[i] == KEY && documentKey == null) {
84+
// this.documentKey = (String) keyValues[i+1];
85+
// } else {
86+
// this.addAttribute((String) keyValues[i], keyValues[i + 1]);
87+
// }
88+
// }
89+
// }
90+
// }
91+
92+
/**
93+
* create an BaseDocument with given attributes
94+
*
95+
* @param properties the attributes (key/value) of the document to be created
96+
*/
97+
public BaseDocument(Map<String, Object> properties) {
98+
this(null, properties);
99+
}
100+
101+
/**
102+
* create an BaseDocument with given key and attributes
103+
*
104+
* @param documentKey the unique key of the document
105+
* @param properties the attributes (key/value) of the document to be created
106+
*/
107+
public BaseDocument(String documentKey, Map<String, Object> properties) {
108+
this.init();
109+
if (documentKey != null) {
110+
this.documentKey = documentKey;
111+
}
112+
if (properties.containsKey(REV)) {
113+
this.documentRevision = (Long) properties.get(REV);
114+
properties.remove(REV);
115+
}
116+
if (properties.containsKey(KEY)) {
117+
if (documentKey == null) {
118+
this.documentKey = (String) properties.get(KEY);
119+
}
120+
properties.remove(KEY);
121+
}
122+
this.properties = properties;
123+
}
124+
125+
private void init () {
126+
//this.properties = new HashMap<String, Object>();
127+
}
128+
129+
@Override
130+
public long getDocumentRevision() {
131+
return this.documentRevision;
132+
}
133+
134+
@Override
135+
public String getDocumentHandle() {
136+
return this.documentHandle;
137+
}
138+
139+
@Override
140+
public String getDocumentKey() {
141+
return this.documentKey;
142+
}
143+
144+
@Override
145+
public void setDocumentRevision(long documentRevision) {
146+
this.documentRevision = documentRevision;
147+
}
148+
149+
@Override
150+
public void setDocumentHandle(String documentHandle) {
151+
this.documentHandle = documentHandle;
152+
}
153+
154+
@Override
155+
public void setDocumentKey(String documentKey) {
156+
this.documentKey = documentKey;
157+
}
158+
159+
public Map<String, Object> getProperties() {
160+
return properties;
161+
}
162+
163+
public void setProperties(Map<String, Object> properties) {
164+
this.properties = properties;
165+
}
166+
167+
168+
/**
169+
* add an attribute to the document. If the key already exists, the value of the attribute will be replaced,
170+
*
171+
* @param key the key of the attribute
172+
* @param value the value of the attribute
173+
*/
174+
public void addAttribute(String key, Object value) {
175+
this.properties.put(key, value);
176+
}
177+
178+
/**
179+
* update the value of the attribute with the given key
180+
*
181+
* @param key the key of the attribute
182+
* @param value the value of the attribute ti replace the old value
183+
*/
184+
public void updateAttribute (String key, Object value) {
185+
this.properties.replace(key, value);
186+
}
187+
188+
// /**
189+
// * check the list if it is suitable
190+
// *
191+
// * @param keyValues
192+
// * @return true, if the list has an even number and is an alternating sequence of instances of String and Object.
193+
// */
194+
// private boolean checkKeyValues(Object... keyValues) {
195+
// if (keyValues.length %2 != 0) {
196+
// return false;
197+
// }
198+
// for (int i = 0; i < keyValues.length; i = i+2) {
199+
// if (! (keyValues[i] instanceof String)) {
200+
// return false;
201+
// }
202+
// }
203+
// return true;
204+
// }
205+
}

src/main/java/com/arangodb/entity/EntityDeserializers.java

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,8 @@
1818

1919
import java.lang.reflect.Type;
2020
import java.math.BigDecimal;
21-
import java.util.ArrayList;
22-
import java.util.Collections;
23-
import java.util.Date;
24-
import java.util.HashMap;
25-
import java.util.Iterator;
26-
import java.util.List;
27-
import java.util.Locale;
28-
import java.util.Map;
21+
import java.util.*;
2922
import java.util.Map.Entry;
30-
import java.util.TreeMap;
3123

3224
import com.arangodb.entity.CollectionEntity.Figures;
3325
import com.arangodb.entity.ReplicationApplierState.LastError;
@@ -39,12 +31,7 @@
3931
import com.arangodb.entity.StatisticsDescriptionEntity.Group;
4032
import com.arangodb.entity.StatisticsEntity.FigureValue;
4133
import com.arangodb.util.DateUtils;
42-
import com.google.gson.JsonArray;
43-
import com.google.gson.JsonDeserializationContext;
44-
import com.google.gson.JsonDeserializer;
45-
import com.google.gson.JsonElement;
46-
import com.google.gson.JsonObject;
47-
import com.google.gson.JsonParseException;
34+
import com.google.gson.*;
4835
import com.google.gson.reflect.TypeToken;
4936

5037
/**
@@ -179,6 +166,9 @@ private static <T extends DocumentHolder> T deserializeDocumentParameter(JsonObj
179166
if (obj.has("_key")) {
180167
entity.setDocumentKey(obj.getAsJsonPrimitive("_key").getAsString());
181168
}
169+
if (true) {
170+
171+
}
182172

183173
return entity;
184174
}
@@ -602,13 +592,91 @@ public DocumentEntity<?> deserialize(JsonElement json, Type typeOfT, JsonDeseria
602592
Class<?> clazz = getParameterized();
603593
if (clazz != null) {
604594
entity.entity = context.deserialize(obj, clazz);
595+
if (clazz.getName().equalsIgnoreCase(BaseDocument.class.getName())) {
596+
// iterate all key/value pairs of the jsonObject and determine its class(String, Number, Boolean, HashMap, List)
597+
((BaseDocument) entity.entity).setProperties(DeserializeSingleEntry.deserializeJsonObject(obj));
598+
}
605599
}
606600

607601
return entity;
608602
}
603+
}
604+
605+
public static class DeserializeSingleEntry {
606+
607+
private static final List<String> nonProperties = new ArrayList<String>() {
608+
{
609+
add("_id");
610+
add("_rev");
611+
add("_key");
612+
}
613+
};
614+
615+
/**
616+
* desirializes any jsonElement
617+
*
618+
* @param jsonElement
619+
* @return
620+
*/
621+
public static Object deserializeJsonElement (JsonElement jsonElement) {
622+
if (jsonElement.getClass() == JsonPrimitive.class) {
623+
return deserializeJsonPrimitive((JsonPrimitive) jsonElement);
624+
} else if (jsonElement.getClass() == JsonArray.class) {
625+
return deserializeJsonArray((JsonArray) jsonElement);
626+
} else if (jsonElement.getClass() == JsonObject.class) {
627+
return deserializeJsonObject((JsonObject) jsonElement);
628+
}
629+
return null;
630+
}
631+
632+
633+
/**
634+
* desirializes a JsonObject into a Map<String, Object>
635+
*
636+
* @param jsonObject a jsonObject
637+
* @return the deserialized jsonObject
638+
*/
639+
private static Map<String, Object> deserializeJsonObject(JsonObject jsonObject) {
640+
Map<String, Object> result = new HashMap<String, Object>();
641+
Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
642+
for(Map.Entry<String,JsonElement> entry : entrySet){
643+
if (! nonProperties.contains(entry.getKey())) {
644+
result.put(entry.getKey(), deserializeJsonElement((JsonElement) jsonObject.get(entry.getKey())));
645+
}
646+
}
647+
return result;
648+
}
649+
650+
private static List<Object> deserializeJsonArray (JsonArray jsonArray) {
651+
List<Object> tmpObjectList = new ArrayList<Object>();
652+
Iterator iterator = (jsonArray.iterator());
653+
while(iterator.hasNext()) {
654+
tmpObjectList.add(deserializeJsonElement((JsonElement) iterator.next()));
655+
}
656+
return tmpObjectList;
657+
}
658+
659+
/**
660+
* deserializes a jsonPrimitiv into the equivalent java primitive
661+
*
662+
* @param jsonPrimitive
663+
* @return null|String|Double|Boolean
664+
*/
665+
private static Object deserializeJsonPrimitive (JsonPrimitive jsonPrimitive) {
666+
if (jsonPrimitive.isBoolean()) {
667+
return jsonPrimitive.getAsBoolean();
668+
} else if (jsonPrimitive.isNumber()) {
669+
return jsonPrimitive.getAsDouble();
670+
} else if (jsonPrimitive.isString()) {
671+
return jsonPrimitive.getAsString();
672+
}
673+
return null;
674+
}
609675

610676
}
611677

678+
679+
612680
public static class DocumentsEntityDeserializer implements JsonDeserializer<DocumentsEntity> {
613681
private Type documentsType = new TypeToken<List<String>>() {
614682
}.getType();

0 commit comments

Comments
 (0)