refactoring fieldaccessors to be used independently
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Configurable;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author Michael Hunger
|
||||
* @since 12.09.2010
|
||||
*/
|
||||
@Configurable
|
||||
public class ConvertingNodePropertyFieldAccessor extends NodePropertyFieldAccessor {
|
||||
|
||||
private final ConversionService conversionService;
|
||||
|
||||
public ConvertingNodePropertyFieldAccessor(final Field field, final ConversionService conversionService) {
|
||||
super(field);
|
||||
this.conversionService = conversionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setValue(final NodeBacked nodeBacked, final Object newVal) {
|
||||
super.setValue(nodeBacked,serializePropertyValue(newVal));
|
||||
return newVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(final NodeBacked nodeBacked) {
|
||||
return deserializePropertyValue(super.getValue(nodeBacked));
|
||||
}
|
||||
|
||||
private Object serializePropertyValue(final Object newVal) {
|
||||
return conversionService.convert(newVal, String.class);
|
||||
}
|
||||
|
||||
private Object deserializePropertyValue(final Object value) {
|
||||
return conversionService.convert(value, field.getType());
|
||||
}
|
||||
|
||||
public static FieldAccessorFactory<NodeBacked> factory() {
|
||||
return new FieldAccessorFactory<NodeBacked>() {
|
||||
@Autowired
|
||||
ConversionService conversionService;
|
||||
|
||||
@Override
|
||||
public boolean accept(final Field field) {
|
||||
return isSerializableField(field) && isDeserializableField(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldAccessor<NodeBacked,?> forField(final Field field) {
|
||||
return new ConvertingNodePropertyFieldAccessor(field,conversionService);
|
||||
}
|
||||
|
||||
private boolean isSerializableField(final Field field) {
|
||||
return !DelegatingFieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(field.getType(), String.class);
|
||||
}
|
||||
|
||||
private boolean isDeserializableField(final Field field) {
|
||||
return !DelegatingFieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(String.class, field.getType());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.DynamicRelationshipType;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.springframework.datastore.graph.api.*;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
|
||||
public class DelegatingFieldAccessorFactory<T> implements FieldAccessorFactory<T> {
|
||||
private final EntityInstantiator<NodeBacked, Node> graphEntityInstantiator;
|
||||
private final EntityInstantiator<RelationshipBacked, Relationship> relationshipEntityInstantiator;
|
||||
|
||||
public DelegatingFieldAccessorFactory(EntityInstantiator<NodeBacked,Node> graphEntityInstantiator, EntityInstantiator<RelationshipBacked, Relationship> relationshipEntityInstantiator) {
|
||||
this.graphEntityInstantiator = graphEntityInstantiator;
|
||||
this.relationshipEntityInstantiator = relationshipEntityInstantiator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accept(Field f) {
|
||||
return isSingleRelationshipField(f) || isOneToNRelationshipEntityField(f) || isReadOnlyOneToNRelationshipField(f) || isOneToNRelationshipField(f);
|
||||
}
|
||||
|
||||
final Collection<FieldAccessorFactory<?>> fieldAccessorFactories = Arrays.<FieldAccessorFactory<?>>asList(
|
||||
NodePropertyFieldAccessor.factory(),
|
||||
ConvertingNodePropertyFieldAccessor.factory(),
|
||||
SingleRelationshipFieldAccessor.factory(),
|
||||
OneToNRelationshipFieldAccessor.factory(),
|
||||
ReadOnlyOneToNRelationshipFieldAccessor.factory(),
|
||||
OneToNRelationshipEntityFieldAccessor.factory()
|
||||
);
|
||||
final Collection<FieldAccessorListenerFactory<?>> fieldAccessorListenerFactories = Arrays.<FieldAccessorListenerFactory<?>>asList(
|
||||
IndexingNodePropertyFieldAccessorListener.factory()
|
||||
);
|
||||
|
||||
public FieldAccessor forField(Field field) {
|
||||
if (Modifier.isTransient(field.getModifiers())) return null;
|
||||
GraphEntityRelationship relAnnotation = field.getAnnotation(GraphEntityRelationship.class);
|
||||
if (isSingleRelationshipField(field)) {
|
||||
if (relAnnotation != null) {
|
||||
return new SingleRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(field), graphEntityInstantiator);
|
||||
}
|
||||
return new SingleRelationshipFieldAccessor(typeFrom(field), Direction.OUTGOING, targetFrom(field), graphEntityInstantiator);
|
||||
}
|
||||
if (isOneToNRelationshipField(field)) {
|
||||
return new OneToNRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphEntityInstantiator);
|
||||
}
|
||||
if (isReadOnlyOneToNRelationshipField(field)) {
|
||||
return new ReadOnlyOneToNRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphEntityInstantiator);
|
||||
}
|
||||
if (isOneToNRelationshipEntityField(field)) {
|
||||
GraphEntityRelationshipEntity relEntityAnnotation = field.getAnnotation(GraphEntityRelationshipEntity.class);
|
||||
return new OneToNRelationshipEntityFieldAccessor(typeFrom(relEntityAnnotation), dirFrom(relEntityAnnotation), targetFrom(relEntityAnnotation), relationshipEntityInstantiator);
|
||||
}
|
||||
throw new IllegalArgumentException("Not a Neo4j relationship field: " + field);
|
||||
}
|
||||
|
||||
|
||||
private Class<? extends NodeBacked> targetFrom(Field field) {
|
||||
return (Class<? extends NodeBacked>) field.getType();
|
||||
}
|
||||
|
||||
private Class<? extends NodeBacked> targetFrom(GraphEntityRelationship relAnnotation) {
|
||||
return relAnnotation.elementClass();
|
||||
}
|
||||
|
||||
private Direction dirFrom(GraphEntityRelationship relAnnotation) {
|
||||
return relAnnotation.direction().toNeo4jDir();
|
||||
}
|
||||
|
||||
private DynamicRelationshipType typeFrom(Field field) {
|
||||
return DynamicRelationshipType.withName(getNeo4jPropertyName(field));
|
||||
}
|
||||
|
||||
private Class<? extends RelationshipBacked> targetFrom(GraphEntityRelationshipEntity relEntityAnnotation) {
|
||||
return relEntityAnnotation.elementClass();
|
||||
}
|
||||
|
||||
private Direction dirFrom(GraphEntityRelationshipEntity relEntityAnnotation) {
|
||||
return relEntityAnnotation.direction().toNeo4jDir();
|
||||
}
|
||||
private DynamicRelationshipType typeFrom(GraphEntityRelationshipEntity relEntityAnnotation) {
|
||||
return DynamicRelationshipType.withName(relEntityAnnotation.type());
|
||||
}
|
||||
|
||||
private DynamicRelationshipType typeFrom(GraphEntityRelationship relAnnotation) {
|
||||
return DynamicRelationshipType.withName(relAnnotation.type());
|
||||
}
|
||||
|
||||
public static boolean isRelationshipField(Field f) {
|
||||
return isSingleRelationshipField(f)
|
||||
|| isOneToNRelationshipField(f)
|
||||
|| isOneToNRelationshipEntityField(f)
|
||||
|| isReadOnlyOneToNRelationshipField(f);
|
||||
}
|
||||
|
||||
private static boolean isSingleRelationshipField(Field f) {
|
||||
return NodeBacked.class.isAssignableFrom(f.getType());
|
||||
}
|
||||
|
||||
private static boolean isOneToNRelationshipField(Field f) {
|
||||
if (!Collection.class.isAssignableFrom(f.getType())) return false;
|
||||
GraphEntityRelationship relAnnotation = f.getAnnotation(GraphEntityRelationship.class);
|
||||
return relAnnotation != null && NodeBacked.class.isAssignableFrom(relAnnotation.elementClass()) && !relAnnotation.elementClass().equals(NodeBacked.class);
|
||||
}
|
||||
|
||||
private static boolean isReadOnlyOneToNRelationshipField(Field f) {
|
||||
GraphEntityRelationship relAnnotation = f.getAnnotation(GraphEntityRelationship.class);
|
||||
return Iterable.class.equals(f.getType())
|
||||
&& relAnnotation != null
|
||||
&& !NodeBacked.class.equals(relAnnotation.elementClass());
|
||||
}
|
||||
|
||||
private static boolean isOneToNRelationshipEntityField(Field f) {
|
||||
GraphEntityRelationshipEntity relEntityAnnotation = f.getAnnotation(GraphEntityRelationshipEntity.class);
|
||||
return Iterable.class.isAssignableFrom(f.getType())
|
||||
&& relEntityAnnotation != null
|
||||
&& !RelationshipBacked.class.equals(relEntityAnnotation.elementClass());
|
||||
}
|
||||
|
||||
public static String getNeo4jPropertyName(Field field) {
|
||||
final Class<?> entityClass = field.getDeclaringClass();
|
||||
if (useShortNames(entityClass)) return field.getName();
|
||||
return String.format("%s.%s", entityClass.getSimpleName(), field.getName());
|
||||
}
|
||||
|
||||
private static boolean useShortNames(Class<?> entityClass) {
|
||||
final GraphEntity graphEntity = entityClass.getAnnotation(GraphEntity.class);
|
||||
if (graphEntity!=null) return graphEntity.useShortNames();
|
||||
final GraphRelationship graphRelationship = entityClass.getAnnotation(GraphRelationship.class);
|
||||
if (graphRelationship!=null) return graphRelationship.useShortNames();
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<FieldAccessor<T, ?>> listenersFor(Field field) {
|
||||
List<FieldAccessor<T,?>> result=new ArrayList<FieldAccessor<T,?>>();
|
||||
for (FieldAccessorListenerFactory<?> fieldAccessorListenerFactory : fieldAccessorListenerFactories) {
|
||||
if (fieldAccessorListenerFactory.accept(field)) {
|
||||
final FieldAccessor<T, ?> listener = (FieldAccessor<T, ?>) fieldAccessorListenerFactory.forField(field);
|
||||
result.add(listener);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
import org.springframework.datastore.graph.api.RelationshipBacked;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Michael Hunger
|
||||
* @since 12.09.2010
|
||||
*/
|
||||
public class EntityStateAccessors<ENTITY, STATE> {
|
||||
private final STATE underlyingState;
|
||||
private final ENTITY entity;
|
||||
private final Class<? extends ENTITY> type;
|
||||
private final Map<Field,FieldAccessor<ENTITY,?>> fieldAccessors=new HashMap<Field, FieldAccessor<ENTITY,?>>();
|
||||
private final Map<Field,List<FieldAccessListener<ENTITY,?>>> fieldAccessorListeners=new HashMap<Field, List<FieldAccessListener<ENTITY,?>>>();
|
||||
|
||||
public EntityStateAccessors(final STATE underlyingState, final ENTITY entity, final Class<? extends ENTITY> type, final EntityInstantiator<NodeBacked, Node> nodeInstantiator, final EntityInstantiator<RelationshipBacked, Relationship> relationshipInstantiator) {
|
||||
this.underlyingState = underlyingState;
|
||||
this.entity = entity;
|
||||
this.type = type;
|
||||
createAccessorsAndListeners(type, nodeInstantiator, relationshipInstantiator);
|
||||
}
|
||||
|
||||
private void createAccessorsAndListeners(final Class<? extends ENTITY> type, final EntityInstantiator<NodeBacked, Node> nodeInstantiator, final EntityInstantiator<RelationshipBacked, Relationship> relationshipInstantiator) {
|
||||
final DelegatingFieldAccessorFactory fieldAccessorFactory = new DelegatingFieldAccessorFactory(nodeInstantiator,relationshipInstantiator);
|
||||
ReflectionUtils.doWithFields(type, new ReflectionUtils.FieldCallback() {
|
||||
public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException {
|
||||
fieldAccessors.put(field, fieldAccessorFactory.forField(field));
|
||||
fieldAccessorListeners.put(field, fieldAccessorFactory.listenersFor(field)); // TODO Bad code
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public Object getValue(final Field field) {
|
||||
return fieldAccessors.get(field).getValue(entity);
|
||||
}
|
||||
public Object setValue(final Field field, final Object newVal) {
|
||||
final Object result = fieldAccessors.get(field).setValue(entity, newVal);
|
||||
notifyListeners(field, result); // async ?
|
||||
return result;
|
||||
}
|
||||
|
||||
private void notifyListeners(Field field, Object result) {
|
||||
if (fieldAccessorListeners.containsKey(field)) {
|
||||
for (final FieldAccessListener<ENTITY, ?> listener : fieldAccessorListeners.get(field)) {
|
||||
listener.valueChanged(entity,null,result); // todo oldValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
public interface FieldAccessListener<ENTITY, TARGET> {
|
||||
|
||||
void valueChanged(ENTITY entity, Object oldVal, Object newVal);
|
||||
|
||||
}
|
||||
@@ -1,121 +1,12 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.DynamicRelationshipType;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.springframework.datastore.graph.api.*;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
|
||||
public class FieldAccessorFactory {
|
||||
private final EntityInstantiator<NodeBacked, Node> graphEntityInstantiator;
|
||||
private final EntityInstantiator<RelationshipBacked, Relationship> relationshipEntityInstantiator;
|
||||
|
||||
public FieldAccessorFactory(EntityInstantiator<NodeBacked,Node> graphEntityInstantiator, EntityInstantiator<RelationshipBacked, Relationship> relationshipEntityInstantiator) {
|
||||
this.graphEntityInstantiator = graphEntityInstantiator;
|
||||
this.relationshipEntityInstantiator = relationshipEntityInstantiator;
|
||||
}
|
||||
|
||||
public FieldAccessor forField(Field field) {
|
||||
if (Modifier.isTransient(field.getModifiers())) return null;
|
||||
GraphEntityRelationship relAnnotation = field.getAnnotation(GraphEntityRelationship.class);
|
||||
if (isSingleRelationshipField(field)) {
|
||||
if (relAnnotation != null) {
|
||||
return new SingleRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(field), graphEntityInstantiator);
|
||||
}
|
||||
return new SingleRelationshipFieldAccessor(typeFrom(field), Direction.OUTGOING, targetFrom(field), graphEntityInstantiator);
|
||||
}
|
||||
if (isOneToNRelationshipField(field)) {
|
||||
return new OneToNRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphEntityInstantiator);
|
||||
}
|
||||
if (isReadOnlyOneToNRelationshipField(field)) {
|
||||
return new ReadOnlyOneToNRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphEntityInstantiator);
|
||||
}
|
||||
if (isOneToNRelationshipEntityField(field)) {
|
||||
GraphEntityRelationshipEntity relEntityAnnotation = field.getAnnotation(GraphEntityRelationshipEntity.class);
|
||||
return new OneToNRelationshipEntityFieldAccessor(typeFrom(relEntityAnnotation), dirFrom(relEntityAnnotation), targetFrom(relEntityAnnotation), relationshipEntityInstantiator);
|
||||
}
|
||||
throw new IllegalArgumentException("Not a Neo4j relationship field: " + field);
|
||||
}
|
||||
|
||||
private Class<? extends RelationshipBacked> targetFrom(GraphEntityRelationshipEntity relEntityAnnotation) {
|
||||
return relEntityAnnotation.elementClass();
|
||||
}
|
||||
|
||||
private Direction dirFrom(GraphEntityRelationshipEntity relEntityAnnotation) {
|
||||
return relEntityAnnotation.direction().toNeo4jDir();
|
||||
}
|
||||
|
||||
private Class<? extends NodeBacked> targetFrom(Field field) {
|
||||
return (Class<? extends NodeBacked>) field.getType();
|
||||
}
|
||||
|
||||
private Class<? extends NodeBacked> targetFrom(GraphEntityRelationship relAnnotation) {
|
||||
return relAnnotation.elementClass();
|
||||
}
|
||||
|
||||
private Direction dirFrom(GraphEntityRelationship relAnnotation) {
|
||||
return relAnnotation.direction().toNeo4jDir();
|
||||
}
|
||||
|
||||
private DynamicRelationshipType typeFrom(Field field) {
|
||||
return DynamicRelationshipType.withName(getNeo4jPropertyName(field));
|
||||
}
|
||||
|
||||
private DynamicRelationshipType typeFrom(GraphEntityRelationshipEntity relEntityAnnotation) {
|
||||
return DynamicRelationshipType.withName(relEntityAnnotation.type());
|
||||
}
|
||||
|
||||
private DynamicRelationshipType typeFrom(GraphEntityRelationship relAnnotation) {
|
||||
return DynamicRelationshipType.withName(relAnnotation.type());
|
||||
}
|
||||
|
||||
public static boolean isRelationshipField(Field f) {
|
||||
return isSingleRelationshipField(f)
|
||||
|| isOneToNRelationshipField(f)
|
||||
|| isOneToNRelationshipEntityField(f)
|
||||
|| isReadOnlyOneToNRelationshipField(f);
|
||||
}
|
||||
|
||||
private static boolean isSingleRelationshipField(Field f) {
|
||||
return NodeBacked.class.isAssignableFrom(f.getType());
|
||||
}
|
||||
|
||||
private static boolean isOneToNRelationshipField(Field f) {
|
||||
if (!Collection.class.isAssignableFrom(f.getType())) return false;
|
||||
GraphEntityRelationship relAnnotation = f.getAnnotation(GraphEntityRelationship.class);
|
||||
return relAnnotation != null && NodeBacked.class.isAssignableFrom(relAnnotation.elementClass()) && !relAnnotation.elementClass().equals(NodeBacked.class);
|
||||
}
|
||||
|
||||
private static boolean isReadOnlyOneToNRelationshipField(Field f) {
|
||||
GraphEntityRelationship relAnnotation = f.getAnnotation(GraphEntityRelationship.class);
|
||||
return Iterable.class.equals(f.getType())
|
||||
&& relAnnotation != null
|
||||
&& !NodeBacked.class.equals(relAnnotation.elementClass());
|
||||
}
|
||||
|
||||
private static boolean isOneToNRelationshipEntityField(Field f) {
|
||||
GraphEntityRelationshipEntity relEntityAnnotation = f.getAnnotation(GraphEntityRelationshipEntity.class);
|
||||
return Iterable.class.isAssignableFrom(f.getType())
|
||||
&& relEntityAnnotation != null
|
||||
&& !RelationshipBacked.class.equals(relEntityAnnotation.elementClass());
|
||||
}
|
||||
|
||||
public static String getNeo4jPropertyName(Field field) {
|
||||
final Class<?> entityClass = field.getDeclaringClass();
|
||||
if (useShortNames(entityClass)) return field.getName();
|
||||
return String.format("%s.%s", entityClass.getSimpleName(), field.getName());
|
||||
}
|
||||
|
||||
private static boolean useShortNames(Class<?> entityClass) {
|
||||
final GraphEntity graphEntity = entityClass.getAnnotation(GraphEntity.class);
|
||||
if (graphEntity!=null) return graphEntity.useShortNames();
|
||||
final GraphRelationship graphRelationship = entityClass.getAnnotation(GraphRelationship.class);
|
||||
if (graphRelationship!=null) return graphRelationship.useShortNames();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @author Michael Hunger
|
||||
* @since 12.09.2010
|
||||
*/
|
||||
interface FieldAccessorFactory<E> {
|
||||
boolean accept(Field f);
|
||||
FieldAccessor<E,?> forField(Field f);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author Michael Hunger
|
||||
* @since 12.09.2010
|
||||
*/
|
||||
interface FieldAccessorListenerFactory<E> {
|
||||
boolean accept(Field f);
|
||||
|
||||
FieldAccessListener<E, ?> forField(Field f);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import org.neo4j.index.IndexService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author Michael Hunger
|
||||
* @since 12.09.2010
|
||||
*/
|
||||
public class IndexingNodePropertyFieldAccessorListener implements FieldAccessListener<NodeBacked, Object> {
|
||||
protected final Field field;
|
||||
private final IndexService indexService;
|
||||
|
||||
public IndexingNodePropertyFieldAccessorListener(final Field field, final IndexService indexService) {
|
||||
this.field = field;
|
||||
this.indexService = indexService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(final NodeBacked nodeBacked, final Object oldVal, final Object newVal) {
|
||||
if (newVal==null) indexService.removeIndex(nodeBacked.getUnderlyingNode(),getPropertyName());
|
||||
else indexService.index(nodeBacked.getUnderlyingNode(), getPropertyName(),newVal);
|
||||
}
|
||||
|
||||
// todo
|
||||
private String getPropertyName() {
|
||||
return DelegatingFieldAccessorFactory.getNeo4jPropertyName(field);
|
||||
}
|
||||
|
||||
public static FieldAccessorListenerFactory<NodeBacked> factory() {
|
||||
return new FieldAccessorListenerFactory<NodeBacked>() {
|
||||
@Autowired
|
||||
IndexService indexService;
|
||||
|
||||
@Override
|
||||
public boolean accept(final Field f) {
|
||||
return NodePropertyFieldAccessor.factory().accept(f) || ConvertingNodePropertyFieldAccessor.factory().accept(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldAccessListener<NodeBacked,?> forField(final Field field) {
|
||||
return new IndexingNodePropertyFieldAccessorListener(field,indexService);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author Michael Hunger
|
||||
* @since 12.09.2010
|
||||
*/
|
||||
public class NodePropertyFieldAccessor implements FieldAccessor<NodeBacked, Object> {
|
||||
protected final Field field;
|
||||
|
||||
public NodePropertyFieldAccessor(final Field field) {
|
||||
this.field = field;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object setValue(final NodeBacked nodeBacked, final Object newVal) {
|
||||
nodeBacked.getUnderlyingNode().setProperty(getPropertyName(),newVal);
|
||||
return newVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(final NodeBacked nodeBacked) {
|
||||
return nodeBacked.getUnderlyingNode().getProperty(getPropertyName());
|
||||
}
|
||||
|
||||
private String getPropertyName() {
|
||||
return DelegatingFieldAccessorFactory.getNeo4jPropertyName(field);
|
||||
}
|
||||
|
||||
public static FieldAccessorFactory<NodeBacked> factory() {
|
||||
return new FieldAccessorFactory<NodeBacked>() {
|
||||
@Override
|
||||
public boolean accept(final Field f) {
|
||||
return isNeo4jPropertyType(f.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldAccessor<NodeBacked,?> forField(final Field field) {
|
||||
return new NodePropertyFieldAccessor(field);
|
||||
}
|
||||
|
||||
private boolean isNeo4jPropertyType(final Class<?> fieldType) {
|
||||
// todo: add array support
|
||||
return fieldType.isPrimitive()
|
||||
|| (fieldType.isArray() && !fieldType.getComponentType().isArray() && isNeo4jPropertyType(fieldType.getComponentType()))
|
||||
|| fieldType.equals(String.class)
|
||||
|| fieldType.equals(Character.class)
|
||||
|| fieldType.equals(Boolean.class)
|
||||
|| (fieldType.getName().startsWith("java.lang") && Number.class.isAssignableFrom(fieldType));
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,34 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.neo4j.graphdb.RelationshipType;
|
||||
import org.neo4j.graphdb.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.datastore.graph.api.GraphEntityRelationshipEntity;
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
import org.springframework.datastore.graph.api.RelationshipBacked;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
|
||||
public class OneToNRelationshipEntityFieldAccessor extends AbstractRelationshipFieldAccessor<NodeBacked, Node, RelationshipBacked,Relationship> {
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public OneToNRelationshipEntityFieldAccessor(final RelationshipType type, final Direction direction, final Class<? extends RelationshipBacked> elementClass, final EntityInstantiator<RelationshipBacked, Relationship> relationshipEntityInstantiator) {
|
||||
super(elementClass,relationshipEntityInstantiator,direction,type);
|
||||
}
|
||||
public class OneToNRelationshipEntityFieldAccessor extends AbstractRelationshipFieldAccessor<NodeBacked, Node, RelationshipBacked, Relationship> {
|
||||
|
||||
@Override
|
||||
public Object setValue(final NodeBacked entity, final Object newVal) {
|
||||
throw new InvalidDataAccessApiUsageException("Cannot set read-only relationship entity field.");
|
||||
}
|
||||
public OneToNRelationshipEntityFieldAccessor(final RelationshipType type, final Direction direction, final Class<? extends RelationshipBacked> elementClass, final EntityInstantiator<RelationshipBacked, Relationship> relationshipEntityInstantiator) {
|
||||
super(elementClass, relationshipEntityInstantiator, direction, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(final NodeBacked entity) {
|
||||
@Override
|
||||
public Object setValue(final NodeBacked entity, final Object newVal) {
|
||||
throw new InvalidDataAccessApiUsageException("Cannot set read-only relationship entity field.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(final NodeBacked entity) {
|
||||
checkUnderlyingNode(entity);
|
||||
final Set<RelationshipBacked> result = createEntitySetFromRelationships(entity);
|
||||
return new ManagedFieldAccessorSet<NodeBacked, RelationshipBacked>(entity, result, this);
|
||||
}
|
||||
return new ManagedFieldAccessorSet<NodeBacked, RelationshipBacked>(entity, result, this);
|
||||
}
|
||||
|
||||
private Set<RelationshipBacked> createEntitySetFromRelationships(final NodeBacked entity) {
|
||||
final Set<RelationshipBacked> result = new HashSet<RelationshipBacked>();
|
||||
@@ -39,17 +39,59 @@ public class OneToNRelationshipEntityFieldAccessor extends AbstractRelationshipF
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<Relationship> getStatesFromEntity(NodeBacked entity) {
|
||||
protected Iterable<Relationship> getStatesFromEntity(final NodeBacked entity) {
|
||||
return entity.getUnderlyingNode().getRelationships(type, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Relationship obtainSingleRelationship(Node start, Relationship end) {
|
||||
protected Relationship obtainSingleRelationship(final Node start, final Relationship end) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node getState(NodeBacked nodeBacked) {
|
||||
protected Node getState(final NodeBacked nodeBacked) {
|
||||
return nodeBacked.getUnderlyingNode();
|
||||
}
|
||||
|
||||
public static FieldAccessorFactory<NodeBacked> factory() {
|
||||
return new RelationshipEntityFieldAccessorFactory();
|
||||
}
|
||||
|
||||
|
||||
private static class RelationshipEntityFieldAccessorFactory implements FieldAccessorFactory<NodeBacked> {
|
||||
@Autowired
|
||||
private EntityInstantiator<RelationshipBacked, Relationship> relationshipEntityInstantiator;
|
||||
|
||||
@Override
|
||||
public boolean accept(final Field f) {
|
||||
return Iterable.class.isAssignableFrom(f.getType()) && hasValidRelationshipAnnotation(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldAccessor<NodeBacked, ?> forField(final Field field) {
|
||||
final GraphEntityRelationshipEntity relEntityAnnotation = getRelationshipAnnotation(field);
|
||||
return new OneToNRelationshipEntityFieldAccessor(typeFrom(relEntityAnnotation), dirFrom(relEntityAnnotation), targetFrom(relEntityAnnotation), relationshipEntityInstantiator);
|
||||
}
|
||||
|
||||
private boolean hasValidRelationshipAnnotation(final Field f) {
|
||||
final GraphEntityRelationshipEntity relEntityAnnotation = getRelationshipAnnotation(f);
|
||||
return relEntityAnnotation != null && !RelationshipBacked.class.equals(relEntityAnnotation.elementClass());
|
||||
}
|
||||
|
||||
private GraphEntityRelationshipEntity getRelationshipAnnotation(final Field field) {
|
||||
return field.getAnnotation(GraphEntityRelationshipEntity.class);
|
||||
}
|
||||
|
||||
private Class<? extends RelationshipBacked> targetFrom(final GraphEntityRelationshipEntity relEntityAnnotation) {
|
||||
return relEntityAnnotation.elementClass();
|
||||
}
|
||||
|
||||
private Direction dirFrom(final GraphEntityRelationshipEntity relEntityAnnotation) {
|
||||
return relEntityAnnotation.direction().toNeo4jDir();
|
||||
}
|
||||
|
||||
private DynamicRelationshipType typeFrom(final GraphEntityRelationshipEntity relEntityAnnotation) {
|
||||
return DynamicRelationshipType.withName(relEntityAnnotation.type());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,58 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.RelationshipType;
|
||||
import org.springframework.datastore.graph.api.GraphEntityRelationship;
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
public class OneToNRelationshipFieldAccessor extends NodeToNodesRelationshipFieldAccessor<NodeBacked> {
|
||||
|
||||
public OneToNRelationshipFieldAccessor(final RelationshipType type, final Direction direction, final Class<? extends NodeBacked> elementClass, final EntityInstantiator<NodeBacked, Node> graphEntityInstantiator) {
|
||||
public OneToNRelationshipFieldAccessor(final RelationshipType type, final Direction direction, final Class<? extends NodeBacked> elementClass, final EntityInstantiator<NodeBacked, Node> graphEntityInstantiator) {
|
||||
super(elementClass, graphEntityInstantiator, direction, type);
|
||||
}
|
||||
}
|
||||
|
||||
public Object setValue(final NodeBacked entity, final Object newVal) {
|
||||
public Object setValue(final NodeBacked entity, final Object newVal) {
|
||||
final Node node = checkUnderlyingNode(entity);
|
||||
if (newVal==null) {
|
||||
if (newVal == null) {
|
||||
removeMissingRelationships(node, Collections.<Node>emptySet());
|
||||
return null;
|
||||
}
|
||||
final Set<Node> targetNodes = checkTargetIsSetOfNodebacked(newVal);
|
||||
checkNoCircularReference(node,targetNodes);
|
||||
checkNoCircularReference(node, targetNodes);
|
||||
removeMissingRelationships(node, targetNodes);
|
||||
createAddedRelationships(node,targetNodes);
|
||||
return createManagedSet(entity, (Set<NodeBacked>)newVal);
|
||||
}
|
||||
createAddedRelationships(node, targetNodes);
|
||||
return createManagedSet(entity, (Set<NodeBacked>) newVal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(final NodeBacked entity) {
|
||||
public Object getValue(final NodeBacked entity) {
|
||||
checkUnderlyingNode(entity);
|
||||
final Set<NodeBacked> result = createEntitySetFromRelationshipEndNodes(entity);
|
||||
return createManagedSet(entity, result);
|
||||
}
|
||||
return createManagedSet(entity, result);
|
||||
}
|
||||
|
||||
public static FieldAccessorFactory<NodeBacked> factory() {
|
||||
return new RelationshipFieldAccessorFactory() {
|
||||
@Override
|
||||
public boolean accept(final Field f) {
|
||||
return Collection.class.isAssignableFrom(f.getType()) && hasValidRelationshipAnnotation(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldAccessor<NodeBacked, ?> forField(final Field field) {
|
||||
final GraphEntityRelationship relAnnotation = getRelationshipAnnotation(field);
|
||||
return new OneToNRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphEntityInstantiator);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,39 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.Relationship;
|
||||
import org.neo4j.graphdb.RelationshipType;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.datastore.graph.api.GraphEntityRelationship;
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
|
||||
public class ReadOnlyOneToNRelationshipFieldAccessor extends OneToNRelationshipFieldAccessor {
|
||||
|
||||
public ReadOnlyOneToNRelationshipFieldAccessor(RelationshipType type, Direction direction, Class<? extends NodeBacked> elementClass, EntityInstantiator<NodeBacked, Node> graphEntityInstantiator) {
|
||||
public ReadOnlyOneToNRelationshipFieldAccessor(final RelationshipType type, final Direction direction, final Class<? extends NodeBacked> elementClass, final EntityInstantiator<NodeBacked, Node> graphEntityInstantiator) {
|
||||
super(type,direction,elementClass,graphEntityInstantiator);
|
||||
}
|
||||
|
||||
public Object setValue(final NodeBacked entity, final Object newVal) {
|
||||
throw new InvalidDataAccessApiUsageException("Cannot set read-only relationship entity field.");
|
||||
}
|
||||
|
||||
public static FieldAccessorFactory<NodeBacked> factory() {
|
||||
return new RelationshipFieldAccessorFactory() {
|
||||
@Override
|
||||
public boolean accept(final Field f) {
|
||||
return Iterable.class.equals(f.getType()) && hasValidRelationshipAnnotation(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldAccessor<NodeBacked, ?> forField(final Field field) {
|
||||
final GraphEntityRelationship relAnnotation = getRelationshipAnnotation(field);
|
||||
return new ReadOnlyOneToNRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(relAnnotation), graphEntityInstantiator);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.DynamicRelationshipType;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Configurable;
|
||||
import org.springframework.datastore.graph.api.GraphEntityRelationship;
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* @author Michael Hunger
|
||||
* @since 12.09.2010
|
||||
*/
|
||||
@Configurable
|
||||
abstract class RelationshipFieldAccessorFactory implements FieldAccessorFactory<NodeBacked> {
|
||||
@Autowired
|
||||
protected EntityInstantiator<NodeBacked, Node> graphEntityInstantiator;
|
||||
|
||||
protected Class<? extends NodeBacked> targetFrom(Field field) {
|
||||
return (Class<? extends NodeBacked>) field.getType();
|
||||
}
|
||||
|
||||
protected Class<? extends NodeBacked> targetFrom(GraphEntityRelationship relAnnotation) {
|
||||
return (Class<? extends NodeBacked>) relAnnotation.elementClass();
|
||||
}
|
||||
|
||||
protected Direction dirFrom(GraphEntityRelationship relAnnotation) {
|
||||
return relAnnotation.direction().toNeo4jDir();
|
||||
}
|
||||
|
||||
protected DynamicRelationshipType typeFrom(Field field) {
|
||||
return DynamicRelationshipType.withName(DelegatingFieldAccessorFactory.getNeo4jPropertyName(field));
|
||||
}
|
||||
|
||||
protected DynamicRelationshipType typeFrom(GraphEntityRelationship relAnnotation) {
|
||||
return DynamicRelationshipType.withName(relAnnotation.type());
|
||||
}
|
||||
|
||||
protected GraphEntityRelationship getRelationshipAnnotation(Field field) {
|
||||
return field.getAnnotation(GraphEntityRelationship.class);
|
||||
}
|
||||
|
||||
protected boolean hasValidRelationshipAnnotation(Field field) {
|
||||
final GraphEntityRelationship relAnnotation = getRelationshipAnnotation(field);
|
||||
return relAnnotation != null && !relAnnotation.elementClass().equals(NodeBacked.class);
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,11 @@ package org.springframework.datastore.graph.neo4j.fieldaccess;
|
||||
import org.neo4j.graphdb.Direction;
|
||||
import org.neo4j.graphdb.Node;
|
||||
import org.neo4j.graphdb.RelationshipType;
|
||||
import org.springframework.datastore.graph.api.GraphEntityRelationship;
|
||||
import org.springframework.datastore.graph.api.NodeBacked;
|
||||
import org.springframework.datastore.graph.api.RelationshipBacked;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -17,7 +18,7 @@ public class SingleRelationshipFieldAccessor extends NodeToNodesRelationshipFiel
|
||||
|
||||
@Override
|
||||
public Object setValue(final NodeBacked entity, final Object newVal) {
|
||||
Node node=checkUnderlyingNode(entity);
|
||||
final Node node=checkUnderlyingNode(entity);
|
||||
if (newVal == null) {
|
||||
removeMissingRelationships(node, Collections.<Node>emptySet());
|
||||
return null;
|
||||
@@ -35,4 +36,22 @@ public class SingleRelationshipFieldAccessor extends NodeToNodesRelationshipFiel
|
||||
final Set<NodeBacked> result = createEntitySetFromRelationshipEndNodes(entity);
|
||||
return result.isEmpty() ? null : result.iterator().next();
|
||||
}
|
||||
|
||||
public static FieldAccessorFactory<NodeBacked> factory() {
|
||||
return new RelationshipFieldAccessorFactory() {
|
||||
@Override
|
||||
public boolean accept(final Field f) {
|
||||
return NodeBacked.class.isAssignableFrom(f.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldAccessor<NodeBacked, ?> forField(final Field field) {
|
||||
final GraphEntityRelationship relAnnotation = getRelationshipAnnotation(field);
|
||||
if (relAnnotation == null)
|
||||
return new SingleRelationshipFieldAccessor(typeFrom(field), Direction.OUTGOING, targetFrom(field), graphEntityInstantiator);
|
||||
return new SingleRelationshipFieldAccessor(typeFrom(relAnnotation), dirFrom(relAnnotation), targetFrom(field), graphEntityInstantiator);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,8 +19,8 @@ import org.springframework.datastore.graph.api.NodeBacked;
|
||||
import org.springframework.datastore.graph.api.RelationshipBacked;
|
||||
|
||||
import org.springframework.datastore.graph.api.GraphEntity;
|
||||
import org.springframework.datastore.graph.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
|
||||
import org.springframework.datastore.graph.neo4j.fieldaccess.FieldAccessor;
|
||||
import org.springframework.datastore.graph.neo4j.fieldaccess.FieldAccessorFactory;
|
||||
import org.springframework.persistence.support.AbstractTypeAnnotatingMixinFields;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -49,7 +49,7 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
|
||||
public EntityInstantiator<NodeBacked, Node> graphEntityInstantiator;
|
||||
|
||||
private FieldAccessorFactory fieldAccessorFactory;
|
||||
private DelegatingFieldAccessorFactory fieldAccessorFactory;
|
||||
|
||||
public EntityInstantiator<RelationshipBacked, Relationship> relationshipEntityInstantiator;
|
||||
|
||||
@@ -66,7 +66,7 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
this.relationshipEntityInstantiator = relationshipEntityInstantiator;
|
||||
this.indexService = indexService;
|
||||
this.conversionService = conversionService;
|
||||
this.fieldAccessorFactory = new FieldAccessorFactory(graphEntityInstantiator, relationshipEntityInstantiator);
|
||||
this.fieldAccessorFactory = new DelegatingFieldAccessorFactory(graphEntityInstantiator, relationshipEntityInstantiator);
|
||||
}
|
||||
|
||||
|
||||
@@ -236,7 +236,7 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
if (isIdField(field)) return new ShouldProceedOrReturn(entity.getUnderlyingNode().getId());
|
||||
if (Modifier.isTransient(field.getModifiers())) return new ShouldProceedOrReturn();
|
||||
if (isNeo4jPropertyType(field.getType()) || isDeserializableField(field)) {
|
||||
String propName = FieldAccessorFactory.getNeo4jPropertyName(field);
|
||||
String propName = DelegatingFieldAccessorFactory.getNeo4jPropertyName(field);
|
||||
log.info("GET " + field + " <- Neo4J simple node property [" + propName + "]");
|
||||
Node node = entity.getUnderlyingNode();
|
||||
Object nodeProperty = deserializePropertyValue(node.getProperty(propName, getDefaultValue(field.getType())), field.getType());
|
||||
@@ -308,7 +308,7 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
if (Modifier.isFinal(field.getModifiers())) return new ShouldProceedOrReturn(newVal);
|
||||
if (Modifier.isTransient(field.getModifiers())) return new ShouldProceedOrReturn(true, newVal);
|
||||
if (isNeo4jPropertyType(field.getType()) || isSerializableField(field)) {
|
||||
String propName = FieldAccessorFactory.getNeo4jPropertyName(field);
|
||||
String propName = DelegatingFieldAccessorFactory.getNeo4jPropertyName(field);
|
||||
Node node = entity.getUnderlyingNode();
|
||||
if (newVal==null) {
|
||||
node.removeProperty(propName);
|
||||
@@ -395,11 +395,11 @@ public aspect Neo4jNodeBacking extends AbstractTypeAnnotatingMixinFields<GraphEn
|
||||
}
|
||||
|
||||
private boolean isSerializableField(Field field) {
|
||||
return !FieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(field.getType(), String.class);
|
||||
return !DelegatingFieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(field.getType(), String.class);
|
||||
}
|
||||
|
||||
private boolean isDeserializableField(Field field) {
|
||||
return !FieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(String.class, field.getType());
|
||||
return !DelegatingFieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(String.class, field.getType());
|
||||
}
|
||||
|
||||
private Object serializePropertyValue(Object newVal, Class<?> fieldType) {
|
||||
|
||||
@@ -12,8 +12,7 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.dao.InvalidDataAccessResourceUsageException;
|
||||
import org.springframework.datastore.graph.api.*;
|
||||
|
||||
import org.springframework.datastore.graph.neo4j.fieldaccess.FieldAccessorFactory;
|
||||
import org.springframework.datastore.graph.neo4j.finder.FinderFactory;
|
||||
import org.springframework.datastore.graph.neo4j.fieldaccess.DelegatingFieldAccessorFactory;
|
||||
import org.springframework.persistence.support.AbstractTypeAnnotatingMixinFields;
|
||||
import org.springframework.persistence.support.EntityInstantiator;
|
||||
|
||||
@@ -104,7 +103,7 @@ public aspect Neo4jRelationshipBacking extends AbstractTypeAnnotatingMixinFields
|
||||
if (rel == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Please set start node and end node before reading from other fields.");
|
||||
}
|
||||
String propName = FieldAccessorFactory.getNeo4jPropertyName(f);
|
||||
String propName = DelegatingFieldAccessorFactory.getNeo4jPropertyName(f);
|
||||
log.info("GET " + f + " <- Neo4J simple relationship property [" + propName + "]");
|
||||
return deserializePropertyValue(rel.getProperty(propName, null), f.getType());
|
||||
}
|
||||
@@ -129,7 +128,7 @@ public aspect Neo4jRelationshipBacking extends AbstractTypeAnnotatingMixinFields
|
||||
if (rel == null) {
|
||||
throw new InvalidDataAccessApiUsageException("Please set start node and end node before assigning to other fields.");
|
||||
}
|
||||
String propName = FieldAccessorFactory.getNeo4jPropertyName(f);
|
||||
String propName = DelegatingFieldAccessorFactory.getNeo4jPropertyName(f);
|
||||
if (newVal==null) {
|
||||
entity.getUnderlyingRelationship().removeProperty(propName);
|
||||
}
|
||||
@@ -164,11 +163,11 @@ public aspect Neo4jRelationshipBacking extends AbstractTypeAnnotatingMixinFields
|
||||
}
|
||||
|
||||
private boolean isSerializableField(Field field) {
|
||||
return !FieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(field.getType(), String.class);
|
||||
return !DelegatingFieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(field.getType(), String.class);
|
||||
}
|
||||
|
||||
private boolean isDeserializableField(Field field) {
|
||||
return !FieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(String.class, field.getType());
|
||||
return !DelegatingFieldAccessorFactory.isRelationshipField(field) && conversionService.canConvert(String.class, field.getType());
|
||||
}
|
||||
|
||||
private Object serializePropertyValue(Object newVal, Class<?> fieldType) {
|
||||
|
||||
Reference in New Issue
Block a user