Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.data.neo4j.aspects.support;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.neo4j.graphdb.Direction;
|
||||
@@ -31,6 +32,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.springframework.data.neo4j.aspects.Person.persistedPerson;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -98,6 +100,16 @@ public class RelationshipEntityTest extends EntityTestBase {
|
||||
Friendship f = p.knows(p2);
|
||||
assertEquals(f, neo4jTemplate.getRelationshipBetween(p, p2, Friendship.class, "knows"));
|
||||
}
|
||||
|
||||
@Ignore("The NodeBacking.getRelationshipTo() method is broken at the moment")
|
||||
@Test
|
||||
@Transactional
|
||||
public void testGetRelationshipTo() {
|
||||
Person p = persistedPerson("Michael", 35);
|
||||
Person p2 = persistedPerson("David", 25);
|
||||
Friendship f = p.knows(p2);
|
||||
assertNotNull(p.getRelationshipTo(p2, "knows"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveRelationshipEntity() {
|
||||
|
||||
@@ -53,7 +53,7 @@ public class TraversalTest extends EntityTestBase {
|
||||
group.setName("dev");
|
||||
group.addPerson(p);
|
||||
final TraversalDescription traversalDescription = Traversal.description().relationships(DynamicRelationshipType.withName("persons")).evaluator(Evaluators.excludeStartPosition());
|
||||
Iterable<Person> people = neo4jTemplate.<Person>findAllByTraversal(group,Person.class, traversalDescription);
|
||||
Iterable<Person> people = neo4jTemplate.<Person>traverse(group, Person.class, traversalDescription);
|
||||
final HashSet<Person> found = new HashSet<Person>();
|
||||
for (Person person : people) {
|
||||
found.add(person);
|
||||
@@ -69,7 +69,7 @@ public class TraversalTest extends EntityTestBase {
|
||||
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 = (Iterable<EntityPath<Group, Person>>) neo4jTemplate.<EntityPath<Group,Person>>findAllByTraversal(group, EntityPath.class, traversalDescription);
|
||||
Iterable<EntityPath<Group,Person>> paths = (Iterable<EntityPath<Group, Person>>) neo4jTemplate.<EntityPath<Group,Person>>traverse(group, EntityPath.class, traversalDescription);
|
||||
for (EntityPath<Group, Person> path : paths) {
|
||||
assertEquals(group, path.startEntity());
|
||||
assertEquals(p, path.endEntity());
|
||||
|
||||
@@ -104,7 +104,7 @@ public class TraversalFieldAccessorFactory implements FieldAccessorFactory {
|
||||
@Override
|
||||
public Object getValue(final Object entity) {
|
||||
final TraversalDescription traversalDescription = fieldTraversalDescriptionBuilder.build(entity, property,params);
|
||||
return doReturn(template.findAllByTraversal(entity,target, traversalDescription));
|
||||
return doReturn(template.traverse(entity, target, traversalDescription));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -231,13 +231,13 @@ class Neo4jPersistentPropertyImpl extends AbstractPersistentProperty<Neo4jPersis
|
||||
}
|
||||
@Override
|
||||
public boolean isEntity() {
|
||||
return super.isEntity() && (isRelationshipEntity() || isNodeEntity());
|
||||
return super.isEntity() && (hasRelationshipEntityType() || hasNodeEntityType());
|
||||
}
|
||||
|
||||
private boolean isRelationshipEntity() {
|
||||
private boolean hasRelationshipEntityType() {
|
||||
return getType().isAnnotationPresent(RelationshipEntity.class);
|
||||
}
|
||||
private boolean isNodeEntity() {
|
||||
private boolean hasNodeEntityType() {
|
||||
return getType().isAnnotationPresent(NodeEntity.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public class NodeGraphRepository<T> extends AbstractGraphRepository<Node, T> imp
|
||||
|
||||
@Override
|
||||
public <N> Iterable<T> findAllByTraversal(final N start, final TraversalDescription traversalDescription) {
|
||||
return template.findAllByTraversal(start, clazz, traversalDescription);
|
||||
return template.traverse(start, clazz, traversalDescription);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -213,4 +213,8 @@ public class MappingInfrastructure {
|
||||
public CypherQueryExecutor getCypherQueryExecutor() {
|
||||
return cypherQueryExecutor;
|
||||
}
|
||||
|
||||
public Neo4jMappingContext getMappingContext() {
|
||||
return mappingContext;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,7 @@ import org.neo4j.helpers.collection.ClosableIterable;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.neo4j.annotation.NodeEntity;
|
||||
import org.springframework.data.neo4j.annotation.QueryType;
|
||||
import org.springframework.data.neo4j.annotation.RelationshipEntity;
|
||||
import org.springframework.data.neo4j.conversion.QueryResultBuilder;
|
||||
import org.springframework.data.neo4j.conversion.Result;
|
||||
import org.springframework.data.neo4j.conversion.ResultConverter;
|
||||
@@ -99,8 +97,10 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public <T> GraphRepository<T> repositoryFor(Class<T> clazz) {
|
||||
notNull(clazz,"entity type");
|
||||
if (isNodeEntity(clazz)) return new NodeGraphRepository(clazz, this);
|
||||
if (isRelationshipEntity(clazz)) return new RelationshipGraphRepository(clazz, this);
|
||||
throw new IllegalArgumentException("Can't create graph repository for non graph entity of type " + clazz);
|
||||
@@ -108,13 +108,16 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
|
||||
|
||||
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type) {
|
||||
notNull(type, "entity type");
|
||||
return infrastructure.getIndexProvider().getIndex(type, null);
|
||||
}
|
||||
|
||||
public <S extends PropertyContainer> Index<S> getIndex(String name) {
|
||||
notNull(name, "index name");
|
||||
return infrastructure.getIndexProvider().getIndex(null, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName) {
|
||||
return infrastructure.getIndexProvider().getIndex(type, indexName, null);
|
||||
}
|
||||
@@ -132,33 +135,44 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public <T> ClosableIterable<T> findAll(final Class<T> entityClass) {
|
||||
notNull(entityClass,"entity type");
|
||||
return infrastructure.getTypeRepresentationStrategies().findAll(entityClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> long count(final Class<T> entityClass) {
|
||||
notNull(entityClass,"entity type");
|
||||
return infrastructure.getTypeRepresentationStrategies().count(entityClass);
|
||||
}
|
||||
|
||||
public <S extends PropertyContainer, T> T createEntityFromStoredType(S state) {
|
||||
notNull(state,"node or relationship");
|
||||
return infrastructure.getEntityPersister().createEntityFromStoredType(state);
|
||||
}
|
||||
|
||||
public <S extends PropertyContainer, T> T createEntityFromState(S state, Class<T> type) {
|
||||
notNull(state,"node or relationship",type,"entity class");
|
||||
return infrastructure.getEntityPersister().createEntityFromState(state, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends PropertyContainer, T> T projectTo(Object entity, Class<T> targetType) {
|
||||
notNull(entity,"entity",targetType,"new entity class");
|
||||
return infrastructure.getEntityPersister().projectTo(entity, targetType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends PropertyContainer> S getPersistentState(Object entity) {
|
||||
notNull(entity,"entity");
|
||||
return infrastructure.getEntityPersister().getPersistentState(entity);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <S extends PropertyContainer, T> T setPersistentState(T entity, S state) {
|
||||
notNull(entity,"entity",state,"node or relationship");
|
||||
infrastructure.getEntityPersister().setPersistentState(entity, state);
|
||||
return entity;
|
||||
}
|
||||
@@ -168,7 +182,9 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
infrastructure.getTypeRepresentationStrategies().postEntityCreation(node, entityClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Object entity) {
|
||||
notNull(entity,"entity");
|
||||
infrastructure.getEntityRemover().remove(entity);
|
||||
}
|
||||
|
||||
@@ -193,7 +209,8 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
return infrastructure.getGraphDatabase().createNode(properties);
|
||||
}
|
||||
|
||||
public <T> T createNode(Class<T> target, Map<String, Object> properties) {
|
||||
@Override
|
||||
public <T> T createNodeAs(Class<T> target, Map<String, Object> properties) {
|
||||
final Node node = createNode(properties);
|
||||
if (isNodeEntity(target)) {
|
||||
infrastructure.getTypeRepresentationStrategies().postEntityCreation(node, target);
|
||||
@@ -201,6 +218,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
return convert(node, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Node> createNodes(Map<String, Object> firstNode, Map<String, Object>... otherNodes) {
|
||||
Collection<Node> result = new ArrayList<Node>(otherNodes.length + 1);
|
||||
result.add(createNode(firstNode));
|
||||
@@ -210,7 +228,8 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
return convert(result);
|
||||
}
|
||||
|
||||
public <T> Iterable<T> createNodes(Class<T> target, Map<String, Object> firstNode, Map<String, Object>... otherNodes) {
|
||||
@Override
|
||||
public <T> Iterable<T> createNodesAs(Class<T> target, Map<String, Object> firstNode, Map<String, Object>... otherNodes) {
|
||||
final TypeRepresentationStrategy<Node> nodeTypeRepresentationStrategy = isNodeEntity(target) ? infrastructure.getTypeRepresentationStrategies().getNodeTypeRepresentationStrategy() : null;
|
||||
Collection<Node> result = new ArrayList<Node>(otherNodes.length + 1);
|
||||
result.add(createNode(firstNode, target, nodeTypeRepresentationStrategy));
|
||||
@@ -243,13 +262,14 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
|
||||
|
||||
public boolean isNodeEntity(Class<?> targetType) {
|
||||
return targetType.isAnnotationPresent(NodeEntity.class);
|
||||
return infrastructure.getMappingContext().isNodeEntity(targetType);
|
||||
}
|
||||
|
||||
public boolean isRelationshipEntity(Class targetType) {
|
||||
return targetType.isAnnotationPresent(RelationshipEntity.class);
|
||||
return infrastructure.getMappingContext().isRelationshipEntity(targetType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T save(T entity) {
|
||||
return (T) infrastructure.getEntityPersister().persist(entity);
|
||||
@@ -259,6 +279,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
return infrastructure.getEntityStateHandler().isManaged(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object query(String statement, Map<String, Object> params, final TypeInformation<?> typeInformation) {
|
||||
final TypeInformation<?> actualType = typeInformation.getActualType();
|
||||
final Class<?> targetType = actualType.getType();
|
||||
@@ -271,6 +292,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
return infrastructure.getCypherQueryExecutor().queryForObject(statement, targetType, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R getRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType) {
|
||||
notNull(start,"start",end,"end",relationshipEntityClass,"relationshipEntityClass",relationshipType,"relationshipType");
|
||||
final Relationship relationship = infrastructure.getEntityStateHandler().getRelationshipTo(start, end, relationshipType);
|
||||
@@ -278,11 +300,13 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
return infrastructure.getEntityPersister().createEntityFromState(relationship, relationshipEntityClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRelationshipBetween(Object start, Object end, String type) {
|
||||
notNull(start,"start",end,"end",type,"relationshipType");
|
||||
infrastructure.getEntityRemover().removeRelationshipTo(start, end, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R createRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType, boolean allowDuplicates) {
|
||||
notNull(start,"start",end,"end",relationshipEntityClass,"relationshipEntityClass",relationshipType,"relationshipType");
|
||||
final RelationshipResult result = infrastructure.getEntityStateHandler().relateTo(start, end, relationshipType, allowDuplicates);
|
||||
@@ -420,14 +444,16 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Iterable<T> findAllByTraversal(Object entity, Class<?> targetType, TraversalDescription traversalDescription) {
|
||||
public <T> Iterable<T> traverse(Object entity, Class<?> targetType, TraversalDescription traversalDescription) {
|
||||
notNull(entity,"entity",targetType,"target type",traversalDescription,"traversal description");
|
||||
return traverse(entity, traversalDescription).to((Class<T>) targetType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Path> traverse(Node startNode, TraversalDescription traversal) {
|
||||
notNull(startNode, "startNode", traversal, "traversal");
|
||||
notNull(startNode, "start node", traversal, "traversal");
|
||||
try {
|
||||
return this.convert(traversal.traverse(startNode));
|
||||
} catch (RuntimeException e) {
|
||||
@@ -437,7 +463,7 @@ public class Neo4jTemplate implements Neo4jOperations, EntityPersister {
|
||||
|
||||
@Override
|
||||
public <T extends PropertyContainer> Result<T> lookup(String indexName, String field, Object value) {
|
||||
notNull(field, "field", value, "value", indexName, "indexName");
|
||||
notNull(field, "field", value, "value", indexName, "index name");
|
||||
try {
|
||||
Index<T> index = getIndex(null, indexName);
|
||||
return convert(index.get(field, value));
|
||||
|
||||
@@ -22,6 +22,18 @@ import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
* @since 17.10.11
|
||||
*/
|
||||
public class ParameterCheck {
|
||||
public static void notNull(Object value, String msg) {
|
||||
if (value==null) throw new InvalidDataAccessApiUsageException("[Assertion failed] - " + msg + " is required; it must not be null");
|
||||
}
|
||||
public static void notNull(Object value, String msg,Object value2, String msg2) {
|
||||
if (value==null) throw new InvalidDataAccessApiUsageException("[Assertion failed] - " + msg + " is required; it must not be null");
|
||||
if (value2==null) throw new InvalidDataAccessApiUsageException("[Assertion failed] - " + msg2 + " is required; it must not be null");
|
||||
}
|
||||
public static void notNull(Object value, String msg,Object value2, String msg2,Object value3, String msg3) {
|
||||
if (value==null) throw new InvalidDataAccessApiUsageException("[Assertion failed] - " + msg + " is required; it must not be null");
|
||||
if (value2==null) throw new InvalidDataAccessApiUsageException("[Assertion failed] - " + msg2 + " is required; it must not be null");
|
||||
if (value3==null) throw new InvalidDataAccessApiUsageException("[Assertion failed] - " + msg3 + " is required; it must not be null");
|
||||
}
|
||||
public static void notNull(Object... pairs) {
|
||||
assert pairs.length % 2 == 0 : "wrong number of pairs to check";
|
||||
for (int i = 0; i < pairs.length; i += 2) {
|
||||
|
||||
@@ -17,15 +17,20 @@
|
||||
package org.springframework.data.neo4j.template;
|
||||
|
||||
import org.neo4j.graphdb.*;
|
||||
import org.neo4j.graphdb.index.Index;
|
||||
import org.neo4j.graphdb.traversal.TraversalDescription;
|
||||
import org.neo4j.helpers.collection.ClosableIterable;
|
||||
import org.springframework.data.neo4j.annotation.QueryType;
|
||||
import org.springframework.data.neo4j.conversion.Result;
|
||||
import org.springframework.data.neo4j.repository.GraphRepository;
|
||||
import org.springframework.data.neo4j.support.query.QueryEngine;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A template with convenience operations, exception translation and implicit transaction for modifying methods
|
||||
*
|
||||
* @author mh
|
||||
* @since 19.02.11
|
||||
*/
|
||||
@@ -33,92 +38,72 @@ public interface Neo4jOperations {
|
||||
|
||||
/**
|
||||
* Executes the callback in a NON-transactional context.
|
||||
*
|
||||
* @param callback for executing graph operations NON-transactionally, not null
|
||||
* @param <T> return type
|
||||
* @param <T> return type
|
||||
* @return whatever the callback chooses to return
|
||||
* @throws org.springframework.dao.DataAccessException subclasses
|
||||
* @throws org.springframework.dao.DataAccessException
|
||||
* subclasses
|
||||
*/
|
||||
<T> T exec(GraphCallback<T> callback);
|
||||
|
||||
<T> GraphRepository<T> repositoryFor(Class<T> clazz);
|
||||
|
||||
<T> T getReferenceNode(Class<T> target);
|
||||
|
||||
/**
|
||||
* Delegates to the GraphDatabase
|
||||
*
|
||||
* @param id node id
|
||||
* @return the requested node of the underlying graph database
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
Node getNode(long id);
|
||||
|
||||
/**
|
||||
* Transactionally creates the node, sets the properties (if any) and indexes the given fields (if any).
|
||||
* Two shortcut means of providing the properties (very short with static imports)
|
||||
* <code>template.createNode(Property._("name","value"));</code>
|
||||
* <code>template.createNode(Property._("name","value","prop","anotherValue"));</code>
|
||||
*
|
||||
*
|
||||
* @param props properties to be set at node creation might be null
|
||||
* @return the newly created node
|
||||
*/
|
||||
Node createNode(Map<String,Object> props);
|
||||
Node createNode(Map<String, Object> props);
|
||||
|
||||
Node createNode();
|
||||
|
||||
<T> T createNodeAs(Class<T> target, Map<String, Object> properties);
|
||||
|
||||
Result<Node> createNodes(Map<String, Object> firstNode, Map<String, Object>... otherNodes);
|
||||
|
||||
<T> Iterable<T> createNodesAs(Class<T> target, Map<String, Object> firstNode, Map<String, Object>... otherNodes);
|
||||
|
||||
|
||||
/**
|
||||
* Delegates to the GraphDatabase
|
||||
*
|
||||
* @param id relationship id
|
||||
* @return the requested relationship of the underlying graph database
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
Relationship getRelationship(long id);
|
||||
|
||||
/**
|
||||
* Transactionally creates the relationship, sets the properties (if any) and indexes the given fielss (if any)
|
||||
* Two shortcut means of providing the properties (very short with static imports)
|
||||
* <code>template.createRelationship(from,to,TYPE, Property._("name","value"));</code>
|
||||
* <code>template.createRelationship(from,to,TYPE, Property._("name","value","prop","anotherValue"));</code>
|
||||
*
|
||||
* @param startNode start-node of relationship
|
||||
* @param endNode end-node of relationship
|
||||
* @param type relationship type, might by an enum implementing RelationshipType or a DynamicRelationshipType.withName("name")
|
||||
* @param props optional initial properties
|
||||
* @return the newly created relationship
|
||||
*/
|
||||
Relationship createRelationshipBetween(Node startNode, Node endNode, RelationshipType type, Map<String, Object> props);
|
||||
|
||||
<R> R getRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType);
|
||||
|
||||
void removeRelationshipBetween(Object start, Object end, String type);
|
||||
|
||||
<R> R createRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType, boolean allowDuplicates);
|
||||
|
||||
|
||||
<S extends PropertyContainer, T> Index<S> getIndex(Class<T> type, String indexName);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* assumes a "node" node index or "relationship" relationship index for a null value
|
||||
* @param element node or relationship to index
|
||||
* @param field field to index
|
||||
* @param value value to index
|
||||
* @param <T> the provided element type
|
||||
* assumes a "node" node index or "relationship" relationship index for a null value
|
||||
* @param element node or relationship to index
|
||||
* @param field field to index
|
||||
* @param value value to index
|
||||
* @param <T> the provided element type
|
||||
* @return the provided element for convenience
|
||||
*/
|
||||
<T extends PropertyContainer> T index(String indexName, T element, String field, Object value);
|
||||
|
||||
/**
|
||||
* Converts the Iterable into a QueryResult object for uniform handling. E.g.
|
||||
* template.convert(node.getRelationships());
|
||||
*/
|
||||
<T> Result<T> convert(Iterable<T> iterable);
|
||||
|
||||
/**
|
||||
* Runs the given cypher statement and packages the result in a QueryResult, simple conversions via the
|
||||
* registered converter-factories are already executed via this method.
|
||||
*/
|
||||
Result<Map<String, Object>> query(String statement,Map<String,Object> params);
|
||||
|
||||
/**
|
||||
* Executes the given Gremlin statement and returns the result packaged as QueryResult as Neo4j types, not
|
||||
* Gremlin types. Table rows are converted to Map<String,Object>.
|
||||
*/
|
||||
Result<Object> execute(String statement, Map<String,Object> params);
|
||||
|
||||
/**
|
||||
* Traverses the graph starting at the given node with the provided traversal description. The Path's of the
|
||||
* traversal will be packaged into a QueryResult which can be easily converted into Nodes, Relationships or
|
||||
* Graph-Entities.
|
||||
*/
|
||||
Result<Path> traverse(Node startNode, TraversalDescription traversal);
|
||||
|
||||
/**
|
||||
* The value is looked up in the Neo4j index returning the IndexHits wrapped in a QueryResult to be converted
|
||||
* into Paths or Entities.
|
||||
@@ -131,20 +116,52 @@ public interface Neo4jOperations {
|
||||
*/
|
||||
<T extends PropertyContainer> Result<T> lookup(String indexName, Object query);
|
||||
|
||||
Result<Path> traverse(Object start, TraversalDescription traversal);
|
||||
|
||||
<T extends PropertyContainer> Result<T> lookup(Class<?> indexedType, Object query);
|
||||
|
||||
Node createNode();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
<T> T convert(Object value, Class<T> type);
|
||||
|
||||
/**
|
||||
* Delegates to the GraphDatabase
|
||||
* @return the reference node of the underlying graph database
|
||||
*/
|
||||
<T> T getReferenceNode(Class<T> target);
|
||||
Object query(String statement, Map<String, Object> params, TypeInformation<?> typeInformation);
|
||||
|
||||
QueryEngine queryEngineFor(QueryType type);
|
||||
|
||||
/**
|
||||
* Runs the given cypher statement and packages the result in a QueryResult, simple conversions via the
|
||||
* registered converter-factories are already executed via this method.
|
||||
*/
|
||||
Result<Map<String, Object>> query(String statement, Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* Executes the given Gremlin statement and returns the result packaged as QueryResult as Neo4j types, not
|
||||
* Gremlin types. Table rows are converted to Map<String,Object>.
|
||||
*/
|
||||
Result<Object> execute(String statement, Map<String, Object> params);
|
||||
|
||||
/**
|
||||
* Traverses the graph starting at the given node with the provided traversal description. The Path's of the
|
||||
* traversal will be packaged into a QueryResult which can be easily converted into Nodes, Relationships or
|
||||
* Graph-Entities.
|
||||
*/
|
||||
Result<Path> traverse(Node startNode, TraversalDescription traversal);
|
||||
|
||||
Result<Path> traverse(Object start, TraversalDescription traversal);
|
||||
|
||||
<T> Iterable<T> traverse(Object entity, Class<?> targetType, TraversalDescription traversalDescription);
|
||||
|
||||
/**
|
||||
* Converts the Iterable into a QueryResult object for uniform handling. E.g.
|
||||
* template.convert(node.getRelationships());
|
||||
*/
|
||||
<T> Result<T> convert(Iterable<T> iterable);
|
||||
|
||||
<T> T convert(Object value, Class<T> type);
|
||||
|
||||
<T> ClosableIterable<T> findAll(Class<T> entityClass);
|
||||
|
||||
<T> long count(Class<T> entityClass);
|
||||
|
||||
<S extends PropertyContainer, T> T projectTo(Object entity, Class<T> targetType);
|
||||
|
||||
<T> T save(T entity);
|
||||
|
||||
void remove(Object entity);
|
||||
|
||||
<S extends PropertyContainer> S getPersistentState(Object entity);
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ public class GraphDatabaseContextTemplateTest {
|
||||
@Test
|
||||
@Transactional
|
||||
public void testCreateEntityWithProperties() throws Exception {
|
||||
Person person = neo4jTemplate.createNode(Person.class, map("name", "name"));
|
||||
Person person = neo4jTemplate.createNodeAs(Person.class, map("name", "name"));
|
||||
assertNotNull("created node", person);
|
||||
assertEquals("property created", "name", person.getName());
|
||||
}
|
||||
@@ -211,7 +211,7 @@ public class GraphDatabaseContextTemplateTest {
|
||||
@Test
|
||||
@Transactional
|
||||
public void testCreateNodeTypeWithProperties() throws Exception {
|
||||
Node person = neo4jTemplate.createNode(Node.class, map("name", "name"));
|
||||
Node person = neo4jTemplate.createNodeAs(Node.class, map("name", "name"));
|
||||
assertNotNull("created node", person);
|
||||
assertEquals("property created", "name", person.getProperty("name"));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.data.test;
|
||||
import org.junit.After;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
@@ -59,13 +60,13 @@ public abstract class DocumentingTestBase {
|
||||
}
|
||||
|
||||
protected String createFooter() {
|
||||
return "</section>\n";
|
||||
return String.format("</section>%n");
|
||||
}
|
||||
|
||||
protected String createHeader() {
|
||||
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
|
||||
"<!DOCTYPE section PUBLIC \"-//OASIS//DTD DocBook XML V4.4//EN\" \"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd\">\n" +
|
||||
"<section>\n";
|
||||
return String.format("<?xml version=\"1.0\" encoding=\"UTF-8\"?>%n" +
|
||||
"<!DOCTYPE section PUBLIC \"-//OASIS//DTD DocBook XML V4.4//EN\" \"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd\">%n" +
|
||||
"<section>%n");
|
||||
}
|
||||
|
||||
protected String createTitle() {
|
||||
@@ -81,10 +82,10 @@ public abstract class DocumentingTestBase {
|
||||
}
|
||||
|
||||
protected String createSnippet() {
|
||||
return String.format("<example>\n" +
|
||||
" <title>%s</title>\n" +
|
||||
" <programlisting language=\"java\"><![CDATA[%s]]></programlisting>\n" +
|
||||
" </example>\n", snippetTitle, collectSnippet());
|
||||
return String.format("<example>%n" +
|
||||
" <title>%s</title>%n" +
|
||||
" <programlisting language=\"java\"><![CDATA[%s]]></programlisting>%n" +
|
||||
" </example>%n", snippetTitle, collectSnippet());
|
||||
}
|
||||
|
||||
protected String collectSnippet() {
|
||||
@@ -99,7 +100,7 @@ public abstract class DocumentingTestBase {
|
||||
continue;
|
||||
}
|
||||
if (inSnippet) {
|
||||
snippetText.append(line).append("\n");
|
||||
snippetText.append(line).append(String.format("%n"));
|
||||
}
|
||||
}
|
||||
reader.close();
|
||||
@@ -110,7 +111,7 @@ public abstract class DocumentingTestBase {
|
||||
}
|
||||
|
||||
protected File getJavaFile() {
|
||||
final String javaFileName = getClass().getName().replaceAll("\\.", File.separator) + ".java";
|
||||
final String javaFileName = getClass().getName().replaceAll("\\.", Matcher.quoteReplacement(File.separator)) + ".java";
|
||||
final File javaFile = new File(testSourceDirectory(), javaFileName);
|
||||
if (!javaFile.exists()) fail("Snippet File " + javaFile + " does not exist ");
|
||||
return javaFile;
|
||||
|
||||
@@ -40,19 +40,19 @@ public class DocumentingTestBaseTest extends DocumentingTestBase {
|
||||
|
||||
@Test
|
||||
public void testTitle() {
|
||||
assertEquals("<title>Documents DocumentingTestBase</title>\n",createTitle());
|
||||
assertEquals(String.format("<title>Documents DocumentingTestBase</title>%n"),createTitle());
|
||||
}
|
||||
@Test
|
||||
public void testParagraphs() {
|
||||
assertEquals("<para>\nThis documents the documenting test base\n</para>\n"+
|
||||
"<para>\nAnd this is a second paragraph\n</para>\n"
|
||||
assertEquals(String.format("<para>%nThis documents the documenting test base%n</para>%n"+
|
||||
"<para>%nAnd this is a second paragraph%n</para>%n")
|
||||
,createText());
|
||||
}
|
||||
@Test
|
||||
public void testCreateSnippet() {
|
||||
assertEquals(" {\n" +
|
||||
" title=\"Documents DocumentingTestBase\";\n" +
|
||||
" }\n" +
|
||||
" snippetTitle = \"SnippetTitle\";\n",collectSnippet());
|
||||
assertEquals(String.format(" {%n" +
|
||||
" title=\"Documents DocumentingTestBase\";%n" +
|
||||
" }%n" +
|
||||
" snippetTitle = \"SnippetTitle\";%n"),collectSnippet());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user