mwgencode 1.4.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. gencode/__init__.py +140 -0
  2. gencode/dd_models.py +256 -0
  3. gencode/ext.py +19 -0
  4. gencode/gen_code.py +343 -0
  5. gencode/gencode/__init__.py +0 -0
  6. gencode/gencode/export_class2swgclass.py +206 -0
  7. gencode/gencode/gen_bo_models_code.py +719 -0
  8. gencode/gencode/gen_state_code.py +171 -0
  9. gencode/gencode/gen_swagger_code.py +94 -0
  10. gencode/gencode/gen_tests_code.py +113 -0
  11. gencode/gencode/sample/__init__.py +2 -0
  12. gencode/gencode/sample/babel.cfg +3 -0
  13. gencode/gencode/sample/config-sample.ini +9 -0
  14. gencode/gencode/sample/config.ini +14 -0
  15. gencode/gencode/sample/create_new_table_run.pys +19 -0
  16. gencode/gencode/sample/dockerignore.dock +57 -0
  17. gencode/gencode/sample/file_utils.pys +396 -0
  18. gencode/gencode/sample/gencode.xmi +33 -0
  19. gencode/gencode/sample/gitignore.git +14 -0
  20. gencode/gencode/sample/migrate_run.bat +5 -0
  21. gencode/gencode/sample/migrate_run.pys +9 -0
  22. gencode/gencode/sample/requirements.txt +17 -0
  23. gencode/gencode/sample/run.sh +27 -0
  24. gencode/gencode/sample/seeds/__init__.py +0 -0
  25. gencode/gencode/sample/seeds/models_rm.pys +187 -0
  26. gencode/gencode/sample/seeds/seed_dev_data.pys +21 -0
  27. gencode/gencode/sample/seeds/seed_init.pys +17 -0
  28. gencode/gencode/sample/seeds/seed_rm.pys +39 -0
  29. gencode/gencode/sample/seeds/seed_run.pys +13 -0
  30. gencode/gencode/sample/seeds/seed_utils.pys +23 -0
  31. gencode/gencode/sample/test__init__.pys +6 -0
  32. gencode/gencode/sample/test_run.pys +4 -0
  33. gencode/gencode/sample/utils.pys +92 -0
  34. gencode/gencode/template/Dockerfile.tmp +55 -0
  35. gencode/gencode/template/README.md +91 -0
  36. gencode/gencode/template/__init__.py +0 -0
  37. gencode/gencode/template/__init__.pys +99 -0
  38. gencode/gencode/template/config.pys +134 -0
  39. gencode/gencode/template/default.conf +21 -0
  40. gencode/gencode/template/docker-compose-dev.yaml +52 -0
  41. gencode/gencode/template/docker-compose.yaml +55 -0
  42. gencode/gencode/template/drone.tmp +45 -0
  43. gencode/gencode/template/flask_models.pys +107 -0
  44. gencode/gencode/template/flask_models_base.pys +159 -0
  45. gencode/gencode/template/gen_code_flask.yaml +21 -0
  46. gencode/gencode/template/gen_code_run.pys +28 -0
  47. gencode/gencode/template/k8s-tmp.yml +141 -0
  48. gencode/gencode/template/run.pys +52 -0
  49. gencode/gencode/template/sample.mdj +1193 -0
  50. gencode/gencode/template/setup.tmp +48 -0
  51. gencode/gencode/template/supervisord.conf +21 -0
  52. gencode/gencode/template/swagger_file.yaml +195 -0
  53. gencode/gencode/template/swg_class.tmp +41 -0
  54. gencode/gencode/template/swg_ctrl_code.pys +130 -0
  55. gencode/gencode/template/swg_package_mng.tmp +4423 -0
  56. gencode/gencode/template/test_test_base.tmp +34 -0
  57. gencode/gencode/template/tests/__init__.py +0 -0
  58. gencode/gencode/template/tests/__init__.pys +5 -0
  59. gencode/gencode/template/tests/init_test_data.pys +80 -0
  60. gencode/gencode/template/tests/run.pys +4 -0
  61. gencode/gencode/template/tests/test_base.pys +87 -0
  62. gencode/gencode/template/tests/test_classmng.pys +58 -0
  63. gencode/gencode/template/uwsgi.ini +20 -0
  64. gencode/gencode/template/uwsgi_run.pys +44 -0
  65. gencode/importmdj/__init__.py +0 -0
  66. gencode/importmdj/import_dd_classes.py +369 -0
  67. gencode/importmdj/import_swagger2_class.py +371 -0
  68. gencode/importmdj/import_uml_models.py +466 -0
  69. gencode/importxmi/__init__.py +1 -0
  70. gencode/importxmi/import_classes.py +342 -0
  71. gencode/importxmi/import_sequences.py +291 -0
  72. gencode/importxmi/import_states.py +150 -0
  73. gencode/importxmi/import_swagger.py +151 -0
  74. gencode/swg2_class_models.py +179 -0
  75. gencode/uml_class_models.py +295 -0
  76. gencode/upgrade.py +113 -0
  77. gencode/utils.py +225 -0
  78. manage.py +194 -0
  79. mwgencode-1.4.1.dist-info/METADATA +325 -0
  80. mwgencode-1.4.1.dist-info/RECORD +84 -0
  81. mwgencode-1.4.1.dist-info/WHEEL +5 -0
  82. mwgencode-1.4.1.dist-info/entry_points.txt +2 -0
  83. mwgencode-1.4.1.dist-info/licenses/LICENSE.txt +19 -0
  84. mwgencode-1.4.1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,342 @@
