From a8c223f0d13ad9db79e9873ca905927c601ec917 Mon Sep 17 00:00:00 2001 From: Michael Hunger Date: Mon, 18 Jul 2011 16:25:07 +0200 Subject: [PATCH] API cleanup Neo4jTemplate, Renaming EmbeddedQueryEngine to CypherQueryEngine --- ...Engine.java => RestCypherQueryEngine.java} | 11 +- .../data/neo4j/rest/RestGraphDatabase.java | 3 +- .../data/neo4j/conversion/QueryResult.java | 1 + .../neo4j/conversion/QueryResultBuilder.java | 51 +++++- .../data/neo4j/core/GraphDatabase.java | 4 +- .../support/DelegatingGraphDatabase.java | 6 +- ...ueryEngine.java => CypherQueryEngine.java} | 6 +- .../neo4j/support/query/QueryExecutor.java | 2 +- .../data/neo4j/template/Neo4jOperations.java | 81 +--------- .../data/neo4j/template/Neo4jTemplate.java | 147 +----------------- .../neo4j/template/Neo4jTemplateApiTest.java | 42 +++-- .../data/neo4j/template/NeoTraversalTest.java | 19 ++- 12 files changed, 118 insertions(+), 255 deletions(-) rename spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/{RestQueryEngine.java => RestCypherQueryEngine.java} (92%) rename spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/{EmbeddedQueryEngine.java => CypherQueryEngine.java} (91%) diff --git a/spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestQueryEngine.java b/spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestCypherQueryEngine.java similarity index 92% rename from spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestQueryEngine.java rename to spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestCypherQueryEngine.java index e922eae92..c55edd66e 100644 --- a/spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestQueryEngine.java +++ b/spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestCypherQueryEngine.java @@ -26,15 +26,15 @@ import java.util.*; * @author mh * @since 22.06.11 */ -public class RestQueryEngine implements QueryEngine { +public class RestCypherQueryEngine implements QueryEngine { private final RestRequest restRequest; private final RestGraphDatabase restGraphDatabase; private final ResultConverter resultConverter; - public RestQueryEngine(RestGraphDatabase restGraphDatabase) { + public RestCypherQueryEngine(RestGraphDatabase restGraphDatabase) { this(restGraphDatabase,null); } - public RestQueryEngine(RestGraphDatabase restGraphDatabase, ResultConverter resultConverter) { + public RestCypherQueryEngine(RestGraphDatabase restGraphDatabase, ResultConverter resultConverter) { this.restGraphDatabase = restGraphDatabase; this.resultConverter = resultConverter!=null ? resultConverter : new DefaultConverter(); this.restRequest = restGraphDatabase.getRestRequest(); @@ -65,6 +65,11 @@ public class RestQueryEngine implements QueryEngine { return result.to(type,converter); } + @Override + public void handle(Handler> handler) { + result.handle(handler); + } + @Override public Iterator> iterator() { return result.iterator(); diff --git a/spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestGraphDatabase.java b/spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestGraphDatabase.java index 33721ecfe..645786954 100644 --- a/spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestGraphDatabase.java +++ b/spring-data-neo4j-rest/src/main/java/org/springframework/data/neo4j/rest/RestGraphDatabase.java @@ -27,7 +27,6 @@ import org.springframework.data.neo4j.core.GraphDatabase; import org.springframework.data.neo4j.core.Property; import org.springframework.data.neo4j.conversion.ResultConverter; import org.springframework.data.neo4j.rest.index.RestIndexManager; -import org.springframework.data.neo4j.rest.index.RestIndexManager; import org.springframework.data.neo4j.support.query.ConversionServiceQueryResultConverter; import org.springframework.data.neo4j.support.query.QueryEngine; @@ -106,7 +105,7 @@ public class RestGraphDatabase implements GraphDatabaseService, GraphDatabase { @Override public QueryEngine queryEngineFor(QueryEngine.Type type) { - return new RestQueryEngine(this, createResultConverter()); + return new RestCypherQueryEngine(this, createResultConverter()); } private ResultConverter createResultConverter() { diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/QueryResult.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/QueryResult.java index 5a0eae281..d0d36f6b6 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/QueryResult.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/QueryResult.java @@ -23,4 +23,5 @@ package org.springframework.data.neo4j.conversion; public interface QueryResult extends Iterable { ConvertedResult to(Class type); ConvertedResult to(Class type, ResultConverter resultConverter); + void handle(Handler handler); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/QueryResultBuilder.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/QueryResultBuilder.java index 0c8e63aed..4a81fe2ac 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/QueryResultBuilder.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/conversion/QueryResultBuilder.java @@ -16,6 +16,8 @@ package org.springframework.data.neo4j.conversion; +import org.neo4j.graphdb.index.IndexHits; +import org.neo4j.helpers.collection.ClosableIterable; import org.neo4j.helpers.collection.IteratorWrapper; import java.util.Iterator; @@ -27,6 +29,8 @@ import java.util.Iterator; public class QueryResultBuilder implements QueryResult { private Iterable result; private final ResultConverter defaultConverter; + private final boolean isClosableIterable; + private boolean isClosed; public QueryResultBuilder(Iterable result) { this(result, new DefaultConverter()); @@ -34,6 +38,7 @@ public class QueryResultBuilder implements QueryResult { public QueryResultBuilder(Iterable result, final ResultConverter defaultConverter) { this.result = result; + this.isClosableIterable = result instanceof IndexHits || result instanceof ClosableIterable; this.defaultConverter = defaultConverter; } @@ -47,17 +52,26 @@ public class QueryResultBuilder implements QueryResult { return new ConvertedResult() { @Override public R single() { - final Iterator it = result.iterator(); - if (!it.hasNext()) throw new IllegalStateException("Expected at least one result, got none."); - final T value = it.next(); - if (it.hasNext()) throw new IllegalStateException("Expected at least one result, got more than one."); - return resultConverter.convert(value, type); + try { + final Iterator it = result.iterator(); + if (!it.hasNext()) throw new IllegalStateException("Expected at least one result, got none."); + final T value = it.next(); + if (it.hasNext()) + throw new IllegalStateException("Expected at least one result, got more than one."); + return resultConverter.convert(value, type); + } finally { + closeIfNeeded(); + } } @Override public void handle(Handler handler) { - for (T value : result) { - handler.handle(resultConverter.convert(value, type)); + try { + for (T value : result) { + handler.handle(resultConverter.convert(value, type)); + } + } finally { + closeIfNeeded(); } } @@ -72,6 +86,29 @@ public class QueryResultBuilder implements QueryResult { }; } + @Override + public void handle(Handler handler) { + try { + for (T value : result) { + handler.handle(value); + } + } finally { + closeIfNeeded(); + } + } + + + private void closeIfNeeded() { + if (isClosableIterable && !isClosed) { + if (result instanceof IndexHits) { + ((IndexHits) result).close(); + } else if (result instanceof ClosableIterable) { + ((ClosableIterable) result).close(); + } + isClosed=true; + } + } + @Override public Iterator iterator() { return result.iterator(); diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/core/GraphDatabase.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/core/GraphDatabase.java index c430630c6..aeaa2c95e 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/core/GraphDatabase.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/core/GraphDatabase.java @@ -23,7 +23,7 @@ import org.neo4j.graphdb.RelationshipType; import org.neo4j.graphdb.index.Index; import org.neo4j.graphdb.traversal.TraversalDescription; import org.springframework.core.convert.ConversionService; -import org.springframework.data.neo4j.support.query.EmbeddedQueryEngine; +import org.springframework.data.neo4j.support.query.CypherQueryEngine; import org.springframework.data.neo4j.support.query.QueryEngine; @@ -95,7 +95,7 @@ public interface GraphDatabase { */ TraversalDescription createTraversalDescription(); - QueryEngine queryEngineFor(EmbeddedQueryEngine.Type type); + QueryEngine queryEngineFor(CypherQueryEngine.Type type); void setConversionService(ConversionService conversionService); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/DelegatingGraphDatabase.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/DelegatingGraphDatabase.java index 523128bae..292cea6e5 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/DelegatingGraphDatabase.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/DelegatingGraphDatabase.java @@ -26,7 +26,7 @@ import org.springframework.core.convert.ConversionService; import org.springframework.data.neo4j.core.GraphDatabase; import org.springframework.data.neo4j.core.Property; import org.springframework.data.neo4j.support.query.ConversionServiceQueryResultConverter; -import org.springframework.data.neo4j.support.query.EmbeddedQueryEngine; +import org.springframework.data.neo4j.support.query.CypherQueryEngine; import org.springframework.data.neo4j.support.query.QueryEngine; import java.util.Map; @@ -126,8 +126,8 @@ public class DelegatingGraphDatabase implements GraphDatabase { } @Override - public QueryEngine queryEngineFor(EmbeddedQueryEngine.Type type) { - return new EmbeddedQueryEngine(delegate, createResultConverter()); + public QueryEngine queryEngineFor(CypherQueryEngine.Type type) { + return new CypherQueryEngine(delegate, createResultConverter()); } private ConversionServiceQueryResultConverter createResultConverter() { diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/EmbeddedQueryEngine.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/CypherQueryEngine.java similarity index 91% rename from spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/EmbeddedQueryEngine.java rename to spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/CypherQueryEngine.java index 01151aba9..95ccc4766 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/EmbeddedQueryEngine.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/CypherQueryEngine.java @@ -29,18 +29,18 @@ import org.springframework.data.neo4j.conversion.ResultConverter; import java.util.Map; -public class EmbeddedQueryEngine implements QueryEngine, QueryOperations { +public class CypherQueryEngine implements QueryEngine, QueryOperations { final ExecutionEngine executionEngine; private ResultConverter resultConverter; private final DefaultQueryOperations queryOperations; - public EmbeddedQueryEngine(GraphDatabaseService graphDatabaseService) { + public CypherQueryEngine(GraphDatabaseService graphDatabaseService) { this(graphDatabaseService, new DefaultConverter()); } - public EmbeddedQueryEngine(GraphDatabaseService graphDatabaseService, ResultConverter resultConverter) { + public CypherQueryEngine(GraphDatabaseService graphDatabaseService, ResultConverter resultConverter) { this.resultConverter = resultConverter != null ? resultConverter : new DefaultConverter(); this.executionEngine = new ExecutionEngine(graphDatabaseService); this.queryOperations = new DefaultQueryOperations(this); diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/QueryExecutor.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/QueryExecutor.java index 8cc1af88d..a5df1bafe 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/QueryExecutor.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/support/query/QueryExecutor.java @@ -31,7 +31,7 @@ public class QueryExecutor implements QueryOperations { public QueryExecutor(GraphDatabaseContext ctx) { EntityResultConverter converter = new EntityResultConverter(ctx); - queryEngine = new EmbeddedQueryEngine(ctx.getGraphDatabaseService(), converter); + queryEngine = new CypherQueryEngine(ctx.getGraphDatabaseService(), converter); } public Iterable> queryForList(String statement) { diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jOperations.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jOperations.java index be482b73a..a74ef89ea 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jOperations.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jOperations.java @@ -18,10 +18,8 @@ package org.springframework.data.neo4j.template; import org.neo4j.graphdb.*; import org.neo4j.graphdb.traversal.TraversalDescription; -import org.neo4j.helpers.collection.ClosableIterable; +import org.springframework.data.neo4j.conversion.QueryResult; import org.springframework.data.neo4j.core.Property; -import org.springframework.data.neo4j.support.path.PathMapper; -import org.springframework.data.neo4j.support.query.QueryEngine; import java.util.Map; @@ -89,73 +87,6 @@ public interface Neo4jOperations { */ Relationship createRelationship(Node startNode, Node endNode, RelationshipType type, Property... props); - /** - * Queries the supplied index with a lucene query string or query object (if the neo4j-index provider is lucene) - * - * - * @param indexName Name of the index, will be checked against existing indexes, first relationship-indexes, then node indexes - * assumes a "node" node index for a null value - * @param queryOrQueryObject a lucene query string or query object (if the neo4j-index provider is lucene) - * @param pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour - * @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the query result mapping - * @see org.springframework.data.neo4j.support.path.IterationController for controlling eagerness of iteration - */ - ClosableIterable lookup(String indexName, Object queryOrQueryObject, PathMapper pathMapper); - - /** - * Queries the supplied index with a field - value combination - * - * - * @param indexName Name of the index, will be checked against existing indexes, first relationship-indexes, then node indexes - * assumes a "node" node index for a null value - * @param field field to query - * @param value value to supply to index query - * @param pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour - * @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the query result mapping - * @see org.springframework.data.neo4j.support.path.IterationController for controlling eagerness of iteration - */ - ClosableIterable lookup(String indexName, String field, String value, PathMapper pathMapper); - - /** - * Traverses the whole path with the given traversal descripting starting at the start node. - * - * @param traversal a traversal description, possibly generated by the Traversal.description()... DSL - * @param startNode start node for the traversal - * @param pathMapper pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour - * @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the traversal result mapping - */ - Iterable traverse(TraversalDescription traversal, Node startNode, PathMapper pathMapper); - - /** - * Traverses only to the direct neighbours of the start node - * @param startNode start node for the traversal - * @param pathMapper pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour - * @param type type of relationships to consider - * @param direction direction of relationship to consider (can be OUTGOING, INCOMING, BOTH) - * @param expected type of result - * @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the traversal result mapping - */ - Iterable traverseNext(Node startNode, PathMapper pathMapper, RelationshipType type, Direction direction); - - /** - * Traverses only to the direct neighbours of the start node for the specified relationship types - * @param startNode start node for the traversal - * @param pathMapper pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour - * @param types types of relationships to consider - * @param expected type of result - * @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the traversal result mapping - */ - Iterable traverseNext(Node startNode, PathMapper pathMapper, RelationshipType... types); - - /** - * Traverses only to all direct neighbours of the start node for all relationships - * @param startNode start node for the traversal - * @param pathMapper pathMapper a mapper that translates from the resulting paths into some domain object, might use PathMapper.WithoutResult for a callback behaviour - * @param expected type of result - * @return a lazy (when mapped) or eagerly (when called back) iterable containing the results of the traversal result mapping - */ - Iterable traverseNext(Node startNode, PathMapper pathMapper); - /** * Indexes the given field and value for the element. * @param indexName Name of the index, will be checked against existing indexes according to the given element @@ -168,9 +99,13 @@ public interface Neo4jOperations { */ T index(String indexName, T element, String field, Object value); - Iterable> query(QueryEngine.Type engineType, String statement); + QueryResult convert(Iterable iterable); - Iterable query(QueryEngine.Type engineType, String statement, Class type); + QueryResult> query(String statement); - T queryForObject(QueryEngine.Type engineType, String statement, Class type); + QueryResult traverse(Node startNode, TraversalDescription traversal); + + QueryResult lookup(String indexName, String field, Object value); + + QueryResult lookup(String indexName, Object valueOrQueryObject); } diff --git a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jTemplate.java b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jTemplate.java index f944b501c..2e7e22365 100644 --- a/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jTemplate.java +++ b/spring-data-neo4j/src/main/java/org/springframework/data/neo4j/template/Neo4jTemplate.java @@ -30,9 +30,8 @@ import org.springframework.data.neo4j.core.GraphDatabase; import org.springframework.data.neo4j.core.Property; import org.springframework.data.neo4j.support.path.NodePath; import org.springframework.data.neo4j.support.path.PathMapper; -import org.springframework.data.neo4j.support.path.PathMappingIterator; import org.springframework.data.neo4j.support.path.RelationshipPath; -import org.springframework.data.neo4j.support.query.EmbeddedQueryEngine; +import org.springframework.data.neo4j.support.query.CypherQueryEngine; import org.springframework.data.neo4j.support.query.QueryEngine; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; @@ -167,34 +166,11 @@ public class Neo4jTemplate implements Neo4jOperations { } @Override - public ClosableIterable lookup(String indexName, Object queryOrQueryObject, final PathMapper pathMapper) { - notNull(queryOrQueryObject, "queryOrQueryObject", pathMapper, "pathMapper",indexName,"indexName"); - try { - Index index = graphDatabase.getIndex(indexName); - if (Relationship.class.isAssignableFrom(index.getEntityType())) { - return mapRelationships(((Index)index).query(queryOrQueryObject), pathMapper); - } - return mapNodes(((Index)index).query(queryOrQueryObject), pathMapper); - } catch (RuntimeException e) { - throw translateExceptionIfPossible(e); - } + public QueryResult convert(Iterable iterable) { + return new QueryResultBuilder(iterable); } - @Override - public ClosableIterable lookup(String indexName, String field, String value, final PathMapper pathMapper) { - notNull(field, "field", value, "value", pathMapper, "pathMapper", indexName, "indexName"); - try { - Index index = graphDatabase.getIndex(indexName); - if (Relationship.class.isAssignableFrom(index.getEntityType())) { - return mapRelationships(((Index)index).get(field, value), pathMapper); - } - return mapNodes(((Index)index).get(field, value), pathMapper); - } catch (RuntimeException e) { - throw translateExceptionIfPossible(e); - } - } - - private QueryEngine queryEngineFor(EmbeddedQueryEngine.Type type) { + private QueryEngine queryEngineFor(CypherQueryEngine.Type type) { return graphDatabase.queryEngineFor(type); } @@ -219,62 +195,6 @@ public class Neo4jTemplate implements Neo4jOperations { }; } - @Override - public Iterable traverse(TraversalDescription traversal, Node startNode, final PathMapper pathMapper) { - notNull(startNode, "startNode", traversal, "traversal", pathMapper, "pathMapper"); - try { - return mapPaths(traversal.traverse(startNode), pathMapper); - } catch (RuntimeException e) { - throw translateExceptionIfPossible(e); - } - } - - private Iterable mapPaths(final Iterable paths, final PathMapper pathMapper) { - return new PathMappingIterator().mapPaths(paths,pathMapper); - } - - - @Override - 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); - } catch (RuntimeException e) { - throw translateExceptionIfPossible(e); - } - } - - @Override - public Iterable traverseNext(Node startNode, final PathMapper pathMapper, RelationshipType... relationshipTypes) { - notNull(startNode, "startNode", relationshipTypes, "relationshipType", pathMapper, "pathMapper"); - try { - return mapRelationships(startNode.getRelationships(relationshipTypes), pathMapper); - } catch (RuntimeException e) { - throw translateExceptionIfPossible(e); - } - } - - @Override - public Iterable traverseNext(Node startNode, final PathMapper pathMapper) { - notNull(startNode, "startNode", pathMapper, "pathMapper"); - try { - return mapRelationships(startNode.getRelationships(), pathMapper); - } catch (RuntimeException e) { - throw translateExceptionIfPossible(e); - } - } - - private Iterable mapRelationships(final Iterable relationships, final PathMapper pathMapper) { - assert relationships != null; - assert pathMapper != null; - return new IterableWrapper(relationships) { - @Override - protected T underlyingObjectToObject(Relationship relationship) { - return pathMapper.mapPath(new RelationshipPath(relationship)); - } - }; - } - @Override public Relationship createRelationship(final Node startNode, final Node endNode, final RelationshipType relationshipType, final Property... properties) { notNull(startNode, "startNode", endNode, "endNode", relationshipType, "relationshipType", properties, "properties"); @@ -286,19 +206,6 @@ public class Neo4jTemplate implements Neo4jOperations { }); } - private T setProperties(T primitive, Map properties) { - assert primitive != null; - 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; - } - private static abstract class IndexHitsIterableWrapper extends IterableWrapper implements ClosableIterable { private final IndexHits indexHits; private final PathMapper pathMapper; @@ -323,25 +230,12 @@ public class Neo4jTemplate implements Neo4jOperations { } @Override - public Iterable> query(QueryEngine.Type engineType, String statement) { - return queryEngineFor(engineType).query(statement); - } - - @Override - public Iterable query(QueryEngine.Type engineType, String statement, Class type) { - return queryEngineFor(engineType).query(statement).to(type); - } - - @Override - public T queryForObject(QueryEngine.Type engineType, String statement, Class type) { - return queryEngineFor(engineType).query(statement).to(type).single(); - } - public QueryResult> query(String statement) { notNull(statement, "statement"); return queryEngineFor(QueryEngine.Type.Cypher).query(statement); } + @Override public QueryResult traverse(Node startNode, TraversalDescription traversal) { notNull(startNode, "startNode", traversal, "traversal"); try { @@ -351,6 +245,7 @@ public class Neo4jTemplate implements Neo4jOperations { } } + @Override public QueryResult lookup(String indexName, String field, Object value) { notNull(field, "field", value, "value", indexName, "indexName"); try { @@ -360,6 +255,7 @@ public class Neo4jTemplate implements Neo4jOperations { throw translateExceptionIfPossible(e); } } + @Override public QueryResult lookup(String indexName, Object valueOrQueryObject) { notNull(valueOrQueryObject, "valueOrQueryObject", indexName, "indexName"); try { @@ -369,35 +265,6 @@ public class Neo4jTemplate implements Neo4jOperations { throw translateExceptionIfPossible(e); } } - - { - /* - final Iterable nodes = query("start n=(0) return n").to(Node.class); - final Iterable nodePaths = query("start n=(0) return n").to(Path.class); - final Iterable costs = lookup("index", "field", "value").to(Long.class, new ResultConverter() { - @Override - public Long convert(Relationship value, Class type) { - return (Long) value.getProperty("cost"); - } - }); - final Iterable people = lookup("index", "field:value*").to(Person.class); - - lookup("index", "field:value*").to(Node.class).handle(new Handler() { - @Override - public void handle(Node node) { - node.setProperty("count",((Integer)node.getProperty("count",0))+1); - } - }); - - final Iterable endNodes = traverse(start, desc).to(Node.class); - final Iterable lastRelationships = traverse(start, desc).to(Relationship.class); - final Iterable pathLengths = traverse(start, desc).to(Integer.class, new ResultConverter() { - public Integer convert(Path path, Class type) { - return path.length(); - } - }); - */ - } } /* diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/Neo4jTemplateApiTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/Neo4jTemplateApiTest.java index f21280d8f..a000ce3aa 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/Neo4jTemplateApiTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/Neo4jTemplateApiTest.java @@ -24,13 +24,14 @@ import org.junit.Before; import org.junit.Test; import org.neo4j.graphdb.*; import org.neo4j.graphdb.index.Index; +import org.neo4j.graphdb.traversal.TraversalDescription; import org.neo4j.test.ImpermanentGraphDatabase; import org.neo4j.kernel.Traversal; import org.neo4j.kernel.impl.transaction.SpringTransactionManager; import org.springframework.dao.DataAccessException; +import org.springframework.data.neo4j.conversion.ResultConverter; import org.springframework.data.neo4j.core.GraphDatabase; import org.springframework.data.neo4j.support.DelegatingGraphDatabase; -import org.springframework.data.neo4j.support.path.PathMapper; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.jta.JtaTransactionManager; @@ -248,40 +249,41 @@ public class Neo4jTemplateApiTest { @Test public void testQueryNodes() throws Exception { - assertSingleResult("node0", template.lookup("node", new TermQuery(new Term("name", "node0")), new NodeNameMapper())); + assertSingleResult("node0", template.lookup("node", new TermQuery(new Term("name", "node0"))).to(String.class, new PropertyContainerNameConverter())); } @Test public void testRetrieveNodes() throws Exception { - assertSingleResult("node0", template.lookup("node", "name", "node0", new NodeNameMapper())); + assertSingleResult("node0", template.lookup("node", "name", "node0").to(String.class, new PropertyContainerNameConverter())); } @Test public void testQueryRelationships() throws Exception { - assertSingleResult("rel1", template.lookup("relationship", new TermQuery(new Term("name", "rel1")), new RelationshipNameMapper())); + assertSingleResult("rel1", template.lookup("relationship", new TermQuery(new Term("name", "rel1"))).to(String.class, new PropertyContainerNameConverter())); } @Test public void testRetrieveRelationships() throws Exception { - assertSingleResult("rel1",template.lookup("relationship", "name", "rel1", new RelationshipNameMapper())); + assertSingleResult("rel1",template.lookup("relationship", "name", "rel1").to(String.class, new PropertyContainerNameConverter())); } @Test public void testTraverse() throws Exception { - assertSingleResult("node1",template.traverse(Traversal.description().relationships(KNOWS).prune(Traversal.pruneAfterDepth(1)).filter(Traversal.returnAllButStartNode()), referenceNode, new NodeNameMapper())); + final TraversalDescription description = Traversal.description().relationships(KNOWS).prune(Traversal.pruneAfterDepth(1)).filter(Traversal.returnAllButStartNode()); + assertSingleResult("node1",template.traverse(referenceNode, description).to(String.class,new PathNodeNameMapper())); } @Test public void shouldGetDirectRelationship() throws Exception { - assertSingleResult("rel1", template.traverseNext(referenceNode, new RelationshipNameMapper())); + assertSingleResult("rel1", template.convert(referenceNode.getRelationships()).to(String.class, new RelationshipNameConverter())); } @Test public void shouldGetDirectRelationshipForType() throws Exception { - assertSingleResult("rel1", template.traverseNext(referenceNode, new RelationshipNameMapper(), KNOWS)); + assertSingleResult("rel1", template.convert(referenceNode.getRelationships(KNOWS)).to(String.class, new RelationshipNameConverter())); } @Test public void shouldGetDirectRelationshipForTypeAndDirection() throws Exception { - assertSingleResult("rel1", template.traverseNext(referenceNode, new RelationshipNameMapper(), KNOWS, Direction.OUTGOING)); + assertSingleResult("rel1", template.convert(referenceNode.getRelationships(KNOWS, Direction.OUTGOING)).to(String.class, new RelationshipNameConverter())); } private void assertSingleResult(T expected, Iterable iterable) { @@ -301,16 +303,30 @@ public class Neo4jTemplateApiTest { assertEquals("rel2",relationship.getProperty("name","not set")); } - private static class RelationshipNameMapper implements PathMapper { + private static class PathRelationshipNameMapper implements ResultConverter { @Override - public String mapPath(Path path) { + public String convert(Path path, Class type) { return (String) path.lastRelationship().getProperty("name","not set"); } } - private static class NodeNameMapper implements PathMapper { + private static class PathNodeNameMapper implements ResultConverter { @Override - public String mapPath(Path path) { + public String convert(Path path, Class type) { return (String) path.endNode().getProperty("name","not set"); } } + + private static class RelationshipNameConverter implements ResultConverter { + @Override + public String convert(Relationship value, Class type) { + return (String) value.getProperty("name"); + } + } + + private static class PropertyContainerNameConverter implements ResultConverter { + @Override + public String convert(PropertyContainer value, Class type) { + return (String) value.getProperty("name"); + } + } } diff --git a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/NeoTraversalTest.java b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/NeoTraversalTest.java index 7236658c4..7a718e4c0 100644 --- a/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/NeoTraversalTest.java +++ b/spring-data-neo4j/src/test/java/org/springframework/data/neo4j/template/NeoTraversalTest.java @@ -17,12 +17,14 @@ package org.springframework.data.neo4j.template; import org.junit.Test; -import org.springframework.data.neo4j.core.GraphDatabase; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Path; import org.neo4j.graphdb.RelationshipType; +import org.neo4j.graphdb.traversal.TraversalDescription; import org.neo4j.kernel.Traversal; -import org.springframework.data.neo4j.support.path.PathMapper; +import org.springframework.data.neo4j.conversion.Handler; +import org.springframework.data.neo4j.conversion.QueryResult; +import org.springframework.data.neo4j.core.GraphDatabase; import java.util.HashSet; import java.util.Set; @@ -49,13 +51,14 @@ public class NeoTraversalTest extends NeoApiTest { }); final Set resultSet = new HashSet(); - template.traverse(Traversal.description().relationships(HAS).filter(returnAllButStartNode()).prune(Traversal.pruneAfterDepth(2)), template.getReferenceNode(), new PathMapper.WithoutResult() { + final TraversalDescription description = Traversal.description().relationships(HAS).filter(returnAllButStartNode()).prune(Traversal.pruneAfterDepth(2)); + final QueryResult queryResult = template.traverse(template.getReferenceNode(), description); + queryResult.handle(new Handler() { @Override - public void eachPath(Path path) { - String nodeName = (String) path.endNode().getProperty("name", ""); - resultSet.add(nodeName); - } - }); + public void handle(Path value) { + final String name = (String) value.endNode().getProperty("name", ""); + resultSet.add(name); + }}); assertEquals("all members", new HashSet(asList("grandpa", "grandma", "daughter", "son", "man", "wife", "family")), resultSet); }