59e3895ce27691348b2d9f4b3f6f8176e66cd7ef
[so.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 - 2019 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
21 package org.onap.aaiclient.client.graphinventory.entities;
22
23 import java.lang.reflect.Field;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.List;
27 import java.util.function.Consumer;
28 import java.util.stream.Collectors;
29 import org.onap.aaiclient.client.aai.entities.QueryStep;
30 import org.onap.aaiclient.client.graphinventory.GraphInventoryObjectName;
31 import com.google.common.base.Joiner;
32
33 public class DSLQueryBuilder<S, E> {
34
35     private List<QueryStep> steps = new ArrayList<>();
36     private String suffix = "";
37
38     protected DSLQueryBuilder() {
39
40     }
41
42     protected DSLQueryBuilder(QueryStep node) {
43         steps.add(node);
44     }
45
46     public <T> DSLQueryBuilder<S, DSLNodeBase<?>> node(DSLNodeBase<?> node) {
47         steps.add(node);
48
49         return (DSLQueryBuilder<S, DSLNodeBase<?>>) this;
50     }
51
52     public DSLQueryBuilder<S, Node> output() {
53         callOnLambda(item -> item.output());
54         return (DSLQueryBuilder<S, Node>) this;
55     }
56
57     public DSLQueryBuilder<S, Node> output(String... fields) {
58         callOnLambda(item -> item.output(fields));
59         return (DSLQueryBuilder<S, Node>) this;
60     }
61
62     protected void callOnLambda(Consumer<DSLNodeBase> consumer) {
63
64         Object obj = steps.get(steps.size() - 1);
65         if (obj instanceof DSLNodeBase) {
66             ((DSLNodeBase) steps.get(steps.size() - 1)).output();
67         } else if (obj.getClass().getName().contains("$$Lambda$")) {
68             // process lambda expressions
69             for (Field f : obj.getClass().getDeclaredFields()) {
70                 f.setAccessible(true);
71                 Object o;
72                 try {
73                     o = f.get(obj);
74                     if (o instanceof DSLQueryBuilder && ((DSLQueryBuilder) o).steps.get(0) instanceof DSLNodeBase) {
75                         consumer.accept(((DSLNodeBase) ((DSLQueryBuilder) o).steps.get(0)));
76                     }
77                 } catch (IllegalArgumentException | IllegalAccessException e) {
78                 }
79                 f.setAccessible(false);
80                 break;
81             }
82         }
83     }
84
85     @SafeVarargs
86     public final <E2> DSLQueryBuilder<S, E2> union(final DSLQueryBuilder<?, E2>... union) {
87
88         List<DSLQueryBuilder<?, ?>> unions = Arrays.asList(union);
89         steps.add(() -> {
90             StringBuilder query = new StringBuilder();
91
92             query.append("> [ ")
93                     .append(Joiner.on(", ")
94                             .join(unions.stream().map(item -> item.compile()).collect(Collectors.toList())))
95                     .append(" ]");
96             return query.toString();
97         });
98
99         return (DSLQueryBuilder<S, E2>) this;
100     }
101
102     public DSLQueryBuilder<S, E> where(DSLQueryBuilder<?, ?> where) {
103
104         steps.add(() -> {
105             StringBuilder query = new StringBuilder();
106             query.append(where.compile()).append(")");
107             String result = query.toString();
108             if (!result.startsWith(">")) {
109                 result = "> " + result;
110             }
111             return "(" + result;
112         });
113         return this;
114     }
115
116     public <E2> DSLQueryBuilder<S, E2> to(DSLQueryBuilder<?, E2> to) {
117         steps.add(() -> {
118             StringBuilder query = new StringBuilder();
119
120             query.append("> ").append(to.compile());
121             return query.toString();
122         });
123         return (DSLQueryBuilder<S, E2>) this;
124     }
125
126     public DSLQueryBuilder<S, E> to(GraphInventoryObjectName name) {
127         return (DSLQueryBuilder<S, E>) to(__.node(name));
128     }
129
130     public DSLQueryBuilder<S, E> to(GraphInventoryObjectName name, DSLNodeKey... key) {
131         return (DSLQueryBuilder<S, E>) to(__.node(name, key));
132     }
133
134     public DSLQueryBuilder<S, E> limit(int limit) {
135         suffix = " LIMIT " + limit;
136         return this;
137     }
138
139     public DSLTraversal<E> build() {
140         return new DSLTraversal<>(compile());
141     }
142
143     @Override
144     public String toString() {
145         return build().get();
146     }
147
148     @Override
149     public boolean equals(Object o) {
150         if (o != null) {
151             return o.toString().equals(toString());
152         }
153         return false;
154     }
155
156     @Override
157     public int hashCode() {
158
159         return compile().hashCode();
160     }
161
162     private String compile() {
163         return String.join(" ", steps.stream().map(item -> item.build()).collect(Collectors.toList())) + suffix;
164     }
165
166     protected QueryStep getFirst() {
167         return steps.get(0);
168     }
169 }