1 package org.onap.sdc.dcae.catalog;
5 import java.util.Arrays;
6 import java.util.Collection;
7 import java.util.Iterator;
10 import java.util.LinkedList;
11 import java.util.HashMap;
12 import java.util.EnumSet;
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;
21 import org.json.JSONArray;
26 public interface Catalog {
29 public abstract URI getUri();
31 public abstract String namespace();
33 public abstract boolean same(Catalog theCatalog);
35 public abstract <T> T proxy(JSONObject theData, Class<T> theType);
38 /* Base class for all Catalog objects.
40 public static interface Element<T extends Element<T>> {
43 * provide a typed 'self' reference
45 public default T self() { return (T)this; }
49 public default Class<T> selfClass() {
50 return (Class<T>)getClass().getInterfaces()[0];
54 public Catalog catalog();
61 * Direct access to the underlying JSON object.
62 * Warning: Modifications to the JSON object are reflected in the Element.
64 public JSONObject data();
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.
71 public String[] labels();
73 /* Allows for typed deep exploration of the backing JSON data structure
76 * element("type", Type.class);
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
84 public default <E extends Element<E>> E element(String theName, Class<E> theType) {
85 JSONObject elemData = data().optJSONObject(theName);
89 return catalog().proxy(elemData, theType);
92 /* Similar to {@link #element(String,Class)} but for collection wrapping.
96 * element("nodes", Nodes.class);
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) {
107 Class etype = Proxies.typeArgument(theType);
108 Elements elems = null;
110 elems = theType.newInstance();
112 catch (ReflectiveOperationException rox) {
113 throw new RuntimeException("Failed to instantiate " + theType, rox);
117 for (Iterator i = elemsData.iterator(); i.hasNext();) {
118 JSONObject elemData = (JSONObject)i.next();
119 elems.add(catalog().proxy(elemData, etype));
123 throw new RuntimeException("Failed to fetch json data ", e);
131 public default boolean same(Element theElem) {
132 return this.catalog().same(theElem.catalog()) &&
133 this.id().equals(theElem.id());
138 * Base class for all collections of elements.
140 public static class Elements<T extends Element>
141 extends LinkedList<T> {
143 public String toString() {
144 StringBuilder sb = new StringBuilder("[");
145 for (Element el: this) {
146 sb.append(el.selfClass().getSimpleName())
152 return sb.toString();
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)
162 public static class Mixels extends Elements<Element> {
167 public static interface Item<T extends Item<T>> extends Element<T> {
169 public String name();
171 public String description();
173 /* catalog item native identifier */
174 public String itemId();
176 /* similar to @ItemAction#withModels
178 default public Future<Templates> models() {
179 Templates t = elements("models", Templates.class);
181 return Futures.succeededFuture(t);
183 return Futures.advance(catalog().item(itemId())
186 item -> (Templates)item.elements("models", Templates.class));
189 /* similar to @ItemAction#withAnnotations
191 default public Future<Annotations> annotations() {
192 Annotations a = elements("annotations", Annotations.class);
194 return Futures.succeededFuture(a);
196 return Futures.advance(catalog().item(itemId())
199 item -> (Annotations)item.elements("annotations", Annotations.class));
204 * Collection of catalog items.
206 public static class Items extends Elements<Item> {
211 public static interface Folder extends Element<Folder> {
213 public String name();
215 public String description();
217 public String itemId();
219 /* the namespace is immutable */
220 public default String namespace() {
221 return catalog().namespace();
226 default public Future<Items> items() {
227 Items i = elements("items", Items.class);
229 return Futures.succeededFuture(i);
231 return Futures.advance(catalog().folder(itemId())
234 folder -> (Items)folder.elements("items", Items.class));
239 default public Future<Folders> parts() {
240 Folders f = elements("parts", Folders.class);
242 return Futures.succeededFuture(f);
244 return Futures.advance(catalog().folder(itemId())
247 folder -> (Folders)folder.elements("parts", Folders.class));
252 public Future<Folders> partof();
257 public static class Folders extends Elements<Folder> {
260 //no predefined properties here
261 public static interface Annotation extends Element<Annotation> {
263 public default String namespace() {
264 return catalog().namespace();
268 public static class Annotations extends Elements<Annotation> {
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)
279 * elements("nodes", Nodes.class)
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.
285 public static interface Template extends Element<Template> {
287 public String name();
289 public String version();
291 public String description();
296 * Collection of {@link Catalog.Template template} instances.
298 public static class Templates extends Elements<Template> {
303 * A TOSCA type declaration.
305 public interface Type extends Element<Type> {
307 public String name();
310 * Allows navigation to the parent {@link Catalog.Type type}, if any.
312 public Future<Type> derivedfrom();
317 * Collection of {@link Catalog.Type type} instances.
319 public static class Types extends Elements<Type> {
323 public static interface TemplateAction extends Action<Template> {
325 public TemplateAction withInputs();
327 public TemplateAction withOutputs();
329 public TemplateAction withNodes();
331 public TemplateAction withNodeProperties();
333 public TemplateAction withNodeRequirements();
335 public TemplateAction withNodePropertiesAssignments();
337 public TemplateAction withNodeCapabilities();
339 public TemplateAction withNodeCapabilityProperties();
341 public TemplateAction withNodeCapabilityPropertyAssignments();
343 public TemplateAction withPolicies();
345 public TemplateAction withPolicyProperties();
347 public TemplateAction withPolicyPropertiesAssignments();
350 public Future<Template> execute();
356 public static interface TypeAction extends Action<Type> {
358 public TypeAction withHierarchy();
360 public TypeAction withRequirements();
362 public TypeAction withCapabilities();
365 public Future<Type> execute();
371 public static interface FolderAction extends Action<Folder> {
373 public FolderAction withAnnotations();
375 public FolderAction withAnnotations(String theSelector);
377 public FolderAction withItems();
379 public FolderAction withItemAnnotations();
381 public FolderAction withItemAnnotations(String theSelector);
383 public FolderAction withItemModels();
385 public FolderAction withParts();
387 public FolderAction withPartAnnotations();
389 public FolderAction withPartAnnotations(String theSelector);
392 public Future<Folder> execute();
397 public static interface ItemAction<T extends Item> extends Action<T> {
399 public ItemAction<T> withModels();
401 public ItemAction<T> withAnnotations();
404 public Future<T> execute();
410 public abstract Future<Folders> roots();
414 public abstract Future<Folders> rootsByLabel(String theLabel);
418 public abstract Future<Mixels> lookup(JSONObject theSelector);
420 public abstract Future<Mixels> lookup(String theAnnotation, JSONObject theSelector);
424 public abstract FolderAction folder(String theFolderId);
428 public abstract <T extends Item> ItemAction<T> item(String theItemId);
432 public abstract TemplateAction template(String theTemplateId);
436 public abstract TypeAction type(String theNamespace, String theTypeName);