added introduced method findAllPathsByTraversal

This commit is contained in:
Michael Hunger
2011-04-04 14:55:16 +02:00
parent 44e667d834
commit e4bf9967fd
6 changed files with 88 additions and 9 deletions

View File

@@ -20,6 +20,7 @@ import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.springframework.data.graph.neo4j.fieldaccess.EntityState;
import org.springframework.data.graph.neo4j.support.EntityPath;
/**
* Interface introduced to objects annotated with @NodeEntity by the {@link org.springframework.data.graph.neo4j.support.node.Neo4jNodeBacking} aspect.
@@ -92,6 +93,15 @@ public interface NodeBacked extends GraphBacked<Node> {
*/
<T extends NodeBacked> Iterable<T> findAllByTraversal(final Class<T> targetType, TraversalDescription traversalDescription);
/**
* Perform a traversal from this entity's underlying node with the given traversal description. The found paths
* are used to create the wrapping entity paths.
*
* @param traversalDescription traversal description used
* @return Lazy {@link java.lang.Iterable} over the traversal result paths, wrapped as entity paths @{link EntityPath}
* entity instances
*/
<S extends NodeBacked, E extends NodeBacked> Iterable<EntityPath<S,E>> findAllPathsByTraversal(TraversalDescription traversalDescription);
/**
* Removes the all relationships of the given type between this entity's underlying node and the target

View File

@@ -25,7 +25,7 @@ import org.neo4j.graphdb.Relationship;
public interface RelationshipBacked extends GraphBacked<Relationship>{
/**
* @return relationship id if there is an underlying relationship
* @return the id of the underlying relationship or null if there is none
*/
Long getRelationshipId();
@@ -40,8 +40,4 @@ public interface RelationshipBacked extends GraphBacked<Relationship>{
<R extends RelationshipBacked> R projectTo(Class<R> targetType);
/**
* @return the id of the underlying relationship or null if there is none
*/
Long getRelationshipId();
}

View File

@@ -0,0 +1,40 @@
/**
* Copyright 2011 the original author or authors.
*
* 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.
*/
package org.springframework.data.graph.neo4j.support.node;
import org.neo4j.graphdb.Path;
import org.neo4j.helpers.collection.IterableWrapper;
import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.neo4j.support.EntityPath;
import org.springframework.data.graph.neo4j.support.GraphDatabaseContext;
/**
* @author mh
* @since 04.04.11
*/
public class EntityPathPathIterableWrapper<S extends NodeBacked, E extends NodeBacked> extends IterableWrapper<EntityPath<S,E>, Path> {
private final GraphDatabaseContext graphDatabaseContext;
public EntityPathPathIterableWrapper(Iterable<Path> paths, GraphDatabaseContext graphDatabaseContext) {
super(paths);
this.graphDatabaseContext = graphDatabaseContext;
}
protected EntityPath<S, E> underlyingObjectToObject(Path path) {
return new EntityPath<S,E>(graphDatabaseContext,path);
}
}

View File

@@ -27,13 +27,14 @@ import org.springframework.data.graph.core.NodeBacked;
import org.springframework.data.graph.core.GraphBacked;
import org.springframework.data.graph.core.RelationshipBacked;
import org.springframework.data.graph.neo4j.fieldaccess.*;
import org.springframework.data.graph.neo4j.support.EntityPath;
import org.springframework.data.graph.neo4j.support.GraphDatabaseContext;
import java.lang.reflect.Field;
import org.springframework.data.graph.annotation.*;
import javax.persistence.Transient;
import javax.persistence.Entity;
import org.springframework.beans.factory.annotation.Configurable;
import java.lang.reflect.Field;
import static org.springframework.data.graph.neo4j.fieldaccess.DoReturn.unwrap;
@@ -173,6 +174,12 @@ public aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMixinFields<No
return new NodeBackedNodeIterableWrapper<T>(traverser, targetType, Neo4jNodeBacking.aspectOf().graphDatabaseContext);
}
public <S extends NodeBacked, E extends NodeBacked> Iterable<EntityPath<S,E>> NodeBacked.findAllPathsByTraversal(TraversalDescription traversalDescription) {
if (!hasPersistentState()) throw new IllegalStateException("No node attached to " + this);
final Traverser traverser = traversalDescription.traverse(this.getPersistentState());
return new EntityPathPathIterableWrapper<S, E>(traverser, Neo4jNodeBacking.aspectOf().graphDatabaseContext);
}
public <R extends RelationshipBacked, N extends NodeBacked> R NodeBacked.relateTo(N target, Class<R> relationshipClass, String relationshipType) {
if (target==null) throw new IllegalArgumentException("Target entity is null");
if (relationshipClass==null) throw new IllegalArgumentException("Relationship class is null");
@@ -264,4 +271,5 @@ public aspect Neo4jNodeBacking { // extends AbstractTypeAnnotatingMixinFields<No
FieldSignature fieldSignature = (FieldSignature)joinPoint.getSignature();
return fieldSignature.getField();
}
}

View File

@@ -20,7 +20,9 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.DynamicRelationshipType;
import org.neo4j.graphdb.traversal.Evaluators;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.kernel.Traversal;
import org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl;
@@ -69,7 +71,7 @@ public class TraversalTest {
Group group = new Group().persist();
group.setName("dev");
group.addPerson(p);
final TraversalDescription traversalDescription = new TraversalDescriptionImpl().relationships(DynamicRelationshipType.withName("persons")).filter(Traversal.returnAllButStartNode());
final TraversalDescription traversalDescription = Traversal.description().relationships(DynamicRelationshipType.withName("persons")).evaluator(Evaluators.excludeStartPosition());
Iterable<Person> people = (Iterable<Person>) group.findAllByTraversal(Person.class, traversalDescription);
final HashSet<Person> found = new HashSet<Person>();
for (Person person : people) {
@@ -77,6 +79,21 @@ public class TraversalTest {
}
assertEquals(Collections.singleton(p),found);
}
@Test
@Transactional
public void testTraverseFromGroupToPeoplePaths() {
Person p = persistedPerson("Michael", 35);
Group group = new Group().persist();
group.setName("dev");
group.addPerson(p);
final TraversalDescription traversalDescription = Traversal.description().relationships(DynamicRelationshipType.withName("persons"), Direction.OUTGOING).evaluator(Evaluators.excludeStartPosition());
Iterable<EntityPath<Group,Person>> paths = group.<Group,Person>findAllPathsByTraversal(traversalDescription);
for (EntityPath<Group, Person> path : paths) {
assertEquals(group, path.startEntity());
assertEquals(p, path.endEntity());
assertEquals(1,path.length());
}
}
@Test
@Transactional

View File

@@ -75,11 +75,19 @@
</listitem>
</varlistentry>
<varlistentry>
<term>traversing, starting at the current node</term>
<term>traversing, starting at the current node, returns end-nodes of traversal converted to provided type</term>
<listitem>
<para><code>nodeEntity.findAllByTraversal(targetType, traversalDescription)</code></para>
</listitem>
</varlistentry>
<varlistentry>
<term>traversing, starting at the current node, returns <code>EntityPath</code>'s of the traversal result
bound to the provided start and end-node-entity types
</term>
<listitem>
<para><code>Iterable&lt;EntityPath&gt; findAllPathsByTraversal(traversalDescription)</code></para>
</listitem>
</varlistentry>
</variablelist>
</para>
</section>