Skip to content

Commit

Permalink
added support for replacing build-in VelocyPack serializer/deserializer
Browse files Browse the repository at this point in the history
  • Loading branch information
mpv1989 committed Mar 17, 2017
1 parent 56ad189 commit 969cc4b
Show file tree
Hide file tree
Showing 14 changed files with 501 additions and 227 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ v4.1.11 (2017-03-xx)
* added connection pooling (issue #103)
* extracted VelocyPack implementation to https://github.com/arangodb/java-velocypack
* fixed NPE in ArangoCursor (issue #112)
* added support for replacing build-in VelocyPack serializer/deserializer

v4.1.10 (2017-02-22)
---------------------------
Expand Down
57 changes: 41 additions & 16 deletions src/main/java/com/arangodb/ArangoDB.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
import com.arangodb.internal.CollectionCache.DBAccess;
import com.arangodb.internal.DocumentCache;
import com.arangodb.internal.InternalArangoDB;
import com.arangodb.internal.util.ArangoDeserializerImpl;
import com.arangodb.internal.util.ArangoSerializerImpl;
import com.arangodb.internal.util.ArangoUtilImpl;
import com.arangodb.internal.velocypack.VPackDriverModule;
import com.arangodb.internal.velocystream.Communication;
import com.arangodb.internal.velocystream.CommunicationSync;
Expand All @@ -50,6 +53,9 @@
import com.arangodb.model.LogOptions;
import com.arangodb.model.UserCreateOptions;
import com.arangodb.model.UserUpdateOptions;
import com.arangodb.util.ArangoDeserializer;
import com.arangodb.util.ArangoSerializer;
import com.arangodb.util.ArangoUtil;
import com.arangodb.velocypack.VPack;
import com.arangodb.velocypack.VPackAnnotationFieldFilter;
import com.arangodb.velocypack.VPackAnnotationFieldNaming;
Expand Down Expand Up @@ -84,15 +90,17 @@ public static class Builder {
private Integer maxConnections;
private final VPack.Builder vpackBuilder;
private final CollectionCache collectionCache;
private final VPackParser.Builder vpackParser;
private final VPackParser.Builder vpackParserBuilder;
private ArangoSerializer serializer;
private ArangoDeserializer deserializer;

public Builder() {
super();
vpackBuilder = new VPack.Builder();
collectionCache = new CollectionCache();
vpackParser = new VPackParser.Builder();
vpackParserBuilder = new VPackParser.Builder();
vpackBuilder.registerModule(new VPackDriverModule(collectionCache));
vpackParser.registerModule(new VPackDriverModule(collectionCache));
vpackParserBuilder.registerModule(new VPackDriverModule(collectionCache));
host = new Host(ArangoDBConstants.DEFAULT_HOST, ArangoDBConstants.DEFAULT_PORT);
hosts = new ArrayList<Host>();
loadProperties(ArangoDB.class.getResourceAsStream(DEFAULT_PROPERTY_FILE));
Expand Down Expand Up @@ -223,28 +231,28 @@ public <T> Builder registerInstanceCreator(final Class<T> clazz, final VPackInst
}

public Builder registerJsonDeserializer(final ValueType type, final VPackJsonDeserializer deserializer) {
vpackParser.registerDeserializer(type, deserializer);
vpackParserBuilder.registerDeserializer(type, deserializer);
return this;
}

public Builder registerJsonDeserializer(
final String attribute,
final ValueType type,
final VPackJsonDeserializer deserializer) {
vpackParser.registerDeserializer(attribute, type, deserializer);
vpackParserBuilder.registerDeserializer(attribute, type, deserializer);
return this;
}

public <T> Builder registerJsonSerializer(final Class<T> clazz, final VPackJsonSerializer<T> serializer) {
vpackParser.registerSerializer(clazz, serializer);
vpackParserBuilder.registerSerializer(clazz, serializer);
return this;
}

public <T> Builder registerJsonSerializer(
final String attribute,
final Class<T> clazz,
final VPackJsonSerializer<T> serializer) {
vpackParser.registerSerializer(attribute, clazz, serializer);
vpackParserBuilder.registerSerializer(attribute, clazz, serializer);
return this;
}

Expand Down Expand Up @@ -272,30 +280,47 @@ public Builder registerModules(final VPackModule... modules) {
return this;
}

public Builder setSerializer(final ArangoSerializer serializer) {
this.serializer = serializer;
return this;
}

public Builder setDeserializer(final ArangoDeserializer deserializer) {
this.deserializer = deserializer;
return this;
}

public ArangoDB build() {
if (hosts.isEmpty()) {
hosts.add(host);
}
final VPack vpacker = vpackBuilder.build();
final VPack vpackerNull = vpackBuilder.serializeNullValues(true).build();
final VPackParser vpackParser = vpackParserBuilder.build();
if (serializer == null) {
serializer = new ArangoSerializerImpl(vpacker, vpackerNull, vpackParser);
}
if (deserializer == null) {
deserializer = new ArangoDeserializerImpl(vpackerNull, vpackParser);
}
return new ArangoDB(
new CommunicationSync.Builder(new DefaultHostHandler(hosts)).timeout(timeout).user(user)
.password(password).useSsl(useSsl).sslContext(sslContext).chunksize(chunksize)
.maxConnections(maxConnections),
vpackBuilder.build(), vpackBuilder.serializeNullValues(true).build(), vpackParser.build(),
collectionCache);
new ArangoUtilImpl(serializer, deserializer), collectionCache);
}

}

public ArangoDB(final CommunicationSync.Builder commBuilder, final VPack vpack, final VPack vpackNull,
final VPackParser vpackParser, final CollectionCache collectionCache) {
super(new ArangoExecutorSync(commBuilder.build(vpack, collectionCache), vpack, vpackNull, vpackParser,
new DocumentCache(), collectionCache));
final Communication<Response, ConnectionSync> cacheCom = commBuilder.build(vpack, collectionCache);
public ArangoDB(final CommunicationSync.Builder commBuilder, final ArangoUtil util,
final CollectionCache collectionCache) {
super(new ArangoExecutorSync(commBuilder.build(util, collectionCache), util, new DocumentCache(),
collectionCache));
final Communication<Response, ConnectionSync> cacheCom = commBuilder.build(util, collectionCache);
collectionCache.init(new DBAccess() {
@Override
public ArangoDatabase db(final String name) {
return new ArangoDatabase(cacheCom, vpackNull, vpack, vpackParser, executor.documentCache(), null,
name);
return new ArangoDatabase(cacheCom, util, executor.documentCache(), null, name);
}
});
}
Expand Down
11 changes: 4 additions & 7 deletions src/main/java/com/arangodb/ArangoDatabase.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@
import com.arangodb.model.GraphCreateOptions;
import com.arangodb.model.TransactionOptions;
import com.arangodb.model.TraversalOptions;
import com.arangodb.util.ArangoUtil;
import com.arangodb.velocypack.Type;
import com.arangodb.velocypack.VPack;
import com.arangodb.velocypack.VPackParser;
import com.arangodb.velocystream.Request;
import com.arangodb.velocystream.Response;

Expand All @@ -70,11 +69,9 @@ protected ArangoDatabase(final ArangoDB arangoDB, final String name) {
super(arangoDB, arangoDB.executor(), name);
}

protected ArangoDatabase(final Communication<Response, ConnectionSync> communication, final VPack vpacker,
final VPack vpackerNull, final VPackParser vpackParser, final DocumentCache documentCache,
final CollectionCache collectionCache, final String name) {
super(null, new ArangoExecutorSync(communication, vpacker, vpackerNull, vpackParser, documentCache,
collectionCache), name);
protected ArangoDatabase(final Communication<Response, ConnectionSync> communication, final ArangoUtil util,
final DocumentCache documentCache, final CollectionCache collectionCache, final String name) {
super(null, new ArangoExecutorSync(communication, util, documentCache, collectionCache), name);
}

/**
Expand Down
8 changes: 3 additions & 5 deletions src/main/java/com/arangodb/internal/ArangoExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@
import com.arangodb.internal.velocystream.Communication;
import com.arangodb.internal.velocystream.Connection;
import com.arangodb.util.ArangoUtil;
import com.arangodb.velocypack.VPack;
import com.arangodb.velocypack.VPackParser;
import com.arangodb.velocypack.VPackSlice;
import com.arangodb.velocypack.exception.VPackException;
import com.arangodb.velocystream.Response;
Expand All @@ -56,13 +54,13 @@ public static interface ResponseDeserializer<T> {
private final CollectionCache collectionCache;
private final ArangoUtil util;

protected ArangoExecutor(final Communication<R, C> communication, final VPack vpacker, final VPack vpackerNull,
final VPackParser vpackParser, final DocumentCache documentCache, final CollectionCache collectionCache) {
protected ArangoExecutor(final Communication<R, C> communication, final ArangoUtil util,
final DocumentCache documentCache, final CollectionCache collectionCache) {
super();
this.communication = communication;
this.documentCache = documentCache;
this.collectionCache = collectionCache;
util = new ArangoUtil(vpacker, vpackerNull, vpackParser);
this.util = util;
}

public Communication<R, C> communication() {
Expand Down
10 changes: 4 additions & 6 deletions src/main/java/com/arangodb/internal/ArangoExecutorSync.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
import com.arangodb.ArangoDBException;
import com.arangodb.internal.velocystream.Communication;
import com.arangodb.internal.velocystream.ConnectionSync;
import com.arangodb.velocypack.VPack;
import com.arangodb.velocypack.VPackParser;
import com.arangodb.util.ArangoUtil;
import com.arangodb.velocypack.exception.VPackException;
import com.arangodb.velocystream.Request;
import com.arangodb.velocystream.Response;
Expand All @@ -37,10 +36,9 @@
*/
public class ArangoExecutorSync extends ArangoExecutor<Response, ConnectionSync> {

public ArangoExecutorSync(final Communication<Response, ConnectionSync> communication, final VPack vpacker,
final VPack vpackerNull, final VPackParser vpackParser, final DocumentCache documentCache,
final CollectionCache collectionCache) {
super(communication, vpacker, vpackerNull, vpackParser, documentCache, collectionCache);
public ArangoExecutorSync(final Communication<Response, ConnectionSync> communication, final ArangoUtil util,
final DocumentCache documentCache, final CollectionCache collectionCache) {
super(communication, util, documentCache, collectionCache);
}

public <T> T execute(final Request request, final Type type) throws ArangoDBException {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* DISCLAIMER
*
* Copyright 2016 ArangoDB GmbH, Cologne, Germany
*
* Licensed 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.
*
* Copyright holder is ArangoDB GmbH, Cologne, Germany
*/

package com.arangodb.internal.util;

import java.lang.reflect.Type;

import com.arangodb.ArangoDBException;
import com.arangodb.util.ArangoDeserializer;
import com.arangodb.velocypack.VPack;
import com.arangodb.velocypack.VPackParser;
import com.arangodb.velocypack.VPackSlice;
import com.arangodb.velocypack.exception.VPackException;

/**
* @author Mark - mark at arangodb.com
*
*/
public class ArangoDeserializerImpl implements ArangoDeserializer {

private final VPack vpacker;
private final VPackParser vpackParser;

public ArangoDeserializerImpl(final VPack vpacker, final VPackParser vpackParser) {
super();
this.vpacker = vpacker;
this.vpackParser = vpackParser;
}

@Override
@SuppressWarnings("unchecked")
public <T> T deserialize(final VPackSlice vpack, final Type type) throws ArangoDBException {
try {
final T doc;
if (type == String.class && !vpack.isString()) {
doc = (T) vpackParser.toJson(vpack);
} else {
doc = vpacker.deserialize(vpack, type);
}
return doc;
} catch (final VPackException e) {
throw new ArangoDBException(e);
}
}
}
118 changes: 118 additions & 0 deletions src/main/java/com/arangodb/internal/util/ArangoSerializerImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* DISCLAIMER
*
* Copyright 2016 ArangoDB GmbH, Cologne, Germany
*
* Licensed 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.
*
* Copyright holder is ArangoDB GmbH, Cologne, Germany
*/

package com.arangodb.internal.util;

import java.lang.reflect.Type;
import java.util.Iterator;
import java.util.Map;

import com.arangodb.ArangoDBException;
import com.arangodb.util.ArangoSerializer;
import com.arangodb.velocypack.VPack;
import com.arangodb.velocypack.VPackParser;
import com.arangodb.velocypack.VPackSlice;
import com.arangodb.velocypack.exception.VPackException;
import com.arangodb.velocypack.exception.VPackParserException;

/**
* @author Mark - mark at arangodb.com
*
*/
public class ArangoSerializerImpl implements ArangoSerializer {

private final VPack vpacker;
private final VPack vpackerNull;
private final VPackParser vpackParser;

public ArangoSerializerImpl(final VPack vpacker, final VPack vpackerNull, final VPackParser vpackParser) {
super();
this.vpacker = vpacker;
this.vpackerNull = vpackerNull;
this.vpackParser = vpackParser;
}

@Override
public VPackSlice serialize(final Object entity) throws ArangoDBException {
return serialize(entity, false);
}

@Override
public VPackSlice serialize(final Object entity, final boolean serializeNullValues) throws ArangoDBException {
return serialize(entity, serializeNullValues, false);
}

@Override
@SuppressWarnings("unchecked")
public VPackSlice serialize(final Object entity, final boolean serializeNullValues, final boolean stringAsJson)
throws ArangoDBException {
try {
final VPackSlice vpack;
final Class<? extends Object> type = entity.getClass();
if (String.class.isAssignableFrom(type)) {
vpack = vpackParser.fromJson((String) entity, serializeNullValues);
} else if (stringAsJson && Iterable.class.isAssignableFrom(type)) {
final Iterator<?> iterator = Iterable.class.cast(entity).iterator();
if (iterator.hasNext() && String.class.isAssignableFrom(iterator.next().getClass())) {
vpack = vpackParser.fromJson((Iterable<String>) entity, serializeNullValues);
} else {
final VPack vp = serializeNullValues ? vpackerNull : vpacker;
vpack = vp.serialize(entity);
}
} else {
final VPack vp = serializeNullValues ? vpackerNull : vpacker;
vpack = vp.serialize(entity);
}
return vpack;
} catch (final VPackException e) {
throw new ArangoDBException(e);
}
}

@Override
public VPackSlice serialize(final Object entity, final Type type) throws ArangoDBException {
try {
return vpacker.serialize(entity, type);
} catch (final VPackException e) {
throw new ArangoDBException(e);
}
}

@Override
public VPackSlice serialize(final Object entity, final Type type, final boolean serializeNullValues)
throws ArangoDBException {
try {
final VPack vp = serializeNullValues ? vpackerNull : vpacker;
return vp.serialize(entity, type);
} catch (final VPackException e) {
throw new ArangoDBException(e);
}
}

@Override
public VPackSlice serialize(final Object entity, final Type type, final Map<String, Object> additionalFields)
throws ArangoDBException {
try {
return vpacker.serialize(entity, type, additionalFields);
} catch (final VPackParserException e) {
throw new ArangoDBException(e);
}
}
}
Loading

0 comments on commit 969cc4b

Please sign in to comment.