root/gaphor/tags/gaphor-0.3.0/utils/convert_0_2.py

Revision 209, 5.4 kB (checked in by arjanmol, 5 years ago)

*** empty log message ***

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 # vim:sw=4:et:
2 """
3 Convert a model from Gaphor version 0.2 to Gaphor version 0.3.
4 """
5 import env
6 import operator
7
8 import gaphor.parser as parser
9 import gaphor.storage as storage
10 import gaphor.UML as UML
11 from gaphor.misc.uniqueid import generate_id
12
13 def get_ref(elem, key):
14     try:
15         return elem.references[key]
16     except KeyError:
17         return elem.references[properties_conversion_map[key]]
18
19 def _convert_multiplicity(elements, elem, prop):
20     spec = parser.element(generate_id(), 'LiteralSpecification')
21     spec.values['value'] = elem.values['multiplicity']
22     elem.references['lowerValue'] = [ spec.id ]
23     elements[spec.id] = spec
24     del elem.values['multiplicity']
25
26 def _convert_aggregation(elements, elem, prop):
27     """Strip first three characters from aggregation type (e.g. ak_none ->none)
28     """
29     #print elem, elem[prop]
30     elem.values['aggregation'] = elem.values['aggregation'][3:]
31
32 def _convert_isNavigable(elements, elem, prop):
33     if eval(elem['isNavigable']):
34         # The property is navigable. This means that it is owned by the
35         # class on the other end of the association.
36         assoc_id = elem.references['association']
37         assert len(assoc_id) == 1
38         assoc = elements[assoc_id[0]]
39         end_ids = get_ref(assoc, 'connection')
40         other_end = elements[(end_ids[0] == elem.id) and end_ids[1] or end_ids[0]]
41         clazz = elements[get_ref(other_end, 'participant')[0]]
42         # Create an class_ -- ownedAttribute relationship
43         attr = clazz.references.get('ownedAttribute')
44         if attr is None:
45             attr = clazz.references['ownedAttribute'] = []
46         attr.append(elem.id)
47         assert elem.references.get('class_') is None
48         elem.references['class_'] = [clazz.id]
49     else:
50         elem.references['owningAssociation'] = elem['association']
51     del elem.values['isNavigable']
52
53 def _convert_ownedElement(elements, elem, prop):
54     for ref in elem.references['ownedElement']:
55         if elements[ref].type == 'Diagram':
56             own = 'ownedDiagram'
57         elif elements[ref].type == 'Package':
58             own = 'nestedPackage'
59         else:
60             own = 'ownedClassifier'
61         l = elem.references.get(own)
62         if l is None:
63             l = elem.references[own] = []
64         l.append(ref)
65
66     del elem.references['ownedElement']
67
68 def remove (elements, elem, prop):
69     del elem.references[prop]
70
71 # Property names are unique (unique enough anyway)
72 properties_conversion_map = {
73     'comment': 'ownedComment',
74     'namespace': 'package',
75     # Association
76     'connection': 'memberEnd',
77     # AssociationEnd
78     'aggregation': _convert_aggregation,
79     'isNavigable': _convert_isNavigable,
80     'multiplicity': _convert_multiplicity,
81     'participant': 'type',
82     # Attribute
83     'Attribute.owner': 'class_',
84     # Class
85     'feature': 'ownedAttribute',
86     'specialization': remove,
87     'Class.association': remove,
88     # Generalization
89     'child': 'specific',
90     'parent': 'general',
91     # Package
92     'ownedElement': _convert_ownedElement
93 }
94
95 classname_conversion_map = {
96     'Model': 'Package',
97     'Attribute': 'Property',
98     'AssociationEnd': 'Property'
99 }
100
101 def convert_elements(elements):
102     """Change the elements dictionary (as it is returned from
103     gaphor.parser.parse()) and convert the entries so they can be loaded in
104     the data model of the current version.
105     """
106     element_list = filter(lambda x: isinstance(x, parser.element), elements.values())
107     # convert property names:
108     for e in element_list:
109         # First ensure that all AssociationEnd have isNavigable set
110         # (This is the only attribute set to True by default):
111         if e.type == 'AssociationEnd' and not e.values.get('isNavigable'):
112             e.values['isNavigable'] = 'True'
113
114         for p in e.values.keys() + e.references.keys():
115             func_or_str = properties_conversion_map.get('%s.%s' % (e.type, p)) \
116                           or properties_conversion_map.get(p)
117             if func_or_str:
118                 if operator.isCallable(func_or_str):
119                     func_or_str(elements, e, p)
120                 else:
121                     if p in e.values.keys():
122                         e.values[func_or_str] = e.values[p]
123                         del e.values[p]
124                     else:
125                         e.references[func_or_str] = e.references[p]
126                         del e.references[p]
127
128     for e in element_list:
129         if e.type in classname_conversion_map.keys():
130             e.type = classname_conversion_map[e.type]
131
132     item_list = filter(lambda x: isinstance(x, parser.canvasitem), elements.values())
133     for i in item_list:
134         subject = i.references.get('subject')
135         if subject:
136             e = elements[subject[0]]
137             p = e.references.get('presentation')
138             if p is None:
139                 p = e.references['presentation'] = []
140             p.append(i.id)
141
142 def convert_factory(factory):
143     for a in factory.select(lambda e: isinstance(e, UML.Association)):
144         # Link Association.package to the package which owns the diagram
145         # the association is drawn in.
146         p = a.presentation[0]
147         a.package = p.canvas.diagram.namespace
148
149         # If an association's end is not owned by a Class and is not
150         # owned by the association, let it be owned by the association
151         for p in a.memberEnd:
152             if not p.class_ and not p.owningAssociation:
153                 p.owningAssociation = a
154
155 if __name__ == '__main__':
156     import sys
157     elements = parser.parse(sys.argv[1])
158     convert_elements(elements)
159     factory = UML.ElementFactory()
160     storage._load(elements, factory)
161     convert_factory(factory)
162     storage.save('converted.gaphor', factory)
163
Note: See TracBrowser for help on using the browser.