Spring-boot 3.1 update
[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  * Modifications Copyright © 2024 DEUTSCHE TELEKOM AG.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *    http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.aai.query.builder;
24
25 import java.io.UnsupportedEncodingException;
26 import java.net.URI;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30
31 import jakarta.ws.rs.core.MultivaluedMap;
32
33 import org.apache.tinkerpop.gremlin.process.traversal.Path;
34 import org.apache.tinkerpop.gremlin.process.traversal.Pop;
35 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
36 import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
37 import org.apache.tinkerpop.gremlin.structure.Edge;
38 import org.apache.tinkerpop.gremlin.structure.Vertex;
39 import org.onap.aai.config.SpringContextAware;
40 import org.onap.aai.db.props.AAIProperties;
41 import org.onap.aai.edges.EdgeIngestor;
42 import org.onap.aai.edges.enums.AAIDirection;
43 import org.onap.aai.edges.enums.EdgeProperty;
44 import org.onap.aai.edges.enums.EdgeType;
45 import org.onap.aai.exceptions.AAIException;
46 import org.onap.aai.introspection.Introspector;
47 import org.onap.aai.introspection.Loader;
48 import org.onap.aai.parsers.query.QueryParser;
49 import org.onap.aai.parsers.query.QueryParserStrategy;
50 import org.onap.aai.query.entities.PaginationResult;
51 import org.springframework.context.ApplicationContext;
52
53 /**
54  * The Class QueryBuilder.
55  */
56 public abstract class QueryBuilder<E> implements Iterator<E> {
57
58     protected final GraphTraversalSource source;
59     protected QueryParserStrategy factory = null;
60     protected Loader loader = null;
61     protected EdgeIngestor edgeRules;
62     protected boolean optimize = false;
63     protected Vertex start = null;
64
65     protected int parentStepIndex = 0;
66     protected int containerStepIndex = 0;
67     protected int stepIndex = 0;
68
69     /**
70      * Instantiates a new query builder.
71      *
72      * @param loader the loader
73      */
74     public QueryBuilder(Loader loader, GraphTraversalSource source) {
75         this.loader = loader;
76         this.source = source;
77         initEdgeIngestor();
78     }
79
80     /**
81      * Instantiates a new query builder.
82      *
83      * @param loader the loader
84      * @param start the start
85      */
86     public QueryBuilder(Loader loader, GraphTraversalSource source, Vertex start) {
87         this.loader = loader;
88         this.start = start;
89         this.source = source;
90         initEdgeIngestor();
91     }
92
93     public void changeLoader(Loader loader) {
94         this.loader = loader;
95     }
96
97     /**
98      * Creates a new {@link QueryBuilder} that contains the traversal up to the provided index.
99      * @param index
100      * @return
101      */
102     protected abstract QueryBuilder<E> cloneQueryAtStep(int index);
103
104     /**
105      * Gets the vertices by indexed property.
106      *
107      * @param key the key
108      * @param value the value
109      * @return the vertices by indexed property
110      */
111     public QueryBuilder<Vertex> getVerticesByIndexedProperty(String key, Object value) {
112         return this.getVerticesByProperty(key, value);
113     }
114
115     /**
116      * Gets the vertices 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> getVerticesByProperty(String key, Object value);
123
124     /**
125      * Gets the edges by property.
126      *
127      * @param key the key
128      * @param value the value
129      * @return the vertices by property
130      */
131     public QueryBuilder<Edge> getEdgesByProperty(String key, Object value) {
132         return this.has(key, value.toString());
133     }
134
135     /**
136      * filters by all the values for this property
137      *
138      * @param key
139      * @param values
140      * @return vertices that match these values
141      */
142     public QueryBuilder<Vertex> getVerticesByIndexedProperty(String key, List<?> values) {
143         return this.getVerticesByProperty(key, values);
144     }
145
146     /**
147      * filters by all the values for this property
148      *
149      * @param key
150      * @param values
151      * @return vertices that match these values
152      */
153     public abstract QueryBuilder<Vertex> getVerticesByProperty(String key, List<?> values);
154
155     /**
156      * filters by all the values for this property
157      *
158      * @param key
159      * @param value in comma delimited string format
160      * @return vertices that match these values
161      */
162     public abstract QueryBuilder<Vertex> getVerticesByCommaSeperatedValue(String key, String value);
163
164     /**
165      * Gets the vertices that have this property key.
166      *
167      * @param key the key
168      * @return the vertices by property
169      */
170     public abstract QueryBuilder<Vertex> getVerticesByProperty(String key);
171
172     /**
173      * Gets the vertices that do not have this property key.
174      *
175      * @param key the key
176      * @return the vertices by property
177      */
178     public abstract QueryBuilder<Vertex> getVerticesExcludeByProperty(String key);
179
180     /**
181      * filters by elements that start with the value for this property
182      *
183      * @param key
184      * @param value
185      * @return vertices that match these values
186      */
187     public abstract QueryBuilder<Vertex> getVerticesStartsWithProperty(String key, Object value);
188
189     /**
190      * Gets the vertices that are excluded by property.
191      *
192      * @param key the key
193      * @param value the value
194      * @return the vertices by property
195      */
196     public abstract QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, Object value);
197
198     /**
199      * filters by all the values for this property and excludes the vertices
200      *
201      * @param key
202      * @param values
203      * @return vertices that match these values
204      */
205     public QueryBuilder<Vertex> getVerticesExcludeByIndexedProperty(String key, List<?> values) {
206         return this.getVerticesExcludeByProperty(key, values);
207     }
208
209     /**
210      * filters by all the values for this property and excludes the vertices
211      *
212      * @param key
213      * @param values
214      * @return vertices that match these values
215      */
216     public abstract QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, List<?> values);
217
218     /**
219      * filters by all the values greater than for this property
220      *
221      * @param key
222      * @param value
223      * @return vertices that match these values
224      */
225     public abstract QueryBuilder<Vertex> getVerticesGreaterThanProperty(String key, Object value);
226
227     /**
228      * filters by all the values less than for this property
229      *
230      * @param key
231      * @param value
232      * @return vertices that match these values
233      */
234
235     public abstract QueryBuilder<Vertex> getVerticesLessThanProperty(String key, Object value);
236
237     /**
238      * Gets the child vertices from parent.
239      *
240      * @param parentKey the parent key
241      * @param parentValue the parent value
242      * @param childType the child type
243      * @return the child vertices from parent
244      */
245     public abstract QueryBuilder<Vertex> getChildVerticesFromParent(String parentKey, String parentValue,
246             String childType);
247
248     /**
249      * Gets the typed vertices by map.
250      *
251      * @param type the type
252      * @param map the map
253      * @return the typed vertices by map
254      */
255     public abstract QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map);
256
257     /**
258      * Creates the DB query.
259      *
260      * @param obj the obj
261      * @return the query builder
262      */
263     public QueryBuilder<Vertex> createDBQuery(Introspector obj) {
264         this.createKeyQuery(obj);
265         this.createContainerQuery(obj);
266         return (QueryBuilder<Vertex>) this;
267     }
268
269     /**
270      * Creates the key query.
271      *
272      * @param obj the obj
273      * @return the query builder
274      */
275     public abstract QueryBuilder<Vertex> createKeyQuery(Introspector obj);
276
277     /**
278      * Creates the container query.<br>
279      * A container query is a query that will return a collection of objects:
280      * <pre>
281      * /cloud-infrastructure/complexes/complex/key1
282      *           ↑              ↑        ↑
283      *       namespace      container  object
284      *
285      * </pre>
286      * @param obj the Introspector into the db schema
287      * @return the query builder
288      */
289     public abstract QueryBuilder<Vertex> createContainerQuery(Introspector obj);
290
291     /**
292      * Creates the edge traversal.
293      *
294      * @param parent the parent
295      * @param child the child
296      * @return the query builder
297      */
298     public abstract QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, Introspector parent, Introspector child)
299             throws AAIException;
300
301     public abstract QueryBuilder<Vertex> getVerticesByBooleanProperty(String key, Object value);
302
303     public QueryBuilder<Vertex> getVerticesByBooleanProperty(String key, MissingOptionalParameter value) {
304         return (QueryBuilder<Vertex>) this;
305     }
306
307     /**
308      * Creates the private edge traversal.
309      *
310      * @param parent the parent
311      * @param child the child
312      * @return the query builder
313      */
314     public abstract QueryBuilder<Vertex> createPrivateEdgeTraversal(EdgeType type, Introspector parent,
315             Introspector child) throws AAIException;
316
317     /**
318      * Creates the edge traversal.
319      *
320      * @param parent the parent
321      * @param child the child
322      * @return the query builder
323      */
324     public QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, Vertex parent, Introspector child)
325             throws AAIException {
326         String nodeType = parent.<String>property(AAIProperties.NODE_TYPE).orElse(null);
327         this.createEdgeTraversal(type, nodeType, child.getDbName());
328         return (QueryBuilder<Vertex>) this;
329     }
330
331     /**
332      *
333      * @param type
334      * @param outNodeType
335      * @param inNodeType
336      * @return
337      * @throws AAIException
338      */
339     public QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, String outNodeType, String inNodeType)
340             throws AAIException {
341         Introspector out = loader.introspectorFromName(outNodeType);
342         Introspector in = loader.introspectorFromName(inNodeType);
343
344         return createEdgeTraversal(type, out, in);
345     }
346
347     /**
348      *
349      * @param edgeType
350      * @param outNodeType
351      * @param inNodeType
352      * @return
353      * @throws AAIException
354      */
355     public QueryBuilder<Vertex> createEdgeTraversal(String edgeType, String outNodeType, String inNodeType)
356             throws AAIException {
357         /*
358          * When the optional parameter edgetype is sent it is a string that needs to be converted to Enum
359          */
360         EdgeType type = EdgeType.valueOf(edgeType);
361         Introspector out = loader.introspectorFromName(outNodeType);
362         Introspector in = loader.introspectorFromName(inNodeType);
363
364         return createEdgeTraversal(type, out, in);
365     }
366
367     /**
368      *
369      * @param edgeType
370      * @param outNodeType
371      * @param inNodeType
372      * @return
373      * @throws AAIException
374      */
375     public QueryBuilder<Vertex> createEdgeTraversal(MissingOptionalParameter edgeType, String outNodeType,
376             String inNodeType) throws AAIException {
377         /*
378          * When no optional parameter edgetype is sent get all edges between the 2 nodetypes
379          */
380         return this.createEdgeTraversal(outNodeType, inNodeType);
381     }
382
383     /**
384      *
385      * @param edgeType
386      * @param outNodeType
387      * @param inNodeType
388      * @return
389      * @throws AAIException
390      */
391     public QueryBuilder<Vertex> createEdgeTraversalWithLabels(MissingOptionalParameter edgeType, String outNodeType,
392             String inNodeType, List<String> labels) throws AAIException {
393         /*
394          * When no optional parameter edgetype is sent get all edges between the 2 nodetypes
395          */
396         return this.createEdgeTraversalWithLabels(outNodeType, inNodeType, labels);
397     }
398
399     public QueryBuilder<Vertex> createEdgeTraversal(String outNodeType, String inNodeType) throws AAIException {
400
401         Introspector out = loader.introspectorFromName(outNodeType);
402         Introspector in = loader.introspectorFromName(inNodeType);
403
404         QueryBuilder<Vertex> cousinBuilder = null;
405         QueryBuilder<Vertex> treeBuilder = null;
406         QueryBuilder<Vertex> queryBuilder = null;
407
408         try {
409             cousinBuilder = this.newInstance().createEdgeTraversal(EdgeType.COUSIN, out, in);
410         } catch (AAIException e) {
411         }
412
413         if (cousinBuilder != null) {
414             try {
415                 treeBuilder = this.newInstance().createEdgeTraversal(EdgeType.TREE, out, in);
416             } catch (AAIException e) {
417             }
418             if (treeBuilder != null) {
419                 queryBuilder = this.union(new QueryBuilder[] {cousinBuilder, treeBuilder});
420             } else {
421                 queryBuilder = this.union(new QueryBuilder[] {cousinBuilder});
422             }
423         } else {
424             treeBuilder = this.newInstance().createEdgeTraversal(EdgeType.TREE, out, in);
425             queryBuilder = this.union(new QueryBuilder[] {treeBuilder});
426         }
427
428         return queryBuilder;
429     }
430
431     public QueryBuilder<Vertex> createEdgeTraversalWithLabels(String outNodeType, String inNodeType,
432             List<String> labels) throws AAIException {
433
434         Introspector out = loader.introspectorFromName(outNodeType);
435         Introspector in = loader.introspectorFromName(inNodeType);
436
437         QueryBuilder<Vertex> cousinBuilder = null;
438         QueryBuilder<Vertex> treeBuilder = null;
439         QueryBuilder<Vertex> queryBuilder = null;
440
441         try {
442             cousinBuilder = this.newInstance().createEdgeTraversalWithLabels(EdgeType.COUSIN, out, in, labels);
443         } catch (AAIException e) {
444         }
445
446         if (cousinBuilder != null) {
447             try {
448                 treeBuilder = this.newInstance().createEdgeTraversalWithLabels(EdgeType.TREE, out, in, labels);
449             } catch (AAIException e) {
450             }
451             if (treeBuilder != null) {
452                 queryBuilder = this.union(new QueryBuilder[] {cousinBuilder, treeBuilder});
453             } else {
454                 queryBuilder = this.union(new QueryBuilder[] {cousinBuilder});
455             }
456         } else {
457             treeBuilder = this.newInstance().createEdgeTraversalWithLabels(EdgeType.TREE, out, in, labels);
458             queryBuilder = this.union(new QueryBuilder[] {treeBuilder});
459         }
460
461         return queryBuilder;
462     }
463
464     public QueryBuilder<Vertex> createPrivateEdgeTraversal(EdgeType type, String outNodeType, String inNodeType)
465             throws AAIException {
466         Introspector out = loader.introspectorFromName(outNodeType);
467         Introspector in = loader.introspectorFromName(inNodeType);
468         return createPrivateEdgeTraversal(type, out, in);
469     }
470
471     /**
472      *
473      * @param type
474      * @param outNodeType
475      * @param inNodeType
476      * @param labels
477      * @return
478      * @throws AAIException
479      */
480     public QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, String outNodeType, String inNodeType,
481             List<String> labels) throws AAIException {
482         Introspector out = loader.introspectorFromName(outNodeType);
483         Introspector in = loader.introspectorFromName(inNodeType);
484
485         return createEdgeTraversalWithLabels(type, out, in, labels);
486     }
487
488     /**
489      *
490      * @param type
491      * @param out
492      * @param in
493      * @param labels
494      * @return
495      */
496     public abstract QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, Introspector out, Introspector in,
497             List<String> labels) throws AAIException;
498
499     /**
500      * This method and it's overloaded counterpart are conditional statements.
501      * This method creates an edge traversal step if an optional property is present
502      * This is necessary in cases such as "if the Optional Property 1 is sent,
503      * find all Nodes of type A with edges to Nodes of type B with property 1,
504      * otherwise, simply find all nodes of type A".
505      *
506      * @param type
507      * @param outNodeType
508      * @param inNodeType
509      * @param value
510      * @return
511      * @throws AAIException
512      */
513     public QueryBuilder<Vertex> createEdgeTraversalIfParameterIsPresent(EdgeType type, String outNodeType,
514             String inNodeType, Object value) throws AAIException {
515         return this.createEdgeTraversal(type, outNodeType, inNodeType);
516     }
517
518     /**
519      * This method and it's overloaded counterpart are conditional statements.
520      * This method skips an edge traversal step if there is an optional property missing.
521      * This is necessary in cases such as "if the Optional Property 1 is sent,
522      * find all Nodes of type A with edges to Nodes of type B with property 1,
523      * otherwise, simply find all nodes of type A".
524      *
525      * @param type
526      * @param outNodeType
527      * @param inNodeType
528      * @param value
529      * @return
530      * @throws AAIException
531      */
532     public QueryBuilder<Vertex> createEdgeTraversalIfParameterIsPresent(EdgeType type, String outNodeType,
533             String inNodeType, MissingOptionalParameter value) throws AAIException {
534         return (QueryBuilder<Vertex>) this;
535     }
536
537     /**
538      *
539      * @param type
540      * @param outNodeType
541      * @param inNodeType
542      * @return
543      * @throws AAIException
544      */
545     public QueryBuilder<Edge> getEdgesBetween(EdgeType type, String outNodeType, String inNodeType)
546             throws AAIException {
547         this.getEdgesBetweenWithLabels(type, outNodeType, inNodeType, null);
548
549         return (QueryBuilder<Edge>) this;
550
551     }
552
553     /**
554      *
555      * @param type
556      * @param outNodeType
557      * @param inNodeType
558      * @param labels
559      * @return
560      * @throws AAIException
561      */
562     public abstract QueryBuilder<Edge> getEdgesBetweenWithLabels(EdgeType type, String outNodeType, String inNodeType,
563             List<String> labels) throws AAIException;
564
565     /**
566      * Creates the query from URI.
567      *
568      * @param uri the uri
569      * @return the query parser
570      * @throws UnsupportedEncodingException the unsupported encoding exception
571      * @throws AAIException the AAI exception
572      */
573     public abstract QueryParser createQueryFromURI(URI uri) throws UnsupportedEncodingException, AAIException;
574
575     /**
576      * Creates the query from URI.
577      *
578      * @param uri the uri
579      * @param queryParams the query params
580      * @return the query parser
581      * @throws UnsupportedEncodingException the unsupported encoding exception
582      * @throws AAIException the AAI exception
583      */
584     public abstract QueryParser createQueryFromURI(URI uri, MultivaluedMap<String, String> queryParams)
585             throws UnsupportedEncodingException, AAIException;
586
587     /**
588      * Creates a queryparser from a given object name.
589      *
590      * @param objName - name of the object type as it appears in the database
591      * @return
592      */
593     public abstract QueryParser createQueryFromObjectName(String objName);
594
595     /**
596      * Creates the query from relationship.
597      *
598      * @param relationship the relationship
599      * @return the query parser
600      * @throws UnsupportedEncodingException the unsupported encoding exception
601      * @throws AAIException the AAI exception
602      */
603     public abstract QueryParser createQueryFromRelationship(Introspector relationship)
604             throws UnsupportedEncodingException, AAIException;
605
606     /**
607      * Gets the parent query.
608      *
609      * @return the parent query
610      */
611     public abstract QueryBuilder<E> getParentQuery();
612
613     /**
614      * Gets the query.
615      *
616      * @return the query
617      */
618     public abstract <E2> E2 getQuery();
619
620     /**
621      * Form boundary.
622      */
623     public abstract void markParentBoundary();
624
625     public abstract QueryBuilder<E> limit(long amount);
626
627     /**
628      * New instance.
629      *
630      * @param start the start
631      * @return the query builder
632      */
633     public abstract QueryBuilder<E> newInstance(Vertex start);
634
635     /**
636      * New instance.
637      *
638      * @return the query builder
639      */
640     public abstract QueryBuilder<E> newInstance();
641
642     /**
643      * Gets the start.
644      *
645      * @return the start
646      */
647     public abstract Vertex getStart();
648
649     protected Object correctObjectType(Object obj) {
650
651         if (obj != null && obj.getClass().equals(Long.class)) {
652             return Integer.valueOf(obj.toString());
653         }
654
655         return obj;
656     }
657
658     /**
659      * uses all fields in the introspector to create a query
660      *
661      * @param obj
662      * @return
663      */
664     public abstract QueryBuilder<Vertex> exactMatchQuery(Introspector obj);
665
666     /**
667      * lets you join any number of QueryBuilders
668      * <b>be careful about starting with a union it will not use indexes</b>
669      *
670      * @param builder
671      * @return
672      */
673     public abstract QueryBuilder<E> union(QueryBuilder<E>... builder);
674
675     public abstract QueryBuilder<E> where(QueryBuilder<E>... builder);
676
677     public abstract QueryBuilder<E> or(QueryBuilder<E>... builder);
678
679     public abstract QueryBuilder<E> store(String name);
680
681     public abstract QueryBuilder<E> cap(String name);
682
683     public abstract QueryBuilder<E> unfold();
684
685     public abstract QueryBuilder<E> fold();
686
687     public abstract QueryBuilder<E> id();
688
689     public abstract QueryBuilder<E> dedup();
690
691     public abstract QueryBuilder<E> emit();
692
693     public abstract QueryBuilder<E> repeat(QueryBuilder<E> builder);
694
695     public abstract QueryBuilder<Edge> outE();
696
697     public abstract QueryBuilder<Edge> inE();
698
699     public abstract QueryBuilder<Vertex> inV();
700
701     public abstract QueryBuilder<Vertex> outV();
702
703     public abstract QueryBuilder<E> not(QueryBuilder<E> builder);
704
705     public abstract QueryBuilder<E> as(String name);
706
707     public abstract QueryBuilder<E> select(String name);
708
709     public abstract QueryBuilder<E> select(Pop pop, String name);
710
711     public abstract QueryBuilder<E> select(String... names);
712
713     public abstract QueryBuilder<E> until(QueryBuilder<E> builder);
714
715     public abstract QueryBuilder<E> groupCount();
716
717     public abstract QueryBuilder<E> by(String name);
718
719     public abstract QueryBuilder<E> valueMap();
720
721     public abstract QueryBuilder<E> valueMap(String... names);
722
723     public abstract QueryBuilder<E> both();
724
725     public abstract QueryBuilder<Tree> tree();
726
727     /**
728      * Used to prevent the traversal from repeating its path through the graph.
729      * See http://tinkerpop.apache.org/docs/3.0.1-incubating/#simplepath-step for more info.
730      *
731      * @return a QueryBuilder with the simplePath step appended to its traversal
732      */
733     public abstract QueryBuilder<E> simplePath();
734
735     /**
736      *
737      * @return QueryBuilder with the path step appended to its traversal
738      */
739     public abstract QueryBuilder<Path> path();
740
741     public abstract void markContainer();
742
743     public abstract QueryBuilder<E> getContainerQuery();
744
745     public abstract List<E> toList();
746
747     /**
748      * Paginate the resulting list.
749      * This is a final step that returns a PaginationResult.
750      * @param pageable object that contains page and page size
751      * @return returns a page of the results and the total count.
752      */
753     public abstract PaginationResult<E> toPaginationResult(Pageable pageable);
754
755     /**
756      * Sort the resulting list.
757      * @param sort object that contains the property to sort by and the direction
758      * @return returns the QueryBuilder for further query building
759      */
760     public abstract QueryBuilder<E> sort(Sort sort);
761
762
763     /**
764      * Used to skip step if there is an optional property missing.
765      *
766      * @param key
767      * @param value
768      * @return
769      */
770     public QueryBuilder<Vertex> getVerticesByProperty(String key, MissingOptionalParameter value) {
771         return (QueryBuilder<Vertex>) this;
772     }
773
774     /**
775      * TODO the edge direction is hardcoded here, make it more generic
776      * Returns the parent edge of the vertex
777      *
778      * @return
779      */
780     public QueryBuilder<Edge> getParentEdge() {
781         this.outE().has(EdgeProperty.CONTAINS.toString(), AAIDirection.IN.toString());
782         return (QueryBuilder<Edge>) this;
783     }
784
785     /**
786      * TODO the edge direction is hardcoded here, make it more generic
787      * Returns the parent vertex of the vertex
788      *
789      * @return
790      */
791     public QueryBuilder<Vertex> getParentVertex() {
792         this.getParentEdge().inV();
793         return (QueryBuilder<Vertex>) this;
794     }
795
796     protected abstract QueryBuilder<Edge> has(String key, String value);
797
798     protected void initEdgeIngestor() {
799         // TODO proper spring wiring, but that requires a lot of refactoring so for now we have this
800         ApplicationContext ctx = SpringContextAware.getApplicationContext();
801         EdgeIngestor ei = ctx.getBean(EdgeIngestor.class);
802         setEdgeIngestor(ei);
803     }
804
805     protected void setEdgeIngestor(EdgeIngestor ei) {
806         this.edgeRules = ei;
807     }
808
809     public QueryBuilder<Vertex> getVerticesByNumberProperty(String key, Object value) {
810         return getVerticesByProperty(key, value);
811     }
812
813     public QueryBuilder<Vertex> getVerticesByNumberProperty(String key) {
814         return getVerticesByProperty(key);
815     }
816
817     public QueryBuilder<Vertex> getVerticesByNumberProperty(String key, MissingOptionalParameter value) {
818         return getVerticesByProperty(key, value);
819     }
820
821     protected abstract void vertexHas(String key, Object value);
822
823     protected abstract void vertexHasNot(String key);
824
825     protected abstract void vertexHas(String key);
826
827     // TODO: This probably is not required but need to test
828     // protected abstract void vertexHas(final String key, final P<?> predicate);
829 }