1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.neo4j.server.rest.domain;
21
22 import java.util.Arrays;
23 import java.util.Collection;
24 import java.util.Map;
25
26 import org.neo4j.graphdb.DynamicRelationshipType;
27 import org.neo4j.graphdb.RelationshipType;
28 import org.neo4j.graphdb.Traverser.Order;
29 import org.neo4j.graphdb.traversal.TraversalDescription;
30 import org.neo4j.kernel.Traversal;
31
32
33
34
35
36 public class TraversalDescriptionBuilder
37 {
38 public static TraversalDescription from( Map<String, Object> description )
39 {
40 try
41 {
42 TraversalDescription result = Traversal.description();
43 result = describeOrder( result, description );
44 result = describeUniqueness( result, description );
45 result = describeRelationships( result, description );
46 result = describePruneEvaluator( result, description );
47 result = describeReturnFilter( result, description );
48 return result;
49 }
50 catch ( NoClassDefFoundError e )
51 {
52
53
54 throw new EvaluationException( e );
55 }
56 }
57
58 @SuppressWarnings("unchecked")
59 private static TraversalDescription describeReturnFilter(
60 TraversalDescription result, Map<String, Object> description )
61 {
62 Object returnDescription = description.get( "return filter" );
63 if ( returnDescription != null )
64 {
65 result = result.filter( EvaluatorFactory.returnFilter( (Map) returnDescription ) );
66 }
67 else
68 {
69
70 result = result.filter( Traversal.returnAllButStartNode() );
71 }
72 return result;
73 }
74
75 @SuppressWarnings("unchecked")
76 private static TraversalDescription describePruneEvaluator(
77 TraversalDescription result, Map<String, Object> description )
78 {
79 Object pruneDescription = description.get( "prune evaluator" );
80 if ( pruneDescription != null )
81 {
82 result = result.prune( EvaluatorFactory.pruneEvaluator( (Map) pruneDescription ) );
83 }
84
85 Object maxDepth = description.get( "max depth" );
86 maxDepth = maxDepth != null || pruneDescription != null ? maxDepth : 1;
87 if ( maxDepth != null )
88 {
89 result = result.prune( Traversal.pruneAfterDepth(
90 ((Number) maxDepth).intValue() ) );
91 }
92 return result;
93 }
94
95 @SuppressWarnings("unchecked")
96 private static TraversalDescription describeRelationships(
97 TraversalDescription result, Map<String, Object> description )
98 {
99 Object relationshipsDescription = description.get( "relationships" );
100 if ( relationshipsDescription != null )
101 {
102 Collection<Object> pairDescriptions;
103 if ( relationshipsDescription instanceof Collection )
104 {
105 pairDescriptions = (Collection<Object>) relationshipsDescription;
106 }
107 else
108 {
109 pairDescriptions = Arrays.asList( relationshipsDescription );
110 }
111
112 for ( Object pairDescription : pairDescriptions )
113 {
114 Map map = (Map) pairDescription;
115 String name = (String) map.get( "type" );
116 RelationshipType type = DynamicRelationshipType.withName( name );
117 String directionName = (String) map.get( "direction" );
118 result = directionName == null ? result.relationships( type ) :
119 result.relationships( type, stringToEnum( directionName,
120 RelationshipDirection.class, true ).internal );
121 }
122 }
123 return result;
124 }
125
126 private static TraversalDescription describeUniqueness(
127 TraversalDescription result, Map<String, Object> description )
128 {
129 Object uniquenessDescription = description.get( "uniqueness" );
130 if ( uniquenessDescription != null )
131 {
132 String name = null;
133 Object value = null;
134 if ( uniquenessDescription instanceof Map )
135 {
136 Map map = (Map) uniquenessDescription;
137 name = (String) map.get( "name" );
138 value = map.get( "value" );
139 }
140 else
141 {
142 name = (String) uniquenessDescription;
143 }
144 org.neo4j.kernel.Uniqueness uniqueness = stringToEnum( enumifyName( name ), org.neo4j.kernel.Uniqueness.class, true );
145 result = value == null ? result.uniqueness( uniqueness ) :
146 result.uniqueness( uniqueness, value );
147 }
148 return result;
149 }
150
151 private static TraversalDescription describeOrder(
152 TraversalDescription result, Map<String, Object> description )
153 {
154 String orderDescription = (String) description.get( "order" );
155 if ( orderDescription != null )
156 {
157 Order order = stringToEnum( enumifyName( orderDescription ), Order.class, true );
158
159 switch ( order )
160 {
161 case BREADTH_FIRST:
162 result = result.breadthFirst();
163 break;
164 case DEPTH_FIRST:
165 result = result.depthFirst();
166 break;
167 }
168 }
169 return result;
170 }
171
172 private static <T extends Enum<T>> T stringToEnum( String name, Class<T> enumClass,
173 boolean fuzzyMatch )
174 {
175 if ( name == null )
176 {
177 return null;
178 }
179
180
181 for ( T candidate : enumClass.getEnumConstants() )
182 {
183 if ( candidate.name().equals( name ) )
184 {
185 return candidate;
186 }
187 }
188 if ( fuzzyMatch )
189 {
190 for ( T candidate : enumClass.getEnumConstants() )
191 {
192 if ( candidate.name().startsWith( name ) )
193 {
194 return candidate;
195 }
196 }
197 }
198 throw new RuntimeException( "Unregognized " + enumClass.getSimpleName() + " '" +
199 name + "'" );
200 }
201
202 private static String enumifyName( String name )
203 {
204 return name.replaceAll( " ", "_" ).toUpperCase();
205 }
206 }