Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 535b981

Browse files
committed
improved deserialize of responses of CRUD operations on multiple documents
1 parent 4585506 commit 535b981

File tree

11 files changed

+141
-153
lines changed

11 files changed

+141
-153
lines changed

‎core/src/main/java/com/arangodb/entity/MultiDocumentEntity.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,17 @@
2020

2121
package com.arangodb.entity;
2222

23+
import java.util.ArrayList;
2324
import java.util.List;
2425

2526
/**
2627
* @author Mark Vollmary
2728
*/
2829
public final class MultiDocumentEntity<E> {
2930

30-
private List<E> documents;
31-
private List<ErrorEntity> errors;
32-
private List<Object> documentsAndErrors;
31+
private List<E> documents = newArrayList<>();
32+
private List<ErrorEntity> errors = newArrayList<>();
33+
private List<Object> documentsAndErrors = newArrayList<>();
3334
private boolean isPotentialDirtyRead = false;
3435

3536
public MultiDocumentEntity() {

‎core/src/main/java/com/arangodb/internal/InternalArangoCollection.java

Lines changed: 15 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@
3232
import java.lang.reflect.Type;
3333
import java.util.ArrayList;
3434
import java.util.Collection;
35-
import java.util.List;
3635

3736
import static com.arangodb.internal.serde.SerdeUtils.constructParametricType;
3837

@@ -109,31 +108,11 @@ private InternalRequest createInsertDocumentRequest(final DocumentCreateOptions
109108
return request;
110109
}
111110

112-
// TODO: avoid serialization-deserialization round-trip
113111
protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentCreateEntity<T>>> insertDocumentsResponseDeserializer(Class<T> userDataClass) {
114112
return (response) -> {
115-
final MultiDocumentEntity<DocumentCreateEntity<T>> multiDocument = new MultiDocumentEntity<>();
116-
final List<DocumentCreateEntity<T>> docs = new ArrayList<>();
117-
final List<ErrorEntity> errors = new ArrayList<>();
118-
final List<Object> documentsAndErrors = new ArrayList<>();
119-
final JsonNode body = getSerde().parse(response.getBody());
120-
for (final JsonNode next : body) {
121-
JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME);
122-
if (isError != null && isError.booleanValue()) {
123-
final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class);
124-
errors.add(error);
125-
documentsAndErrors.add(error);
126-
} else {
127-
Type type = constructParametricType(DocumentCreateEntity.class, userDataClass);
128-
final DocumentCreateEntity<T> doc = getSerde().deserialize(next, type);
129-
docs.add(doc);
130-
documentsAndErrors.add(doc);
131-
}
132-
}
133-
multiDocument.setDocuments(docs);
134-
multiDocument.setErrors(errors);
135-
multiDocument.setDocumentsAndErrors(documentsAndErrors);
136-
return multiDocument;
113+
Type type = constructParametricType(MultiDocumentEntity.class,
114+
constructParametricType(DocumentCreateEntity.class, userDataClass));
115+
return getSerde().deserialize(response.getBody(), type);
137116
};
138117
}
139118

@@ -185,32 +164,12 @@ protected InternalRequest getDocumentsRequest(final Iterable<String> keys, final
185164
return request;
186165
}
187166

