DCAE-D be initial commit
[sdc/dcae-d/dt-be-main.git] / dcaedt_catalog / api / src / main / java / org / onap / sdc / dcae / catalog / Catalog.java
1 package org.onap.sdc.dcae.catalog;
2
3 import java.net.URI;
4
5 import java.util.Arrays;
6 import java.util.Collection;
7 import java.util.Iterator;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.LinkedList;
11 import java.util.HashMap;
12 import java.util.EnumSet;
13
14 import org.json.JSONObject;
15 import org.onap.sdc.dcae.catalog.commons.Action;
16 import org.onap.sdc.dcae.catalog.commons.Future;
17 import org.onap.sdc.dcae.catalog.commons.Futures;
18 import org.onap.sdc.dcae.catalog.commons.Proxies;
19
20
21 import org.json.JSONArray;
22
23 /*
24  *
25  */
26 public interface Catalog {
27
28
29         public abstract URI getUri();
30
31         public abstract String namespace();
32
33         public abstract boolean same(Catalog theCatalog);
34
35         public abstract <T> T proxy(JSONObject theData, Class<T> theType);
36                 
37         
38         /* Base class for all Catalog objects.
39          */
40         public static interface Element<T extends Element<T>> {
41         
42                 /**
43                  * provide a typed 'self' reference
44                  */
45                 public default T self() { return (T)this; }
46
47                 /**
48                  */
49                 public default Class<T> selfClass() {
50                         return (Class<T>)getClass().getInterfaces()[0];
51                 }
52
53                 /* */
54                 public Catalog catalog();
55
56                 /**
57                  */
58                 public String id();
59
60                 /**
61                  * Direct access to the underlying JSON object.
62                  * Warning: Modifications to the JSON object are reflected in the Element.
63                  */
64                 public JSONObject data();
65
66                 /**
67                  * Provides the labels of the artifacts (we use labels to type/classify the 
68                  * neo4j artifacts, nodes and edges.
69                  * Currently not all queries retrieve the labels.
70                  */
71                 public String[] labels();
72
73                 /* Allows for typed deep exploration of the backing JSON data structure 
74                  * <pre>
75                  * {@code
76                  * element("type", Type.class);
77                  * }
78                  * </pre>
79                  *
80                  * @arg theName name of a JSON entry ; It must map another JSONObject.
81                  * @arg theType the expected wrapping catalog artifact type
82                  * @return the JSON entry wrapped in the specified type
83                  */
84                 public default <E extends Element<E>> E element(String theName, Class<E> theType) {
85                         JSONObject elemData = data().optJSONObject(theName);
86                         if (elemData == null)
87                                 return null;
88                         else
89                                 return catalog().proxy(elemData, theType);
90                 }
91         
92                 /* Similar to {@link #element(String,Class)} but for collection wrapping.
93                  * Example:
94                  * <pre>
95                  * {@code
96                  * element("nodes", Nodes.class);
97                  * }
98                  * </pre>
99                  */
100                 public default <E extends Elements> E elements(String theName, Class<E> theType) {
101                                                                                                                                                                                                                                                         //throws ReflectiveOperationException {
102                         JSONArray elemsData = data().optJSONArray(theName);
103                         if (elemsData == null) {
104                                 return null;
105                         }
106                         else {
107                                 Class etype = Proxies.typeArgument(theType);
108                                 Elements elems = null;
109                                 try {
110                                         elems = theType.newInstance();
111                                 }
112                                 catch (ReflectiveOperationException rox) {
113                                         throw new RuntimeException("Failed to instantiate " + theType, rox);
114                                 }
115
116                                 try{
117                                         for (Iterator i = elemsData.iterator(); i.hasNext();) {
118                                                 JSONObject elemData = (JSONObject)i.next();
119                                                 elems.add(catalog().proxy(elemData,     etype));
120                                         }
121                                 }
122                                 catch(Exception e){
123                                         throw new RuntimeException("Failed to fetch json data ", e);
124                                 }
125                                 return (E)elems;
126                         }
127                 }
128
129                 /*
130                  */
131                 public default boolean same(Element theElem) {
132                         return this.catalog().same(theElem.catalog()) &&
133                                                  this.id().equals(theElem.id());
134                 }
135         }
136
137         /*
138          * Base class for all collections of elements.
139          */
140         public static class Elements<T extends Element> 
141                                                                                                 extends LinkedList<T> {
142
143                 public String toString() {
144                         StringBuilder sb = new StringBuilder("[");
145                         for (Element el: this) {
146                                 sb.append(el.selfClass().getSimpleName())
147                                         .append("(")
148                                         .append(el.data())
149                                         .append("),");
150                         }
151                         sb.append("]");
152                         return sb.toString();
153                 }
154         }
155
156         /*
157          * We need this contraption in order to store a mix of Folders and CatalogItem
158          * instances (Elements in self is not good because it is defined around a 
159          * type variable so we cannot use reflection to determine the type at runtime
160          * - generics are resolved compile time)
161          */
162         public static class Mixels extends Elements<Element> {
163         }
164
165         /*
166          */
167         public static interface Item<T extends Item<T>> extends Element<T> {
168
169                 public String name();
170
171                 public String description();
172
173                 /* catalog item native identifier */
174                 public String itemId();
175
176                 /* similar to @ItemAction#withModels
177                  */
178                 default public Future<Templates> models() {
179                         Templates t = elements("models", Templates.class);
180                         if (t != null)
181                                 return Futures.succeededFuture(t);
182                         else
183                                 return Futures.advance(catalog().item(itemId())
184                                                                                                                                                                         .withModels()
185                                                                                                                                                                         .execute(),
186                                                                                                                          item -> (Templates)item.elements("models", Templates.class));
187                 }
188                 
189                 /* similar to @ItemAction#withAnnotations
190                  */
191                 default public Future<Annotations> annotations() {
192                         Annotations a = elements("annotations", Annotations.class);
193                         if (a != null)
194                                 return Futures.succeededFuture(a);
195                         else
196                                 return Futures.advance(catalog().item(itemId())
197                                                                                                                                                                         .withAnnotations()
198                                                                                                                                                                         .execute(),
199                                                                                                                          item -> (Annotations)item.elements("annotations", Annotations.class));
200                 } 
201         }
202
203         /*
204          * Collection of catalog items.
205          */
206         public static class Items extends Elements<Item> {
207         }
208
209         /*
210          */
211   public static interface Folder extends Element<Folder> {
212
213                 public String name();
214
215                 public String description();
216                 
217                 public String itemId();
218
219                  /* the namespace is immutable */
220                 public default String namespace() {
221                         return catalog().namespace();
222                 }
223
224                 /*
225                  */
226                 default public Future<Items> items() {
227                         Items i = elements("items", Items.class);
228                         if (i != null)
229                                 return Futures.succeededFuture(i);
230                         else
231                                 return Futures.advance(catalog().folder(itemId())
232                                                                                                                                                                         .withItems()
233                                                                                                                                                                         .execute(),
234                                                                                                                          folder -> (Items)folder.elements("items", Items.class));
235                 }
236
237                 /*
238                  */
239                 default public Future<Folders> parts() {
240                         Folders f = elements("parts", Folders.class);
241                         if (f != null)
242                                 return Futures.succeededFuture(f);
243                         else
244                                 return Futures.advance(catalog().folder(itemId())
245                                                                                                                                                                         .withParts()
246                                                                                                                                                                         .execute(),
247                                                                                                                          folder -> (Folders)folder.elements("parts", Folders.class));
248                 }
249
250                 /*
251                  */
252                 public Future<Folders> partof(); 
253         
254         }
255
256
257         public static class Folders extends Elements<Folder> {
258         }
259
260         //no predefined properties here
261   public static interface Annotation extends Element<Annotation> {
262
263     public default String namespace() {
264       return catalog().namespace();
265     }
266   }
267
268   public static class Annotations extends Elements<Annotation> {
269   }
270
271         /**
272          * A TOSCA teamplate.
273          * When a deep loading method is used to obtain a Template its collection
274          * of inputs and nodes will be immediately available (and 'cached' within
275          * the backing JSON object). It can be retrieved through a call to 
276          * {@link Element#elements(String,Class)} as in:
277          *      elements("inputs", Inputs.class)
278          * or
279          *  elements("nodes", Nodes.class)
280          * 
281          * The same result will be obtained through one of the methods of the
282          * navigation interface, {@link #inputs()} or {@link #nodes()}; in this case
283          * the result does not become part of the backing JSONObject.
284          */
285         public static interface Template extends Element<Template> {
286
287                 public String name();
288
289                 public String version();
290
291                 public String description();
292
293         }
294         
295         /**
296          * Collection of {@link Catalog.Template template} instances.
297          */
298         public static class Templates extends Elements<Template> {
299         }
300
301
302         /**
303          * A TOSCA type declaration.
304          */
305         public interface Type extends Element<Type> {
306                 
307                 public String name();
308
309                 /**
310                  * Allows navigation to the parent {@link Catalog.Type type}, if any.
311                  */
312                 public Future<Type> derivedfrom();
313                         
314         }
315         
316         /**
317          * Collection of {@link Catalog.Type type} instances.
318          */
319         public static class Types extends Elements<Type> {
320         }
321         
322
323         public static interface TemplateAction extends Action<Template> {
324
325                 public TemplateAction withInputs(); 
326                 
327                 public TemplateAction withOutputs(); 
328
329                 public TemplateAction withNodes(); 
330         
331                 public TemplateAction withNodeProperties(); 
332         
333                 public TemplateAction withNodeRequirements(); 
334                 
335                 public TemplateAction withNodePropertiesAssignments(); 
336
337                 public TemplateAction withNodeCapabilities(); 
338
339                 public TemplateAction withNodeCapabilityProperties(); 
340                 
341                 public TemplateAction withNodeCapabilityPropertyAssignments();
342                 
343                 public TemplateAction withPolicies();
344
345                 public TemplateAction withPolicyProperties(); 
346                 
347                 public TemplateAction withPolicyPropertiesAssignments(); 
348
349                 @Override
350                 public Future<Template> execute();
351
352         }
353         
354         /*
355          */
356         public static interface TypeAction extends Action<Type> {
357                 
358                 public TypeAction withHierarchy(); 
359         
360                 public TypeAction withRequirements();
361                 
362                 public TypeAction withCapabilities(); 
363         
364                 @Override
365                 public Future<Type> execute();
366
367         }
368
369         /*
370          */
371         public static interface FolderAction extends Action<Folder> {
372
373                 public FolderAction withAnnotations();
374
375                 public FolderAction withAnnotations(String theSelector); 
376
377           public FolderAction withItems();
378
379                 public FolderAction withItemAnnotations();
380
381                 public FolderAction withItemAnnotations(String theSelector);
382
383                 public FolderAction withItemModels(); 
384
385                 public FolderAction withParts(); 
386                 
387                 public FolderAction withPartAnnotations();
388
389                 public FolderAction withPartAnnotations(String theSelector);
390
391                 @Override
392                 public Future<Folder> execute();
393         }
394
395         /*
396          */
397         public static interface ItemAction<T extends Item> extends Action<T> {
398
399                 public ItemAction<T> withModels();
400
401                 public ItemAction<T> withAnnotations();
402                 
403                 @Override
404                 public Future<T> execute();
405
406         }
407
408         /**
409          */
410         public abstract Future<Folders> roots();
411
412         /**
413          */
414         public abstract Future<Folders> rootsByLabel(String theLabel);
415
416         /**
417    */
418         public abstract Future<Mixels> lookup(JSONObject theSelector); 
419         
420         public abstract Future<Mixels> lookup(String theAnnotation, JSONObject theSelector); 
421         
422         /**
423    */
424         public abstract FolderAction folder(String theFolderId);
425
426         /**
427          */
428         public abstract <T extends Item> ItemAction<T> item(String theItemId);
429
430         /**
431    */
432         public abstract TemplateAction template(String theTemplateId); 
433
434         /**
435    */
436         public abstract TypeAction type(String theNamespace, String theTypeName);
437
438
439
440 }