Add to aai-common query builder get parent step
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / query / builder / QueryBuilder.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *    http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.aai.query.builder;
21
22 import java.io.UnsupportedEncodingException;
23 import java.net.URI;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27
28 import javax.ws.rs.core.MultivaluedMap;
29
30 import org.apache.tinkerpop.gremlin.process.traversal.Path;
31 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
32 import org.apache.tinkerpop.gremlin.structure.Edge;
33 import org.apache.tinkerpop.gremlin.structure.Vertex;
34 import org.onap.aai.db.props.AAIProperties;
35 import org.onap.aai.exceptions.AAIException;
36 import org.onap.aai.introspection.Introspector;
37 import org.onap.aai.introspection.Loader;
38 import org.onap.aai.parsers.query.QueryParser;
39 import org.onap.aai.parsers.query.QueryParserStrategy;
40 import org.onap.aai.serialization.db.AAIDirection;
41 import org.onap.aai.serialization.db.EdgeProperty;
42 import org.onap.aai.serialization.db.EdgeType;
43
44 /**
45  * The Class QueryBuilder.
46  */
47 public abstract class QueryBuilder<E> implements Iterator<E> {
48
49         protected final GraphTraversalSource source;
50         protected QueryParserStrategy factory = null;
51         protected Loader loader = null;
52         protected boolean optimize = false;
53         protected Vertex start = null;
54         
55         /**
56          * Instantiates a new query builder.
57          *
58          * @param loader the loader
59          */
60         public QueryBuilder(Loader loader, GraphTraversalSource source) {
61                 this.loader = loader;
62                 this.source = source;
63         }
64         
65         /**
66          * Instantiates a new query builder.
67          *
68          * @param loader the loader
69          * @param start the start
70          */
71         public QueryBuilder(Loader loader, GraphTraversalSource source, Vertex start) {
72                 this.loader = loader;
73                 this.start = start;
74                 this.source = source;
75         }
76         
77         /**
78          * Gets the vertices by indexed property.
79          *
80          * @param key the key
81          * @param value the value
82          * @return the vertices by indexed property
83          */
84         public QueryBuilder<Vertex> getVerticesByIndexedProperty(String key, Object value) {
85                 return this.getVerticesByProperty(key, value);
86         }
87         
88         /**
89          * Gets the vertices by property.
90          *
91          * @param key the key
92          * @param value the value
93          * @return the vertices by property
94          */
95         public abstract QueryBuilder<Vertex> getVerticesByProperty(String key, Object value);
96         
97         /**
98          * filters by all the values for this property
99          * @param key
100          * @param values
101          * @return vertices that match these values
102          */
103         public QueryBuilder<Vertex> getVerticesByIndexedProperty(String key, List<?> values) {
104                 return this.getVerticesByProperty(key, values);
105         }
106
107         /**
108          * filters by all the values for this property
109          * @param key
110          * @param values
111          * @return vertices that match these values
112          */
113         public abstract QueryBuilder<Vertex> getVerticesByProperty(String key, List<?> values);
114
115         /**
116          * Gets the vertices that are excluded by property.
117          *
118          * @param key the key
119          * @param value the value
120          * @return the vertices by property
121          */
122         public abstract QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, Object value);
123
124         /**
125          * filters by all the values for this property and excludes the vertices
126          * @param key
127          * @param values
128          * @return vertices that match these values
129          */
130         public QueryBuilder<Vertex> getVerticesExcludeByIndexedProperty(String key, List<?> values) {
131                 return this.getVerticesExcludeByProperty(key, values);
132         }
133
134         /**
135          * filters by all the values for this property and excludes the vertices
136          * @param key
137          * @param values
138          * @return vertices that match these values
139          */
140         public abstract QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, List<?> values);
141
142         /**
143          * Gets the child vertices from parent.
144          *
145          * @param parentKey the parent key
146          * @param parentValue the parent value
147          * @param childType the child type
148          * @return the child vertices from parent
149          */
150         public abstract QueryBuilder<Vertex> getChildVerticesFromParent(String parentKey, String parentValue, String childType);
151                 
152         /**
153          * Gets the typed vertices by map.
154          *
155          * @param type the type
156          * @param map the map
157          * @return the typed vertices by map
158          */
159         public abstract QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map);
160
161         /**
162          * Creates the DB query.
163          *
164          * @param obj the obj
165          * @return the query builder
166          */
167         public QueryBuilder<Vertex> createDBQuery(Introspector obj) {
168                 this.createKeyQuery(obj);
169                 this.createContainerQuery(obj);
170                 return (QueryBuilder<Vertex>) this;
171         }
172         
173         /**
174          * Creates the key query.
175          *
176          * @param obj the obj
177          * @return the query builder
178          */
179         public abstract QueryBuilder<Vertex> createKeyQuery(Introspector obj);
180         
181         /**
182          * Creates the container query.
183          *
184          * @param obj the obj
185          * @return the query builder
186          */
187         public abstract QueryBuilder<Vertex> createContainerQuery(Introspector obj);
188         
189         /**
190          * Creates the edge traversal.
191          *
192          * @param parent the parent
193          * @param child the child
194          * @return the query builder
195          */
196         public abstract QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, Introspector parent, Introspector child) throws AAIException;
197         
198         /**
199          * Creates the edge traversal.
200          *
201          * @param parent the parent
202          * @param child the child
203          * @return the query builder
204          */
205         public QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, Vertex parent, Introspector child) throws AAIException {
206                 String nodeType = parent.<String>property(AAIProperties.NODE_TYPE).orElse(null);
207                 this.createEdgeTraversal(type, nodeType, child.getDbName());
208                 return (QueryBuilder<Vertex>) this;
209
210         }
211
212         /**
213          *
214          * @param type
215          * @param outNodeType
216          * @param inNodeType
217          * @return
218          * @throws AAIException
219          */
220         public QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, String outNodeType, String inNodeType) throws AAIException {
221                 Introspector out = loader.introspectorFromName(outNodeType);
222                 Introspector in = loader.introspectorFromName(inNodeType);
223
224                 return createEdgeTraversal(type, out, in);
225         }
226
227         /**
228          *
229          * @param type
230          * @param outNodeType
231          * @param inNodeType
232          * @param labels
233          * @return
234          * @throws AAIException
235          */
236         public QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, String outNodeType, String inNodeType, List<String> labels) throws AAIException {
237                 Introspector out = loader.introspectorFromName(outNodeType);
238                 Introspector in = loader.introspectorFromName(inNodeType);
239
240                 return createEdgeTraversalWithLabels(type, out, in, labels);
241         }
242
243         /**
244          *
245          * @param type
246          * @param out
247          * @param in
248          * @param labels
249          * @return
250          */
251         public abstract QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, Introspector out, Introspector in, List<String> labels) throws AAIException;
252
253         /**
254          *
255          * @param type
256          * @param outNodeType
257          * @param inNodeType
258          * @return
259          * @throws AAIException
260          */
261         public QueryBuilder<Edge> getEdgesBetween(EdgeType type, String outNodeType, String inNodeType) throws AAIException {
262                 this.getEdgesBetweenWithLabels(type, outNodeType, inNodeType, null);
263
264                 return (QueryBuilder<Edge>)this;
265
266         }
267         /**
268          *
269          * @param type
270          * @param outNodeType
271          * @param inNodeType
272          * @param labels
273          * @return
274          * @throws AAIException
275          */
276         public abstract QueryBuilder<Edge> getEdgesBetweenWithLabels(EdgeType type, String outNodeType, String inNodeType, List<String> labels) throws AAIException;
277
278         /**
279          * Creates the query from URI.
280          *
281          * @param uri the uri
282          * @return the query parser
283          * @throws UnsupportedEncodingException the unsupported encoding exception
284          * @throws AAIException the AAI exception
285          */
286         public abstract QueryParser createQueryFromURI(URI uri) throws UnsupportedEncodingException, AAIException;
287         
288         /**
289          * Creates the query from URI.
290          *
291          * @param uri the uri
292          * @param queryParams the query params
293          * @return the query parser
294          * @throws UnsupportedEncodingException the unsupported encoding exception
295          * @throws AAIException the AAI exception
296          */
297         public abstract QueryParser createQueryFromURI(URI uri, MultivaluedMap<String, String> queryParams) throws UnsupportedEncodingException, AAIException;
298
299         /**
300          * Creates a queryparser from a given object name.
301          * 
302          * @param objName - name of the object type as it appears in the database
303          * @return
304          */
305         public abstract QueryParser createQueryFromObjectName(String objName);
306         
307         /**
308          * Creates the query from relationship.
309          *
310          * @param relationship the relationship
311          * @return the query parser
312          * @throws UnsupportedEncodingException the unsupported encoding exception
313          * @throws AAIException the AAI exception
314          */
315         public abstract QueryParser createQueryFromRelationship(Introspector relationship) throws UnsupportedEncodingException, AAIException;
316
317         /**
318          * Gets the parent query.
319          *
320          * @return the parent query
321          */
322         public abstract QueryBuilder<E> getParentQuery();
323         
324         /**
325          * Gets the query.
326          *
327          * @return the query
328          */
329         public abstract <E2> E2 getQuery();
330         
331         /**
332          * Form boundary.
333          */
334         public abstract void markParentBoundary();
335         
336         public abstract QueryBuilder<E> limit(long amount);
337
338         /**
339          * New instance.
340          *
341          * @param start the start
342          * @return the query builder
343          */
344         public abstract QueryBuilder<E> newInstance(Vertex start);
345         
346         /**
347          * New instance.
348          *
349          * @return the query builder
350          */
351         public abstract QueryBuilder<E> newInstance();
352         
353         /**
354          * Gets the start.
355          *
356          * @return the start
357          */
358         public abstract Vertex getStart();
359
360         protected Object correctObjectType(Object obj) {
361                 
362                 if (obj != null && obj.getClass().equals(Long.class)) {
363                         return new Integer(obj.toString());
364                 }
365                 
366                 return obj;
367         }
368         /**
369          * uses all fields in the introspector to create a query
370          * 
371          * @param obj
372          * @return
373          */
374         public abstract QueryBuilder<Vertex> exactMatchQuery(Introspector obj);
375
376         /**
377          * lets you join any number of QueryBuilders
378          * <b>be careful about starting with a union it will not use indexes</b>
379          * @param builder
380          * @return
381          */
382         public abstract QueryBuilder<E> union(QueryBuilder<E>... builder);
383         
384         public abstract QueryBuilder<E> where(QueryBuilder<E>... builder);
385         
386         public abstract QueryBuilder<E> store(String name);
387         public abstract QueryBuilder<E> cap(String name);
388         public abstract QueryBuilder<E> unfold();
389         public abstract QueryBuilder<E> dedup();
390         public abstract QueryBuilder<E> emit();
391         public abstract QueryBuilder<E> repeat(QueryBuilder<E> builder);
392         public abstract QueryBuilder<Edge> outE();
393         public abstract QueryBuilder<Edge> inE();
394         public abstract QueryBuilder<Vertex> inV();
395         public abstract QueryBuilder<Vertex> outV();
396         public abstract QueryBuilder<E> not(QueryBuilder<E> builder);
397         public abstract QueryBuilder<E> as(String name);
398         public abstract QueryBuilder<E> select(String name);
399         public abstract QueryBuilder<E> until(QueryBuilder<E> builder);
400         public abstract QueryBuilder<E> groupCount();
401         public abstract QueryBuilder<E> by(String name);
402         public abstract QueryBuilder<E> both();
403         
404         /**
405          * Used to prevent the traversal from repeating its path through the graph.
406          * See http://tinkerpop.apache.org/docs/3.0.1-incubating/#simplepath-step for more info.
407          * 
408          * @return a QueryBuilder with the simplePath step appended to its traversal
409          */
410         public abstract QueryBuilder<E> simplePath();
411
412         /**
413          *
414          * @return QueryBuilder with the path step appended to its traversal
415          */
416         public abstract QueryBuilder<Path> path();
417         
418         public abstract void markContainer();
419
420         public abstract QueryBuilder<E> getContainerQuery();
421
422         public abstract List<E> toList();
423
424         /**
425          * Used to skip step if there is an optional property missing.
426          * @param key
427          * @param value
428          * @return
429          */
430         public QueryBuilder<Vertex> getVerticesByProperty(String key, MissingOptionalParameter value) {
431                 return (QueryBuilder<Vertex>) this;
432         }
433
434         /**
435          * TODO the edge direction is hardcoded here, make it more generic
436          * Returns the parent edge of the vertex
437          * @return
438          */
439         public QueryBuilder<Edge> getParentEdge() {
440                 this.outE().has(EdgeProperty.CONTAINS.toString(), AAIDirection.IN.toString());
441                 return (QueryBuilder<Edge>)this;
442         }
443
444         /**
445          * TODO the edge direction is hardcoded here, make it more generic
446          * Returns the parent vertex of the vertex
447          * @return
448          */
449         public QueryBuilder<Vertex> getParentVertex() {
450                 this.getParentEdge().inV();
451                 return (QueryBuilder<Vertex>)this;
452         }
453
454         protected abstract QueryBuilder<Edge> has(String key, String value);
455 }