188-
// TODO: avoid serialization-deserialization round-trip
189-
protected <T> ResponseDeserializer<MultiDocumentEntity<T>> getDocumentsResponseDeserializer(
190-
final Class<T> type) {
167+
protected <T> ResponseDeserializer<MultiDocumentEntity<T>> getDocumentsResponseDeserializer(final Class<T> type) {
191168
return (response) -> {
192-
final MultiDocumentEntity<T> multiDocument = new MultiDocumentEntity<>();
169+
MultiDocumentEntity<T> multiDocument = getSerde().deserialize(response.getBody(),
170+
constructParametricType(MultiDocumentEntity.class, type));
193171
boolean potentialDirtyRead = Boolean.parseBoolean(response.getMeta("X-Arango-Potential-Dirty-Read"));
194172
multiDocument.setPotentialDirtyRead(potentialDirtyRead);
195-
final List<T> docs = new ArrayList<>();
196-
final List<ErrorEntity> errors = new ArrayList<>();
197-
final List<Object> documentsAndErrors = new ArrayList<>();
198-
final JsonNode body = getSerde().parse(response.getBody());
199-
for (final JsonNode next : body) {
200-
JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME);
201-
if (isError != null && isError.booleanValue()) {
202-
final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class);
203-
errors.add(error);
204-
documentsAndErrors.add(error);
205-
} else {
206-
final T doc = getSerde().deserializeUserData(getSerde().serialize(next), type);
207-
docs.add(doc);
208-
documentsAndErrors.add(doc);
209-
}
210-
}
211-
multiDocument.setDocuments(docs);
212-
multiDocument.setErrors(errors);
213-
multiDocument.setDocumentsAndErrors(documentsAndErrors);
214173
return multiDocument;
215174
};
216175
}
@@ -249,32 +208,12 @@ private InternalRequest createReplaceDocumentRequest(final DocumentReplaceOption
249208
return request;
250209
}
251210

252-
// TODO: avoid serialization-deserialization round-trip
253211
protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentUpdateEntity<T>>> replaceDocumentsResponseDeserializer(
254212
final Class<T> returnType) {
255213
return (response) -> {
256-
final MultiDocumentEntity<DocumentUpdateEntity<T>> multiDocument = new MultiDocumentEntity<>();
257-
final List<DocumentUpdateEntity<T>> docs = new ArrayList<>();
258-
final List<ErrorEntity> errors = new ArrayList<>();
259-
final List<Object> documentsAndErrors = new ArrayList<>();
260-
final JsonNode body = getSerde().parse(response.getBody());
261-
for (final JsonNode next : body) {
262-
JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME);
263-
if (isError != null && isError.booleanValue()) {
264-
final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class);
265-
errors.add(error);
266-
documentsAndErrors.add(error);
267-
} else {
268-
Type type = constructParametricType(DocumentUpdateEntity.class, returnType);
269-
final DocumentUpdateEntity<T> doc = getSerde().deserialize(next, type);
270-
docs.add(doc);
271-
documentsAndErrors.add(doc);
272-
}
273-
}
274-
multiDocument.setDocuments(docs);
275-
multiDocument.setErrors(errors);
276-
multiDocument.setDocumentsAndErrors(documentsAndErrors);
277-
return multiDocument;
214+
Type type = constructParametricType(MultiDocumentEntity.class,
215+
constructParametricType(DocumentUpdateEntity.class, returnType));
216+
return getSerde().deserialize(response.getBody(), type);
278217
};
279218
}
280219

@@ -313,32 +252,12 @@ private InternalRequest createUpdateDocumentRequest(final DocumentUpdateOptions
313252
return request;
314253
}
315254

316-
// TODO: avoid serialization-deserialization round-trip
317255
protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentUpdateEntity<T>>> updateDocumentsResponseDeserializer(
318256
final Class<T> returnType) {
319257
return (response) -> {
320-
final MultiDocumentEntity<DocumentUpdateEntity<T>> multiDocument = new MultiDocumentEntity<>();
321-
final List<DocumentUpdateEntity<T>> docs = new ArrayList<>();
322-
final List<ErrorEntity> errors = new ArrayList<>();
323-
final List<Object> documentsAndErrors = new ArrayList<>();
324-
final JsonNode body = getSerde().parse(response.getBody());
325-
for (final JsonNode next : body) {
326-
JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME);
327-
if (isError != null && isError.booleanValue()) {
328-
final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class);
329-
errors.add(error);
330-
documentsAndErrors.add(error);
331-
} else {
332-
Type type = constructParametricType(DocumentUpdateEntity.class, returnType);
333-
final DocumentUpdateEntity<T> doc = getSerde().deserialize(next, type);
334-
docs.add(doc);
335-
documentsAndErrors.add(doc);
336-
}
337-
}
338-
multiDocument.setDocuments(docs);
339-
multiDocument.setErrors(errors);
340-
multiDocument.setDocumentsAndErrors(documentsAndErrors);
341-
return multiDocument;
258+
Type type = constructParametricType(MultiDocumentEntity.class,
259+
constructParametricType(DocumentUpdateEntity.class, returnType));
260+
return getSerde().deserialize(response.getBody(), type);
342261
};
343262
}
344263

