Skip to content

Commit

Permalink
Mapping refactoring (#311)
Browse files Browse the repository at this point in the history
* added changes from #303

* added test changes from #303
  • Loading branch information
rashtao authored Jun 19, 2024
1 parent 6d4e94e commit 7b29bff
Show file tree
Hide file tree
Showing 35 changed files with 746 additions and 337 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
/**
* @author Mark Vollmary
* @author Christian Lechner
*
*/
public interface ArangoEntityReader extends EntityReader<Object, JsonNode> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ private void readProperty(
final String parentId,
final PersistentPropertyAccessor<?> accessor,
final JsonNode source,
final ArangoPersistentProperty property) {

final ArangoPersistentProperty property
) {
Object propertyValue = readPropertyValue(entity, parentId, source, property);
if (propertyValue != null || !property.getType().isPrimitive()) {
accessor.setProperty(property, propertyValue);
Expand All @@ -234,8 +234,8 @@ private Object readPropertyValue(
final ArangoPersistentEntity<?> entity,
final String parentId,
final JsonNode source,
final ArangoPersistentProperty property) {

final ArangoPersistentProperty property
) {
Optional<Ref> ref = property.getRef();
if (ref.isPresent()) {
return readReference(source, property, ref.get()).orElse(null);
Expand Down Expand Up @@ -329,8 +329,8 @@ private Object readArray(final TypeInformation<?> type, final JsonNode source) {
private Optional<Object> readReference(
final JsonNode source,
final ArangoPersistentProperty property,
final Annotation annotation) {

final Annotation annotation
) {
if (source.isMissingNode() || source.isNull()) {
return Optional.empty();
}
Expand Down Expand Up @@ -366,8 +366,8 @@ private <A extends Annotation> Optional<Object> readRelation(
final String parentId,
final JsonNode source,
final ArangoPersistentProperty property,
final A annotation) {

final A annotation
) {
if (source.isNull()) {
return Optional.empty();
}
Expand Down Expand Up @@ -505,8 +505,8 @@ private DBDocumentEntity readDBDocumentEntity(final JsonNode source) {

private ParameterValueProvider<ArangoPersistentProperty> getParameterProvider(
final ArangoPersistentEntity<?> entity,
final JsonNode source) {

final JsonNode source
) {
PropertyValueProvider<ArangoPersistentProperty> provider = new ArangoPropertyValueProvider(entity, source);
return new PersistentEntityParameterValueProvider<>(entity, provider, null);
}
Expand Down Expand Up @@ -781,7 +781,7 @@ private Optional<String> getRefId(final Object source, final ArangoPersistentEnt
.map(key -> {
if (annotation != null) {
return resolverFactory.getReferenceResolver(annotation)
.map(resolver -> resolver.write(source, entity, convertId(key), annotation))
.map(resolver -> resolver.write(source, entity, convertId(key)))
.orElseThrow(() -> new IllegalArgumentException("Missing reference resolver for " + annotation));
} else {
return MetadataUtils.createIdFromCollectionAndKey(entity.getCollection(), convertId(key));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
package com.arangodb.springframework.core.convert.resolver;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.function.Supplier;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
Expand All @@ -39,9 +39,8 @@
/**
* @author Mark Vollmary
* @author Christian Lechner
*
*/
public abstract class AbstractResolver<A extends Annotation> {
public abstract class AbstractResolver {

private static final Method GET_ENTITY_METHOD;
private static final Method GET_REF_ID_METHOD;
Expand All @@ -66,19 +65,11 @@ protected AbstractResolver(final ConversionService conversionService) {
this.objenesis = new ObjenesisStd(true);
}

public interface ResolverCallback<A extends Annotation> {

Object resolve(String id, TypeInformation<?> type, A annotation);

}

@SuppressWarnings({ "rawtypes", "unchecked" })
protected Object proxy(
final String id,
final TypeInformation<?> type,
final A annotation,
final ResolverCallback<A> callback) {
final ProxyInterceptor interceptor = new ProxyInterceptor(id, type, annotation, callback, conversionService);
final Supplier<Object> callback) {
final ProxyInterceptor interceptor = new ProxyInterceptor(id, type, callback, conversionService);
if (type.getType().isInterface()) {
final ProxyFactory proxyFactory = new ProxyFactory(new Class<?>[] { type.getType() });
for (final Class<?> interf : type.getType().getInterfaces()) {
Expand All @@ -102,24 +93,22 @@ private Class<?> enhancedTypeFor(final Class<?> type) {
return enhancer.createClass();
}

static class ProxyInterceptor<A extends Annotation> implements Serializable,
static class ProxyInterceptor implements Serializable,
org.springframework.cglib.proxy.MethodInterceptor, org.aopalliance.intercept.MethodInterceptor {

private static final long serialVersionUID = -6722757823918987065L;
private final String id;
final TypeInformation<?> type;
private final A annotation;
private final ResolverCallback<A> callback;
private final Supplier<Object> callback;
private volatile boolean resolved;
private Object result;
private final ConversionService conversionService;

public ProxyInterceptor(final String id, final TypeInformation<?> type, final A annotation,
final ResolverCallback<A> callback, final ConversionService conversionService) {
public ProxyInterceptor(final String id, final TypeInformation<?> type,
final Supplier<Object> callback, final ConversionService conversionService) {
super();
this.id = id;
this.type = type;
this.annotation = annotation;
this.callback = callback;
this.conversionService = conversionService;
result = null;
Expand Down Expand Up @@ -178,7 +167,7 @@ private Object ensureResolved() {

private synchronized Object resolve() {
if (!resolved) {
return convertIfNecessary(callback.resolve(id, type, annotation), type.getType());
return convertIfNecessary(callback.get(), type.getType());
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,49 +30,50 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

/**
* @author Mark Vollmary
* @author Christian Lechner
*
*/
public class DocumentFromResolver extends AbstractResolver<From> implements RelationResolver<From> {
public class DocumentFromResolver extends AbstractResolver implements RelationResolver<From> {

private final ArangoOperations template;
private final ArangoOperations template;

public DocumentFromResolver(final ArangoOperations template) {
super(template.getConverter().getConversionService());
this.template = template;
}
public DocumentFromResolver(final ArangoOperations template) {
super(template.getConverter().getConversionService());
this.template = template;
}

@Override
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final From annotation) {
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t))
: _resolveOne(id, type);
}
@Override
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes,
final From annotation) {
Supplier<Object> supplier = () -> _resolveOne(id, type);
return annotation.lazy() ? proxy(id, type, supplier) : supplier.get();
}

private Object _resolveOne(final String id, final TypeInformation<?> type) {
ArangoCursor<?> it = _resolve(id, type.getType(), true);
return it.hasNext() ? it.next() : null;
}
private Object _resolveOne(final String id, final TypeInformation<?> type) {
ArangoCursor<?> it = _resolve(id, type.getType(), true);
return it.hasNext() ? it.next() : null;
}

@Override
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final From annotation) {
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveMultiple(i, t))
: _resolveMultiple(id, type);
}
@Override
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes,
final From annotation) {
Supplier<Object> supplier = () -> _resolveMultiple(id, type);
return annotation.lazy() ? proxy(id, type, supplier) : supplier.get();
}

private Object _resolveMultiple(final String id, final TypeInformation<?> type) {
return _resolve(id, getNonNullComponentType(type).getType(), false).asListRemaining();
}
private Object _resolveMultiple(final String id, final TypeInformation<?> type) {
return _resolve(id, getNonNullComponentType(type).getType(), false).asListRemaining();
}

private ArangoCursor<?> _resolve(final String id, final Class<?> type, final boolean limit) {
final String query = String.format("FOR e IN @@edge FILTER e._from == @id %s RETURN e", limit ? "LIMIT 1" : "");
Map<String, Object> bindVars = new HashMap<>();
bindVars.put("@edge", type);
bindVars.put("id", id);
return template.query(query, bindVars, new AqlQueryOptions(),
type);
}
private ArangoCursor<?> _resolve(final String id, final Class<?> type, final boolean limit) {
final String query = String.format("FOR e IN @@edge FILTER e._from == @id %s RETURN e", limit ? "LIMIT 1" : "");
Map<String, Object> bindVars = new HashMap<>();
bindVars.put("@edge", type);
bindVars.put("id", id);
return template.query(query, bindVars, new AqlQueryOptions(), type);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,47 +30,50 @@
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

/**
* @author Mark Vollmary
* @author Christian Lechner
*
*/
public class DocumentToResolver extends AbstractResolver<To> implements RelationResolver<To> {
public class DocumentToResolver extends AbstractResolver implements RelationResolver<To> {

private final ArangoOperations template;
private final ArangoOperations template;

public DocumentToResolver(final ArangoOperations template) {
super(template.getConverter().getConversionService());
this.template = template;
}
public DocumentToResolver(final ArangoOperations template) {
super(template.getConverter().getConversionService());
this.template = template;
}

@Override
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final To annotation) {
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t)) : _resolveOne(id, type);
}
@Override
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes,
final To annotation) {
Supplier<Object> supplier = () -> _resolveOne(id, type);
return annotation.lazy() ? proxy(id, type, supplier) : supplier.get();
}

private Object _resolveOne(final String id, final TypeInformation<?> type) {
ArangoCursor<?> it = _resolve(id, type.getType(), true);
return it.hasNext() ? it.next() : null;
}
private Object _resolveOne(final String id, final TypeInformation<?> type) {
ArangoCursor<?> it = _resolve(id, type.getType(), true);
return it.hasNext() ? it.next() : null;
}

@Override
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final To annotation) {
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveMultiple(i, t))
: _resolveMultiple(id, type);
}
@Override
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes,
final To annotation) {
Supplier<Object> supplier = () -> _resolveMultiple(id, type);
return annotation.lazy() ? proxy(id, type, supplier) : supplier.get();
}

private Object _resolveMultiple(final String id, final TypeInformation<?> type) {
return _resolve(id, getNonNullComponentType(type).getType(), false).asListRemaining();
}
private Object _resolveMultiple(final String id, final TypeInformation<?> type) {
return _resolve(id, getNonNullComponentType(type).getType(), false).asListRemaining();
}

private ArangoCursor<?> _resolve(final String id, final Class<?> type, final boolean limit) {
final String query = String.format("FOR e IN @@edge FILTER e._to == @id %s RETURN e", limit ? "LIMIT 1" : "");
Map<String, Object> bindVars = new HashMap<>();
bindVars.put("@edge", type);
bindVars.put("id", id);
return template.query(query, bindVars, new AqlQueryOptions(), type);
}
private ArangoCursor<?> _resolve(final String id, final Class<?> type, final boolean limit) {
final String query = String.format("FOR e IN @@edge FILTER e._to == @id %s RETURN e", limit ? "LIMIT 1" : "");
Map<String, Object> bindVars = new HashMap<>();
bindVars.put("@edge", type);
bindVars.put("id", id);
return template.query(query, bindVars, new AqlQueryOptions(), type);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
import com.arangodb.springframework.core.ArangoOperations;

import java.util.Collection;
import java.util.function.Supplier;

/**
* @author Mark Vollmary
*
*/
public class EdgeFromResolver extends AbstractResolver<From> implements RelationResolver<From> {
public class EdgeFromResolver extends AbstractResolver implements RelationResolver<From> {

private final ArangoOperations template;

Expand All @@ -41,8 +41,10 @@ public EdgeFromResolver(final ArangoOperations template) {
}

@Override
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final From annotation) {
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t)) : _resolveOne(id, type);
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes,
final From annotation) {
Supplier<Object> supplier = () -> _resolveOne(id, type);
return annotation.lazy() ? proxy(id, type, supplier) : supplier.get();
}

private Object _resolveOne(final String id, final TypeInformation<?> type) {
Expand All @@ -51,7 +53,8 @@ private Object _resolveOne(final String id, final TypeInformation<?> type) {
}

@Override
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final From annotation) {
public Object resolveMultiple(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes,
final From annotation) {
throw new UnsupportedOperationException("Edges with multiple 'from' values are not supported.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
import com.arangodb.springframework.core.ArangoOperations;

import java.util.Collection;
import java.util.function.Supplier;

/**
* @author Mark Vollmary
*
*/
public class EdgeToResolver extends AbstractResolver<To> implements RelationResolver<To> {
public class EdgeToResolver extends AbstractResolver implements RelationResolver<To> {

private final ArangoOperations template;

Expand All @@ -41,8 +41,10 @@ public EdgeToResolver(final ArangoOperations template) {
}

@Override
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes, final To annotation) {
return annotation.lazy() ? proxy(id, type, annotation, (i, t, a) -> _resolveOne(i, t)) : _resolveOne(id, type);
public Object resolveOne(final String id, final TypeInformation<?> type, Collection<TypeInformation<?>> traversedTypes,
final To annotation) {
Supplier<Object> supplier = () -> _resolveOne(id, type);
return annotation.lazy() ? proxy(id, type, supplier) : supplier.get();
}

private Object _resolveOne(final String id, final TypeInformation<?> type) {
Expand Down
Loading

0 comments on commit 7b29bff

Please sign in to comment.