1
+ try: # 导入模块
2
+ import xml.etree.cElementTree as ET
3
+ except ImportError:
4
+ import xml.etree.ElementTree as ET
5
+ from gencode.dd_models import *
6
+ from gencode.ext import Session,engine
7
+
8
+ from gencode.utils import Keytype,FieldFrom,DBDataType,DBDataType_len,convert2dbType
9
+ uml="http://schema.omg.org/spec/UML/2.0"
10
+ xmi="{http://schema.omg.org/spec/XMI/2.1}"
11
+ _id = xmi+"id"
12
+ _type = xmi+"type"
13
+ _extension = xmi+'Extension'
14
+
15
+ class ImportModels():
16
+ def __init__(self,underline=False,isIntID=False):
17
+ '''
18
+ :param underline: Id 为int 时,如果underline 为True 则关联id前加下划线
19
+ :param isIntID: True为没有指定类型时为int id
20
+ '''
21
+ self.database = None
22
+ self.tables = {}
23
+ self.roles = []
24
+ self.underline = underline
25
+ self.isIntID = isIntID
26
+
27
+ def _create_db(self,dbname,dbdesc):
28
+ database = Databasedictionary()
29
+ database.name = dbname
30
+ database.description = dbdesc
31
+ database.id = 'dbid'
32
+ self.session = Session()
33
+ return database
34
+ # self.session.add(db)
35
+
36
+ def _create_tb(self, cls):
37
+ # print(' ')
38
+ # print(' class:', cls.attrib)
39
+ if cls.attrib.get('isAbstract', 'false') != 'false':
40
+ return
41
+ table = Tabledictionary()
42
+ table.databasedictionaryid = self.database.id
43
+ table.tablename = cls.attrib.get('name', None).lower().replace(' ','')
44
+ table.id = cls.attrib.get(_id, None)
45
+ # print('class name',tb.attrib.get('name',None))
46
+ extens = cls.find(_extension)
47
+ if extens is not None:
48
+ # print(' extens:',extens.attrib)
49
+ cls_doc = extens.find('documentation')
50
+ if cls_doc is not None:
51
+ # print(' doc:',cls_doc.attrib)
52
+ table.description = cls_doc.attrib.get('value','')
53
+ stereotype = extens.find('stereotype')
54
+ if stereotype is not None:
55
+ stereotype=stereotype.attrib.get('value','').split('/')
56
+ for stype in stereotype:
57
+ if stype.lower().startswith('map'):
58
+ # 如:customerid = map{c_id}
59
+ table.maptablename = stype[4:-1].lower()
60
+ break
61
+ return table
62
+
63
+ def _create_idfld(self,clsidvalue):
64
+ field = Fielddictionary()
65
+ field.id = clsidvalue
66
+ field.tabledictionaryid = clsidvalue
67
+ field.fieldname = 'id'
68
+ if self.isIntID:
69
+ field.fieldtype = DBDataType.int.value
70
+ field.fieldsize = DBDataType_len.int.value
71
+ else:
72
+ field.fieldtype = DBDataType.varchar.value
73
+ field.fieldsize = DBDataType_len.varchar.value
74
+ field.englishname = field.fieldname
75
+ field.othername = field.fieldname
76
+ field.keytype = Keytype.key.value
77
+ field.fieldfrom = FieldFrom.database.value
78
+ field.gb32name = field.fieldname
79
+ field.isallownull = False
80
+ return field
81
+
82
+
83
+ def create_fnkeyfld(self,role):
84
+ if role.assocmulitplicity != 1 or not role.assocnavigable:
85
+ return None
86
+ # role = Roledictionary()
87
+ field = Fielddictionary()
88
+ field.id = role.id
89
+ field.tabledictionaryid = role.ownertableid
90
+ tb = self.session.query(Tabledictionary).filter_by(id=role.reftableid).first()
91
+ key_fld = tb.get_keyfield()
92
+ # # 如果是autoint 则采用_id,传统的用id
93
+ # get_id = lambda key_fld:'_id' if key_fld.fieldtype == 'int' and self.underline else 'id'
94
+ # if role.assocrolename:
95
+ # field.fieldname = (role.assocrolename +get_id(key_fld)).lower()
96
+ # else:
97
+ field.fieldname = role.get_role_id(self.session)
98
+ field.fieldtype = key_fld.fieldtype
99
+ field.fieldsize = key_fld.fieldsize
100
+ field.englishname = field.fieldname
101
+ field.othername = field.fieldname
102
+ field.keytype = Keytype.foreignkey.value
103
+ field.fieldfrom = FieldFrom.database.value
104
+ field.gb32name = field.fieldname
105
+ if role.req:
106
+ field.isallownull = False
107
+ return field
108
+
109
+ def _create_fld(self,attr,table):
110
+ field = Fielddictionary()
111
+ field.id = attr.attrib.get(_id)
112
+ field.tabledictionaryid = table.id
113
+ field.fieldname = attr.attrib.get('name').replace(' ','').lower()
114
+ field.fieldtype = convert2dbType(attr.attrib.get('type').split('_')[0])
115
+ type_s = attr.attrib.get('type').split('_')[0].lower().strip()
116
+ if type_s.startswith('string') and len(type_s)>6:
117
+ type_len = int(type_s[6:])
118
+ else:
119
+ type_len = DBDataType_len[field.fieldtype].value
120
+ field.fieldsize = type_len
121
+ field.englishname = field.fieldname
122
+ field.othername = field.fieldname
123
+ field.gb32name = field.fieldname
124
+ field.big5name = field.fieldname
125
+ if attr.attrib.get('isID') != 'false':
126
+ field.keytype = Keytype.key.value
127
+ else:
128
+ field.keytype = Keytype.notkey.value
129
+ if attr.attrib.get('isUnique') != 'false':
130
+ field.repfields = field.fieldname
131
+ field.fieldfrom = FieldFrom.database.value
132
+ lowv = attr.find('lowerValue')
133
+ if lowv is not None:
134
+ # print(' lv:', lowv.attrib)
135
+ field.fieldsize = int(lowv.attrib.get('value'))
136
+ upperv = attr.find('upperValue')
137
+ if upperv is not None:
138
+ # print(' uv:', upperv.attrib)
139
+ field.fieldsize = int(lowv.attrib.get('value'))
140
+ defaultv = attr.find('defaultValue')
141
+ if defaultv is not None:
142
+ # print(' dv:', defaultv.attrib)
143
+ field.defaultvalue = defaultv.attrib.get('value')
144
+
145
+ # print(' attr:', attr.attrib)
146
+ extens_attr = attr.find(_extension)
147
+ if extens_attr is not None:
148
+ attr_doc = extens_attr.find('documentation')
149
+ if attr_doc is not None:
150
+ # print(' doc:', attr_doc.attrib)
151
+ field.gb32name = attr_doc.attrib.get('value')
152
+ attr_stype = extens_attr.find('stereotype')
153
+ if attr_stype is not None:
154
+ # print(' stype:', attr_stype.attrib)
155
+ stypes = attr_stype.attrib.get('value').split('/')
156
+ for stype in stypes:
157
+ if stype.lower() == 'req':
158
+ field.isallownull = False
159
+ elif stype.lower() == 'rep':
160
+ field.repfields = field.fieldname.lower()
161
+ elif stype.lower().startswith('map'):
162
+ # 如:customerid = map{c_id}
163
+ field.mapname = stype[4:-1].lower()
164
+ elif stype.lower().startswith('rep'):
165
+ # 如:rep{id;name}
166
+ # stype[4:-1].split(';')=>['id','name']
167
+ stype_l = stype[4:-1].lower().split(';')
168
+ stype_l.append(field.fieldname)
169
+ field.repfields = ';'.join(stype_l)
170
+ elif stype.lower().startswith('plk'):
171
+ field.plkfieldcode = field.gb32name
172
+ field.plkfieldpath = stype[4:-1].lower()
173
+ field.fieldfrom = FieldFrom.lookup.value
174
+
175
+ return field
176
+ # self.session.add(field)
177
+
178
+ def _create_role(self,memb,table):
179
+ def getMultiplicitye(end):
180
+ upperv = end.find('upperValue')
181
+ if upperv is not None:
182
+ # print(' uv:', upperv0.attrib)
183
+ if upperv.attrib.get('value') == '*':
184
+ return 65535
185
+ elif upperv.attrib.get('value') == '1':
186
+ return 1
187
+ else:
188
+ return 65535
189
+
190
+ def getReqire(end):
191
+ lowerv = end.find('lowerValue')
192
+ if lowerv is not None:
193
+ # print(' uv:', upperv0.attrib)
194
+ return lowerv.attrib.get('value') != '0'
195
+ return False
196
+
197
+ def getRole(end0,end1,table,stereotype):
198
+ '''
199
+ 因xmi档案不能带入navigable,只能根据end的顺序和multiplicity 来确定
200
+ 1,1 -> 1 只有单向关系
201
+ 2,* -> 1 lookup的关系 (非组合或聚合的关系视为单向)
202
+ 3,* <-> 1 组合或聚合关系 (为双向)
203
+ '''
204
+ if end0.attrib.get('isDerived')=='true' or end1.attrib.get('isDerived')=='true':
205
+ return None
206
+ role = Roledictionary()
207
+ role.id = end0.attrib.get(_id)
208
+ role.underline = self.underline or '_id' in stereotype
209
+ role.ownertableid = end0.attrib.get('type', '')
210
+ role.end1_multiplicity = getMultiplicitye(end0)
211
+ # 取另一端的requre
212
+ role.req = getReqire(end1)
213
+ role.end1_rolename = end0.attrib.get('name', '').lower().replace(' ', '')
214
+ if role == '':
215
+ role.end1_rolename = table.tablename
216
+ # master 和 detail 均有masterdetail role
217
+ role.masterdetail = end0.attrib.get('aggregation') == 'composite' or\
218
+ end1.attrib.get('aggregation') == 'composite'
219
+ role.end2_reftableid = end1.attrib.get('type', '')
220
+ role.end2_rolename = end1.attrib.get('name', '').lower().replace(' ', '')
221
+ if role.end2_rolename== '' and role.end2_reftableid==table.id:
222
+ role.end2_rolename=table.tablename
223
+ role.end2_multiplicity = getMultiplicitye(end1)
224
+ role.end1_navigable = end0.attrib.get('aggregation') != 'none' or \
225
+ end1.attrib.get('aggregation') != 'none'
226
+ role.end2_navigable = end0.attrib.get('aggregation') != 'none' or \
227
+ end1.attrib.get('aggregation') != 'none'
228
+ # 如果aggregation 都为none 代表是单向关系,画图时需要顺着方向画
229
+ if not role.end1_navigable and not role.end2_navigable:
230
+ # 1 -> 1 关系只返回
231
+ if role.end1_multiplicity == 1 and role.end2_multiplicity == 1:
232
+ if role.ownertableid == table.id:
233
+ role.end1_navigable = False
234
+ role.end2_navigable = True
235
+ else:
236
+ role.end1_navigable = True
237
+ role.end2_navigable = False
238
+ # * -> 1 关系,1 方为True,*方为false
239
+ elif role.end1_multiplicity == 1:
240
+ role.end1_navigable = True
241
+ role.end2_navigable = False
242
+ else:
243
+ role.end1_navigable = False
244
+ role.end2_navigable = True
245
+ return role
246
+
247
+ ends = memb.findall('ownedEnd')
248
+ if not ends:
249
+ return []
250
+ extens = memb.find(_extension)
251
+ stereotype = []
252
+ if extens is not None:
253
+ # print(' extens:',extens.attrib)
254
+ stereotype_s = extens.find('stereotype')
255
+ if stereotype_s is not None:
256
+ stereotype=stereotype_s.attrib.get('value','').split('/')
257
+ # 任何一个memb 都会产生两个role
258
+ role0 = getRole(ends[0],ends[1],table,stereotype)
259
+ role1 = getRole(ends[1],ends[0],table,stereotype)
260
+ if role0 and role1:
261
+ return [role0,role1]
262
+ else:
263
+ return []
264
+
265
+ def handle_cls(self,pkg):
266
+ table = self._create_tb(pkg)
267
+ if not table:
268
+ return
269
+ self.tables[table.id] = table
270
+ self.session.add(table)
271
+ attrs = pkg.findall('ownedAttribute')
272
+ hasid = False
273
+ for attr in attrs:
274
+ if attr.attrib.get(_type, None) == 'uml:Property':
275
+ field = self._create_fld(attr,table)
276
+ if field.keytype == Keytype.key.value:
277
+ hasid = True
278
+ self.session.add(field)
279
+ if not hasid:
280
+ self.session.add(self._create_idfld(table.id))
281
+
282
+ members = pkg.findall('ownedMember')
283
+ for memb in members:
284
+ if memb.attrib.get(_type,None) == 'uml:Association':
285
+ roles = self._create_role(memb,table)
286
+ self.roles.extend(roles)
287
+
288
+ def handle_pkgElm(self,pkgElms):
289
+ for pkg in pkgElms:
290
+ pkg_type = pkg.attrib.get(_type, None)
291
+ # swagger 包中的uml:class不用处理
292
+ if pkg.attrib.get('name',None) == 'swagger':
293
+ continue
294
+ if pkg_type == 'uml:Class':
295
+ self.handle_cls(pkg)
296
+ else:
297
+ node = pkg.findall('packagedElement')
298
+ if node:
299
+ self.handle_pkgElm(node)
300
+
301
+ def init_database(self):
302
+ Base.metadata.drop_all(engine)
303
+ Base.metadata.create_all(engine) # 创建资料库结构
304
+ # if current_app.config['SQLALCHEMY_DATABASE_URI'].startswith('sqlite'):
305
+ # drop_all()
306
+ # create_all()
307
+ # else:
308
+ # self.session.execute('DELETE FROM [dbo].[databasedictionary]')
309
+ # self.session.commit()
310
+
311
+ def handleRoles(self):
312
+ for role in self.roles:
313
+ field = self.create_fnkeyfld(role)
314
+ if field is not None:
315
+ self.session.add(field)
316
+ self.session.add_all(self.roles)
317
+ self.session.commit()
318
+ for role in self.roles:
319
+ if role.assocrolename == '':
320
+ role.assocrolename=role.reftable.tablename
321
+ self.session.add_all(self.roles)
322
+ self.session.commit()
323
+
324
+ def impxml(self,file):
325
+ self.init_database()
326
+ self.database = self._create_db(file.split()[-1].split('.')[0],"")
327
+ self.session.add(self.database)
328
+ self.session.commit()
329
+ tree = ET.parse(file) # 分析XML文件
330
+ root = tree.getroot()
331
+ # print('0', root)
332
+ for idx0,r in enumerate(root):
333
+ # print('%d'%idx0, r.attrib)
334
+ if r.attrib.get('name',None) != 'RootModel':
335
+ continue
336
+ self.handle_pkgElm(r.findall('packagedElement'))
337
+ self.handleRoles()
338
+
339
+ if __name__ == '__main__':
340
+ i = ImportModels()
341
+ i.impxml(r"Untitled.xml")
342
+ # i.impxml(r"test.xml")
@@ -0,0 +1,291 @@
1
+ try: # 导入模块
2
+ import xml.etree.cElementTree as ET
3
+ except ImportError:
4
+ import xml.etree.ElementTree as ET
5
+
6
+
7
+ from jinja2 import FileSystemLoader,Environment
8
+
9
+
10
+ uml="http://schema.omg.org/spec/UML/2.0"
11
+ xmi="{http://schema.omg.org/spec/XMI/2.1}"
12
+ _id = xmi+"id"
13
+ _type = xmi+"type"
14
+ _extension = xmi+'Extension'
15
+
16
+ PORT =8000
17
+
18
+ class Tag:
19
+ def __init__(self,name,desc):
20
+ self.name=name
21
+ self.desc=desc
22
+
23
+ class Path:
24
+ def __init__(self,tag_name,summy,desc):
25
+ self.summy=summy
26
+ self.tag_name=tag_name
27
+ self.desc=desc
28
+ self.action=None
29
+ self.name=None
30
+ self.params=[]
31
+ self.resps=[]
32
+
33
+ class Path_param:
34
+ def __init__(self,name,type,desc):
35
+ self.name=name
36
+ self.type=type
37
+ self.desc=desc
38
+ class Resp:
39
+ def __init__(self,type,code):
40
+ self.type=type
41
+ self.code =code
42
+ self.class_name=''
43
+
44
+ class Defin:
45
+ def __init__(self,id,name,desc):
46
+ self.id=id
47
+ self.name=name
48
+ self.desc=desc
49
+ self.attrs=[]
50
+
51
+ class DeAttr:
52
+ def __init__(self,name, type, desc ):
53
+ self.name=name
54
+ self.type=type
55
+ self.desc=desc
56
+
57
+
58
+
59
+ class RestFile:
60
+ def __init__(self,name,desc):
61
+ self.name=name
62
+ self.desc=desc
63
+ self.tags=[]
64
+ self.paths=[]
65
+ self.defines=[]
66
+
67
+
68
+ def has_defin(self,id):
69
+ for defin in self.defines:
70
+ if defin.id==id:
71
+ return True
72
+ return False
73
+
74
+ def gen_text(self,templ):
75
+ return templ.render(name=self.name,
76
+ desc=self.desc,
77
+ port =PORT,
78
+ tags=self.tags,
79
+ paths=self.paths,
80
+ defines=self.defines)
81
+
82
+
83
+ # def gen_text(self):
84
+ # head =f_head.format(desc=self.desc,
85
+ # name=self.name,
86
+ # tags=self.tags)
87
+ # if len(self.paths)>0:
88
+ # head+='paths:\r\n'
89
+ # for path in self.paths:
90
+ # head+=path
91
+ # if len(self.definitions)>0:
92
+ # head += 'definitions:\r\n'
93
+ # for defin in self.definitions:
94
+ # head+=defin
95
+ #
96
+ #
97
+ # return head
98
+
99
+
100
+
101
+ class XmlParser:
102
+ def filter_els(self,parent_el,el_name,el_type):
103
+ els =parent_el.findall(el_name)
104
+ def match_type(el):
105
+ return el.attrib.get(_type,None)==el_type
106
+ return filter(match_type,els)
107
+
108
+ def load(self,filename):
109
+ tree = ET.parse(filename) # 分析XML文件
110
+ root = tree.getroot()
111
+ # print('0', root)
112
+ for idx0,r in enumerate(root):
113
+ # print('%d'%idx0, r.attrib)
114
+ if r.attrib.get('name', None) != 'RootModel':
115
+ continue
116
+ self.r =r
117
+
118
+ def _get_exten_value(self,el,name):
119
+ exten =el.find(_extension)
120
+ if exten is not None:
121
+ docu =exten.find(name)
122
+ if docu is not None:
123
+ return docu.attrib.get('value','')
124
+ return ''
125
+
126
+ def _get_exten_list(self,el,name):
127
+ exten =el.find(_extension)
128
+ if exten is not None:
129
+ return exten.findall(name)
130
+ return None
131
+
132
+ def _get_documentation(self,el):
133
+ return self._get_exten_value(el,'documentation')
134
+
135
+ def _get_stereotype(self,el):
136
+ return self._get_exten_value(el,'stereotype')
137
+
138
+ #根据class name 找class
139
+ def _get_class_el(self,name):
140
+ pkgs=self.r.findall('packagedElement')
141
+ for pkg in pkgs:
142
+ if pkg.attrib.get(_type, None) =='uml:Model':
143
+ classes =pkg.findall('packagedElement')
144
+ for cls in classes:
145
+ if cls.attrib.get('name',None)==name :
146
+ return cls
147
+ return None
148
+
149
+ # 根据class id 找class
150
+ def _get_class_el_byid(self,class_id):
151
+ pkgs=self.r.findall('packagedElement')
152
+ for pkg in pkgs:
153
+ if pkg.attrib.get(_type, None) =='uml:Model':
154
+ classes =pkg.findall('packagedElement')
155
+ for cls in classes:
156
+ if cls.attrib.get(_id,None)==class_id :
157
+ return cls
158
+ return None
159
+
160
+ def _get_class_attr(self,attr):
161
+ name =attr.attrib.get('name','')
162
+ if name.find(':')>=0:
163
+ ls=name.split(':')
164
+ name=ls[0]
165
+ datatype=ls[1]
166
+ else:
167
+ datatype=attr.attrib.get('type','').split('_')[0]
168
+ if datatype=='double':
169
+ datatype='number'
170
+ desc =self._get_documentation(attr)
171
+
172
+ return name,datatype,desc
173
+
174
+ #取得 message的参数
175
+ def _get_message_args(self,msg):
176
+ args =msg.find('argument')
177
+ if args is not None:
178
+ return args.attrib.get('value',None)
179
+ return None
180
+
181
+ class SequencetoRest(XmlParser):
182
+ def __init__(self):
183
+ self.rests = []
184
+
185
+ def _handle_class_params(self,class_type,cls,path):
186
+ if cls is not None:
187
+ if class_type=='inquery':
188
+ attrs =self.filter_els(cls,'ownedAttribute','uml:Property')
189
+ for attr in attrs:
190
+ name,datatype,desc=self._get_class_attr(attr)
191
+ path.params.append(Path_param(name,datatype,desc))
192
+
193
+
194
+ def _handle_message_params(self,path,msg):
195
+ tags= self._get_exten_list(msg,'tag')
196
+ for tag in tags:
197
+ keys=tag.keys()
198
+ for key in keys:
199
+ value =tag.attrib.get(key,None) #class id
200
+ if value is not None:
201
+ cls = self._get_class_el_byid(value)
202
+ self._handle_class_params(key, cls, path)
203
+
204
+
205
+ def _add_definitions(self,rs,cls,cls_id):
206
+ defin =Defin(cls_id,cls.attrib.get('name',''),self._get_documentation(cls))
207
+ rs.defines.append(defin)
208
+ attrs = self.filter_els(cls, 'ownedAttribute', 'uml:Property')
209
+ for attr in attrs:
210
+ attr_name, datatype, desc = self._get_class_attr(attr)
211
+ defin.attrs.append(DeAttr(attr_name, datatype, desc))
212
+
213
+
214
+ def _handle_msg_tag(self,tag,path,rs):
215
+ keys=tag.keys()
216
+
217
+ # key like str|obj|array:response_code
218
+ for key in keys:
219
+ value =tag.attrib.get(key,None)
220
+ ls =key.split("_")
221
+ resp=Resp(ls[0],ls[1])
222
+ path.resps.append(resp)
223
+ cls = self._get_class_el_byid(value)
224
+ if cls is not None:
225
+ resp.class_name=cls.attrib.get('name','')
226
+
227
+ #add definitions
228
+ if rs.has_defin(value)==False:
229
+ self._add_definitions(rs,cls,value)
230
+
231
+
232
+
233
+
234
+
235
+ def _get_rest_path(self,rs,path,interact):
236
+ path.action =self._get_stereotype(interact)
237
+
238
+ #get message
239
+
240
+ msgs =self.filter_els(interact,'message','uml:Message')
241
+ for msg in msgs :
242
+ if (self._get_stereotype(msg)=='send'):
243
+ path.name=msg.attrib.get('name','')
244
+ self._handle_message_params(path,msg)
245
+
246
+ #response msg
247
+ elif (msg.attrib.get(_type,None)=='uml:Message') and (self._get_stereotype(msg)=='ack'):
248
+ tags = self._get_exten_list(msg, 'tag')
249
+ for tag in tags:
250
+ self._handle_msg_tag( tag, path,rs)
251
+
252
+
253
+ def _handle_package(self,pkg):
254
+ # each package is a rest file
255
+ rs = RestFile(pkg.attrib.get('name', ''),self._get_documentation(pkg))
256
+ self.rests.append(rs)
257
+
258
+ collabs =self.filter_els(pkg,'packagedElement',"uml:Collaboration")
259
+
260
+ for collab in collabs:
261
+ tag_name = collab.attrib.get('name', '')
262
+ rs.tags.append(Tag(tag_name ,self._get_documentation(collab)))
263
+
264
+ #get Interaction
265
+ interacts =self.filter_els(collab,'ownedMember','uml:Interaction')
266
+ for interact in interacts:
267
+ path=Path(tag_name,interact.attrib.get('name', ''),
268
+ self._get_documentation(interact))
269
+ rs.paths.append(path)
270
+ self._get_rest_path(rs,path,interact)
271
+ #
272
+ #rs.paths.append(self._get_rest_path(interact,tag_name,rs))
273
+
274
+ def parse_xml_data(self): ##
275
+ # get package
276
+ pkgs =self.filter_els(self.r,'packagedElement',"uml:Package")
277
+ for pkg in pkgs:
278
+ self._handle_package(pkg)
279
+
280
+ if __name__ == '__main__':
281
+
282
+ load=FileSystemLoader('./template')
283
+ env =Environment(loader=load)
284
+ t=env.get_template('swagger_file')
285
+
286
+
287
+ rests = SequencetoRest()
288
+ rests.load(r"/home/vagrant/data/docs/test.xmi")
289
+ rests.parse_xml_data()
290
+ for rest in rests.rests:
291
+ print(rest.gen_text(t))