@@ -371,32 +290,12 @@ private InternalRequest createDeleteDocumentRequest(final DocumentDeleteOptions
371290
return request;
372291
}
373292

374-
// TODO: avoid serialization-deserialization round-trip
375293
protected <T> ResponseDeserializer<MultiDocumentEntity<DocumentDeleteEntity<T>>> deleteDocumentsResponseDeserializer(
376294
final Class<T> userDataClass) {
377295
return (response) -> {
378-
final MultiDocumentEntity<DocumentDeleteEntity<T>> multiDocument = new MultiDocumentEntity<>();
379-
final List<DocumentDeleteEntity<T>> docs = new ArrayList<>();
380-
final List<ErrorEntity> errors = new ArrayList<>();
381-
final List<Object> documentsAndErrors = new ArrayList<>();
382-
final JsonNode body = getSerde().parse(response.getBody());
383-
for (final JsonNode next : body) {
384-
JsonNode isError = next.get(ArangoResponseField.ERROR_FIELD_NAME);
385-
if (isError != null && isError.booleanValue()) {
386-
final ErrorEntity error = getSerde().deserialize(next, ErrorEntity.class);
387-
errors.add(error);
388-
documentsAndErrors.add(error);
389-
} else {
390-
Type type = constructParametricType(DocumentDeleteEntity.class, userDataClass);
391-
final DocumentDeleteEntity<T> doc = getSerde().deserialize(next, type);
392-
docs.add(doc);
393-
documentsAndErrors.add(doc);
394-
}
395-
}
396-
multiDocument.setDocuments(docs);
397-
multiDocument.setErrors(errors);
398-
multiDocument.setDocumentsAndErrors(documentsAndErrors);
399-
return multiDocument;
296+
Type type = constructParametricType(MultiDocumentEntity.class,
297+
constructParametricType(DocumentDeleteEntity.class, userDataClass));
298+
return getSerde().deserialize(response.getBody(), type);
400299
};
401300
}
402301

