2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.aai.query.builder;
22 import java.io.UnsupportedEncodingException;
24 import java.util.Iterator;
25 import java.util.List;
28 import javax.ws.rs.core.MultivaluedMap;
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;
45 * The Class QueryBuilder.
47 public abstract class QueryBuilder<E> implements Iterator<E> {
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;
56 * Instantiates a new query builder.
58 * @param loader the loader
60 public QueryBuilder(Loader loader, GraphTraversalSource source) {
66 * Instantiates a new query builder.
68 * @param loader the loader
69 * @param start the start
71 public QueryBuilder(Loader loader, GraphTraversalSource source, Vertex start) {
78 * Gets the vertices by indexed property.
81 * @param value the value
82 * @return the vertices by indexed property
84 public QueryBuilder<Vertex> getVerticesByIndexedProperty(String key, Object value) {
85 return this.getVerticesByProperty(key, value);
89 * Gets the vertices by property.
92 * @param value the value
93 * @return the vertices by property
95 public abstract QueryBuilder<Vertex> getVerticesByProperty(String key, Object value);
98 * filters by all the values for this property
101 * @return vertices that match these values
103 public QueryBuilder<Vertex> getVerticesByIndexedProperty(String key, List<?> values) {
104 return this.getVerticesByProperty(key, values);
108 * filters by all the values for this property
111 * @return vertices that match these values
113 public abstract QueryBuilder<Vertex> getVerticesByProperty(String key, List<?> values);
116 * Gets the vertices that are excluded by property.
119 * @param value the value
120 * @return the vertices by property
122 public abstract QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, Object value);
125 * filters by all the values for this property and excludes the vertices
128 * @return vertices that match these values
130 public QueryBuilder<Vertex> getVerticesExcludeByIndexedProperty(String key, List<?> values) {
131 return this.getVerticesExcludeByProperty(key, values);
135 * filters by all the values for this property and excludes the vertices
138 * @return vertices that match these values
140 public abstract QueryBuilder<Vertex> getVerticesExcludeByProperty(String key, List<?> values);
143 * Gets the child vertices from parent.
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
150 public abstract QueryBuilder<Vertex> getChildVerticesFromParent(String parentKey, String parentValue, String childType);
153 * Gets the typed vertices by map.
155 * @param type the type
157 * @return the typed vertices by map
159 public abstract QueryBuilder<Vertex> getTypedVerticesByMap(String type, Map<String, String> map);
162 * Creates the DB query.
165 * @return the query builder
167 public QueryBuilder<Vertex> createDBQuery(Introspector obj) {
168 this.createKeyQuery(obj);
169 this.createContainerQuery(obj);
170 return (QueryBuilder<Vertex>) this;
174 * Creates the key query.
177 * @return the query builder
179 public abstract QueryBuilder<Vertex> createKeyQuery(Introspector obj);
182 * Creates the container query.
185 * @return the query builder
187 public abstract QueryBuilder<Vertex> createContainerQuery(Introspector obj);
190 * Creates the edge traversal.
192 * @param parent the parent
193 * @param child the child
194 * @return the query builder
196 public abstract QueryBuilder<Vertex> createEdgeTraversal(EdgeType type, Introspector parent, Introspector child) throws AAIException;
199 * Creates the edge traversal.
201 * @param parent the parent
202 * @param child the child
203 * @return the query builder
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;
218 * @throws AAIException
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);
224 return createEdgeTraversal(type, out, in);
234 * @throws AAIException
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);
240 return createEdgeTraversalWithLabels(type, out, in, labels);
251 public abstract QueryBuilder<Vertex> createEdgeTraversalWithLabels(EdgeType type, Introspector out, Introspector in, List<String> labels) throws AAIException;
259 * @throws AAIException
261 public QueryBuilder<Edge> getEdgesBetween(EdgeType type, String outNodeType, String inNodeType) throws AAIException {
262 this.getEdgesBetweenWithLabels(type, outNodeType, inNodeType, null);
264 return (QueryBuilder<Edge>)this;
274 * @throws AAIException
276 public abstract QueryBuilder<Edge> getEdgesBetweenWithLabels(EdgeType type, String outNodeType, String inNodeType, List<String> labels) throws AAIException;
279 * Creates the query from URI.
282 * @return the query parser
283 * @throws UnsupportedEncodingException the unsupported encoding exception
284 * @throws AAIException the AAI exception
286 public abstract QueryParser createQueryFromURI(URI uri) throws UnsupportedEncodingException, AAIException;
289 * Creates the query from 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
297 public abstract QueryParser createQueryFromURI(URI uri, MultivaluedMap<String, String> queryParams) throws UnsupportedEncodingException, AAIException;
300 * Creates a queryparser from a given object name.
302 * @param objName - name of the object type as it appears in the database
305 public abstract QueryParser createQueryFromObjectName(String objName);
308 * Creates the query from relationship.
310 * @param relationship the relationship
311 * @return the query parser
312 * @throws UnsupportedEncodingException the unsupported encoding exception
313 * @throws AAIException the AAI exception
315 public abstract QueryParser createQueryFromRelationship(Introspector relationship) throws UnsupportedEncodingException, AAIException;
318 * Gets the parent query.
320 * @return the parent query
322 public abstract QueryBuilder<E> getParentQuery();
329 public abstract <E2> E2 getQuery();
334 public abstract void markParentBoundary();
336 public abstract QueryBuilder<E> limit(long amount);
341 * @param start the start
342 * @return the query builder
344 public abstract QueryBuilder<E> newInstance(Vertex start);
349 * @return the query builder
351 public abstract QueryBuilder<E> newInstance();
358 public abstract Vertex getStart();
360 protected Object correctObjectType(Object obj) {
362 if (obj != null && obj.getClass().equals(Long.class)) {
363 return new Integer(obj.toString());
369 * uses all fields in the introspector to create a query
374 public abstract QueryBuilder<Vertex> exactMatchQuery(Introspector obj);
377 * lets you join any number of QueryBuilders
378 * <b>be careful about starting with a union it will not use indexes</b>
382 public abstract QueryBuilder<E> union(QueryBuilder<E>... builder);
384 public abstract QueryBuilder<E> where(QueryBuilder<E>... builder);
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();
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.
408 * @return a QueryBuilder with the simplePath step appended to its traversal
410 public abstract QueryBuilder<E> simplePath();
414 * @return QueryBuilder with the path step appended to its traversal
416 public abstract QueryBuilder<Path> path();
418 public abstract void markContainer();
420 public abstract QueryBuilder<E> getContainerQuery();
422 public abstract List<E> toList();
425 * Used to skip step if there is an optional property missing.
430 public QueryBuilder<Vertex> getVerticesByProperty(String key, MissingOptionalParameter value) {
431 return (QueryBuilder<Vertex>) this;
435 * TODO the edge direction is hardcoded here, make it more generic
436 * Returns the parent edge of the vertex
439 public QueryBuilder<Edge> getParentEdge() {
440 this.outE().has(EdgeProperty.CONTAINS.toString(), AAIDirection.IN.toString());
441 return (QueryBuilder<Edge>)this;
445 * TODO the edge direction is hardcoded here, make it more generic
446 * Returns the parent vertex of the vertex
449 public QueryBuilder<Vertex> getParentVertex() {
450 this.getParentEdge().inV();
451 return (QueryBuilder<Vertex>)this;
454 protected abstract QueryBuilder<Edge> has(String key, String value);