ontomde-uml2-jpa 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,483 @@
1
+ #Depending on whether you annotate fields or methods, the access type used by Hibernate will be field or property.
2
+ #The EJB3 spec requires that you declare annotations on the element type that will be accessed, i.e. the getter method if you use property access, the field if you use field access.
3
+ #Mixing EJB3 annotations in both fields and methods should be avoided. Hibernate will guess the access type from the position of @Id or @EmbeddedId.
4
+ #
5
+ #NOT SUPPORTED:
6
+ #* Qualifiers are not supported.
7
+ #* multi-valued attributes (JPA limitation)
8
+ #* Clashing variables with different types in same type hierarchy.
9
+ #X and Y classes derives from Z. X has attribute c of type int and Y has attribute c of type String.
10
+
11
+ module DB
12
+ EntityManager="javax.persistence.EntityManager"
13
+ EntityManagerFactory="javax.persistence.EntityManagerFactory"
14
+ EntityGenericInterface="xmda.jpa.XmdaEntity"
15
+ EntityInterface="#{EntityGenericInterface}<Long>"
16
+ end
17
+
18
+
19
+ module Muml_Classifier
20
+ #Class is meant to be a Data Access Object
21
+ rdf_safe_attr_reader_many :db_isDAO
22
+ #rdf_safe_attr_reader_many :db_isTransient
23
+
24
+ #This DAO class is associated to this persistent class
25
+ rdf_safe_attr_reader_many :java_persistentClass
26
+
27
+ #This peristent class is associated to this DAO class.
28
+ rdf_safe_attr_reader_many :java_DAOClass
29
+ end
30
+ module Mrdf_Model
31
+ def db_addPersistence!
32
+ jpa_addPersistence!
33
+ end
34
+ def db_Class_persistent
35
+ ret=Set.new
36
+ uml_Class_all.each { |c|
37
+ next if c.kind_of?(Muml_Interface) || c.kind_of?(Muml_Enumeration)
38
+ next unless c.kind_of?(Muml_Class)
39
+ if context[:db_useStereotypeMarker,false]
40
+ c.db_isTransient=((c.umlx_hasStereotype?(context[:db_persistentStereotype,'Persistent'])) ? RDF_FALSE : RDF_TRUE)
41
+ end
42
+ next if c.db_isTransient?
43
+ if c.umlx_package.nil?
44
+ log.error("no package for #{c}::#{c.class.name} #{c.rdf_uri}. Skipping addPersistence!")
45
+ next
46
+ end
47
+ ret<< c
48
+ }
49
+ return ret
50
+ end
51
+ def jpa_addPersistence!
52
+ #jpa_copyInterfaceAttributesToClass!
53
+ uml_Class_all.each { |c|
54
+ next unless c.kind_of?(Muml_Interface) || c.kind_of?(Muml_Enumeration)
55
+ c.db_isTransient=RDF_TRUE
56
+ }
57
+ db_Class_persistent.each { |c|
58
+ c.jpa_addPersistence!()
59
+ c.jpa_addPersistenceId!
60
+ c.jpa_addOptimisticLockingVar!
61
+ }
62
+ uml_Class_all.each { |i|
63
+ #TODO ???
64
+ next unless i.kind_of?(Muml_Interface)
65
+ i.jpa_addPersistenceId!
66
+ #c.jpa_addOptimisticLockingVar!
67
+ }
68
+
69
+
70
+ end
71
+ def jpa_copyInterfaceAttributesToClass!
72
+ uml_Class_all.each { |c|
73
+ next unless c.kind_of?(Muml_Interface)
74
+ puts "found interface #{c}"
75
+ c.uml_ownedAttribute.each { |a|
76
+ puts "found attribute #{a.uml_name}"
77
+ }
78
+ }
79
+ end
80
+ def db_addDAO!
81
+ db_Class_persistent.each { |c|
82
+ c.jpa_addDAO!
83
+ }
84
+ end
85
+ end
86
+
87
+ module Muml_Stereotype
88
+ #nop
89
+ def jpa_addPersistence!
90
+ #nop
91
+ end
92
+ end
93
+
94
+
95
+
96
+ module DAO
97
+ def jpa_addPersistenceContext!
98
+ end
99
+ def jpa_addPersist!
100
+ c=umlx_createAndAddOperation(rdf_uri+"_persist","persist")
101
+ c.java_code="getEntityManager().persist(this);"
102
+ end
103
+ def jpa_addMerge!
104
+ c=umlx_createAndAddOperation(rdf_uri+"_merge","merge")
105
+ c.java_code="return (#{self.java_qualifiedName})getEntityManager().merge(this);"
106
+ r=c.umlx_createAndAddReturnParameter("#{c.rdf_uri}_ret")
107
+ r.uml_type=self
108
+ end
109
+
110
+ def jpa_addRemove!
111
+ c=umlx_createAndAddOperation(rdf_uri+"_remove","remove")
112
+ c.java_code="getEntityManager().remove(this);"
113
+ end
114
+ def jpa_addDAO!
115
+ return if db_isDAO?
116
+ return if java_ignoreMe?
117
+
118
+ if !context[:db_autonomousDAO,false]
119
+ self.java_DAOClass=self
120
+ self.java_persistentClass=self
121
+ else
122
+
123
+ #log.debug { "adding dao for #{self}" }
124
+ p=umlx_package
125
+
126
+
127
+
128
+
129
+ #p=self
130
+ p=p.umlx_getOrCreatePackage(context[:dbDAOsubPackage,"dao"],p)
131
+ c=p.umlx_createAndAddClass(rdf_uri+"_dao")
132
+ c.db_isDAO=RDF_TRUE
133
+ c.db_isTransient=RDF_TRUE
134
+ self.java_DAOClass=c
135
+ c.java_persistentClass=self
136
+ c.uml_name=uml_name_one+"Dao"
137
+
138
+ #log.debug { "DAO added: #{c.uml_name} in #{c.umlx_package.uml_name}"}
139
+ java_DAOClass_one.jpa_addEntityManager!()
140
+ java_DAOClass_one.jpa_addStdImports!
141
+ #jpa_addGetDao!()
142
+ end
143
+ jpa_addPersist!
144
+ jpa_addMerge!
145
+ jpa_addRemove!
146
+ jpa_addFindByPrimaryKey!(java_DAOClass_one)
147
+ jpa_addFindAll!(java_DAOClass_one)
148
+ end
149
+ def jpa_addGetDao!()
150
+ return if uml_isAbstract?
151
+ umlx_classifier_generalization_indirect.each {|c|
152
+ return unless c.uml_isAbstract?
153
+ }
154
+ m=umlx_createAndAddOperation(rdf_uri+"_getdao")
155
+ m.uml_name="dao"
156
+ m.uml_class=self
157
+ m.uml_visibility=Cuml_VisibilityKind::Public
158
+ m.uml_isStatic=RDF_TRUE
159
+ #m.db_isTransient=RDF_TRUE
160
+
161
+ #em=m.umlx_createAndAddParameter(m.rdf_uri+"_entityManager","entityManager")
162
+ #em.uml_type=umlx_getOrCreateClass(DB::EntityManager)
163
+ #em.uml_direction=Cuml_ParameterDirectionKind::In
164
+ #em.uml_upperValue=umlx_literal(1)
165
+ #em.uml_lowerValue=umlx_literal(1)
166
+
167
+ rp=m.umlx_createAndAddParameter(m.rdf_uri+"_ret_param","return")
168
+ rp.uml_direction=Cuml_ParameterDirectionKind::Return
169
+ rp.uml_upperValue=umlx_literal(1)
170
+ rp.uml_lowerValue=umlx_literal(1)
171
+ rp.uml_type=java_DAOClass_one
172
+ m.java_code="return new #{java_DAOClass_one.java_qualifiedName}();"
173
+ return m
174
+ end
175
+ end
176
+ module Mrdf_Model
177
+ def db_findNameUsingDB_URI_ALIAS(k)
178
+ n="-- key not found for #{k}--"
179
+ if self[k].nil?
180
+ # an uri present in old file no longer exists
181
+ ::Muml_Class::DB_URI_ALIAS.each {|key,v|
182
+ n=key if v==k
183
+ }
184
+ else
185
+ n=self[k].java_qualifiedName
186
+ end
187
+ return n
188
+ end
189
+
190
+ def db_saveDB_DISCRIMINATOR
191
+ return unless context[:dbTypeDiscriminator]==:int
192
+ mtk_writeSession("#{context[:targetDir]}/#{context[:dbDiscriminatorCacheRelFile]}") {
193
+ write <<END
194
+ # saved discriminator numbers
195
+ # This file is read and rewritten by generator
196
+ def declarePredefinedDiscrimators()
197
+ # first parameter is java qualified class name
198
+ # second parameter is the identifier used in database
199
+ # when different java type are stored in a
200
+ # single table and need to be differenciated.
201
+ END
202
+ ::Muml_Class::DB_DISCRIMINATOR.sort{|a,b| a[1]<=>b[1]}.each { |k|
203
+ n=db_findNameUsingDB_URI_ALIAS(k[0])
204
+ write(%{ db_disc("#{n}",#{k[1]})\n})
205
+ }
206
+ write("end\n")
207
+ write <<END
208
+ # ###########################
209
+ # END OF USER MODIFIABLE ZONE
210
+ # ###########################
211
+
212
+
213
+
214
+ # Conversion to model URI
215
+ def db_disc(k,v)
216
+ ::Muml_Class::DB_DISCRIMINATOR[::Muml_Class::DB_URI_ALIAS[k]]=v
217
+ end
218
+ ::Muml_Class::DB_URI_ALIAS.merge!({
219
+ END
220
+ ::Muml_Class::DB_DISCRIMINATOR.sort{|a,b| a[0]<=>b[0]}.each { |k|
221
+ n=db_findNameUsingDB_URI_ALIAS(k[0])
222
+ write(" %{#{n}} => %{#{k[0]}} ,\n")
223
+ }
224
+ write("})\n")
225
+ write <<END
226
+ declarePredefinedDiscrimators();
227
+ #free ressources
228
+ def declarePredefinedDiscrimators()
229
+ end
230
+ END
231
+ }
232
+
233
+ end
234
+ end
235
+
236
+ module Muml_Class
237
+
238
+ JPA_TX_BEGIN=""
239
+ JPA_TX_COMMIT=""
240
+ #JPA_TX_BEGIN="javax.persistence.EntityTransaction tx=xmda.jpa.TestEnv.getEntityManager().getTransaction();\ntx.begin(); try {"
241
+ #JPA_TX_COMMIT="tx.commit(); } catch (RuntimeException e) {log.error(e);if(tx.isActive()){ tx.rollback();}throw(e);}"
242
+
243
+ #returns java_code enclosed in begin/commit with catch cleanup
244
+ def db_tx(java_code)
245
+ jpa_tx(java_code)
246
+ end
247
+ #returns java_code enclosed in begin/commit with catch cleanup
248
+ def jpa_tx(java_code)
249
+ return "#{JPA_TX_BEGIN}#{java_code}#{JPA_TX_COMMIT}"
250
+ end
251
+
252
+ JAVA_NOT_PERSISTENT_NAMESPACE=["java","javax"]
253
+ include DAO
254
+ def jpa_addPersistOperation!
255
+ end
256
+
257
+ DB_Context="xmda.jpa.DbContext"
258
+ def jpa_addEntityManager!
259
+
260
+ gem=umlx_createAndAddOperation(rdf_uri+"getEntityManager","getEntityManager")
261
+ gem.uml_isStatic=RDF_TRUE
262
+ ret=gem.umlx_createAndAddReturnParameter(DB_Context+"_ret")
263
+ ret.uml_upperValue=umlx_literal(1)
264
+ ret.uml_lowerValue=umlx_literal(0)
265
+ ret.uml_type=umlx_getOrCreateClass(DB::EntityManager)
266
+ gem.java_code="return #{DB_Context}.getEntityManager();"
267
+
268
+ end
269
+
270
+ # xMDA does *not* generate generic DAO type remove method.
271
+ # object should be removed using their composite object
272
+ def jpa_addRemoveOperation!
273
+ # Possible implementation
274
+ # get container
275
+ # call remove method
276
+ end
277
+
278
+ def jpa_addRefreshOperation!
279
+ end
280
+
281
+
282
+
283
+
284
+ def jpa_deriveFromPersistent?
285
+ uml_generalization.each { |c|
286
+ return true if c.uml_general_one.jpa_isPersistent?
287
+ }
288
+ return false
289
+ end
290
+ def jpa_isPersistent?
291
+ #an external class is supposed to be not persistent
292
+ #if umlx_external?
293
+ # return false
294
+ #end
295
+ return false if db_isTransient? || db_isDAO?
296
+ return true if jpa_deriveFromPersistent?
297
+ #return false unless uml_generalization.empty?
298
+ return jpa_carryPersistence?
299
+ end
300
+ def jpa_carryPersistence?
301
+ qn=java_qualifiedName
302
+ JAVA_NOT_PERSISTENT_NAMESPACE.each { |ns|
303
+ return false if qn.index(ns)==0
304
+ }
305
+ #external is supposed not to carry persistence
306
+ #return false if umlx_external?
307
+ return true;
308
+ end
309
+
310
+ def jpa_hasPersistenceId?
311
+ return false if jpa_deriveFromPersistent?
312
+ return false unless jpa_carryPersistence?
313
+ return true
314
+ end
315
+ def log_error_db_tableName_too_long(tableName)
316
+ return if log_already_displayed?("#{rdf_uri}__tableName")
317
+ log.error {
318
+ <<END
319
+ ********* SGBD TABLE NAME TOO LONG **********
320
+ ** This software has detected a table name exceeding 63 character
321
+ ** ( tableName(#{tableName.length})="#{tableName}" )
322
+ **
323
+ ** This table name is related to element:
324
+ ** #{mtk_object_message}
325
+ **
326
+ ** Default Table name can be overidden using method call:
327
+ ** db_addTableNameOverride("#{tableName}","MYSHORTTABLENAME")
328
+ **
329
+ ** This model element is related to these other model elements:
330
+ #{mtk_related_message}********* SGBD TABLE NAME TOO LONG **********
331
+ END
332
+ }
333
+ end
334
+
335
+ #Maximum allowed length for a sgbd table name
336
+ #cf:
337
+ # Mysql: http://dev.mysql.com/doc/refman/5.0/en/identifiers.html
338
+ DB_MAX_TABLE_NAME_LENGTH=64
339
+
340
+ #table name override
341
+ DB_TABLE_NAME_OVERRIDE=Hash.new
342
+
343
+ #Table name for this element
344
+ def db_tableName
345
+ r=java_uniqueName
346
+ if r.length<=DB_MAX_TABLE_NAME_LENGTH
347
+ #ok. nothing to do
348
+ elsif ! DB_TABLE_NAME_OVERRIDE[r].nil?
349
+ #no check performed on overriden name
350
+ r=DB_TABLE_NAME_OVERRIDE[r]
351
+ elsif context[:silentlyTruncateTableName,false]
352
+ log.debug { "silently truncating table name #{r}" }
353
+ r=r[0,DB_MAX_TABLE_NAME_LENGTH]
354
+ else
355
+ log_error_db_tableName_too_long(r)
356
+ end
357
+ return r
358
+ end
359
+
360
+ DB_URI_ALIAS=Hash.new
361
+ DB_DISCRIMINATOR=Hash.new
362
+ def jpa_addPersistence!
363
+ #jpa_addDAO!
364
+
365
+ #Ajout l'interface XmdaEntity
366
+ ent=umlx_getOrCreateInterface(DB::EntityInterface)
367
+ ent.java_isGeneric=RDF_TRUE
368
+ umlx_createAndAddImplementation(ent)
369
+
370
+ jpa_addEntityManager! # required for query, persist,...
371
+ uml_ownedOperation.each { |o|
372
+ o.jpa_addPersistence!
373
+ }
374
+ java_makeSerializable!
375
+ java_annotation_add("@Entity")
376
+ java_uniqueName # this call enforces uniqueness
377
+ java_annotation_add("@Table (name=\"#{db_tableName}\")") if jpa_hasPersistenceId?
378
+
379
+ if context[:dbTypeDiscriminator]==:int
380
+ k=rdf_uri.to_s
381
+ disc=DB_DISCRIMINATOR[k]
382
+ if disc.nil?
383
+ disc=0
384
+ DB_DISCRIMINATOR.each { |kx,v|
385
+ disc=v+1 if disc<=v
386
+ }
387
+ DB_DISCRIMINATOR[k]=disc
388
+ end
389
+ #TODO: generate only when necessary
390
+ java_annotation_add(%{@DiscriminatorColumn(discriminatorType = DiscriminatorType.INTEGER)})
391
+ java_annotation_add(%{@DiscriminatorValue(value = "#{disc}" )})
392
+ end
393
+ jpa_addStdImports!
394
+ end
395
+
396
+ def jpa_addStdImports!
397
+ #java_import_add("java.util.ArrayList")
398
+ #java_import_add("java.util.Set")
399
+ #java_import_add("java.util.List")
400
+ #java_import_add("javax.persistence.*")
401
+ java_import_add("javax.persistence.Entity")
402
+ java_import_add("javax.persistence.Table")
403
+ java_import_add("javax.persistence.DiscriminatorColumn")
404
+ java_import_add("javax.persistence.DiscriminatorValue")
405
+ java_import_add("javax.persistence.DiscriminatorType")
406
+ java_import_add("javax.persistence.Version")
407
+ java_import_add("javax.persistence.Basic")
408
+ java_import_add("javax.persistence.Column")
409
+ java_import_add("javax.persistence.Lob")
410
+ java_import_add("javax.persistence.Id")
411
+ java_import_add("javax.persistence.GeneratedValue")
412
+ java_import_add("javax.persistence.JoinTable")
413
+ java_import_add("javax.persistence.OneToMany")
414
+ java_import_add("javax.persistence.ManyToOne")
415
+ java_import_add("javax.persistence.ManyToMany")
416
+ java_import_add("javax.persistence.Temporal")
417
+ java_import_add("javax.persistence.CascadeType")
418
+ java_import_add("javax.persistence.FetchType")
419
+ java_import_add("javax.persistence.OneToOne")
420
+ java_import_add("javax.persistence.JoinColumn")
421
+ java_import_add("javax.persistence.TemporalType")
422
+
423
+
424
+
425
+ #com.francetelecom.rd.cil.commons.common.CommonException
426
+ #com.francetelecom.rd.cil.commons.model.IdentifiedObject
427
+ ##{java_packageQualifiedName}.vo.#{java_Name}Value
428
+ ##{java_packageQualifiedName}.vo.*
429
+ end
430
+ def jpa_addPersistenceIdAnnnotation!(p)
431
+ p.java_annotation_add("@Id")
432
+ p.java_annotation_add("@GeneratedValue")
433
+ end
434
+
435
+ end
436
+ module Muml_Classifier
437
+ def jpa_addPersistenceId!
438
+ #return unless uml_generalization.empty?
439
+ return unless context[:db_useOptimisticLocking,true]
440
+ return unless jpa_hasPersistenceId?
441
+
442
+ p=umlx_createAndAddProperty(rdf_uri+"_auto_id","id")
443
+ jpa_addPersistenceIdAnnnotation!(p)
444
+ #p.uml_type=umlx_dataType_long
445
+ p.uml_type=umlx_getOrCreateDataType("Long")
446
+ p.uml_visibility=::Cuml_VisibilityKind::Private
447
+ java_addAccessorsFor!(p)
448
+
449
+ #TODO Surcharge le getter : A enlever une fois avoir corrig� incompatibilit� avec couche Struts
450
+ gettter = p.java_AttributeGlobalGetter
451
+ #removed ? : operator to make checkstyle happy.
452
+ gettter[0].java_code = %{if(#{p.java_Name} == null) { return Long.valueOf(0);} else {return #{p.java_Name};}}
453
+ end
454
+ end
455
+ module Muml_Property
456
+ def jpa_isPersistent?
457
+ return false if uml_isDerived?
458
+ return true
459
+ end
460
+ end
461
+ module Muml_Interface
462
+ #JPA does not support persistent interface
463
+ def jpa_isPersistent?
464
+ return false
465
+ end
466
+ def jpa_hasPersistenceId?
467
+ uml_ownedAttribute.each { |a|
468
+ next unless a.umlx_isComposite?
469
+ next if a.uml_type_one.db_isTransient?
470
+ return true ;
471
+ }
472
+ return false
473
+ end
474
+ def jpa_addPersistenceIdAnnnotation!(p)
475
+ #nop
476
+ end
477
+ end
478
+
479
+ #adds a directive for replacing default table name orgname by overridenname
480
+ def db_addTableNameOverride(orgname,overridenname)
481
+ ::Muml_Class::DB_TABLE_NAME_OVERRIDE[orgname.to_s]=overridenname.to_s
482
+ end
483
+
@@ -0,0 +1,20 @@
1
+ # Features:
2
+ # reflexive association
3
+ # multiple associations between 2 classes
4
+ # Set of objects
5
+ # Ordered set
6
+ # multi-valued set (non unique)
7
+ # single inheritance
8
+ # automatic generation of int primary key
9
+ # automatic generation of a finder by primary key
10
+ # automatic generation of a finder findAll
11
+ # automatic generation of EntityManger
12
+ # automatic generation of persistence.xml
13
+ #
14
+ # Not currently Supported
15
+ # JPA makes it difficult to support multiple inheritance.
16
+ # A workaround is planned to overcome this limitation.
17
+ # UML Qualifiers are not supported
18
+ # JPA does not support multiple-valued attributes
19
+ # Proper care should be applied to avoid clashing variable names of different types in same type hierarch. (
20
+ # Example: X and Y classes derives from Z. X has attribute c of type int and Y has attribute c of type String.
@@ -0,0 +1,17 @@
1
+
2
+ module Muml_Classifier
3
+ def jpa_addOptimisticLockingAnnotation!(p)
4
+ p.java_annotation_add("@Version")
5
+ p.java_annotation_add(%{@SuppressWarnings("unused")})
6
+ end
7
+
8
+ DB_OBJECT_VERSION_FIELD="objectVersion"
9
+ def jpa_addOptimisticLockingVar!
10
+ return unless jpa_hasPersistenceId?
11
+ p=umlx_createAndAddProperty(rdf_uri+"_auto_version",DB_OBJECT_VERSION_FIELD)
12
+ jpa_addOptimisticLockingAnnotation!(p)
13
+ p.uml_type=umlx_dataType_long
14
+ p.uml_visibility=::Cuml_VisibilityKind::Private
15
+ #java_addAccessorsFor!(p)
16
+ end
17
+ end