‎core/src/main/java/com/arangodb/internal/serde/InternalDeserializers.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ public RawJson deserialize(JsonParser p, DeserializationContext ctxt) throws IOE
3434
if (JsonFactory.FORMAT_NAME_JSON.equals(p.getCodec().getFactory().getFormatName())) {
3535
return RawJson.of(new String(SerdeUtils.extractBytes(p), StandardCharsets.UTF_8));
3636
} else {
37-
// TODO: compare perfs using ByteArrayOutputStream and StringWriter
3837
StringWriter w = new StringWriter();
3938
try (JsonGenerator gen = SerdeUtils.INSTANCE.getJsonMapper().createGenerator(w)) {
4039
gen.copyCurrentStructure(p);

‎core/src/main/java/com/arangodb/internal/serde/InternalModule.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.arangodb.entity.CollectionStatus;
44
import com.arangodb.entity.CollectionType;
55
import com.arangodb.entity.InvertedIndexPrimarySort;
6+
import com.arangodb.entity.MultiDocumentEntity;
67
import com.arangodb.entity.ReplicationFactor;
78
import com.arangodb.util.RawBytes;
89
import com.arangodb.util.RawJson;
@@ -11,15 +12,12 @@
1112
import com.fasterxml.jackson.databind.Module;
1213
import com.fasterxml.jackson.databind.module.SimpleModule;
1314

14-
importjava.util.function.Supplier;
15+
classInternalModule {
1516

16-
enumInternalModuleimplementsSupplier<Module> {
17-
INSTANCE;
17+
staticModuleget(InternalSerdeserde) {
18+
SimpleModulemodule = newSimpleModule();
1819

19-
private final SimpleModule module;
20-
21-
InternalModule() {
22-
module = new SimpleModule();
20+
module.addDeserializer(MultiDocumentEntity.class, new MultiDocumentEntityDeserializer(serde));
2321

2422
module.addSerializer(RawJson.class, InternalSerializers.RAW_JSON_SERIALIZER);
2523
module.addSerializer(InternalRequest.class, InternalSerializers.REQUEST);
@@ -32,11 +30,7 @@ enum InternalModule implements Supplier<Module> {
3230
module.addDeserializer(ReplicationFactor.class, InternalDeserializers.REPLICATION_FACTOR);
3331
module.addDeserializer(InternalResponse.class, InternalDeserializers.RESPONSE);
3432
module.addDeserializer(InvertedIndexPrimarySort.Field.class, InternalDeserializers.INVERTED_INDEX_PRIMARY_SORT_FIELD);
35-
}
3633

37-
@Override
38-
public Module get() {
3934
return module;
4035
}
41-
4236
}

‎core/src/main/java/com/arangodb/internal/serde/InternalSerde.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import com.arangodb.arch.UsedInApi;
44
import com.arangodb.serde.ArangoSerde;
55
import com.arangodb.ContentType;
6+
import com.fasterxml.jackson.core.JsonParser;
7+
import com.fasterxml.jackson.databind.JavaType;
68
import com.fasterxml.jackson.databind.JsonNode;
79

810
import java.lang.reflect.Type;
@@ -59,14 +61,6 @@ default <T> T deserialize(JsonNode node, Class<T> clazz) {
5961
*/
6062
<T> T deserialize(JsonNode node, Type type);
6163

62-
/**
63-
* Parses the content.
64-
*
65-
* @param content VPack or byte encoded JSON string
66-
* @return root of the parsed tree
67-
*/
68-
JsonNode parse(byte[] content);
69-
7064
/**
7165
* Parses the content at json pointer.
7266
*
@@ -136,6 +130,16 @@ default <T> T deserialize(byte[] content, String jsonPointer, Type type) {
136130
*/
137131
<T> T deserializeUserData(byte[] content, Type type);
138132

133+
/**
134+
* Deserializes the parsed json node and binds it to the target data type.
135+
* The parser is not closed.
136+
*
137+
* @param parser json parser
138+
* @param clazz class of target data type
139+
* @return deserialized object
140+
*/
141+
<T> T deserializeUserData(JsonParser parser, JavaType clazz);
142+
139143
/**
140144
* @return the user serde
141145
*/

‎core/src/main/java/com/arangodb/internal/serde/InternalSerdeImpl.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.fasterxml.jackson.core.JsonProcessingException;
1313
import com.fasterxml.jackson.core.JsonToken;
1414
import com.fasterxml.jackson.databind.DeserializationFeature;
15+
import com.fasterxml.jackson.databind.JavaType;
1516
import com.fasterxml.jackson.databind.JsonNode;
1617
import com.fasterxml.jackson.databind.Module;
1718
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -39,7 +40,7 @@ final class InternalSerdeImpl implements InternalSerde {
3940
mapper.deactivateDefaultTyping();
4041
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
4142
mapper.enable(JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION);
42-
mapper.registerModule(InternalModule.INSTANCE.get());
43+
mapper.registerModule(InternalModule.get(this));
4344
if (protocolModule != null) {
4445
mapper.registerModule(protocolModule);
4546
}
@@ -113,16 +114,6 @@ public byte[] extract(final byte[] content, final String jsonPointer) {
113114
}
114115
}
115116

116-
// TODO: remove
117-
@Override
118-
public JsonNode parse(byte[] content) {
119-
try {
120-
return mapper.readTree(content);
121-
} catch (IOException e) {
122-
throw ArangoDBException.of(e);
123-
}
124-
}
125-
126117
@Override
127118
public JsonNode parse(byte[] content, String jsonPointer) {
128119
try {
@@ -184,6 +175,19 @@ public <T> T deserializeUserData(byte[] content, Type type) {
184175
}
185176
}
186177

178+
@Override
179+
public <T> T deserializeUserData(JsonParser parser, JavaType clazz) {
180+
try {
181+
if (SerdeUtils.isManagedClass(clazz.getRawClass())) {
182+
return mapper.readerFor(clazz).readValue(parser);
183+
} else {
184+
return deserializeUserData(extractBytes(parser), clazz);
185+
}
186+
} catch (IOException e) {
187+
throw ArangoDBException.of(e);
188+
}
189+
}
190+
187191
@Override
188192
public ArangoSerde getUserSerde() {
189193
return userSerde;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /