toscaparser: Support deriving from capability types of no property
[parser.git] / tosca2heat / tosca-parser / toscaparser / elements / capabilitytype.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 from toscaparser.elements.property_definition import PropertyDef
14 from toscaparser.elements.statefulentitytype import StatefulEntityType
15
16
17 class CapabilityTypeDef(StatefulEntityType):
18     '''TOSCA built-in capabilities type.'''
19     TOSCA_TYPEURI_CAPABILITY_ROOT = 'tosca.capabilities.Root'
20
21     def __init__(self, name, ctype, ntype, custom_def=None):
22         self.name = name
23         super(CapabilityTypeDef, self).__init__(ctype, self.CAPABILITY_PREFIX,
24                                                 custom_def)
25         self.nodetype = ntype
26         self.properties = None
27         self.custom_def = custom_def
28         if self.defs and self.PROPERTIES in self.defs:
29             self.properties = self.defs[self.PROPERTIES]
30         self.parent_capabilities = self._get_parent_capabilities(custom_def)
31
32     def get_properties_def_objects(self):
33         '''Return a list of property definition objects.'''
34         properties = []
35         parent_properties = {}
36         if self.parent_capabilities:
37             for type, value in self.parent_capabilities.items():
38                 parent_properties[type] = value.get('properties', {})
39         if self.properties:
40             for prop, schema in self.properties.items():
41                 properties.append(PropertyDef(prop, None, schema))
42         if parent_properties:
43             for parent, props in parent_properties.items():
44                 for prop, schema in props.items():
45                     # add parent property if not overridden by children type
46                     if not self.properties or \
47                             prop not in self.properties.keys():
48                         properties.append(PropertyDef(prop, None, schema))
49         return properties
50
51     def get_properties_def(self):
52         '''Return a dictionary of property definition name-object pairs.'''
53         return {prop.name: prop
54                 for prop in self.get_properties_def_objects()}
55
56     def get_property_def_value(self, name):
57         '''Return the definition of a given property name.'''
58         props_def = self.get_properties_def()
59         if props_def and name in props_def:
60             return props_def[name].value
61
62     def _get_parent_capabilities(self, custom_def=None):
63         capabilities = {}
64         parent_cap = self.parent_type
65         if parent_cap:
66             parent_cap = parent_cap.type
67             while parent_cap != self.TOSCA_TYPEURI_CAPABILITY_ROOT:
68                 if parent_cap in self.TOSCA_DEF.keys():
69                     capabilities[parent_cap] = self.TOSCA_DEF[parent_cap]
70                 elif custom_def and parent_cap in custom_def.keys():
71                     capabilities[parent_cap] = custom_def[parent_cap]
72                 parent_cap = capabilities[parent_cap]['derived_from']
73         return capabilities
74
75     @property
76     def parent_type(self):
77         '''Return a capability this capability is derived from.'''
78         if not hasattr(self, 'defs'):
79             return None
80         pnode = self.derived_from(self.defs)
81         if pnode:
82             return CapabilityTypeDef(self.name, pnode,
83                                      self.nodetype, self.custom_def)
84
85     def inherits_from(self, type_names):
86         '''Check this capability is in type_names
87
88            Check if this capability or some of its parent types
89            are in the list of types: type_names
90         '''
91         if self.type in type_names:
92             return True
93         elif self.parent_type:
94             return self.parent_type.inherits_from(type_names)
95         else:
96             return False