Fix checkstyle violations in sdc/jtosca
[sdc/sdc-tosca.git] / src / main / java / org / onap / sdc / toscaparser / api / elements / EntityType.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 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.sdc.toscaparser.api.elements;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.util.ArrayList;
26 import java.util.LinkedHashMap;
27 import java.util.Map;
28
29 import org.onap.sdc.toscaparser.api.common.JToscaValidationIssue;
30 import org.onap.sdc.toscaparser.api.utils.CopyUtils;
31 import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
32 import org.onap.sdc.toscaparser.api.extensions.ExtTools;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
35 import org.yaml.snakeyaml.Yaml;
36
37 public class EntityType {
38
39     private static Logger log = LoggerFactory.getLogger(EntityType.class.getName());
40
41     private static final String TOSCA_DEFINITION_1_0_YAML = "TOSCA_definition_1_0.yaml";
42     protected static final String DERIVED_FROM = "derived_from";
43     protected static final String PROPERTIES = "properties";
44     protected static final String ATTRIBUTES = "attributes";
45     protected static final String REQUIREMENTS = "requirements";
46     protected static final String INTERFACES = "interfaces";
47     protected static final String CAPABILITIES = "capabilities";
48     protected static final String TYPE = "type";
49     protected static final String ARTIFACTS = "artifacts";
50
51     @SuppressWarnings("unused")
52     private static final String SECTIONS[] = {
53             DERIVED_FROM, PROPERTIES, ATTRIBUTES, REQUIREMENTS,
54             INTERFACES, CAPABILITIES, TYPE, ARTIFACTS
55     };
56
57     public static final String TOSCA_DEF_SECTIONS[] = {
58             "node_types", "data_types", "artifact_types",
59             "group_types", "relationship_types",
60             "capability_types", "interface_types",
61             "policy_types"};
62
63
64     // TOSCA definition file
65     //private final static String path = EntityType.class.getProtectionDomain().getCodeSource().getLocation().getPath();
66
67     //private final static String path =  EntityType.class.getClassLoader().getResource("TOSCA_definition_1_0.yaml").getFile();
68     //private final static String TOSCA_DEF_FILE = EntityType.class.getClassLoader().getResourceAsStream("TOSCA_definition_1_0.yaml");
69
70     private static LinkedHashMap<String, Object> TOSCA_DEF_LOAD_AS_IS = loadTdf();
71
72     //EntityType.class.getClassLoader().getResourceAsStream("TOSCA_definition_1_0.yaml");
73
74     @SuppressWarnings("unchecked")
75     private static LinkedHashMap<String, Object> loadTdf() {
76         String toscaDefLocation = EntityType.class.getClassLoader().getResource(TOSCA_DEFINITION_1_0_YAML).getFile();
77         InputStream input = EntityType.class.getClassLoader().getResourceAsStream(TOSCA_DEFINITION_1_0_YAML);
78         if (input == null) {
79             log.error("EntityType - loadTdf - Couldn't load TOSCA_DEF_FILE {}", toscaDefLocation);
80         }
81         Yaml yaml = new Yaml();
82         Object loaded = yaml.load(input);
83         //@SuppressWarnings("unchecked")
84         return (LinkedHashMap<String, Object>) loaded;
85     }
86
87     // Map of definition with pre-loaded values of TOSCA_DEF_FILE_SECTIONS
88     public static LinkedHashMap<String, Object> TOSCA_DEF;
89
90     static {
91         TOSCA_DEF = new LinkedHashMap<String, Object>();
92         for (String section : TOSCA_DEF_SECTIONS) {
93             @SuppressWarnings("unchecked")
94             LinkedHashMap<String, Object> value = (LinkedHashMap<String, Object>) TOSCA_DEF_LOAD_AS_IS.get(section);
95             if (value != null) {
96                 for (String key : value.keySet()) {
97                     TOSCA_DEF.put(key, value.get(key));
98                 }
99             }
100         }
101     }
102
103     public static final String DEPENDSON = "tosca.relationships.DependsOn";
104     public static final String HOSTEDON = "tosca.relationships.HostedOn";
105     public static final String CONNECTSTO = "tosca.relationships.ConnectsTo";
106     public static final String ATTACHESTO = "tosca.relationships.AttachesTo";
107     public static final String LINKSTO = "tosca.relationships.network.LinksTo";
108     public static final String BINDSTO = "tosca.relationships.network.BindsTo";
109
110     public static final String RELATIONSHIP_TYPE[] = {
111             "tosca.relationships.DependsOn",
112             "tosca.relationships.HostedOn",
113             "tosca.relationships.ConnectsTo",
114             "tosca.relationships.AttachesTo",
115             "tosca.relationships.network.LinksTo",
116             "tosca.relationships.network.BindsTo"};
117
118     public static final String NODE_PREFIX = "tosca.nodes.";
119     public static final String RELATIONSHIP_PREFIX = "tosca.relationships.";
120     public static final String CAPABILITY_PREFIX = "tosca.capabilities.";
121     public static final String INTERFACE_PREFIX = "tosca.interfaces.";
122     public static final String ARTIFACT_PREFIX = "tosca.artifacts.";
123     public static final String POLICY_PREFIX = "tosca.policies.";
124     public static final String GROUP_PREFIX = "tosca.groups.";
125     //currently the data types are defined only for network
126     // but may have changes in the future.
127     public static final String DATATYPE_PREFIX = "tosca.datatypes.";
128     public static final String DATATYPE_NETWORK_PREFIX = DATATYPE_PREFIX + "network.";
129     public static final String TOSCA = "tosca";
130
131     protected String type;
132     protected LinkedHashMap<String, Object> defs = null;
133
134     public Object getParentType() {
135         return null;
136     }
137
138     public String derivedFrom(LinkedHashMap<String, Object> defs) {
139         // Return a type this type is derived from
140         return (String) entityValue(defs, "derived_from");
141     }
142
143     public boolean isDerivedFrom(String type_str) {
144         // Check if object inherits from the given type
145         // Returns true if this object is derived from 'type_str'
146         // False otherwise.
147         if (type == null || this.type.isEmpty()) {
148             return false;
149         } else if (type == type_str) {
150             return true;
151         } else if (getParentType() != null) {
152             return ((EntityType) getParentType()).isDerivedFrom(type_str);
153         } else {
154             return false;
155         }
156     }
157
158     public Object entityValue(LinkedHashMap<String, Object> defs, String key) {
159         if (defs != null) {
160             return defs.get(key);
161         }
162         return null;
163     }
164
165     @SuppressWarnings("unchecked")
166     public Object getValue(String ndtype, LinkedHashMap<String, Object> _defs, boolean parent) {
167         Object value = null;
168         if (_defs == null) {
169             if (defs == null) {
170                 return null;
171             }
172             _defs = this.defs;
173         }
174         Object defndt = _defs.get(ndtype);
175         if (defndt != null) {
176             // copy the value to avoid that next operations add items in the
177             // item definitions
178             //value = copy.copy(defs[ndtype])
179             value = CopyUtils.copyLhmOrAl(defndt);
180         }
181
182         if (parent) {
183             EntityType p = this;
184             if (p != null) {
185                 while (p != null) {
186                     if (p.defs != null && p.defs.get(ndtype) != null) {
187                         // get the parent value
188                         Object parentValue = p.defs.get(ndtype);
189                         if (value != null) {
190                             if (value instanceof LinkedHashMap) {
191                                 for (Map.Entry<String, Object> me : ((LinkedHashMap<String, Object>) parentValue).entrySet()) {
192                                     String k = me.getKey();
193                                     if (((LinkedHashMap<String, Object>) value).get(k) == null) {
194                                         ((LinkedHashMap<String, Object>) value).put(k, me.getValue());
195                                     }
196                                 }
197                             }
198                             if (value instanceof ArrayList) {
199                                 for (Object pValue : (ArrayList<Object>) parentValue) {
200                                     if (!((ArrayList<Object>) value).contains(pValue)) {
201                                         ((ArrayList<Object>) value).add(pValue);
202                                     }
203                                 }
204                             }
205                         } else {
206                             // value = copy.copy(parent_value)
207                             value = CopyUtils.copyLhmOrAl(parentValue);
208                         }
209                     }
210                     p = (EntityType) p.getParentType();
211                 }
212             }
213         }
214
215         return value;
216     }
217
218     @SuppressWarnings("unchecked")
219     public Object getDefinition(String ndtype) {
220         Object value = null;
221         LinkedHashMap<String, Object> _defs;
222         // no point in hasattr, because we have it, and it 
223         // doesn't do anything except emit an exception anyway
224         //if not hasattr(self, 'defs'):
225         //    defs = None
226         //    ValidationIssueCollector.appendException(
227         //        ValidationError(message="defs is " + str(defs)))
228         //else:
229         //    defs = self.defs          
230         _defs = this.defs;
231
232
233         if (_defs != null && _defs.get(ndtype) != null) {
234             value = _defs.get(ndtype);
235         }
236
237         Object p = getParentType();
238         if (p != null) {
239             Object inherited = ((EntityType) p).getDefinition(ndtype);
240             if (inherited != null) {
241                 // inherited = dict(inherited) WTF?!?
242                 if (value == null) {
243                     value = inherited;
244                 } else {
245                     //?????
246                     //inherited.update(value)
247                     //value.update(inherited)
248                     for (Map.Entry<String, Object> me : ((LinkedHashMap<String, Object>) inherited).entrySet()) {
249                         ((LinkedHashMap<String, Object>) value).put(me.getKey(), me.getValue());
250                     }
251                 }
252             }
253         }
254         return value;
255     }
256
257     public static void updateDefinitions(String version) {
258         ExtTools exttools = new ExtTools();
259         String extensionDefsFile = exttools.getDefsFile(version);
260
261         try (InputStream input = EntityType.class.getClassLoader().getResourceAsStream(extensionDefsFile);) {
262             Yaml yaml = new Yaml();
263             LinkedHashMap<String, Object> nfvDefFile = (LinkedHashMap<String, Object>) yaml.load(input);
264             LinkedHashMap<String, Object> nfvDef = new LinkedHashMap<>();
265             for (String section : TOSCA_DEF_SECTIONS) {
266                 if (nfvDefFile.get(section) != null) {
267                     LinkedHashMap<String, Object> value =
268                             (LinkedHashMap<String, Object>) nfvDefFile.get(section);
269                     for (String key : value.keySet()) {
270                         nfvDef.put(key, value.get(key));
271                     }
272                 }
273             }
274             TOSCA_DEF.putAll(nfvDef);
275         } catch (IOException e) {
276             log.error("EntityType - updateDefinitions - Failed to update definitions from defs file {}", extensionDefsFile);
277             log.error("Exception:", e);
278             ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE280",
279                     String.format("Failed to update definitions from defs file \"%s\" ", extensionDefsFile)));
280             return;
281         }
282     }
283 }
284
285 /*python
286
287 from toscaparser.common.exception import ValidationIssueCollector
288 from toscaparser.common.exception import ValidationError
289 from toscaparser.extensions.exttools import ExtTools
290 import org.onap.sdc.toscaparser.api.utils.yamlparser
291
292 log = logging.getLogger('tosca')
293
294
295 class EntityType(object):
296     '''Base class for TOSCA elements.'''
297
298     SECTIONS = (DERIVED_FROM, PROPERTIES, ATTRIBUTES, REQUIREMENTS,
299                 INTERFACES, CAPABILITIES, TYPE, ARTIFACTS) = \
300                ('derived_from', 'properties', 'attributes', 'requirements',
301                 'interfaces', 'capabilities', 'type', 'artifacts')
302
303     TOSCA_DEF_SECTIONS = ['node_types', 'data_types', 'artifact_types',
304                           'group_types', 'relationship_types',
305                           'capability_types', 'interface_types',
306                           'policy_types']
307
308     '''TOSCA definition file.'''
309     TOSCA_DEF_FILE = os.path.join(
310         os.path.dirname(os.path.abspath(__file__)),
311         "TOSCA_definition_1_0.yaml")
312
313     loader = toscaparser.utils.yamlparser.load_yaml
314
315     TOSCA_DEF_LOAD_AS_IS = loader(TOSCA_DEF_FILE)
316
317     # Map of definition with pre-loaded values of TOSCA_DEF_FILE_SECTIONS
318     TOSCA_DEF = {}
319     for section in TOSCA_DEF_SECTIONS:
320         if section in TOSCA_DEF_LOAD_AS_IS.keys():
321             value = TOSCA_DEF_LOAD_AS_IS[section]
322             for key in value.keys():
323                 TOSCA_DEF[key] = value[key]
324
325     RELATIONSHIP_TYPE = (DEPENDSON, HOSTEDON, CONNECTSTO, ATTACHESTO,
326                          LINKSTO, BINDSTO) = \
327                         ('tosca.relationships.DependsOn',
328                          'tosca.relationships.HostedOn',
329                          'tosca.relationships.ConnectsTo',
330                          'tosca.relationships.AttachesTo',
331                          'tosca.relationships.network.LinksTo',
332                          'tosca.relationships.network.BindsTo')
333
334     NODE_PREFIX = 'tosca.nodes.'
335     RELATIONSHIP_PREFIX = 'tosca.relationships.'
336     CAPABILITY_PREFIX = 'tosca.capabilities.'
337     INTERFACE_PREFIX = 'tosca.interfaces.'
338     ARTIFACT_PREFIX = 'tosca.artifacts.'
339     POLICY_PREFIX = 'tosca.policies.'
340     GROUP_PREFIX = 'tosca.groups.'
341     # currently the data types are defined only for network
342     # but may have changes in the future.
343     DATATYPE_PREFIX = 'tosca.datatypes.'
344     DATATYPE_NETWORK_PREFIX = DATATYPE_PREFIX + 'network.'
345     TOSCA = 'tosca'
346
347     def derived_from(self, defs):
348         '''Return a type this type is derived from.'''
349         return self.entity_value(defs, 'derived_from')
350
351     def is_derived_from(self, type_str):
352         '''Check if object inherits from the given type.
353
354         Returns true if this object is derived from 'type_str'.
355         False otherwise.
356         '''
357         if not self.type:
358             return False
359         elif self.type == type_str:
360             return True
361         elif self.parent_type:
362             return self.parent_type.is_derived_from(type_str)
363         else:
364             return False
365
366     def entity_value(self, defs, key):
367         if key in defs:
368             return defs[key]
369
370     def get_value(self, ndtype, defs=None, parent=None):
371         value = None
372         if defs is None:
373             if not hasattr(self, 'defs'):
374                 return None
375             defs = self.defs
376         if ndtype in defs:
377             # copy the value to avoid that next operations add items in the
378             # item definitions
379             value = copy.copy(defs[ndtype])
380         if parent:
381             p = self
382             if p:
383                 while p:
384                     if ndtype in p.defs:
385                         # get the parent value
386                         parent_value = p.defs[ndtype]
387                         if value:
388                             if isinstance(value, dict):
389                                 for k, v in parent_value.items():
390                                     if k not in value.keys():
391                                         value[k] = v
392                             if isinstance(value, list):
393                                 for p_value in parent_value:
394                                     if p_value not in value:
395                                         value.append(p_value)
396                         else:
397                             value = copy.copy(parent_value)
398                     p = p.parent_type
399         return value
400
401     def get_definition(self, ndtype):
402         value = None
403         if not hasattr(self, 'defs'):
404             defs = None
405             ValidationIssueCollector.appendException(
406                 ValidationError(message="defs is " + str(defs)))
407         else:
408             defs = self.defs
409         if defs is not None and ndtype in defs:
410             value = defs[ndtype]
411         p = self.parent_type
412         if p:
413             inherited = p.get_definition(ndtype)
414             if inherited:
415                 inherited = dict(inherited)
416                 if not value:
417                     value = inherited
418                 else:
419                     inherited.update(value)
420                     value.update(inherited)
421         return value
422
423
424 def update_definitions(version):
425     exttools = ExtTools()
426     extension_defs_file = exttools.get_defs_file(version)
427     loader = toscaparser.utils.yamlparser.load_yaml
428     nfv_def_file = loader(extension_defs_file)
429     nfv_def = {}
430     for section in EntityType.TOSCA_DEF_SECTIONS:
431         if section in nfv_def_file.keys():
432             value = nfv_def_file[section]
433             for key in value.keys():
434                 nfv_def[key] = value[key]
435     EntityType.TOSCA_DEF.update(nfv_def)
436 */