DATAGRAPH-351 - Let Neo4jPersistentProperty extend AnnotationBasedPersistentProperty.

This commit is contained in:
Oliver Gierke
2013-04-29 18:36:41 +02:00
parent 926e685016
commit f3452ba2e0
6 changed files with 143 additions and 113 deletions

View File

@@ -16,52 +16,51 @@
package org.springframework.data.neo4j.cross_store.fieldaccess;
import javax.persistence.Id;
import org.springframework.data.neo4j.fieldaccess.FieldAccessListener;
import org.springframework.data.neo4j.fieldaccess.FieldAccessorListenerFactory;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import javax.persistence.Id;
/**
* @author Michael Hunger
* @since 12.09.2010
*/
public class JpaIdFieldAccessListenerFactory implements FieldAccessorListenerFactory
{
private final Neo4jTemplate template;
public class JpaIdFieldAccessListenerFactory implements FieldAccessorListenerFactory {
private final Neo4jTemplate template;
public JpaIdFieldAccessListenerFactory(Neo4jTemplate template) {
this.template = template;
}
public JpaIdFieldAccessListenerFactory(Neo4jTemplate template) {
this.template = template;
}
@Override
public boolean accept(final Neo4jPersistentProperty property) {
return property.isAnnotationPresent(Id.class);
}
@Override
public boolean accept(final Neo4jPersistentProperty property) {
return property.getAnnotation(Id.class) != null;
}
@Override
public FieldAccessListener forField(final Neo4jPersistentProperty property) {
return new JpaIdFieldListener(property, template);
}
@Override
public FieldAccessListener forField(final Neo4jPersistentProperty property) {
return new JpaIdFieldListener(property, template);
}
public static class JpaIdFieldListener implements FieldAccessListener {
protected final Neo4jPersistentProperty property;
private final Neo4jTemplate template;
public static class JpaIdFieldListener implements FieldAccessListener {
protected final Neo4jPersistentProperty property;
private final Neo4jTemplate template;
public JpaIdFieldListener(final Neo4jPersistentProperty property, Neo4jTemplate template) {
this.property = property;
this.template = template;
}
public JpaIdFieldListener(final Neo4jPersistentProperty property, Neo4jTemplate template) {
this.property = property;
this.template = template;
}
@Override
public void valueChanged(Object entity, Object oldVal, Object newVal) {
if (newVal != null) {
template.save(entity);
/* TODO EntityState entityState = entity.getEntityState();
entityState.persist();
*/
}
}
}
@Override
public void valueChanged(Object entity, Object oldVal, Object newVal) {
if (newVal != null) {
template.save(entity);
/* TODO EntityState entityState = entity.getEntityState();
entityState.persist();
*/
}
}
}
}

View File

@@ -15,6 +15,9 @@
*/
package org.springframework.data.neo4j.cross_store.support.node;
import java.util.Arrays;
import java.util.Collection;
import org.springframework.data.neo4j.annotation.GraphProperty;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.cross_store.fieldaccess.JpaIdFieldAccessListenerFactory;
@@ -35,9 +38,6 @@ import org.springframework.data.neo4j.fieldaccess.TraversalFieldAccessorFactory;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import java.util.Arrays;
import java.util.Collection;
/**
* @author mh
* @since 30.04.12
@@ -57,7 +57,7 @@ public class CrossStoreNodeDelegatingFieldAccessorFactory extends DelegatingFiel
newConvertingNodePropertyFieldAccessorFactory()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(GraphProperty.class) && super.accept(property);
return property.getAnnotation(GraphProperty.class) != null && super.accept(property);
}
},
new JpaIdFieldAccessListenerFactory(template));
@@ -75,7 +75,7 @@ public class CrossStoreNodeDelegatingFieldAccessorFactory extends DelegatingFiel
new RelatedToSingleFieldAccessorFactory(getTemplate()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(RelatedTo.class) && super.accept(property);
return property.getAnnotation(RelatedTo.class) != null && super.accept(property);
}
},
new RelatedToCollectionFieldAccessorFactory(getTemplate()),
@@ -89,7 +89,7 @@ public class CrossStoreNodeDelegatingFieldAccessorFactory extends DelegatingFiel
return new ConvertingNodePropertyFieldAccessorFactory(getTemplate()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(GraphProperty.class) && super.accept(property);
return property.getAnnotation(GraphProperty.class) != null && super.accept(property);
}
};
}
@@ -98,7 +98,7 @@ public class CrossStoreNodeDelegatingFieldAccessorFactory extends DelegatingFiel
return new PropertyFieldAccessorFactory(getTemplate()) {
@Override
public boolean accept(Neo4jPersistentProperty property) {
return property.isAnnotationPresent(GraphProperty.class) && super.accept(property);
return property.getAnnotation(GraphProperty.class) != null && super.accept(property);
}
};
}

View File

@@ -16,21 +16,18 @@
package org.springframework.data.neo4j.fieldaccess;
import static org.springframework.data.neo4j.support.DoReturn.*;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.StartNode;
import org.springframework.data.neo4j.mapping.MappingPolicy;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.support.Neo4jTemplate;
import static org.springframework.data.neo4j.support.DoReturn.doReturn;
/**
* @author Michael Hunger
* @author Oliver Gierke
* @since 21.09.2010
*/
public class RelationshipNodeFieldAccessorFactory implements FieldAccessorFactory {
@@ -48,11 +45,11 @@ public class RelationshipNodeFieldAccessorFactory implements FieldAccessorFactor
}
private boolean isEndNodeField(final Neo4jPersistentProperty f) {
return f.isAnnotationPresent(EndNode.class);
return f.isEndNode();
}
private boolean isStartNodeField(final Neo4jPersistentProperty f) {
return f.isAnnotationPresent(StartNode.class);
return f.isStartNode();
}
@Override

View File

@@ -16,12 +16,12 @@
package org.springframework.data.neo4j.mapping;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.mapping.PersistentProperty;
import java.lang.annotation.Annotation;
import java.util.Collection;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.mapping.PersistentProperty;
/**
* Interface for Neo4J specific {@link PersistentProperty}s. Declares additional metadata to lookup relationship
* information.
@@ -67,8 +67,12 @@ public interface Neo4jPersistentProperty extends PersistentProperty<Neo4jPersist
Collection<? extends Annotation> getAnnotations();
<T extends Annotation> T getAnnotation(Class<? extends T> annotationType);
<T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType);
boolean isStartNode();
boolean isEndNode();
boolean isRelationshipType();
void setValue(Object entity, Object newValue);

View File

@@ -16,26 +16,6 @@
package org.springframework.data.neo4j.support.mapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.annotation.Transient;
import org.springframework.data.annotation.Version;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.model.AbstractPersistentProperty;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.mapping.IndexInfo;
import org.springframework.data.neo4j.mapping.ManagedEntity;
import org.springframework.data.neo4j.mapping.MappingPolicy;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.mapping.RelationshipInfo;
import org.springframework.data.neo4j.support.DoReturn;
import org.springframework.data.util.TypeInformation;
import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
@@ -45,12 +25,42 @@ import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.model.AnnotationBasedPersistentProperty;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.neo4j.annotation.EndNode;
import org.springframework.data.neo4j.annotation.Fetch;
import org.springframework.data.neo4j.annotation.GraphId;
import org.springframework.data.neo4j.annotation.GraphProperty;
import org.springframework.data.neo4j.annotation.Indexed;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.annotation.RelatedTo;
import org.springframework.data.neo4j.annotation.RelatedToVia;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.annotation.RelationshipType;
import org.springframework.data.neo4j.annotation.StartNode;
import org.springframework.data.neo4j.mapping.IndexInfo;
import org.springframework.data.neo4j.mapping.ManagedEntity;
import org.springframework.data.neo4j.mapping.MappingPolicy;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.mapping.RelationshipInfo;
import org.springframework.data.neo4j.support.DoReturn;
import org.springframework.data.util.TypeInformation;
/**
* Implementation of {@link org.springframework.data.neo4j.mapping.Neo4jPersistentProperty}.
*
* @author Oliver Gierke
*/
class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersistentProperty> implements
class Neo4jPersistentPropertyImpl extends AnnotationBasedPersistentProperty<Neo4jPersistentProperty> implements
Neo4jPersistentProperty {
private final static Logger log = LoggerFactory.getLogger(Neo4jPersistentProperty.class);
@@ -67,25 +77,22 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
private final Boolean isAssociation;
private final String neo4jPropertyName;
private final int hash;
private final boolean isVersionProperty;
public Neo4jPersistentPropertyImpl(Field field, PropertyDescriptor propertyDescriptor,
PersistentEntity<?, Neo4jPersistentProperty> owner, SimpleTypeHolder simpleTypeHolder, Neo4jMappingContext ctx) {
super(field, propertyDescriptor, owner, simpleTypeHolder);
this.hash = getField().hashCode();
this.annotations = extractAnnotations(field);
this.relationshipInfo = extractRelationshipInfo(field, ctx);
this.annotations = extractAnnotations(field);
this.propertyType = extractPropertyType();
this.isAssociation = ctx.isReference(this);
this.isNeo4jEntityType = isNeo4jPropertyType(getType());
this.neo4jPropertyName = createNeo4jPropertyName();
this.indexInfo = extractIndexInfo();
this.isIdProperty = annotations.containsKey(GraphId.class);
this.isIdProperty = super.isIdProperty() || getAnnotation(GraphId.class) != null;
this.defaultValue = extractDefaultValue();
this.myAssociation = isAssociation() ? super.getAssociation() == null ? createAssociation() : super.getAssociation() : null;
this.query = extractQuery();
this.isVersionProperty = isAnnotationPresent(Version.class);
}
private String extractQuery() {
@@ -131,12 +138,6 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
return findAnnotation(annotationType);
}
@SuppressWarnings("unchecked")
public <A extends Annotation> A findAnnotation(Class<? extends A> annotationType) {
return (A) annotations.get(annotationType);
}
private RelationshipInfo extractRelationshipInfo(final Field field, Neo4jMappingContext ctx) {
if (isAnnotationPresent(RelatedTo.class)) {
return RelationshipInfo.fromField(field, getAnnotation(RelatedTo.class), getTypeInformation(), ctx);
@@ -151,9 +152,6 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
return null;
}
public <T extends Annotation> boolean isAnnotationPresent(Class<T> annotationType) {
return annotations.containsKey(annotationType);
}
@Override
public void setValue(Object entity, Object newValue) {
@@ -169,16 +167,6 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
return typeInformation.getActualType().getType().isAnnotationPresent(annotationClass);
}
@Override
public boolean isIdProperty() {
return this.isIdProperty;
}
@Override
public boolean isVersionProperty() {
return isVersionProperty;
}
@Override
protected Association<Neo4jPersistentProperty> createAssociation() {
return new Association<Neo4jPersistentProperty>(this, null);
@@ -273,6 +261,11 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
@Override
public Collection<? extends Annotation> getAnnotations() {
if (annotations == null) {
}
return annotations.values();
}
@@ -328,7 +321,7 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
@Override
public Neo4jPersistentEntity<?> getOwner() {
return (Neo4jPersistentEntity<?>)super.getOwner();
return (Neo4jPersistentEntity<?>) super.getOwner();
}
@Override
public boolean isEntity() {
@@ -392,11 +385,7 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
if (providedMappingPolicy != null) return providedMappingPolicy;
return getMappingPolicy();
}
public boolean equals(Object other) {
if (other==this) return true;
if (!AbstractPersistentProperty.class.isInstance(other)) return false;
return getField().equals(((AbstractPersistentProperty)other).getField());
}
public int hashCode() {
return hash;
}
@@ -422,4 +411,40 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
public boolean isTargetTypeEnforced() {
return getAnnotation( RelatedTo.class ) != null && getAnnotation( RelatedTo.class ).enforceTargetType();
}
/*
* (non-Javadoc)
* @see org.springframework.data.neo4j.mapping.Neo4jPersistentProperty#isStartNode()
*/
@Override
public boolean isStartNode() {
return isAnnotationPresent(StartNode.class);
}
/*
* (non-Javadoc)
* @see org.springframework.data.neo4j.mapping.Neo4jPersistentProperty#isEndNode()
*/
@Override
public boolean isEndNode() {
return isAnnotationPresent(EndNode.class);
}
/*
* (non-Javadoc)
* @see org.springframework.data.neo4j.mapping.Neo4jPersistentProperty#isRelationshipType()
*/
@Override
public boolean isRelationshipType() {
return isAnnotationPresent(RelationshipType.class);
}
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.model.AnnotationBasedPersistentProperty#isIdProperty()
*/
@Override
public boolean isIdProperty() {
return isIdProperty;
}
}

View File

@@ -16,6 +16,10 @@
package org.springframework.data.neo4j.support.mapping;
import java.lang.annotation.Annotation;
import java.util.IdentityHashMap;
import java.util.Map;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.PropertyContainer;
import org.neo4j.graphdb.Relationship;
@@ -23,14 +27,15 @@ import org.springframework.data.mapping.Association;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.model.BasicPersistentEntity;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.neo4j.annotation.*;
import org.springframework.data.neo4j.mapping.*;
import org.springframework.data.neo4j.annotation.NodeEntity;
import org.springframework.data.neo4j.annotation.RelationshipEntity;
import org.springframework.data.neo4j.mapping.ManagedEntity;
import org.springframework.data.neo4j.mapping.MappingPolicy;
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
import org.springframework.data.neo4j.mapping.RelationshipProperties;
import org.springframework.data.util.TypeInformation;
import java.lang.annotation.Annotation;
import java.util.IdentityHashMap;
import java.util.Map;
/**
* Implementation of {@link org.springframework.data.neo4j.mapping.Neo4jPersistentEntity}.
*
@@ -163,7 +168,7 @@ public class Neo4jPersistentEntityImpl<T> extends BasicPersistentEntity<T, Neo4j
@Override
public void addPersistentProperty(Neo4jPersistentProperty property) {
super.addPersistentProperty(property);
if (property.isAnnotationPresent(RelationshipType.class)) {
if (property.isRelationshipType()) {
this.relationshipType = property;
}
if (property.isUnique()) {
@@ -177,10 +182,10 @@ public class Neo4jPersistentEntityImpl<T> extends BasicPersistentEntity<T, Neo4j
public void addAssociation(Association<Neo4jPersistentProperty> neo4jPersistentPropertyAssociation) {
super.addAssociation(neo4jPersistentPropertyAssociation);
final Neo4jPersistentProperty property = neo4jPersistentPropertyAssociation.getInverse();
if (property.isAnnotationPresent(StartNode.class)) {
if (property.isStartNode()) {
this.startNodeProperty = property;
}
if (property.isAnnotationPresent(EndNode.class)) {
if (property.isEndNode()) {
this.endNodeProperty = property;
}
}