Merge "EntityTemplate has no property of parent_type"
[parser.git] / tosca2heat / tosca-parser / toscaparser / elements / entity_type.py
1 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
2 #    not use this file except in compliance with the License. You may obtain
3 #    a copy of the License at
4 #
5 #         http://www.apache.org/licenses/LICENSE-2.0
6 #
7 #    Unless required by applicable law or agreed to in writing, software
8 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 #    License for the specific language governing permissions and limitations
11 #    under the License.
12
13 import copy
14 import logging
15 import os
16 from toscaparser.common.exception import ExceptionCollector
17 from toscaparser.common.exception import ValidationError
18 from toscaparser.extensions.exttools import ExtTools
19 import toscaparser.utils.yamlparser
20
21 log = logging.getLogger('tosca')
22
23
24 class EntityType(object):
25     '''Base class for TOSCA elements.'''
26
27     SECTIONS = (DERIVED_FROM, PROPERTIES, ATTRIBUTES, REQUIREMENTS,
28                 INTERFACES, CAPABILITIES, TYPE, ARTIFACTS) = \
29                ('derived_from', 'properties', 'attributes', 'requirements',
30                 'interfaces', 'capabilities', 'type', 'artifacts')
31
32     '''TOSCA definition file.'''
33     TOSCA_DEF_FILE = os.path.join(
34         os.path.dirname(os.path.abspath(__file__)),
35         "TOSCA_definition_1_0.yaml")
36
37     loader = toscaparser.utils.yamlparser.load_yaml
38
39     TOSCA_DEF = loader(TOSCA_DEF_FILE)
40
41     RELATIONSHIP_TYPE = (DEPENDSON, HOSTEDON, CONNECTSTO, ATTACHESTO,
42                          LINKSTO, BINDSTO) = \
43                         ('tosca.relationships.DependsOn',
44                          'tosca.relationships.HostedOn',
45                          'tosca.relationships.ConnectsTo',
46                          'tosca.relationships.AttachesTo',
47                          'tosca.relationships.network.LinksTo',
48                          'tosca.relationships.network.BindsTo')
49
50     NODE_PREFIX = 'tosca.nodes.'
51     RELATIONSHIP_PREFIX = 'tosca.relationships.'
52     CAPABILITY_PREFIX = 'tosca.capabilities.'
53     INTERFACE_PREFIX = 'tosca.interfaces.'
54     ARTIFACT_PREFIX = 'tosca.artifacts.'
55     POLICY_PREFIX = 'tosca.policies.'
56     GROUP_PREFIX = 'tosca.groups.'
57     # currently the data types are defined only for network
58     # but may have changes in the future.
59     DATATYPE_PREFIX = 'tosca.datatypes.network.'
60     TOSCA = 'tosca'
61
62     def derived_from(self, defs):
63         '''Return a type this type is derived from.'''
64         return self.entity_value(defs, 'derived_from')
65
66     def is_derived_from(self, type_str):
67         '''Check if object inherits from the given type.
68
69         Returns true if this object is derived from 'type_str'.
70         False otherwise.
71         '''
72         if not self.type:
73             return False
74         elif self.type == type_str:
75             return True
76         elif self.parent_type:
77             return self.parent_type.is_derived_from(type_str)
78         else:
79             return False
80
81     def entity_value(self, defs, key):
82         if key in defs:
83             return defs[key]
84
85     def get_value(self, ndtype, defs=None, parent=None):
86         value = None
87         if defs is None:
88             if not hasattr(self, 'defs'):
89                 return None
90             defs = self.defs
91         if ndtype in defs:
92             # copy the value to avoid that next operations add items in the
93             # item definitions
94             value = copy.copy(defs[ndtype])
95         if parent:
96             p = self
97             if p:
98                 while p:
99                     if ndtype in p.defs:
100                         # get the parent value
101                         parent_value = p.defs[ndtype]
102                         if value:
103                             if isinstance(value, dict):
104                                 for k, v in parent_value.items():
105                                     if k not in value.keys():
106                                         value[k] = v
107                             if isinstance(value, list):
108                                 for p_value in parent_value:
109                                     if isinstance(p_value, dict):
110                                         if p_value.keys()[0] not in [
111                                             item.keys()[0] for item in value]:
112                                             value.append(p_value)
113                                     else:
114                                         if p_value not in value:
115                                             value.append(p_value)
116                         else:
117                             value = copy.copy(parent_value)
118                     p = p.parent_type
119         return value
120
121     def get_definition(self, ndtype):
122         value = None
123         if not hasattr(self, 'defs'):
124             defs = None
125             ExceptionCollector.appendException(
126                 ValidationError(message="defs is " + str(defs)))
127         else:
128             defs = self.defs
129         if defs is not None and ndtype in defs:
130             value = defs[ndtype]
131         p = self.parent_type
132         if p:
133             inherited = p.get_definition(ndtype)
134             if inherited:
135                 inherited = dict(inherited)
136                 if not value:
137                     value = inherited
138                 else:
139                     inherited.update(value)
140                     value.update(inherited)
141         return value
142
143
144 def update_definitions(version):
145     exttools = ExtTools()
146     extension_defs_file = exttools.get_defs_file(version)
147
148     loader = toscaparser.utils.yamlparser.load_yaml
149
150     EntityType.TOSCA_DEF.update(loader(extension_defs_file))