Cleaning up a bit

This commit is contained in:
Andres Taylor
2011-03-29 09:55:20 +02:00
parent f386810565
commit 96bbbfc5bc
2 changed files with 165 additions and 95 deletions

View File

@@ -1,155 +1,222 @@
package org.neo4j.rest.graphdb;
import com.sun.jersey.api.client.ClientResponse;
import org.neo4j.graphdb.*;
import org.neo4j.graphdb.traversal.*;
import org.neo4j.graphdb.Direction;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Path;
import org.neo4j.graphdb.RelationshipExpander;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.traversal.BranchOrderingPolicy;
import org.neo4j.graphdb.traversal.Evaluator;
import org.neo4j.graphdb.traversal.PruneEvaluator;
import org.neo4j.graphdb.traversal.TraversalDescription;
import org.neo4j.graphdb.traversal.Traverser;
import org.neo4j.graphdb.traversal.UniquenessFactory;
import org.neo4j.helpers.Predicate;
import org.neo4j.kernel.Traversal;
import org.neo4j.kernel.Uniqueness;
import javax.ws.rs.core.Response;
import java.lang.reflect.Field;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* @author Michael Hunger
* @since 02.02.11
*/
public class RestTraversal implements RestTraversalDescription {
public class RestTraversal implements RestTraversalDescription
{
private static final String FULLPATH = "fullpath";
private final Map<String, Object> description=new HashMap<String, Object>();
private final Map<String, Object> description = new HashMap<String, Object>();
@Override
public String toString() {
public String toString()
{
return description.toString();
}
public TraversalDescription uniqueness(UniquenessFactory uniquenessFactory) {
return uniqueness(uniquenessFactory,null);
public TraversalDescription uniqueness( UniquenessFactory uniquenessFactory )
{
return uniqueness( uniquenessFactory, null );
}
public TraversalDescription uniqueness(UniquenessFactory uniquenessFactory, Object value) {
String uniqueness = restify(uniquenessFactory);
add("uniqueness",value==null ? uniqueness : toMap("name",uniqueness, "value", value));
public TraversalDescription uniqueness( UniquenessFactory uniquenessFactory, Object value )
{
String uniqueness = restify( uniquenessFactory );
add( "uniqueness", value == null ? uniqueness : toMap( "name", uniqueness, "value", value ) );
return null;
}
private String restify(UniquenessFactory uniquenessFactory) {
if (uniquenessFactory instanceof Uniqueness) {
return ((Uniqueness)uniquenessFactory).name().toLowerCase().replace("_"," ");
private String restify( UniquenessFactory uniquenessFactory )
{
if ( uniquenessFactory instanceof Uniqueness )
{
return ( (Uniqueness)uniquenessFactory ).name().toLowerCase().replace( "_", " " );
}
throw new UnsupportedOperationException("Only values of "+Uniqueness.class+" are supported");
throw new UnsupportedOperationException( "Only values of " + Uniqueness.class + " are supported" );
}
public TraversalDescription prune(PruneEvaluator pruneEvaluator) {
Integer maxDepth= getMaxDepthValueOrNull(pruneEvaluator);
if (maxDepth!=null) {
return maxDepth(maxDepth);
public TraversalDescription prune( PruneEvaluator pruneEvaluator )
{
Integer maxDepth = getMaxDepthValueOrNull( pruneEvaluator );
if ( maxDepth != null )
{
return maxDepth( maxDepth );
}
throw new UnsupportedOperationException("Only max depth supported");
throw new UnsupportedOperationException( "Only max depth supported" );
}
private Integer getMaxDepthValueOrNull(PruneEvaluator pruneEvaluator) {
try {
final Field depthField = pruneEvaluator.getClass().getDeclaredField("val$depth");
depthField.setAccessible(true);
return (Integer) depthField.get(pruneEvaluator);
} catch (Exception e) {
private Integer getMaxDepthValueOrNull( PruneEvaluator pruneEvaluator )
{
try
{
final Field depthField = pruneEvaluator.getClass().getDeclaredField( "val$depth" );
depthField.setAccessible( true );
return (Integer)depthField.get( pruneEvaluator );
} catch ( Exception e )
{
return null;
}
}
public TraversalDescription filter(Predicate<Path> pathPredicate) {
if (pathPredicate == Traversal.returnAll()) return add("return filter",toMap("language","builtin", "name","all"));
if (pathPredicate == Traversal.returnAllButStartNode()) return add("return filter",toMap("language","builtin", "name","all but start node"));
throw new UnsupportedOperationException("Only builtin paths supported");
public TraversalDescription filter( Predicate<Path> pathPredicate )
{
if ( pathPredicate == Traversal.returnAll() )
{
return add( "return filter", toMap( "language", "builtin", "name", "all" ) );
}
if ( pathPredicate == Traversal.returnAllButStartNode() )
{
return add( "return filter", toMap( "language", "builtin", "name", "all but start node" ) );
}
throw new UnsupportedOperationException( "Only builtin paths supported" );
}
public TraversalDescription evaluator(Evaluator evaluator) {
public TraversalDescription evaluator( Evaluator evaluator )
{
return null;
}
public TraversalDescription prune(ScriptLanguage language, String code) {
return add("prune evaluator",toMap("language",language.name().toLowerCase(),"body",code ));
public TraversalDescription prune( ScriptLanguage language, String code )
{
return add( "prune evaluator", toMap( "language", language.name().toLowerCase(), "body", code ) );
}
public TraversalDescription filter(ScriptLanguage language, String code) {
return add("return filter",toMap("language",language.name().toLowerCase(),"body",code ));
public TraversalDescription filter( ScriptLanguage language, String code )
{
return add( "return filter", toMap( "language", language.name().toLowerCase(), "body", code ) );
}
public TraversalDescription maxDepth(int depth) {
return add("max depth",depth);
public TraversalDescription maxDepth( int depth )
{
return add( "max depth", depth );
}
public TraversalDescription order(BranchOrderingPolicy branchOrderingPolicy) {
public TraversalDescription order( BranchOrderingPolicy branchOrderingPolicy )
{
throw new UnsupportedOperationException();
}
public TraversalDescription depthFirst() {
return add("order","depth first");
public TraversalDescription depthFirst()
{
return add( "order", "depth first" );
}
public TraversalDescription breadthFirst() {
return add("order", "breadth first");
public TraversalDescription breadthFirst()
{
return add( "order", "breadth first" );
}
private RestTraversalDescription add(String key, Object value) {
description.put(key,value);
private RestTraversalDescription add( String key, Object value )
{
description.put( key, value );
return this;
}
public TraversalDescription relationships(RelationshipType relationshipType) {
return relationships(relationshipType, null);
public TraversalDescription relationships( RelationshipType relationshipType )
{
return relationships( relationshipType, null );
}
public TraversalDescription relationships(RelationshipType relationshipType, Direction direction) {
if (!description.containsKey("relationships")) {
description.put("relationships",new HashSet<Map<String,Object>>());
public TraversalDescription relationships( RelationshipType relationshipType, Direction direction )
{
if ( !description.containsKey( "relationships" ) )
{
description.put( "relationships", new HashSet<Map<String, Object>>() );
}
Set<Map<String,Object>> relationships= (Set<Map<String, Object>>) description.get("relationships");
relationships.add(toMap("type", relationshipType, "direction", directionString(direction)));
Set<Map<String, Object>> relationships = (Set<Map<String, Object>>)description.get( "relationships" );
relationships.add( toMap( "type", relationshipType, "direction", directionString( direction ) ) );
return this;
}
private Map<String, Object> toMap(Object...params) {
if (params.length % 2 != 0) throw new IllegalArgumentException("toMap needs an even number of arguments, but was "+Arrays.toString(params));
private Map<String, Object> toMap( Object... params )
{
if ( params.length % 2 != 0 )
{
throw new IllegalArgumentException( "toMap needs an even number of arguments, but was " + Arrays.toString( params ) );
}
Map<String, Object> result = new HashMap<String, Object>();
for (int i = 0; i < params.length; i+=2) {
if (params[i+1] == null) continue;
result.put(params[i].toString(), params[i + 1].toString());
for ( int i = 0; i < params.length; i += 2 )
{
if ( params[ i + 1 ] == null )
{
continue;
}
result.put( params[ i ].toString(), params[ i + 1 ].toString() );
}
return result;
}
private String directionString(Direction direction) {
if (direction==Direction.INCOMING) return "in";
if (direction==Direction.OUTGOING) return "out";
private String directionString( Direction direction )
{
switch ( direction )
{
case INCOMING:
return "in";
case OUTGOING:
return "out";
default:
return null;
}
}
public TraversalDescription expand( RelationshipExpander relationshipExpander )
{
return null;
}
public TraversalDescription expand(RelationshipExpander relationshipExpander) {
return null;
}
public Traverser traverse(Node node) {
final RestNode restNode = (RestNode) node;
public Traverser traverse( Node node )
{
final RestNode restNode = (RestNode)node;
final RestRequest request = restNode.getRestRequest();
final String traversalJson = JsonHelper.createJsonFrom(description);
final ClientResponse result = request.post("traverse/" + FULLPATH, traversalJson);
if (request.statusOtherThan(result, Response.Status.OK)) throw new RuntimeException(String.format("Error executing traversal: %d %s",result.getStatus(), traversalJson));
final Object col = request.toEntity(result);
if (!(col instanceof Collection)) throw new RuntimeException(String.format("Unexpected traversal result, %s instead of collection", col!=null ? col.getClass() : null));
return new RestTraverser((Collection) col,restNode.getGraphDatabase());
final String traversalJson = JsonHelper.createJsonFrom( description );
final ClientResponse result = request.post( "traverse/" + FULLPATH, traversalJson );
if ( request.statusOtherThan( result, Response.Status.OK ) )
{
throw new RuntimeException( String.format( "Error executing traversal: %d %s", result.getStatus(), traversalJson ) );
}
final Object col = request.toEntity( result );
if ( !( col instanceof Collection ) )
{
throw new RuntimeException( String.format( "Unexpected traversal result, %s instead of collection", col != null ? col.getClass() : null ) );
}
return new RestTraverser( (Collection)col, restNode.getGraphDatabase() );
}
public static RestTraversalDescription description() {
public static RestTraversalDescription description()
{
return new RestTraversal();
}
public Map<String,Object> getPostData() {
public Map<String, Object> getPostData()
{
return description;
}
}

View File

@@ -5,7 +5,6 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.neo4j.rest.graphdb.RestTestBase;
import org.springframework.data.graph.neo4j.support.ProjectionTest;
import org.springframework.data.graph.neo4j.support.TraversalTest;
import org.springframework.test.context.CleanContextCacheTestExecutionListener;
import org.springframework.test.context.ContextConfiguration;
@@ -15,29 +14,33 @@ import org.springframework.test.context.support.DependencyInjectionTestExecution
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
/**
* @author mh
* @since 28.03.11
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:org/springframework/data/graph/neo4j/support/Neo4jGraphPersistenceTest-context.xml",
"classpath:RestTest-context.xml"})
@TestExecutionListeners({CleanContextCacheTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class})
public class RestTraversalTest extends TraversalTest {
* @author mh
* @since 28.03.11
*/
@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration( locations = {"classpath:org/springframework/data/graph/neo4j/support/Neo4jGraphPersistenceTest-context.xml",
"classpath:RestTest-context.xml"} )
@TestExecutionListeners( {CleanContextCacheTestExecutionListener.class, DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class} )
public class RestTraversalTest extends TraversalTest
{
@BeforeClass
public static void startDb() throws Exception {
RestTestBase.startDb();
}
@BeforeClass
public static void startDb() throws Exception
{
RestTestBase.startDb();
}
@Before
public void cleanDb() {
RestTestBase.cleanDb();
}
@Before
public void cleanDb()
{
RestTestBase.cleanDb();
}
@AfterClass
public static void shutdownDb() {
RestTestBase.shutdownDb();
}
@AfterClass
public static void shutdownDb()
{
RestTestBase.shutdownDb();
}
}