1b8844116a52164014b1a883a6e07c66eeb991ba
[so.git] / common / src / main / java / org / onap / so / client / graphinventory / entities / uri / SimpleUri.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP - SO
4  * ================================================================================
5  * Copyright (C) 2017 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.so.client.graphinventory.entities.uri;
22
23 import java.io.IOException;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
26 import java.io.Serializable;
27 import java.net.URI;
28 import java.nio.charset.StandardCharsets;
29 import java.util.HashMap;
30 import java.util.Map;
31 import java.util.Set;
32
33 import javax.ws.rs.core.UriBuilder;
34
35 import org.apache.commons.lang3.builder.HashCodeBuilder;
36 import org.onap.so.client.graphinventory.Format;
37 import org.onap.so.client.graphinventory.GraphInventoryObjectPlurals;
38 import org.onap.so.client.graphinventory.GraphInventoryObjectType;
39 import org.onap.so.client.graphinventory.entities.uri.parsers.UriParser;
40 import org.onap.so.client.graphinventory.entities.uri.parsers.UriParserSpringImpl;
41 import org.onap.so.client.graphinventory.exceptions.IncorrectNumberOfUriKeys;
42 import org.springframework.web.util.UriUtils;
43
44 public class SimpleUri implements GraphInventoryResourceUri, Serializable {
45
46         private static final long serialVersionUID = -337701171277616439L;
47         
48         protected transient UriBuilder internalURI;
49         protected final static String relationshipAPI = "/relationship-list/relationship";
50         protected final static String relatedTo = "/related-to";
51         protected final Object[] values;
52         protected final GraphInventoryObjectType type;
53         protected final GraphInventoryObjectPlurals pluralType;
54         protected SimpleUri(GraphInventoryObjectType type, Object... values) {
55                 this.type = type;
56                 this.pluralType = null;
57                 this.internalURI = UriBuilder.fromPath(this.getTemplate(type));
58                 this.values = values;
59                 validateValuesSize(this.getTemplate(type), values);
60         }
61         protected SimpleUri(GraphInventoryObjectType type, URI uri) {
62                 this.type = type;
63                 this.pluralType = null;
64                 this.internalURI = UriBuilder.fromPath(uri.getRawPath().replaceAll("/aai/v\\d+", ""));
65                 this.values = new Object[0];
66         }
67         protected SimpleUri(GraphInventoryObjectType type, UriBuilder builder, Object... values) {
68                 this.internalURI = builder;
69                 this.values = values;
70                 this.type = type;
71                 this.pluralType = null;
72         }
73         protected SimpleUri(GraphInventoryObjectPlurals type, UriBuilder builder, Object... values) {
74                 this.internalURI = builder;
75                 this.values = values;
76                 this.type = null;
77                 this.pluralType = type;
78         }
79         protected SimpleUri(GraphInventoryObjectPlurals type) {
80                 this.type = null;
81                 this.pluralType = type;
82                 this.internalURI = UriBuilder.fromPath(this.getTemplate(type));
83                 this.values = new Object[0];
84         }
85         protected SimpleUri(GraphInventoryObjectPlurals type, Object... values) {
86                 this.type = null;
87                 this.pluralType = type;
88                 this.internalURI = UriBuilder.fromPath(this.getTemplate(type));
89                 this.values = values;
90                 validateValuesSize(this.getTemplate(type), values);
91         }
92         protected SimpleUri(GraphInventoryResourceUri parentUri, GraphInventoryObjectType childType, Object... childValues) {
93                 this.type = childType;
94                 this.pluralType = null;
95                 this.internalURI = UriBuilder.fromUri(parentUri.build()).path(childType.partialUri());
96                 this.values = childValues;
97                 validateValuesSize(childType.partialUri(), values);
98         }
99         
100         protected SimpleUri(GraphInventoryResourceUri parentUri, GraphInventoryObjectPlurals childType) {
101                 this.type = null;
102                 this.pluralType = childType;
103                 this.internalURI =  UriBuilder.fromUri(parentUri.build()).path(childType.partialUri());
104                 this.values = new Object[0];
105         }
106         
107         protected void setInternalURI(UriBuilder builder) {
108                 this.internalURI = builder;
109         }
110         @Override
111         public SimpleUri relationshipAPI() {
112                 this.internalURI = internalURI.path(relationshipAPI);
113                 return this;
114         }
115         
116         @Override
117         public SimpleUri relatedTo(GraphInventoryObjectPlurals plural) {
118                 
119                 this.internalURI = internalURI.path(relatedTo).path(plural.partialUri());
120                 return this;
121         }
122         @Override
123         public SimpleUri relatedTo(GraphInventoryObjectType type, String... values) {
124                 this.internalURI = internalURI.path(relatedTo).path(UriBuilder.fromPath(type.partialUri()).build(values).toString());
125                 return this;
126         }
127         
128         @Override
129         public SimpleUri resourceVersion(String version) {
130                 this.internalURI = internalURI.replaceQueryParam("resource-version", version);
131                 return this;
132         }
133         
134         @Override
135         public SimpleUri queryParam(String name, String... values) {
136                 this.internalURI = internalURI.queryParam(name, values);
137                 return this;
138         }
139         
140         @Override
141         public SimpleUri replaceQueryParam(String name, String... values) {
142                 this.internalURI = internalURI.replaceQueryParam(name, values);
143                 return this;
144         }
145         
146         @Override
147         public SimpleUri resultIndex(int index) {
148                 this.internalURI = internalURI.replaceQueryParam("resultIndex", index);
149                 return this;
150         }
151         
152         @Override
153         public SimpleUri resultSize(int size) {
154                 this.internalURI = internalURI.replaceQueryParam("resultSize", size);
155                 return this;
156         }
157         
158         @Override
159         public SimpleUri limit(int size) {
160                 return this.resultIndex(0).resultSize(size);
161         }
162         
163         @Override
164         public URI build() {
165                 return build(this.values);
166         }
167         
168         protected URI build(Object... values) {
169                 //This is a workaround because resteasy does not encode URIs correctly
170                 final String[] encoded = new String[values.length];
171                 for (int i = 0; i < values.length; i++) {                       
172                                 encoded[i] = UriUtils.encode(values[i].toString(), StandardCharsets.UTF_8.toString());                  
173                 }
174                 return internalURI.buildFromEncoded(encoded);
175         }
176         
177         @Override
178         public Map<String, String> getURIKeys() {
179                 return this.getURIKeys(this.build().toString());
180         }
181         
182         protected Map<String, String> getURIKeys(String uri) {
183                 UriParser parser;
184                 if (this.type != null) {
185                         if (!("".equals(this.getTemplate(type)))) {
186                                 parser = new UriParserSpringImpl(this.getTemplate(type));
187                         } else {
188                                 return new HashMap<>();
189                         }
190                 } else {
191                         parser = new UriParserSpringImpl(this.getTemplate(pluralType));
192                 }
193                 
194                 
195                 return parser.parse(uri);
196         }
197         
198         @Override
199         public SimpleUri clone() {
200                 if (this.type != null) {
201                         return new SimpleUri(this.type, this.internalURI.clone(), values);
202                 } else {
203                         return new SimpleUri(this.pluralType, this.internalURI.clone(), values);
204                 }
205         }
206         
207         @Override
208         public GraphInventoryObjectType getObjectType() {
209                 return this.type;
210         }
211         
212         @Override
213         public boolean equals(Object o) {
214                 if (o instanceof GraphInventoryUri) {
215                         return this.build().equals(((GraphInventoryUri)o).build());
216                 }
217                 return false;
218         }
219         
220         @Override
221         public int hashCode() {         
222                 return new HashCodeBuilder().append(this.build()).toHashCode();
223         }
224         
225         
226         @Override
227         public SimpleUri depth(Depth depth) {
228                 this.internalURI.replaceQueryParam("depth", depth.toString());
229                 return this;
230         }
231         @Override
232         public SimpleUri nodesOnly(boolean nodesOnly) {
233                 if (nodesOnly) {
234                         this.internalURI.replaceQueryParam("nodes-only", "");
235                 }
236                 return this;
237         }
238         
239         @Override
240         public SimpleUri format(Format format) {
241                 this.internalURI.replaceQueryParam("format", format);
242                 return this;
243         }
244         
245         public void validateValuesSize(String template, Object... values) {
246                 UriParser parser = new UriParserSpringImpl(template);
247                 Set<String> variables = parser.getVariables();
248                 if (variables.size() != values.length) {
249                         throw new IncorrectNumberOfUriKeys(String.format("Expected %s variables: %s", variables.size(), variables));
250                 }
251         }
252         
253         protected String getTemplate(GraphInventoryObjectType type) {
254                 return type.uriTemplate();
255         }
256         
257         protected String getTemplate(GraphInventoryObjectPlurals type) {
258                 return type.uriTemplate();
259         }
260         
261         private void writeObject(ObjectOutputStream oos) throws IOException {
262                 oos.defaultWriteObject();
263                 oos.writeUTF(this.internalURI.toTemplate());
264         }
265         
266         private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
267                  ois.defaultReadObject();
268                  String uri = ois.readUTF();
269                  this.setInternalURI(UriBuilder.fromUri(uri));
270         }
271 }