[AAI] Fix doc config files
[aai/aai-common.git] / aai-core / src / main / java / org / onap / aai / serialization / queryformats / RawFormat.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
21 package org.onap.aai.serialization.queryformats;
22
23 import com.google.gson.Gson;
24 import com.google.gson.JsonArray;
25 import com.google.gson.JsonObject;
26 import com.google.gson.JsonParser;
27 import java.util.Collections;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Optional;
32 import java.util.Set;
33 import java.util.stream.Collectors;
34 import org.apache.tinkerpop.gremlin.structure.Direction;
35 import org.apache.tinkerpop.gremlin.structure.Edge;
36 import org.apache.tinkerpop.gremlin.structure.Vertex;
37 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
38 import org.onap.aai.db.props.AAIProperties;
39 import org.onap.aai.introspection.Loader;
40 import org.onap.aai.serialization.db.DBSerializer;
41 import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
42 import org.onap.aai.serialization.queryformats.params.AsTree;
43 import org.onap.aai.serialization.queryformats.params.Depth;
44 import org.onap.aai.serialization.queryformats.params.NodesOnly;
45 import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
46
47 public class RawFormat extends MultiFormatMapper {
48     protected JsonParser parser = new JsonParser();
49     protected final DBSerializer serializer;
50     protected final Loader loader;
51     protected final UrlBuilder urlBuilder;
52     protected final int depth;
53     protected final boolean nodesOnly;
54
55     protected RawFormat(Builder builder) {
56         this.urlBuilder = builder.getUrlBuilder();
57         this.loader = builder.getLoader();
58         this.serializer = builder.getSerializer();
59         this.depth = builder.getDepth();
60         this.nodesOnly = builder.isNodesOnly();
61         this.isTree = builder.isTree();
62     }
63
64     @Override
65     public Optional<JsonObject> getJsonFromVertex(Vertex v, Map<String, List<String>> selectedProps) throws AAIFormatVertexException {
66         JsonObject json = new JsonObject();
67         json.addProperty("id", v.id().toString());
68         json.addProperty("node-type", v.<String>value(AAIProperties.NODE_TYPE));
69         json.addProperty("url", this.urlBuilder.pathed(v));
70         Optional<JsonObject> properties = this.createSelectedPropertiesObject(v, selectedProps);
71         if (properties.isPresent()) {
72             json.add("properties", properties.get());
73         } else {
74             return Optional.empty();
75         }
76         if (!nodesOnly) {
77             json.add("related-to", this.createRelationshipObject(v));
78         }
79         return Optional.of(json);
80     }
81
82     @Override
83     public int parallelThreshold() {
84         return 100;
85     }
86
87     public Optional<JsonObject> createPropertiesObject(Vertex v) throws AAIFormatVertexException {
88         JsonObject json = new JsonObject();
89         Iterator<VertexProperty<Object>> iter = v.properties();
90
91         while (iter.hasNext()) {
92             VertexProperty<Object> prop = iter.next();
93             if (prop.value() instanceof String) {
94                 json.addProperty(prop.key(), (String) prop.value());
95             } else if (prop.value() instanceof Boolean) {
96                 json.addProperty(prop.key(), (Boolean) prop.value());
97             } else if (prop.value() instanceof Number) {
98                 json.addProperty(prop.key(), (Number) prop.value());
99             } else if (prop.value() instanceof List) {
100                 Gson gson = new Gson();
101                 String list = gson.toJson(prop.value());
102
103                 json.addProperty(prop.key(), list);
104             } else {
105                 // throw exception?
106                 return Optional.empty();
107             }
108         }
109
110         return Optional.of(json);
111     }
112
113     public Optional<JsonObject> createSelectedPropertiesObject(Vertex v, Map<String, List<String>> selectedProps) throws AAIFormatVertexException {
114         JsonObject json = new JsonObject();
115         String nodeType = v.<String>value(AAIProperties.NODE_TYPE);
116         Set<String> propList = removeSingleQuotesForProperties(selectedProps.get(nodeType));
117         Iterator<VertexProperty<Object>> iter = v.properties();
118
119         Gson gson = new Gson();
120         while (iter.hasNext()) {
121             VertexProperty<Object> prop = iter.next();
122             if (propList != null && !propList.isEmpty()) {
123                 if (propList.contains(prop.label())) {
124                     if (prop.value() instanceof String) {
125                         json.addProperty(prop.key(), (String) prop.value());
126                     } else if (prop.value() instanceof Boolean) {
127                         json.addProperty(prop.key(), (Boolean) prop.value());
128                     } else if (prop.value() instanceof Number) {
129                         json.addProperty(prop.key(), (Number) prop.value());
130                     } else if (prop.value() instanceof List) {
131                         json.addProperty(prop.key(), gson.toJson(prop.value()));
132                     } else {
133                         // throw exception?
134                         return Optional.empty();
135                     }
136                 }
137             } else {
138                 return this.createPropertiesObject(v);
139             }
140         }
141
142         return Optional.of(json);
143     }
144
145     private Set<String> removeSingleQuotesForProperties(List<String> props){
146         if (props != null && !props.isEmpty()) {
147             return props.stream().map(
148                 e -> e.substring(1, e.length()-1)).collect(Collectors.toSet());
149         } else {
150             return Collections.emptySet();
151         }
152
153     }
154
155     protected JsonArray createRelationshipObject(Vertex v) throws AAIFormatVertexException {
156         JsonArray jarray = new JsonArray();
157         Iterator<Edge> inIter = v.edges(Direction.IN);
158         Iterator<Edge> outIter = v.edges(Direction.OUT);
159
160         while (inIter.hasNext()) {
161             Edge e = inIter.next();
162             Vertex outVertex = e.outVertex();
163             this.addEdge(e, outVertex, jarray);
164         }
165
166         while (outIter.hasNext()) {
167             Edge e = outIter.next();
168             Vertex inVertex = e.inVertex();
169             this.addEdge(e, inVertex, jarray);
170         }
171
172         return jarray;
173     }
174
175     protected void addEdge(Edge e, Vertex vertex, JsonArray array) throws AAIFormatVertexException {
176         array.add(this.getRelatedObject(e.label(), vertex));
177     }
178
179     protected JsonObject getRelatedObject(String label, Vertex related) throws AAIFormatVertexException {
180         JsonObject json = new JsonObject();
181         json.addProperty("id", related.id().toString());
182         json.addProperty("relationship-label", label);
183         json.addProperty("node-type", related.<String>value(AAIProperties.NODE_TYPE));
184         json.addProperty("url", this.urlBuilder.pathed(related));
185
186         return json;
187     }
188
189     public static class Builder implements NodesOnly<Builder>, Depth<Builder>, AsTree<Builder> {
190
191         protected final Loader loader;
192         protected final DBSerializer serializer;
193         protected final UrlBuilder urlBuilder;
194         protected boolean includeUrl = false;
195         protected boolean nodesOnly = false;
196         protected int depth = 1;
197         protected boolean modelDriven = false;
198         protected boolean tree = false;
199
200         public Builder(Loader loader, DBSerializer serializer, UrlBuilder urlBuilder) {
201             this.loader = loader;
202             this.serializer = serializer;
203             this.urlBuilder = urlBuilder;
204         }
205
206         protected Loader getLoader() {
207             return this.loader;
208         }
209
210         protected DBSerializer getSerializer() {
211             return this.serializer;
212         }
213
214         protected UrlBuilder getUrlBuilder() {
215             return this.urlBuilder;
216         }
217
218         protected boolean isTree() { return this.tree; }
219
220         public Builder isTree(Boolean tree) {
221             this.tree = tree;
222             return this;
223         }
224
225         public Builder includeUrl() {
226             this.includeUrl = true;
227             return this;
228         }
229
230         public Builder nodesOnly(Boolean nodesOnly) {
231             this.nodesOnly = nodesOnly;
232             return this;
233         }
234
235         public boolean isNodesOnly() {
236             return this.nodesOnly;
237         }
238
239         public Builder depth(Integer depth) {
240             this.depth = depth;
241             return this;
242         }
243
244         public int getDepth() {
245             return this.depth;
246         }
247
248         public boolean isIncludeUrl() {
249             return this.includeUrl;
250         }
251
252         public Builder modelDriven() {
253             this.modelDriven = true;
254             return this;
255         }
256
257         public boolean getModelDriven() {
258             return this.modelDriven;
259         }
260
261         public RawFormat build() {
262             if (modelDriven) {
263                 return new SimpleFormat(this);
264             } else {
265                 return new RawFormat(this);
266             }
267         }
268     }
269
270     @Override
271     protected Optional<JsonObject> getJsonFromVertex(Vertex v) throws AAIFormatVertexException {
272
273         JsonObject json = new JsonObject();
274         json.addProperty("id", v.id().toString());
275         json.addProperty("node-type", v.<String>value(AAIProperties.NODE_TYPE));
276         json.addProperty("url", this.urlBuilder.pathed(v));
277         Optional<JsonObject> properties = this.createPropertiesObject(v);
278         if (properties.isPresent()) {
279             json.add("properties", properties.get());
280         } else {
281             return Optional.empty();
282         }
283         if (!nodesOnly) {
284             json.add("related-to", this.createRelationshipObject(v));
285         }
286         return Optional.of(json);
287     }
288 }