Fix bug in python3.4: 'dict_keys' object does not support indexing
[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.'
60     DATATYPE_NETWORK_PREFIX = DATATYPE_PREFIX + 'network.'
61     TOSCA = 'tosca'
62
63     def derived_from(self, defs):
64         '''Return a type this type is derived from.'''
65         return self.entity_value(defs, 'derived_from')
66
67     def is_derived_from(self, type_str):
68         '''Check if object inherits from the given type.
69
70         Returns true if this object is derived from 'type_str'.
71         False otherwise.
72         '''
73         if not self.type:
74             return False
75         elif self.type == type_str:
76             return True
77         elif self.parent_type:
78             return self.parent_type.is_derived_from(type_str)
79         else:
80             return False
81
82     def entity_value(self, defs, key):
83         if key in defs:
84             return defs[key]
85
86     def get_value(self, ndtype, defs=None, parent=None):
87         value = None
88         if defs is None:
89             if not hasattr(self, 'defs'):
90                 return None
91             defs = self.defs
92         if ndtype in defs:
93             # copy the value to avoid that next operations add items in the
94             # item definitions
95             value = copy.copy(defs[ndtype])
96         if parent:
97             p = self
98             if p:
99                 while p:
100                     if ndtype in p.defs:
101                         # get the parent value
102                         parent_value = p.defs[ndtype]
103                         if value:
104                             if isinstance(value, dict):
105                                 for k, v in parent_value.items():
106                                     if k not in value.keys():
107                                         value[k] = v
108                             if isinstance(value, list):
109                                 for p_value in parent_value:
110                                     if isinstance(p_value, dict):
111                                         if list(p_value.keys())[0] not in [
112                                             list(item.keys())[0] for item in
113                                             value]:
114                                             value.append(p_value)
115                                     else:
116                                         if p_value not in value:
117                                             value.append(p_value)
118                         else:
119                             value = copy.copy(parent_value)
120                     p = p.parent_type
121         return value
122
123     def get_definition(self, ndtype):
124         value = None
125         if not hasattr(self, 'defs'):
126             defs = None
127             ExceptionCollector.appendException(
128                 ValidationError(message="defs is " + str(defs)))
129         else:
130             defs = self.defs
131         if defs is not None and ndtype in defs:
132             value = defs[ndtype]
133         p = self.parent_type
134         if p:
135             inherited = p.get_definition(ndtype)
136             if inherited:
137                 inherited = dict(inherited)
138                 if not value:
139                     value = inherited
140                 else:
141                     inherited.update(value)
142                     value.update(inherited)
143         return value
144
145
146 def update_definitions(version):
147     exttools = ExtTools()
148     extension_defs_file = exttools.get_defs_file(version)
149
150     loader = toscaparser.utils.yamlparser.load_yaml
151
152     EntityType.TOSCA_DEF.update(loader(extension_defs_file))