From aa9c09b6b41712f23204a0b71df2d90c787cd6b5 Mon Sep 17 00:00:00 2001 From: Michael Hunger Date: Tue, 22 Feb 2011 15:13:03 +0100 Subject: [PATCH] Neo4j Template Api Evolution --- .../neo4j/template/GraphDescription.java | 80 ---------- .../template/GraphTransactionCallback.java | 86 ----------- .../graph/neo4j/template/Neo4jOperations.java | 31 ++-- .../graph/neo4j/template/Neo4jTemplate.java | 139 ++++++++++-------- .../data/graph/neo4j/template/NodeInfo.java | 97 ------------ .../{Property.java => PropertyMap.java} | 37 ++--- .../graph/neo4j/template/PropertyParser.java | 69 --------- .../neo4j/template/RelationShipNodeInfo.java | 57 ------- .../neo4j/template/Neo4jTemplateApiTest.java | 83 ++++++----- .../neo4j/template/Neo4jTemplateTest.java | 20 +-- .../data/graph/neo4j/template/NeoApiTest.java | 7 +- .../template/NeoGraphDescriptionTest.java | 68 --------- .../neo4j/template/NeoTraversalTest.java | 105 ++++++------- 13 files changed, 208 insertions(+), 671 deletions(-) delete mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/GraphDescription.java delete mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/GraphTransactionCallback.java delete mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/NodeInfo.java rename spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/{Property.java => PropertyMap.java} (53%) delete mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/PropertyParser.java delete mode 100644 spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/RelationShipNodeInfo.java delete mode 100644 spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoGraphDescriptionTest.java diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/GraphDescription.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/GraphDescription.java deleted file mode 100644 index b9ef60a13..000000000 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/GraphDescription.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2010 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.template; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.RelationshipType; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Properties; - -public class GraphDescription -{ - - private Map nodes = new LinkedHashMap(); - - public GraphDescription(final Properties props) - { - if (props == null) - throw new IllegalArgumentException("Properties must not be null"); - new PropertyParser(props).load(this); - } - - - public GraphDescription() - { - } - - public NodeInfo add(final String nodeName, final String attributeName, final Object value) - { - return getNode(nodeName).setProperty(attributeName, value); - } - - private NodeInfo getNode(final String nodeName) - { - final NodeInfo node = nodes.get(nodeName); - if (node != null) return node; - final NodeInfo newNode = new NodeInfo(nodeName); - nodes.put(nodeName, newNode); - return newNode; - } - - public void relate(final String from, final RelationshipType type, final String to) - { - getNode(from).relateTo(type, getNode(to)); - } - - void addToGraph(GraphDatabaseService graph) - { - boolean first = true; - for (NodeInfo nodeInfo : nodes.values()) - { - final Node node = first ? graph.getReferenceNode() : graph.createNode(); - first = false; - nodeInfo.updateProperties(node); - } - - for (NodeInfo nodeInfo : nodes.values()) - { - final Node from = graph.getNodeById(nodeInfo.getId()); - nodeInfo.updateRelations(from, graph); - } - } - -} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/GraphTransactionCallback.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/GraphTransactionCallback.java deleted file mode 100644 index 0c6dad91f..000000000 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/GraphTransactionCallback.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.springframework.data.graph.neo4j.template; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Transaction; -import org.springframework.dao.DataAccessException; -import org.springframework.data.graph.UncategorizedGraphStoreException; - -/** - * @author mh - * @since 18.02.11 - */ -public abstract class GraphTransactionCallback implements GraphCallback { - - public interface Status { - void mustRollback(); - - void interimCommit(); - } - - public abstract T doWithGraph(Status status, GraphDatabaseService graph) throws Exception; - - @Override - public T doWithGraph(GraphDatabaseService graph) throws Exception { - final TransactionStatus status = new TransactionStatus(graph); - try { - return doWithGraph(status, graph); - } catch (Exception e) { - status.mustRollback(); - throw e; - } finally { - status.finish(); - } - } - - private static class TransactionStatus implements Status { - private boolean rollback; - private final GraphDatabaseService neo; - private Transaction tx; - - private TransactionStatus(final GraphDatabaseService neo) { - if (neo == null) - throw new IllegalArgumentException("GraphDatabaseService must not be null"); - this.neo = neo; - begin(); - } - - private void begin() { - tx = neo.beginTx(); - } - - public void mustRollback() { - this.rollback = true; - } - - public void interimCommit() { - finish(); - begin(); - } - - private void finish() { - try { - if (rollback) { - tx.failure(); - } else { - tx.success(); - } - } finally { - tx.finish(); - } - } - } - - /** - * @author mh - * @since 19.02.11 - */ - public abstract static class WithoutResult extends GraphTransactionCallback { - @Override - public Void doWithGraph(Status status, GraphDatabaseService graph) throws Exception { - doWithGraphWithoutResult(status,graph); - return null; - } - - public abstract void doWithGraphWithoutResult(Status status, GraphDatabaseService graph) throws Exception; - } -} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Neo4jOperations.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Neo4jOperations.java index ad0bed5aa..27ae6e820 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Neo4jOperations.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Neo4jOperations.java @@ -3,42 +3,39 @@ package org.springframework.data.graph.neo4j.template; import org.neo4j.graphdb.*; import org.neo4j.graphdb.traversal.TraversalDescription; +import java.util.Map; + /** * @author mh * @since 19.02.11 */ public interface Neo4jOperations { - T doInTransaction(GraphTransactionCallback callback); + T update(GraphCallback callback); - T execute(GraphCallback callback); + T exec(GraphCallback callback); Node getReferenceNode(); Node getNode(long id); - Node createNode(Property... props); + Node createNode(Map props, String... indexFields); Relationship getRelationship(long id); - Relationship createRelationship(Node startNode, Node endNode, RelationshipType type, Property... props); + Relationship createRelationship(Node startNode, Node endNode, RelationshipType type, Map props, String... indexFields); - Iterable queryNodes(String indexName, Object queryOrQueryObject, PathMapper pathMapper); + Iterable query(String indexName, PathMapper pathMapper, Object queryOrQueryObject); - Iterable retrieveNodes(String indexName, String field, String value, PathMapper pathMapper); + Iterable query(String indexName, PathMapper pathMapper, String field, String value); - Iterable queryRelationships(String indexName, Object queryOrQueryObject, PathMapper pathMapper); + Iterable traverseGraph(Node startNode, PathMapper pathMapper, TraversalDescription traversal); - Iterable retrieveRelationships(String indexName, String field, String value, PathMapper pathMapper); + Iterable traverseNext(Node startNode, PathMapper pathMapper, RelationshipType type, Direction direction); - Iterable traverse(Node startNode, TraversalDescription traversal, PathMapper pathMapper); + Iterable traverseNext(Node startNode, PathMapper pathMapper, RelationshipType... type); - Iterable traverseDirectRelationships(Node startNode, RelationshipType type, Direction direction, PathMapper pathMapper); + Iterable traverseNext(Node startNode, PathMapper pathMapper); - Iterable traverseDirectRelationships(Node startNode, PathMapper pathMapper, RelationshipType... type); - - Iterable traverseDirectRelationships(Node startNode, PathMapper pathMapper); - - void index(Relationship relationship, String indexName, String field, Object value); - - void index(Node node, String indexName, String field, Object value); + T index(String indexName, T element, String field, Object value); + T autoIndex(String indexName, T element, String... indexFields); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Neo4jTemplate.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Neo4jTemplate.java index dd0766e83..c25a9da63 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Neo4jTemplate.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Neo4jTemplate.java @@ -18,20 +18,21 @@ package org.springframework.data.graph.neo4j.template; import org.neo4j.graphdb.*; import org.neo4j.graphdb.index.Index; +import org.neo4j.graphdb.index.IndexManager; import org.neo4j.graphdb.index.RelationshipIndex; import org.neo4j.graphdb.traversal.TraversalDescription; import org.neo4j.helpers.collection.IterableWrapper; import org.springframework.dao.DataAccessException; import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.dao.support.PersistenceExceptionTranslator; -import java.util.Arrays; +import java.util.Map; -public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTranslator { +public class Neo4jTemplate implements Neo4jOperations { private final GraphDatabaseService graphDatabaseService; private final Neo4jExceptionTranslator exceptionTranslator = new Neo4jExceptionTranslator(); + private final IndexManager index; private static void notNull(Object... pairs) { assert pairs.length % 2 == 0 : "wrong number of pairs to check"; @@ -45,22 +46,32 @@ public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTrans public Neo4jTemplate(final GraphDatabaseService graphDatabaseService) { notNull(graphDatabaseService, "graphDatabaseService"); this.graphDatabaseService = graphDatabaseService; + index = this.graphDatabaseService.index(); } - @Override public DataAccessException translateExceptionIfPossible(RuntimeException ex) { return exceptionTranslator.translateExceptionIfPossible(ex); } @Override - public T doInTransaction(final GraphTransactionCallback callback) { + public T update(final GraphCallback callback) { notNull(callback, "callback"); - return execute(callback); + Transaction tx = graphDatabaseService.beginTx(); + try { + T result = exec(callback); + tx.success(); + return result; + } catch (RuntimeException e) { + tx.failure(); + throw e; + } finally { + tx.finish(); + } } @Override - public T execute(final GraphCallback callback) { + public T exec(final GraphCallback callback) { notNull(callback, "callback"); try { return callback.doWithGraph(graphDatabaseService); @@ -81,12 +92,13 @@ public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTrans } @Override - public Node createNode(final Property... properties) { - notNull(properties, "properties"); - return doInTransaction(new GraphTransactionCallback() { + public Node createNode(final Map properties, final String... indexFields) { + return update(new GraphCallback() { @Override - public Node doWithGraph(Status status, GraphDatabaseService graph) throws Exception { - return setProperties(graphDatabaseService.createNode(), properties); + public Node doWithGraph(GraphDatabaseService graph) throws Exception { + Node node = graphDatabaseService.createNode(); + if (properties == null) return node; + return autoIndex(null, setProperties(node, properties), indexFields); } }); } @@ -112,35 +124,48 @@ public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTrans } @Override - public void index(final Relationship relationship, final String indexName, final String field, final Object value) { - notNull(relationship, "relationship", field, "field", value, "value"); - doInTransaction(new GraphTransactionCallback.WithoutResult() { - @Override - public void doWithGraphWithoutResult(Status status, GraphDatabaseService graph) throws Exception { - relationshipIndex(indexName).add(relationship, field, value); - } - }); + public T autoIndex(String indexName, T element, String... indexFields) { + for (String indexField : indexFields) { + if (!element.hasProperty(indexField)) continue; + index(indexName,element, indexField,element.getProperty(indexField)); + } + return element; } @Override - public void index(final Node node, final String indexName, final String field, final Object value) { - notNull(node, "node", field, "field", value, "value"); - doInTransaction(new GraphTransactionCallback.WithoutResult() { + public T index(final String indexName, final T element, final String field, final Object value) { + notNull(element, "element", field, "field", value, "value"); + update(new GraphCallback.WithoutResult() { @Override - public void doWithGraphWithoutResult(Status status, GraphDatabaseService graph) throws Exception { - nodeIndex(indexName).add(node, field, value); + public void doWithGraphWithoutResult(GraphDatabaseService graph) throws Exception { + RelationshipIndex relationshipIndex = relationshipIndex(indexName); + if (relationshipIndex != null && element instanceof Relationship) { + relationshipIndex.add((Relationship) element, field, value); + } else if (element instanceof Node) { + nodeIndex(indexName).add((Node) element, field, value); + } else { + throw new IllegalArgumentException("Provided element is neither node nor relationship " + element); + } } }); + return element; } private RelationshipIndex relationshipIndex(String indexName) { - return graphDatabaseService.index().forRelationships(indexName == null ? "relationship" : indexName); + if (indexName != null && index.existsForRelationships(indexName)) { + return index.forRelationships(indexName); + } + return null; } @Override - public Iterable queryNodes(String indexName, Object queryOrQueryObject, final PathMapper pathMapper) { + public Iterable query(String indexName, final PathMapper pathMapper, Object queryOrQueryObject) { notNull(queryOrQueryObject, "queryOrQueryObject", pathMapper, "pathMapper"); try { + RelationshipIndex relationshipIndex = relationshipIndex(indexName); + if (relationshipIndex!=null) { + return mapRelationships(relationshipIndex.query(queryOrQueryObject), pathMapper); + } return mapNodes(nodeIndex(indexName).query(queryOrQueryObject), pathMapper); } catch (RuntimeException e) { throw translateExceptionIfPossible(e); @@ -148,35 +173,19 @@ public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTrans } @Override - public Iterable retrieveNodes(String indexName, String field, String value, final PathMapper pathMapper) { + public Iterable query(String indexName, final PathMapper pathMapper, String field, String value) { notNull(field, "field", value, "value", pathMapper, "pathMapper"); try { + RelationshipIndex relationshipIndex = relationshipIndex(indexName); + if (relationshipIndex!=null) { + return mapRelationships(relationshipIndex.get(field, value), pathMapper); + } return mapNodes(nodeIndex(indexName).get(field, value), pathMapper); } catch (RuntimeException e) { throw translateExceptionIfPossible(e); } } - @Override - public Iterable queryRelationships(String indexName, Object queryOrQueryObject, final PathMapper pathMapper) { - notNull(queryOrQueryObject, "queryOrQueryObject", pathMapper, "pathMapper"); - try { - return mapRelationships(relationshipIndex(indexName).query(queryOrQueryObject), pathMapper); - } catch (RuntimeException e) { - throw translateExceptionIfPossible(e); - } - } - - @Override - public Iterable retrieveRelationships(String indexName, String field, String value, final PathMapper pathMapper) { - notNull(field, "field", value, "value", pathMapper, "pathMapper"); - try { - return mapRelationships(relationshipIndex(indexName).get(field, value), pathMapper); - } catch (RuntimeException e) { - throw translateExceptionIfPossible(e); - } - } - private Iterable mapNodes(final Iterable nodes, final PathMapper pathMapper) { assert nodes != null; assert pathMapper != null; @@ -189,11 +198,11 @@ public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTrans } private Index nodeIndex(String indexName) { - return graphDatabaseService.index().forNodes(indexName == null ? "node" : indexName); + return index.forNodes(indexName == null ? "node" : indexName); } @Override - public Iterable traverse(Node startNode, TraversalDescription traversal, final PathMapper pathMapper) { + public Iterable traverseGraph(Node startNode, final PathMapper pathMapper, TraversalDescription traversal) { notNull(startNode, "startNode", traversal, "traversal", pathMapper, "pathMapper"); try { return mapPaths(traversal.traverse(startNode), pathMapper); @@ -214,7 +223,7 @@ public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTrans } @Override - public Iterable traverseDirectRelationships(Node startNode, RelationshipType relationshipType, Direction direction, final PathMapper pathMapper) { + public Iterable traverseNext(Node startNode, final PathMapper pathMapper, RelationshipType relationshipType, Direction direction) { notNull(startNode, "startNode", relationshipType, "relationshipType", direction, "direction", pathMapper, "pathMapper"); try { return mapRelationships(startNode.getRelationships(relationshipType, direction), pathMapper); @@ -224,7 +233,7 @@ public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTrans } @Override - public Iterable traverseDirectRelationships(Node startNode, final PathMapper pathMapper, RelationshipType... relationshipTypes) { + public Iterable traverseNext(Node startNode, final PathMapper pathMapper, RelationshipType... relationshipTypes) { notNull(startNode, "startNode", relationshipTypes, "relationshipType", pathMapper, "pathMapper"); try { return mapRelationships(startNode.getRelationships(relationshipTypes), pathMapper); @@ -234,7 +243,7 @@ public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTrans } @Override - public Iterable traverseDirectRelationships(Node startNode, final PathMapper pathMapper) { + public Iterable traverseNext(Node startNode, final PathMapper pathMapper) { notNull(startNode, "startNode", pathMapper, "pathMapper"); try { return mapRelationships(startNode.getRelationships(), pathMapper); @@ -255,23 +264,27 @@ public class Neo4jTemplate implements Neo4jOperations, PersistenceExceptionTrans } @Override - public Relationship createRelationship(final Node startNode, final Node endNode, final RelationshipType relationshipType, final Property... properties) { + public Relationship createRelationship(final Node startNode, final Node endNode, final RelationshipType relationshipType, final Map properties, final String... indexFields) { notNull(startNode, "startNode", endNode, "endNode", relationshipType, "relationshipType", properties, "properties"); - return doInTransaction(new GraphTransactionCallback() { + return update(new GraphCallback() { @Override - public Relationship doWithGraph(Status status, GraphDatabaseService graph) throws Exception { - return setProperties(startNode.createRelationshipTo(endNode, relationshipType), properties); + public Relationship doWithGraph(GraphDatabaseService graph) throws Exception { + Relationship relationship = startNode.createRelationshipTo(endNode, relationshipType); + if (properties == null) return relationship; + return autoIndex("relationship", setProperties(relationship, properties), indexFields); } }); } - private T setProperties(T primitive, Property... properties) { + private T setProperties(T primitive, Map properties) { assert primitive != null; - assert properties != null; - for (Property prop : properties) { - if (prop == null) - throw new IllegalArgumentException("at least one Property is null: " + Arrays.toString(properties)); - primitive.setProperty(prop.getName(), prop.getValue()); + if (properties==null) return primitive; + for (Map.Entry prop : properties.entrySet()) { + if (prop.getValue()==null) { + primitive.removeProperty(prop.getKey()); + } else { + primitive.setProperty(prop.getKey(), prop.getValue()); + } } return primitive; } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/NodeInfo.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/NodeInfo.java deleted file mode 100644 index 311a0e6ec..000000000 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/NodeInfo.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2010 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.template; - -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.RelationshipType; - -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -class NodeInfo -{ - - private final String name; - private final Map props = new LinkedHashMap(); - - private final Set relations = new LinkedHashSet(); - private long id; - - public NodeInfo(final String nodeName) - { - this.name = nodeName; - } - - public NodeInfo setProperty(final String name, final Object value) - { - this.props.put(name, value); - return this; - } - - public void relateTo(final RelationshipType type, final NodeInfo node) - { - this.relations.add(new RelationShipNodeInfo(type, node)); - } - - public void setId(final long id) - { - this.id = id; - } - - public long getId() - { - return id; - } - - void updateProperties(final Node node) - { - node.setProperty("name", name); - for (Map.Entry prop : props.entrySet()) - { - node.setProperty(prop.getKey(), prop.getValue()); - } - setId(node.getId()); - } - - void updateRelations(final Node from, final GraphDatabaseService nodeService) - { - for (RelationShipNodeInfo relation : relations) - { - final Node to = nodeService.getNodeById(relation.getNodeInfo().getId()); - from.createRelationshipTo(to, relation.getRelationshipType()); - } - } - - public boolean equals(final Object o) - { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final NodeInfo nodeInfo = (NodeInfo) o; - - return name.equals(nodeInfo.name); - - } - - public int hashCode() - { - return name.hashCode(); - } -} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Property.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/PropertyMap.java similarity index 53% rename from spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Property.java rename to spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/PropertyMap.java index 062d048bc..821f3a057 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/Property.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/PropertyMap.java @@ -16,33 +16,28 @@ package org.springframework.data.graph.neo4j.template; -public class Property -{ - private final String name; - private final Object value; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; - private Property(final String name, final Object value) - { - if (name == null) - throw new IllegalArgumentException("Name must not be null"); - if (value == null) - throw new IllegalArgumentException("Value must not be null"); - this.name = name; - this.value = value; +public class PropertyMap { + + private final Map properties = new HashMap(); + + public PropertyMap set(String name, Object value) { + properties.put(name, value); + return this; } - public static Property _(String name, Object value) - { - return new Property(name, value); + public static PropertyMap props() { + return new PropertyMap(); } - public Object getValue() - { - return value; + public Map toMap() { + return properties; } - public String getName() - { - return name; + public static Map _(String name, Object value) { + return Collections.singletonMap(name,value); } } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/PropertyParser.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/PropertyParser.java deleted file mode 100644 index 0c57b701f..000000000 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/PropertyParser.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2010 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.template; - -import org.neo4j.graphdb.DynamicRelationshipType; -import org.springframework.data.graph.neo4j.template.util.Converter; - -import static java.lang.String.format; -import java.util.Map; -import java.util.Properties; -import java.util.SortedMap; -import java.util.TreeMap; - -public class PropertyParser -{ - private final Properties props; - private final Converter converter = new Converter(); - - public PropertyParser(final Properties props) - { - this.props = props; - } - - public void load(final GraphDescription graph) - { - final SortedMap sortedSet = new TreeMap(props); - for (Map.Entry entry : sortedSet.entrySet()) - { - if (entry.getKey() == null || entry.getValue() == null) - throw new IllegalArgumentException(format("%s=%s is partially null%nproperties %s", - entry.getKey(), entry.getValue(), props)); - - final String key = entry.getKey().toString(); - final String value = entry.getValue().toString(); - final String[] prop = key.split("\\."); - if (prop.length == 2) - { - final String[] values = value.split(":"); - if (values.length != 2) - graph.add(prop[0], prop[1], value); - else - { - graph.add(prop[0], prop[1], converter.convert(values[0], values[1])); - } - } else - { - final String[] relationships = key.split("->"); - if (relationships.length == 2) - { - graph.relate(relationships[0], DynamicRelationshipType.withName(relationships[1]), value); - } - } - } - } -} diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/RelationShipNodeInfo.java b/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/RelationShipNodeInfo.java deleted file mode 100644 index 059a6f60c..000000000 --- a/spring-data-neo4j/src/main/java/org/springframework/data/graph/neo4j/template/RelationShipNodeInfo.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2010 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.template; - -import org.neo4j.graphdb.RelationshipType; - -class RelationShipNodeInfo -{ - private final RelationshipType relationshipType; - private final NodeInfo nodeInfo; - - RelationShipNodeInfo(final RelationshipType relationshipType, final NodeInfo nodeInfo) - { - this.relationshipType = relationshipType; - this.nodeInfo = nodeInfo; - } - - public boolean equals(final Object o) - { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - final RelationShipNodeInfo that = (RelationShipNodeInfo) o; - - return nodeInfo.equals(that.nodeInfo) && relationshipType.name().equals(that.relationshipType.name()); - - } - - public int hashCode() - { - return relationshipType.name().hashCode() * 31 + nodeInfo.hashCode(); - } - - public NodeInfo getNodeInfo() - { - return nodeInfo; - } - - public RelationshipType getRelationshipType() - { - return relationshipType; - } -} diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/Neo4jTemplateApiTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/Neo4jTemplateApiTest.java index b97103d48..50e2ab848 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/Neo4jTemplateApiTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/Neo4jTemplateApiTest.java @@ -1,30 +1,24 @@ package org.springframework.data.graph.neo4j.template; import org.apache.lucene.index.Term; -import org.apache.lucene.search.NumericRangeQuery; import org.apache.lucene.search.TermQuery; -import org.hamcrest.CoreMatchers; -import org.hibernate.ejb.criteria.ParameterContainer; -import org.jboss.netty.util.HashedWheelTimer; import org.junit.*; -import org.mockito.Mockito; import org.neo4j.graphdb.*; import org.neo4j.kernel.ImpermanentGraphDatabase; import org.neo4j.kernel.Traversal; import org.springframework.dao.DataAccessException; -import org.springframework.dao.InvalidDataAccessApiUsageException; -import org.springframework.data.graph.neo4j.support.node.Neo4jHelper; - -import javax.print.attribute.HashAttributeSet; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionTemplate; import java.util.Iterator; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.springframework.data.graph.neo4j.template.Property._; +import static org.junit.Assert.*; +import static org.springframework.data.graph.neo4j.template.PropertyMap._; +import static org.springframework.data.graph.neo4j.template.PropertyMap.props; /** * @author mh @@ -34,14 +28,17 @@ public class Neo4jTemplateApiTest { private static final DynamicRelationshipType KNOWS = DynamicRelationshipType.withName("knows"); private static final DynamicRelationshipType HAS = DynamicRelationshipType.withName("has"); private Neo4jTemplate template; - private static ImpermanentGraphDatabase graphDatabase; + private static GraphDatabaseService graphDatabase; + private static PlatformTransactionManager tm; private Node referenceNode; private Relationship relationship1; private Node node1; + @BeforeClass public static void startDb() throws Exception { graphDatabase = new ImpermanentGraphDatabase(); +// tm = new JtaTransactionManager(new SpringTransactionManager(graphDatabase)); } @Before @@ -86,9 +83,9 @@ public class Neo4jTemplateApiTest { @Test public void shouldExecuteCallbackInTransaction() throws Exception { - Node refNode = template.doInTransaction(new GraphTransactionCallback() { + Node refNode = template.update(new GraphCallback() { @Override - public Node doWithGraph(Status status, GraphDatabaseService graph) throws Exception { + public Node doWithGraph(GraphDatabaseService graph) throws Exception { Node referenceNode = graph.getReferenceNode(); referenceNode.setProperty("test", "testDoInTransaction"); return referenceNode; @@ -101,10 +98,10 @@ public class Neo4jTemplateApiTest { @Test public void shouldRollbackTransactionOnException() { try { - template.doInTransaction(new GraphTransactionCallback.WithoutResult() { + template.update(new GraphCallback.WithoutResult() { @Override - public void doWithGraphWithoutResult(Status status, GraphDatabaseService graph) throws Exception { - graph.getReferenceNode().setProperty("test","shouldRollbackTransactionOnException"); + public void doWithGraphWithoutResult(GraphDatabaseService graph) throws Exception { + graph.getReferenceNode().setProperty("test", "shouldRollbackTransactionOnException"); throw new RuntimeException("please rollback"); } }); @@ -115,12 +112,18 @@ public class Neo4jTemplateApiTest { } @Test + @Ignore("until the ImpermanentGraphDatabase cast issue is resolved in neo4j") public void shouldRollbackViaStatus() throws Exception { - template.doInTransaction(new GraphTransactionCallback.WithoutResult() { + new TransactionTemplate(tm).execute(new TransactionCallbackWithoutResult() { @Override - public void doWithGraphWithoutResult(Status status, GraphDatabaseService graph) throws Exception { - graph.getReferenceNode().setProperty("test","shouldRollbackTransactionOnException"); - status.mustRollback(); + protected void doInTransactionWithoutResult(final TransactionStatus status) { + template.update(new GraphCallback.WithoutResult() { + @Override + public void doWithGraphWithoutResult(GraphDatabaseService graph) throws Exception { + graph.getReferenceNode().setProperty("test", "shouldRollbackTransactionOnException"); + status.setRollbackOnly(); + } + }); } }); Assert.assertThat((String) graphDatabase.getReferenceNode().getProperty("test","not set"), not("shouldRollbackTransactionOnException")); @@ -128,7 +131,7 @@ public class Neo4jTemplateApiTest { @Test(expected = RuntimeException.class) public void shouldNotConvertUserRuntimeExceptionToDataAccessException() { - template.execute(new GraphCallback.WithoutResult() { + template.exec(new GraphCallback.WithoutResult() { @Override public void doWithGraphWithoutResult(GraphDatabaseService graph) throws Exception { throw new RuntimeException(); @@ -138,7 +141,7 @@ public class Neo4jTemplateApiTest { @Test(expected = DataAccessException.class) public void shouldConvertMissingTransactionExceptionToDataAccessException() { - template.execute(new GraphCallback.WithoutResult() { + template.exec(new GraphCallback.WithoutResult() { @Override public void doWithGraphWithoutResult(GraphDatabaseService graph) throws Exception { graph.createNode(); @@ -147,7 +150,7 @@ public class Neo4jTemplateApiTest { } @Test(expected = DataAccessException.class) public void shouldConvertNotFoundExceptionToDataAccessException() { - template.execute(new GraphCallback.WithoutResult() { + template.exec(new GraphCallback.WithoutResult() { @Override public void doWithGraphWithoutResult(GraphDatabaseService graph) throws Exception { graph.getNodeById(Long.MAX_VALUE); @@ -161,7 +164,7 @@ public class Neo4jTemplateApiTest { @Test public void shouldExecuteCallback() throws Exception { - Long refNodeId = template.execute(new GraphCallback() { + Long refNodeId = template.exec(new GraphCallback() { @Override public Long doWithGraph(GraphDatabaseService graph) throws Exception { return graph.getReferenceNode().getId(); @@ -177,17 +180,13 @@ public class Neo4jTemplateApiTest { @Test public void testCreateNode() throws Exception { - Node node=template.createNode(); + Node node=template.createNode(null); assertNotNull("created node",node); } - @Test(expected = InvalidDataAccessApiUsageException.class) - public void shouldFailForNullProperties() throws Exception { - template.createNode(null); - } @Test public void testCreateNodeWithProperties() throws Exception { - Node node=template.createNode(_("test", "testCreateNodeWithProperties")); + Node node=template.createNode(props().set("test", "testCreateNodeWithProperties").toMap()); assertTestPropertySet(node, "testCreateNodeWithProperties"); } @@ -216,47 +215,47 @@ public class Neo4jTemplateApiTest { @Test public void testIndexNode() throws Exception { - template.index(node1,null,"name","node1"); + template.index(null, node1, "name","node1"); Node lookedUpNode=graphDatabase.index().forNodes("node").get("name","node1").getSingle(); assertThat("same node from index",lookedUpNode,is(node1)); } @Test public void testQueryNodes() throws Exception { - assertSingleResult("node0", template.queryNodes(null, new TermQuery(new Term("name", "node0")), new NodeNameMapper())); + assertSingleResult("node0", template.query(null, new NodeNameMapper(), new TermQuery(new Term("name", "node0")))); } @Test public void testRetrieveNodes() throws Exception { - assertSingleResult("node0", template.retrieveNodes(null, "name", "node0", new NodeNameMapper())); + assertSingleResult("node0", template.query(null, new NodeNameMapper(), "name", "node0")); } @Test public void testQueryRelationships() throws Exception { - assertSingleResult("rel1", template.queryRelationships(null, new TermQuery(new Term("name", "rel1")), new RelationshipNameMapper())); + assertSingleResult("rel1", template.query("relationship", new RelationshipNameMapper(), new TermQuery(new Term("name", "rel1")))); } @Test public void testRetrieveRelationships() throws Exception { - assertSingleResult("rel1",template.retrieveRelationships(null, "name", "rel1", new RelationshipNameMapper())); + assertSingleResult("rel1",template.query("relationship", new RelationshipNameMapper(), "name", "rel1")); } @Test public void testTraverse() throws Exception { - assertSingleResult("node1",template.traverse(referenceNode, Traversal.description().relationships(KNOWS).prune(Traversal.pruneAfterDepth(1)).filter(Traversal.returnAllButStartNode()), new NodeNameMapper())); + assertSingleResult("node1",template.traverseGraph(referenceNode, new NodeNameMapper(), Traversal.description().relationships(KNOWS).prune(Traversal.pruneAfterDepth(1)).filter(Traversal.returnAllButStartNode()))); } @Test public void shouldGetDirectRelationship() throws Exception { - assertSingleResult("rel1", template.traverseDirectRelationships(referenceNode, new RelationshipNameMapper())); + assertSingleResult("rel1", template.traverseNext(referenceNode, new RelationshipNameMapper())); } @Test public void shouldGetDirectRelationshipForType() throws Exception { - assertSingleResult("rel1", template.traverseDirectRelationships(referenceNode, new RelationshipNameMapper(),KNOWS)); + assertSingleResult("rel1", template.traverseNext(referenceNode, new RelationshipNameMapper(), KNOWS)); } @Test public void shouldGetDirectRelationshipForTypeAndDirection() throws Exception { - assertSingleResult("rel1", template.traverseDirectRelationships(referenceNode, KNOWS, Direction.OUTGOING, new RelationshipNameMapper())); + assertSingleResult("rel1", template.traverseNext(referenceNode, new RelationshipNameMapper(), KNOWS, Direction.OUTGOING)); } private void assertSingleResult(T expected, Iterable iterable) { diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/Neo4jTemplateTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/Neo4jTemplateTest.java index 06bebebc4..37139562c 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/Neo4jTemplateTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/Neo4jTemplateTest.java @@ -15,7 +15,7 @@ public class Neo4jTemplateTest extends NeoApiTest { @Test public void testRefNode() { - Node refNodeById = new Neo4jTemplate(graph).execute(new GraphCallback() { + Node refNodeById = new Neo4jTemplate(graph).exec(new GraphCallback() { public Node doWithGraph(GraphDatabaseService graph) throws Exception { Node refNode = graph.getReferenceNode(); return graph.getNodeById(refNode.getId()); @@ -27,8 +27,8 @@ public class Neo4jTemplateTest extends NeoApiTest { @Test public void testSingleNode() { final Neo4jOperations template = new Neo4jTemplate(graph); - template.doInTransaction(new GraphTransactionCallback() { - public Void doWithGraph(Status status, GraphDatabaseService graph) throws Exception { + template.update(new GraphCallback() { + public Void doWithGraph(GraphDatabaseService graph) throws Exception { Node refNode = graph.getReferenceNode(); // TODO easy API Node node = graph.createNode(Property._("name", "Test"), Property._("size", 100)); Node node = graph.createNode(); @@ -43,8 +43,8 @@ public class Neo4jTemplateTest extends NeoApiTest { return null; } }); - template.doInTransaction(new GraphTransactionCallback() { - public Void doWithGraph(Status status, GraphDatabaseService graph) throws Exception { + template.update(new GraphCallback() { + public Void doWithGraph(GraphDatabaseService graph) throws Exception { Node refNode = graph.getReferenceNode(); final Relationship toTestNode = refNode.getSingleRelationship(HAS, Direction.OUTGOING); final Node nodeByRelationship = toTestNode.getEndNode(); @@ -58,16 +58,18 @@ public class Neo4jTemplateTest extends NeoApiTest { @Test public void testRollback() { final Neo4jOperations template = new Neo4jTemplate(graph); - template.doInTransaction(new GraphTransactionCallback.WithoutResult() { + try { + template.update(new GraphCallback.WithoutResult() { @Override - public void doWithGraphWithoutResult(Status status, GraphDatabaseService graph) throws Exception { + public void doWithGraphWithoutResult(GraphDatabaseService graph) throws Exception { Node node = graph.getReferenceNode(); node.setProperty("test", "test"); assertEquals("test", node.getProperty("test")); - status.mustRollback(); + throw new RuntimeException(); } }); - template.execute(new GraphCallback.WithoutResult() { + } catch(RuntimeException ignore) {} + template.exec(new GraphCallback.WithoutResult() { public void doWithGraphWithoutResult(final GraphDatabaseService graph) throws Exception { Node node = graph.getReferenceNode(); assertFalse(node.hasProperty("test")); diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoApiTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoApiTest.java index 85f8ba3d5..ff698c3e5 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoApiTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoApiTest.java @@ -7,10 +7,13 @@ import org.neo4j.kernel.EmbeddedGraphDatabase; public abstract class NeoApiTest { protected GraphDatabaseService graph; + protected Neo4jTemplate template; + @Before public void setUp() { graph = new EmbeddedGraphDatabase("target/template-db"); + template = new Neo4jTemplate(graph); } @After @@ -23,8 +26,8 @@ public abstract class NeoApiTest { private void clear() { try { - new Neo4jTemplate(graph).doInTransaction(new GraphTransactionCallback() { - public Void doWithGraph(Status status, GraphDatabaseService graph) throws Exception { + template.update(new GraphCallback() { + public Void doWithGraph(GraphDatabaseService graph) throws Exception { for (Node node : graph.getAllNodes()) { for (Relationship relationship : node.getRelationships()) { relationship.delete(); diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoGraphDescriptionTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoGraphDescriptionTest.java deleted file mode 100644 index 8015ac7b6..000000000 --- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoGraphDescriptionTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package org.springframework.data.graph.neo4j.template; - -import org.junit.Test; -import org.neo4j.graphdb.Direction; -import org.neo4j.graphdb.GraphDatabaseService; -import org.neo4j.graphdb.Node; -import org.neo4j.graphdb.RelationshipType; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Properties; - -import static org.junit.Assert.assertEquals; -import static org.springframework.data.graph.neo4j.template.NeoGraphDescriptionTest.Type.HAS; - - -public class NeoGraphDescriptionTest extends NeoApiTest { - - enum Type implements RelationshipType { - HAS - } - - @Test - public void testLoadGraph() { - final Neo4jOperations template = new Neo4jTemplate(graph); - template.doInTransaction(new GraphTransactionCallback.WithoutResult() { - public void doWithGraphWithoutResult(Status status, GraphDatabaseService graph) throws Exception { - final GraphDescription heaven = new GraphDescription(); - heaven.add("adam", "age", 1); - heaven.add("eve", "age", 0); - heaven.relate("adam", HAS, "eve"); - heaven.addToGraph(graph); - checkHeaven(graph); - } - }); - } - - private void checkHeaven(final GraphDatabaseService graph) { - final Node adam = graph.getReferenceNode(); - assertEquals("adam", adam.getProperty("name")); - assertEquals(1, adam.getProperty("age")); - final Node eve = adam.getSingleRelationship(HAS, Direction.OUTGOING).getEndNode(); - assertEquals("eve", eve.getProperty("name")); - assertEquals(0, eve.getProperty("age")); - } - - @Test - public void testLoadGraphProps() { - final Neo4jOperations template = new Neo4jTemplate(graph); - template.doInTransaction(new GraphTransactionCallback.WithoutResult() { - public void doWithGraphWithoutResult(Status status, GraphDatabaseService graph) throws Exception { - final GraphDescription heaven = new GraphDescription(createGraphProperties()); - heaven.addToGraph(graph); - checkHeaven(graph); - } - }); - } - - private Properties createGraphProperties() throws IOException { - Properties props = new Properties(); - props.load(new ByteArrayInputStream(( - "adam.age=Integer:1\n" + - "eve.age=Integer:0\n" + - "adam->HAS=eve" - ).getBytes("UTF-8"))); - return props; - } -} \ No newline at end of file diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoTraversalTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoTraversalTest.java index 2ae56b5cd..a329a5434 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoTraversalTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/graph/neo4j/template/NeoTraversalTest.java @@ -1,18 +1,20 @@ package org.springframework.data.graph.neo4j.template; -import org.junit.Ignore; import org.junit.Test; import org.neo4j.graphdb.GraphDatabaseService; +import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.RelationshipType; -import org.neo4j.graphdb.traversal.TraversalDescription; -import org.neo4j.helpers.collection.IteratorUtil; import org.neo4j.kernel.Traversal; +import java.util.HashSet; +import java.util.Set; + import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; import static org.neo4j.kernel.Traversal.returnAllButStartNode; import static org.springframework.data.graph.neo4j.template.NeoTraversalTest.Type.HAS; +import static org.springframework.data.graph.neo4j.template.PropertyMap._; public class NeoTraversalTest extends NeoApiTest { @@ -22,73 +24,56 @@ public class NeoTraversalTest extends NeoApiTest { @Test public void testSimpleTraverse() { - runAndCheckTraverse(Traversal.description().filter(returnAllButStartNode()).relationships(HAS), "grandpa", "grandma","daughter","son","man","wife" ); - } - - - @Ignore - @Test - public void testComplexTraversal() { - final TraversalDescription traversal = Traversal.description().relationships(HAS).prune(Traversal.pruneAfterDepth(1)); - runAndCheckTraverse(traversal, "grandpa", "grandma", "daughter", "son", "man", "wife"); - } - - private void runAndCheckTraverse(final TraversalDescription traversal, final String... names) { - final Neo4jOperations template = new Neo4jTemplate(graph); - template.doInTransaction(new GraphTransactionCallback() { - public Void doWithGraph(Status status, GraphDatabaseService graph) throws Exception { - createFamily(graph); + template.update(new GraphCallback() { + public Void doWithGraph(GraphDatabaseService graph) throws Exception { + createFamily(); return null; - }}); - Iterable result=template.traverse(template.getReferenceNode(), traversal, - new PathMapper() { - @Override - public String mapPath(Path path) { - return (String) path.endNode().getProperty("name", ""); - } - }); - assertEquals("all members", asList(names), IteratorUtil.asCollection(result)); + } + }); + + final Set resultSet = new HashSet(); + template.traverseGraph(template.getReferenceNode(), new PathMapper.WithoutResult() { + @Override + public void eachPath(Path path) { + String nodeName = (String) path.endNode().getProperty("name", ""); + resultSet.add(nodeName); + } + }, Traversal.description().filter(returnAllButStartNode()).relationships(HAS)); + assertEquals("all members", new HashSet(asList("grandpa", "grandma", "daughter", "son", "man", "wife", "family")), resultSet); } - private void createFamily(final GraphDatabaseService graph) { - final GraphDescription family = new GraphDescription(); - family.add("family", "type", "small"); - family.relate("family", HAS, "wife"); - family.relate("family", HAS, "man"); + private void createFamily() { - family.add("man", "age", 35); - family.add("wife", "age", 30); - family.relate("man", Type.MARRIED, "wife"); - family.relate("wife", Type.MARRIED, "man"); - family.relate("man", Type.WIFE, "wife"); - family.relate("wife", Type.HUSBAND, "man"); + Node family = template.createNode(_("name", "family")); + Node man = template.createNode(_("name", "wife")); + Node wife = template.createNode(_("name", "man")); + family.createRelationshipTo(man, HAS); + family.createRelationshipTo(wife, HAS); - family.add("daughter", "age", 10); - family.add("son", "age", 8); + Node daughter = template.createNode(_("name", "daughter")); + family.createRelationshipTo(daughter, HAS); + Node son = template.createNode(_("name", "son")); + family.createRelationshipTo(son, HAS); + man.createRelationshipTo(son, Type.CHILD); + wife.createRelationshipTo(son, Type.CHILD); + man.createRelationshipTo(daughter, Type.CHILD); + wife.createRelationshipTo(daughter, Type.CHILD); - family.relate("family", HAS, "son"); - family.relate("family", HAS, "daughter"); + Node grandma = template.createNode(_("name", "grandma")); + Node grandpa = template.createNode(_("name", "grandpa")); - family.relate("man", Type.CHILD, "son"); - family.relate("wife", Type.CHILD, "son"); - family.relate("man", Type.CHILD, "daughter"); - family.relate("wife", Type.CHILD, "daughter"); + family.createRelationshipTo(grandma, HAS); + family.createRelationshipTo(grandpa, HAS); - family.add("grandma", "age", 60); - family.add("grandpa", "age", 75); + grandma.createRelationshipTo(man, Type.CHILD); + grandpa.createRelationshipTo(man, Type.CHILD); - family.relate("family", HAS, "grandma"); - family.relate("family", HAS, "grandpa"); + grandma.createRelationshipTo(son, Type.GRANDSON); + grandpa.createRelationshipTo(son, Type.GRANDSON); + grandma.createRelationshipTo(daughter, Type.GRANDDAUGHTER); + grandpa.createRelationshipTo(daughter, Type.GRANDDAUGHTER); - family.relate("grandpa", Type.CHILD, "man"); - family.relate("grandma", Type.CHILD, "man"); - - family.relate("grandpa", Type.GRANDSON, "son"); - family.relate("grandma", Type.GRANDSON, "son"); - family.relate("grandpa", Type.GRANDDAUGHTER, "daughter"); - family.relate("grandma", Type.GRANDDAUGHTER, "daughter"); - - family.addToGraph(graph); + graph.getReferenceNode().createRelationshipTo(family,HAS); } } \ No newline at end of file