ontomde-uml2-java 1.0.4

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.
@@ -0,0 +1,78 @@
1
+ This tool is a java code generator for UML2 model.
2
+
3
+ =Main advantages
4
+ * Open Source
5
+ * Case tool independant
6
+ * Very low maintenance (<5000 lines of code and no dependency)
7
+ * High perenity (no dependency on external tools and library)
8
+ * Very fast and scalable for large UML models
9
+ * Generator is fully object oriented
10
+ * Does not use tool specific template or extension language
11
+
12
+ =Required skills to generate java code from uml2 model
13
+ * None, just lauch the generator command line (uml2java)
14
+
15
+ =Required skills to customize the standard java code
16
+ * UML2 model structure
17
+ * Standard Ruby knowledge
18
+ * Read this documentation
19
+ * No tool specific language (template, extension, ...)
20
+
21
+ =Currently supported UML case tools are
22
+ * IBM Rational RSM 6.0 (full export, *incremental* export)
23
+ * Magic Draw 11.5 (full export)
24
+
25
+ =Standard features
26
+ * Generates Java Enum for UML Enum
27
+ * Generates Java Class for UML Class
28
+ * Generates Java inner Class for UML inner Class
29
+ * Generates Java interface for UML interface
30
+ * Generates Java operation squeleton for UML operation
31
+ * Generates Java Attribute getter for java attribute (using a model transformation)
32
+ * Generates Java Attribute setter for java attribute (using a model transformation)
33
+ * Generates Java Attribute remover for java attribute (using a model transformation)
34
+ * Generates UML exception for methods
35
+
36
+ =Extended features
37
+ * Model tranformation is used extensively for model enhancement (addition of getter/setter)
38
+ * Generates Java accessors handling bi-directionnal associations (other end is updated)
39
+ * Requires *no* external java library
40
+ * Requires *no* internal java library (that would be provided by this tool)
41
+ * Every accessor/getter/... may be modified in Java file and preserved by subsequent generation.
42
+ * Generator has access to every UML2 model element (class model, state model, ...)
43
+ * Performant model traversal. Every UML2 model element may be navigated both ways, unlike tools such as EMF/UML2 or Objecteering for example who require expensive full model lookup (to find out who inherits from me)
44
+ * CodeSave feature. (When a method is deleted from UML model, Java code is saved in a file) (also works with any hand written code).
45
+
46
+ =Eclipse Integration
47
+ * Imports can be modified inline (in java file) by Eclipse
48
+ * Imports generate by Eclipse "organize imports" are preserved by subsequent generations.
49
+
50
+ * Java operation squeleton can be modified inline (in java file) using Eclipse.
51
+ * Eclipse Ruby editor can be used to customize Java code generator.
52
+
53
+ =Performance features
54
+ * Model loading time is *linear* unlike MDR based products (such as AndroMDA)
55
+ * Model loading time is similar to JAVA/EMF loading time
56
+ * *Incremental* model update allow nearly instantaneous generation time even on very large models.
57
+
58
+ =High end features
59
+ * Model transformation are fully redefinable
60
+ * Code generation is fully redefinable
61
+ * Generator is fully object oriented
62
+
63
+ =Agile Programming Feature
64
+ * Generation runtime is independant of GUI and can be executed by daily builds on servers.
65
+
66
+ =Versionning features
67
+ * Several versions of ontomde may be installed simultaneously on one machine.
68
+ * Project may request one version of ontomde or a range (>=1, >=1 <2, ...)
69
+
70
+ =Near zero dependency
71
+ This tool relies on
72
+ * UML2 specification
73
+ * Ruby 1.8
74
+ * itself (<
75
+ * and *nothing* else
76
+ This tool lifecycle is independant of case tools and Eclipse continous evolution.
77
+ You will never be forced to upgrade all of your generation scripts because you chose to change or upgrade your UML case tool.
78
+
@@ -0,0 +1,25 @@
1
+ class JHelper
2
+ def JHelper.to_firstUpper(name)
3
+ result = String.new(name)
4
+ if !result.empty?
5
+ result[0] = result[0, 1].upcase
6
+ end
7
+ return result
8
+ end
9
+ def JHelper.to_NameProperty(name)
10
+ result = String.new(name)
11
+ if !result.empty?
12
+ result[0] = result[0, 1].downcase
13
+ end
14
+ return result
15
+ end
16
+ # remove the last caracter if 's'
17
+ def JHelper.to_SingleName(name)
18
+ result = String.new(name)
19
+ if !result.empty? && result[result.size-1]==115 #'s'
20
+ result = result[0, result.size - 1]
21
+ end
22
+ return result
23
+ end
24
+ end
25
+
@@ -0,0 +1,420 @@
1
+ #Template used for jsp input field generation
2
+
3
+ #wrapper to easylly create a new datatype mapping
4
+ #* umlDataTypeName is the name of the data type in source uml model
5
+ #* baseMapping is the base definition mapping to derive from
6
+ #* regexp is the string regexp used for display
7
+ def addDataTypeMapping(umlDataTypeName,baseMapping,regexp=nil,&block)
8
+ if !baseMapping.kind_of?(Class)
9
+ raise Exception.new(%{Bad parameter type used for baseMapping got "#{baseMapping.class}" and expected "Class"})
10
+ end
11
+
12
+ rubyName=umlDataTypeName.tr('^a-zA-Z0-9','_')
13
+ s=%{
14
+ class JavaMapping#{rubyName} < #{baseMapping.name}
15
+ include Singleton
16
+ def appliesTo?(datatype)
17
+ return datatype.uml_name.to_s=="#{umlDataTypeName}"
18
+ end
19
+ #{regexp.nil? ? "" : %{
20
+ def getValidationRegexp
21
+ return /#{regexp.source}/
22
+ end
23
+ }
24
+ }
25
+ end
26
+ JavaMapping#{rubyName}.class_eval( &block ) unless block.nil?
27
+
28
+ JavaMapping#{rubyName}.instance #register
29
+ }
30
+ t=eval s
31
+
32
+
33
+ end
34
+
35
+ class JavaMapping
36
+ include Singleton
37
+ def getMappings
38
+ return @@types
39
+ end
40
+ @@types=Array.new
41
+ def initialize
42
+ return if self.class==JavaMapping
43
+ @@types << self
44
+ #log.debug { %{registered(##{@@types.size}): #{self.class}} }
45
+ end
46
+ #returns true if this templates applies to datatype
47
+ def appliesTo?(datatype)
48
+ # inheriting class should redefine this method
49
+ log.error %{appliesTo? not implemented for #{self.class}}
50
+ return false
51
+ end
52
+ def getTemplate(datatype)
53
+ @@types.each {|t|
54
+ next unless t.appliesTo?(datatype)
55
+ return t
56
+ }
57
+ if !datatype.context[:silentlyForceUnknownDatatypeToString,false]
58
+ msg= %{No template #{self.class} found for datatype "#{datatype}"}
59
+ log.error msg unless log_already_displayed?(msg)
60
+ end
61
+
62
+ return JavaMappingText.instance
63
+ #return JavaMappingerror.instance
64
+ end
65
+
66
+ def getJavaType
67
+ # inheriting class should redefine this method
68
+ log.error %{getJavaType not implemented for #{self.class}}
69
+ return %{/* TODO: implement ruby getJavaType for #{self.class}*/}
70
+ end
71
+
72
+ # max length of this element represented as a string
73
+ attr :maxStringLength
74
+ attr_writer :maxStringLength
75
+ @maxStringLength=nil
76
+
77
+ def getValidationRegexp
78
+ #log.error %{getValidationRegexp not implemented for #{self.class}}
79
+ return nil #%{/* TODO: implement ruby getValidationRegexp for #{self.class}*/}
80
+ end
81
+ end
82
+ class JavaMappingText < JavaMapping
83
+ include Singleton
84
+
85
+ #default string length
86
+ @maxStringLength=10
87
+
88
+ MATCHING_UML_NAME=["String","string"]
89
+ #MATCHING_JAVA_NAME=["String","java.lang.String"]
90
+ def appliesTo?(datatype)
91
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
92
+ #return true if MATCHING_JAVA_NAME.include?(datatype.java_qualifiedName)
93
+ return false
94
+ end
95
+
96
+ def getJavaType
97
+ return "java.lang.String"
98
+ end
99
+ end
100
+
101
+ class JavaMappingLargeText < JavaMappingText
102
+ include Singleton
103
+ MATCHING_UML_NAME=["LargeText"]
104
+ def appliesTo?(datatype)
105
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
106
+ return false
107
+ end
108
+ end
109
+
110
+
111
+ class JavaMappingMimeType < JavaMappingText
112
+ include Singleton
113
+ MATCHING_UML_NAME=["MimeType"]
114
+ def appliesTo?(datatype)
115
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
116
+ end
117
+ end
118
+
119
+ class JavaMappingOrdinal < JavaMappingText
120
+ include Singleton
121
+ end
122
+
123
+ class JavaMappingInteger < JavaMappingOrdinal
124
+ include Singleton
125
+ MATCHING_UML_NAME=["integer","Integer","int"]
126
+ #MATCHING_JAVA_NAME=[]
127
+ def appliesTo?(datatype)
128
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
129
+ # return true if MATCHING_JAVA_NAME.include?(datatype.java_qualifiedName)
130
+ return false
131
+ end
132
+
133
+
134
+ def getJavaType
135
+ return "int"
136
+ end
137
+
138
+ end
139
+ class JavaMappingLong < JavaMappingOrdinal
140
+ include Singleton
141
+ MATCHING_UML_NAME=["long"]
142
+ #MATCHING_JAVA_NAME=[]
143
+ def appliesTo?(datatype)
144
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
145
+ # return true if MATCHING_JAVA_NAME.include?(datatype.java_qualifiedName)
146
+ return false
147
+ end
148
+ def getJavaType
149
+ return "long"
150
+ end
151
+ end
152
+ class JavaMappingLongObject < JavaMappingOrdinal
153
+ include Singleton
154
+ MATCHING_UML_NAME=["Long"]
155
+ #MATCHING_JAVA_NAME=[]
156
+ def appliesTo?(datatype)
157
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
158
+ # return true if MATCHING_JAVA_NAME.include?(datatype.java_qualifiedName)
159
+ return false
160
+ end
161
+ def getJavaType
162
+ return "Long"
163
+ end
164
+ end
165
+ class JavaMappingFile < JavaMapping
166
+ include Singleton
167
+ MATCHING_UML_NAME=["file"]
168
+ def appliesTo?(datatype)
169
+ return false unless datatype.kind_of?(Muml_DataType)
170
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
171
+ #return datatype.struts_isBlob?
172
+ #return ["image"].include?(datatype.java_qualifiedName)
173
+ end
174
+ def getJavaType
175
+ return "java.lang.Object"
176
+ end
177
+ end
178
+
179
+ class JavaMappingBoolean < JavaMapping
180
+ include Singleton
181
+ MATCHING_UML_NAME=["Boolean","boolean"]
182
+ #MATCHING_JAVA_NAME=[]
183
+ def appliesTo?(datatype)
184
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
185
+ # return true if MATCHING_JAVA_NAME.include?(datatype.java_qualifiedName)
186
+ return false
187
+ end
188
+
189
+ #name of the key used by struts to referece
190
+ #current bean in session.
191
+ STRUTS_BEAN_KEY= "org.apache.struts.taglib.html.BEAN";
192
+
193
+
194
+ def getJavaType
195
+ return "boolean"
196
+ end
197
+
198
+ end
199
+
200
+ #struts jsp template for a timestamp datatype.
201
+ #A timestamp is a precise periode in time, including date,hours,minutes and seconds.
202
+ #NOTE:
203
+ # "Date" datatype name is discourage because it is ambiguous.
204
+ # (a java date is a timestamp)
205
+ # Calendar and TimeStamp should be prefered.
206
+ class JavaMappingTimeStamp < JavaMapping
207
+ include Singleton
208
+ MATCHING_UML_NAME=["TimeStamp","Date"]
209
+ #MATCHING_JAVA_NAME=[]
210
+ def appliesTo?(datatype)
211
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
212
+ #return true if MATCHING_JAVA_NAME.include?(datatype.java_qualifiedName)
213
+ return false
214
+ end
215
+ def getValidationRegexp
216
+ return nil
217
+ end
218
+ def getJavaType
219
+ return "java.util.Date"
220
+ end
221
+
222
+ end
223
+
224
+ #struts jsp template for a Calendar datatype.
225
+ #A Calendar datatype is a calendar date, not including hours,minutes and seconds
226
+ #A Calendar is not to be mistaken for a TimeStamp
227
+ #NOTE:
228
+ # "Date" datatype name is not used because it is ambiguous.
229
+ # Calendar and TimeStamp are used instead
230
+ class JavaMappingCalendar < JavaMapping
231
+ include Singleton
232
+ MATCHING_UML_NAME=["Calendar"]
233
+ #MATCHING_JAVA_NAME=[]
234
+ def appliesTo?(datatype)
235
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
236
+ #return true if MATCHING_JAVA_NAME.include?(datatype.java_qualifiedName)
237
+ return false
238
+ end
239
+
240
+ def getValidationRegexp
241
+ return nil
242
+ end
243
+ def getJavaType
244
+ return "java.util.Date"
245
+ end
246
+
247
+ end
248
+
249
+
250
+
251
+
252
+ class JavaMappingGenericClass < JavaMapping
253
+ include Singleton
254
+ def appliesTo?(datatype)
255
+ return false if datatype.kind_of?(Muml_Enumeration)
256
+ return false if datatype.kind_of?(Muml_DataType)
257
+ #return true if datatype.kind_of?(Muml_Class)
258
+ return true
259
+ end
260
+
261
+ def getFormCopyTo(field)
262
+ a=field
263
+ return "/* #{a.java_NameBean} is transient */\n" if a.uml_type_one.java_DAOClass.empty?
264
+ if a.umlx_oneSide?
265
+ return %{_to.set#{a.java_NameBean}(this.get#{a.java_NameBean}().compareTo("nil")==0 ? null : #{a.uml_type_one.java_DAOClass_one.java_qualifiedName}.find(Long.parseLong(this.get#{a.java_NameBean}())));\n}
266
+ else # many
267
+ cm=a.java_getCollectionMapping
268
+ return <<END333
269
+ { // UML: #{field.uml_name}
270
+ String[] src=this.get#{a.java_NameBean}();
271
+ #{cm.addCollectionInterface(a.uml_type_one.java_qualifiedName)} newCol= #{cm.addNew(a.uml_type_one.java_qualifiedName)};
272
+ int max=src==null ? 0 : src.length;
273
+ #{a.uml_type_one.java_qualifiedName} item=null;
274
+ for(int i=0; i<max;i++) {
275
+ //log.error("loading : "+src[i]);
276
+ if(src[i]==null) continue;
277
+ item=#{a.uml_type_one.java_DAOClass_one.java_qualifiedName}.find(Long.parseLong(src[i]));
278
+ newCol.add(item);
279
+ }
280
+ _to.set#{a.java_NameBean}(newCol);
281
+ }
282
+ END333
283
+ end
284
+ end
285
+ def getFormInitFrom(field)
286
+ a=field
287
+ if a.umlx_oneSide?
288
+ return %{this.set#{a.java_NameBean}(_from.get#{a.java_NameBean}()==null? "nil" : Long.toString(_from.get#{a.java_NameBean}().getId()));\n}
289
+ else
290
+ return %{
291
+ { /*STRUTS:2001*/
292
+ this.set#{a.java_NameBean}(null);
293
+ java.util.Iterator<?> iter=_from.get#{a.java_NameBean}().iterator();
294
+ #{a.uml_type_one.java_qualifiedName} item=null;
295
+ while(iter.hasNext()){
296
+ item=(#{a.uml_type_one.java_qualifiedName})iter.next();
297
+ this.add#{a.java_NameBean}(Long.toString(item.getId()));
298
+ }
299
+ }
300
+ }
301
+ end
302
+ end
303
+ def getJavaType
304
+ return "java.lang.Object"
305
+ end
306
+
307
+ end
308
+
309
+ class JavaMappingGenericEnum < JavaMapping
310
+ include Singleton
311
+ def appliesTo?(datatype)
312
+ return true if datatype.kind_of?(Muml_Enumeration)
313
+ return false
314
+ end
315
+
316
+
317
+ NULL_ENUM_VALUE_AS_STRING="nil"
318
+ def getFormCopyTo(field)
319
+ a=field
320
+ return %{_to.set#{a.java_NameBean}(this.get#{a.java_NameBean}().compareTo("#{NULL_ENUM_VALUE_AS_STRING}")!=0 ? Enum.valueOf(#{a.uml_type_one.java_qualifiedName}.class,this.get#{a.java_NameBean}()):null);\n}
321
+ end
322
+ def getFormInitFrom(field)
323
+ #return "this.set#{field.java_NameBean}(_from.get#{field.java_NameBean}()==null ? -1 :_from.get#{field.java_NameBean}().ordinal());\n"
324
+ return %{this.set#{field.java_NameBean}(_from.get#{field.java_NameBean}()==null ? "#{NULL_ENUM_VALUE_AS_STRING}" :_from.get#{field.java_NameBean}().name());\n}
325
+ end
326
+
327
+ def getJavaType
328
+ return "java.lang.Object"
329
+ end
330
+
331
+ end
332
+
333
+
334
+ class JavaMappingURL < JavaMappingText
335
+ include Singleton
336
+ MATCHING_UML_NAME=["URL","URI"]
337
+ #MATCHING_JAVA_NAME=[]
338
+ def appliesTo?(datatype)
339
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
340
+ #return true if MATCHING_JAVA_NAME.include?(datatype.java_qualifiedName)
341
+ return false
342
+ end
343
+ end
344
+
345
+ class JavaMappingBLOB < JavaMapping
346
+ include Singleton
347
+ MATCHING_UML_NAME=["Blob"]
348
+ def appliesTo?(datatype)
349
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
350
+ return false
351
+ end
352
+ def getJavaType
353
+ return "byte[]"
354
+ end
355
+ end
356
+ class JavaMappingIMG < JavaMappingBLOB
357
+ include Singleton
358
+ MATCHING_UML_NAME=["Img","Image"]
359
+ def appliesTo?(datatype)
360
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
361
+ return false
362
+ end
363
+ end
364
+
365
+ class JavaMappingGRAPHVIZ < JavaMappingLargeText
366
+ include Singleton
367
+ MATCHING_UML_NAME=["Graphviz"]
368
+ def appliesTo?(datatype)
369
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
370
+ return false
371
+ end
372
+ end
373
+
374
+ class JavaMappingPassword < JavaMappingText
375
+ include Singleton
376
+ MATCHING_UML_NAME=["Password"]
377
+ def appliesTo?(datatype)
378
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
379
+ return false
380
+ end
381
+ end
382
+
383
+ class JavaMappingEmailAddress < JavaMappingText
384
+ include Singleton
385
+ MATCHING_UML_NAME=["EmailAdress"]
386
+ def appliesTo?(datatype)
387
+ return true if MATCHING_UML_NAME.include?(datatype.uml_name_one)
388
+ return false
389
+ end
390
+
391
+ # EMAIL address regexp
392
+ # cf : http://www.regular-expressions.info/email.html
393
+ def getValidationRegexp
394
+ return /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}/
395
+ end
396
+ end
397
+
398
+
399
+
400
+ JavaMappingGenericEnum.instance #register
401
+
402
+ JavaMappingCalendar.instance #register
403
+ JavaMappingText.instance #register
404
+ JavaMappingLargeText.instance #register
405
+ JavaMappingPassword.instance #register
406
+ JavaMappingEmailAddress.instance #register
407
+ JavaMappingURL.instance #register
408
+ JavaMappingFile.instance #register
409
+ JavaMappingBoolean.instance #register
410
+ JavaMappingTimeStamp.instance #register
411
+ JavaMappingGenericClass.instance #register
412
+ JavaMappingLong.instance #register
413
+ JavaMappingLongObject.instance #register
414
+ JavaMappingInteger.instance #register
415
+ JavaMappingBLOB.instance #register
416
+ JavaMappingIMG.instance #register
417
+ JavaMappingGRAPHVIZ.instance #register
418
+ JavaMappingMimeType.instance #register
419
+
420
+
@@ -0,0 +1,3 @@
1
+ TODO:
2
+ * Handle manual constructors
3
+ * Implement hashcode (pour hashtable)