ontomde-core 1.0.2 → 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.
@@ -1,538 +1,547 @@
1
- #:include: ../shared/license.rdoc
2
-
3
- require 'fileutils'
4
- #require 'ontomde-core/exceptions.rb'
5
- #require 'ontomde-core/fileTypes.rb'
6
-
7
- class WarningReverseBadOrMissingEnd < Warning
8
- end
9
-
10
- #Internal use.
11
- class LoadModelLazyWriter
12
-
13
- #Internal use.
14
- def initialize (fn,ft)
15
- @fileName=fn
16
- @fileType=ft
17
- @model=nil
18
- @usedResources=nil
19
- end
20
- def fileType
21
- if @fileType.nil?
22
- @fileType=FileType.getFileType(@fileName)
23
- end
24
- return @fileType
25
- end
26
-
27
- #Internal use.
28
- def protectedMode?
29
- return !@model.nil?
30
- end
31
-
32
- def [](key)
33
- if @model.nil?
34
- @model=Crdf_Model.new
35
- @model.mtk_retrieveProtected(@fileName,fileType)
36
- end
37
- if @usedResources.nil?
38
- @usedResources=Array.new
39
- end
40
- ret=@model[key]
41
- @usedResources << key unless ret.nil?
42
- return ret
43
- end
44
-
45
- def unusedData
46
- return nil if @model.nil?
47
- ret=nil
48
- @model.each { |k,c|
49
- next if @usedResources.include?(k)
50
- # c is either a String or a bootstrap element.
51
- next if c.kind_of?(Mrdf_Resource) && c.ext_isBootstrap?
52
- ret=Array.new if ret.nil?
53
- ret << k
54
- }
55
- return ret
56
- end
57
-
58
- end
59
- module Mmtk_helper
60
-
61
- end
62
-
63
- module Mrdf_Resource
64
- include Mmtk_helper
65
- end
66
-
67
- class Crdf_Model
68
- include Mmtk_helper
69
- end
70
- class Crdf_Resource
71
- include Mmtk_helper
72
- end
73
-
74
- module Mrdf_Model
75
- include Mmtk_helper
76
- end
77
- module Mmtk_helper
78
- # Internal use.
79
- #
80
- # Used primarily by mtk server
81
- def mtk_stringWriteSession()
82
- fileName=context.get(:mtk_filename)
83
- fileName='string-file' if fileName.nil?
84
- file=StringOutputStream.new
85
-
86
- ret=nil
87
- mtk_context(:mtk_out=>file,:mtk_fileName=>fileName) {
88
- @@mtk_out=context[:mtk_out] # perf
89
- yield
90
- ret=@@mtk_out.to_s
91
- }
92
- @@mtk_out=context.get(:mtk_out) # perf
93
- return ret
94
- end
95
-
96
- #mtk_writeSession temporary file suffix.
97
- TEMP_FILE_SUFFIX=".xmda_toolkit_temporary"
98
-
99
- @@max_file_logged=30
100
-
101
- #le fichier fileName a ete genere pour la resource res
102
- attr_reader :fileGenerated
103
- #@fileGenerated=Array.new
104
- def notifyFileGenerated(fileName,res)
105
- #@fileGenerated << [ fileName , res ]
106
- end
107
-
108
- #Opens a file for writing.
109
- #Note:
110
- # Existing file is deleted
111
- # Directory are automatically created
112
- # Write is atomic. In case of failure existing file is not affected.
113
- # The name of the current file is available in context: context[:mtk_fileName]
114
- #
115
- # if context[:dryRun] is true, file writes will be skipped.
116
- # Note that reverse (file read) **will** be performed however.
117
- #Example:
118
- #mtk_writeSession('file1.java') {
119
- # write('this goes into file1.java')
120
- # mtk_writeSession('file2.java') {
121
- # write('this goes into file2.java')
122
- # puts context[:mtk_fileName]
123
- # }
124
- # write('this goes into file1.java')
125
- # }
126
- MTK_WRITE_SESSION_FILE_NAMES=Set.new
127
- def mtk_writeSession(fileName,fileType=nil)
128
- # Open or create session
129
- mtk_writeSessionNameClashErrorDetection(fileName.to_s)
130
-
131
- protectedReverse=LoadModelLazyWriter.new(fileName,fileType)
132
- FileUtils.mkdir_p(File.dirname(fileName))
133
- notifyFileGenerated(File.expand_path(fileName),self)
134
-
135
- doNotOverwrite=mtk_autoNewFileCreationCheck(fileName)
136
- if context[:dryRun,false]
137
- file=NullFileWriter.instance
138
- log.debug { "Simulating Write to #{fileName} (because context[:dryRun]==true)" }
139
- mtk_context(:mtk_out=>file,:mtk_fileName=>fileName,:protectedReverse=>protectedReverse) {
140
- @@mtk_out=context[:mtk_out] # perf
141
- yield
142
- }
143
- @@mtk_out=context.get(:mtk_out) # perf
144
- return
145
- end
146
- File.open(fileName+TEMP_FILE_SUFFIX,File::CREAT|File::TRUNC|File::RDWR, 0644) {
147
- |file|
148
- mtk_context(:mtk_out=>file,:mtk_fileName=>fileName,:protectedReverse=>protectedReverse) {
149
- log.debug { "Writing #{fileName}" }
150
- @@mtk_out=context[:mtk_out] # perf
151
- yield
152
- }
153
- @@mtk_out=context.get(:mtk_out) # perf
154
- }
155
- #Le fichier temporaire a bien �t� g�n�r�.
156
- unusedData=protectedReverse.unusedData
157
- if(!unusedData.nil?)
158
- log.info { "warning: saved code appended to #{fileName}.mtk_save" }
159
- msg=""
160
- File.open(fileName+".mtk_save",File::CREAT|File::APPEND|File::RDWR, 0644) { |file|
161
- unusedData.each {|k|
162
- msg=msg+%{\n ** uri="#{k}"}
163
- file.write <<END
164
- //***********************
165
- //XMDA BEGIN SAVED DATA : uri="#{k}"
166
- //***********************
167
- #{protectedReverse[k]}
168
- //***********************
169
- //END SAVED DATA
170
- //***********************
171
-
172
- END
173
-
174
- }
175
- }
176
- if !context[:allowAutomaticCodeDeletion,false]
177
- doNotOverwrite=true
178
- log.error { %{
179
- ***************************************************************
180
- Code generation has been *halted* to prevent code loss in
181
- #{fileName}
182
-
183
- Code to be deleted is stored in
184
- #{fileName}.mtk_save
185
-
186
- You must take the appropriate actions before re-running generator.
187
- * fix your model for unwanted deletion.
188
- * manually delete unused code for #{msg}
189
- * rename
190
- #{fileName+TEMP_FILE_SUFFIX}
191
- to
192
- #{fileName}
193
- #
194
- ***************************************************************
195
- }}
196
- #exit(1)
197
- end
198
-
199
- end
200
-
201
- puts "Writing: #{fileName}" if context[:logFileWrite,false]
202
- retryCount=0
203
- while true
204
- begin
205
- # On some windows machine,
206
- # file is sometimes locked by some management
207
- # daemon (probably some corporate audit daemon)
208
- # This cause code generation to fail.
209
- # This loop gives the daemon a chance to
210
- # unlock the file.
211
- # We just wait a few seconds and try again.
212
- #raise IOException.new(),"KO" if retryCount<2
213
- File.rename(fileName+TEMP_FILE_SUFFIX,fileName)
214
- puts "Retry succeeded." if retryCount>0
215
- break # exit while
216
- rescue => e
217
- retryCount=retryCount+1
218
- #log.warn "#{e}"
219
- raise e if retryCount > 3
220
- puts "Rename failed. Retrying (#{retryCount})"
221
- sleep(2) #
222
- end
223
- end
224
- return nil
225
- end
226
-
227
- #checks if fileName already exists
228
- def mtk_autoNewFileCreationCheck(fileName)
229
- doNotOverwrite=!context[:autoNewFileCreation,true] && !File.exists?(fileName)
230
- if doNotOverwrite
231
- # xmda is not allowed to create new file
232
- log.error { %{
233
- ********* NEW FILE DETECTED **********
234
- ** A new file needs to be added to your project:
235
- ** "#{fileName}"
236
- **
237
- ** Generator has been halted to let
238
- ** you take proper actions such as:
239
- **
240
- ** * Refactor your code if this new file is a renamed file
241
- ** * Create a blank file and Add this file to version control
242
- **
243
- ** Model Element being processed is:
244
- ** #{mtk_object_message}
245
- **
246
- ** Model element being processed is related to:
247
- ** #{mtk_related_message}
248
- ********* NEW FILE DETECTED **********
249
- }}
250
- #exit(1)
251
- end
252
- return doNotOverwrite
253
- end
254
-
255
- #detects if fileName has already been used.
256
- #Logs an error if a clash is detected.
257
- def mtk_writeSessionNameClashErrorDetection(fileName)
258
- if(MTK_WRITE_SESSION_FILE_NAMES.include?(fileName.to_s))
259
- log.error{ %{********* NAME CLASH DETECTED ********** #{fileName}
260
- ********* NAME CLASH DETECTED **********
261
- ** This software has detected that a generated file
262
- ** is being overwritten in the same code generation session.
263
- ** This most likely is caused by a name clash in the source model.
264
- **
265
- ** Filename being overwritten is
266
- ** "#{fileName}"
267
- ** Model Element being processed is:
268
- ** #{mtk_object_message}
269
- **
270
- ** Model element being processed is related to:
271
- ** #{mtk_related_message}
272
- ********* NAME CLASH DETECTED **********
273
- }}
274
- else
275
- MTK_WRITE_SESSION_FILE_NAMES<< fileName.to_s
276
- end
277
- end
278
-
279
- #writes before string,
280
- #yield block and then writes after.
281
- #
282
- #EXAMPLE.
283
- # encloseWrite("<title>","</title>") { write "Today news" }
284
- def encloseWrite(beforeStr,afterStr,&middleBlock)
285
- write(beforeStr.to_s)
286
- yield
287
- write(afterStr.to_s)
288
- end
289
-
290
- # Write string to the current file opened by mtk_writeSession.
291
- def write(str)
292
- if !@@mtk_out.nil?
293
- @@mtk_out.write(str)
294
- return
295
- end
296
- raise Warning.new(), <<END
297
- There is no file currently opened.
298
- Please use mtk_writeSession prior to using any write method.
299
- Example:
300
- # mtk_writeSession('file1.java') {
301
- # write("Package .... ;")
302
- # }
303
- # }
304
- END
305
- end
306
-
307
- # Internal use.
308
- #
309
- # Transforms a uri to a uri qualified by the current file name
310
- def mtk_qualifyBlockURI(_uri)
311
- return "#{_uri}__#{context[:mtk_fileName]}"
312
- end
313
-
314
- #def mtk_fileType
315
- # fileType=nil
316
- # puts "fileType1=#{fileType}"
317
- # fileType=context.get(:mtk_fileType)
318
- # puts "fileType2=#{fileType}"
319
- # fileType=FileType.get(fileName) if fileType.nil?
320
- # puts "fileType3=#{fileType}"
321
- #
322
- # #fileType=FileTypeJava.instance
323
- # return fileType
324
- #end
325
-
326
- #
327
- # Internal use.
328
- #
329
- # Reverse the file currently being written by mtk_writeSession.
330
- # This method is automaticaly called
331
- def mtk_retrieveProtected(fileName,fileType)
332
- return false unless File.exists?(fileName)
333
-
334
- mtk_context(:mtk_fileName=>fileName) {
335
- File.open(fileName,'r') { |aFile|
336
- i=0
337
- reading=false
338
- block_uri=nil
339
- buffer=''
340
- reverseMode=nil
341
-
342
- aFile.each_line { |line|
343
- i=i+1
344
- if !reading
345
- #return if !line.include?("PROTECTED REGION XMDA BEGIN") # optimisation ?
346
- m=fileType.re_begin.match(line)
347
- log.debug {"beg match_ok=#{!m.nil?} line=#{line}"}
348
- next if m.nil?
349
- #raise Warning.new,"Error Reading Protected region header\n#{fileName}:line #{i}: #{line}" if m.nil?
350
- reading=true
351
- buffer=''
352
- linesep=''
353
- block_uri=fileType.unescape(m[2].to_s)
354
- log.debug { "ma: #{m[0]} block_uri=#{block_uri}" }
355
- raise Warning.new,'Error Reading Protected region header nil uri' if block_uri.nil?
356
- case m[1]
357
- when 'yes' then reverseMode=true
358
- when 'no' then reverseMode=false
359
- else raise Warning.new,%{Bad reverseMode value in file #{fileName}. reverse="yes" or reverse="no" expected (got "#{m[1]}" line ##{i}).}
360
- end
361
- raise Warning.new,'Error Reading Protected region header nil uri' if reverseMode.nil?
362
- log.debug { "!!!!!! block_ri=--#{block_uri}--" }
363
- else
364
- #log.debug "#{reading} line=#{line}"
365
- m=fileType.re_end.match(line)
366
- #log.debug "end match_ok=#{!m.nil?} line=#{line}"
367
- if m.nil?
368
- buffer=buffer.nil? ? line : "#{buffer}#{line}"
369
- next
370
- end
371
- block_uri_end=fileType.unescape(m[1].to_s)
372
- if block_uri_end!=block_uri
373
- raise WarningReverseBadOrMissingEnd.new, <<ENDERRORMSG
374
- Bad non matching END tag in #{fileName}
375
- expected uri="#{block_uri}"
376
- and got uri="#{block_uri_end}"
377
- line ##{i})
378
- ENDERRORMSG
379
- end
380
- reading=false
381
- #log.debug "block_uri=#{block_uri} protected ->xxxxxxx\n#{buffer}xxxxxxxxxx"
382
- qualified_block_uri=mtk_qualifyBlockURI(block_uri)
383
- if reverseMode
384
- self[qualified_block_uri]=buffer[0,buffer.size-1]
385
- else
386
- #log.debug "Reverse ignored #{context[:mtk_fileName]}!"
387
- end
388
- end
389
-
390
- }
391
- }}
392
- return true # un fichier a ete retro
393
- end
394
- end
395
-
396
- #module Mrdf_Resource
397
- #end
398
- module Mmtk_helper #_Resource
399
- REVERSE=true
400
- NOREVERSE=false
401
-
402
- # mtk_protected is used when generated code can be modified by user and preserved by subsequent generation.
403
- # The code generated in the block passed as parameter will be generated encolosed between identifiable tags.
404
- #
405
- # NOTE:
406
- # The block is identified by the current rdf resource URI.
407
- # If more than one block is to be generated in one file, zoneId must be used.
408
- #
409
- #
410
- #
411
- #
412
- #Example 1: default
413
- # mtk_writeSession('file1.java') {
414
- # write("Package .... ;")
415
- # a.mtk_protected() {
416
- # write("default code to be redefined by user");
417
- # }
418
- # b.mtk_protected() {
419
- # write("default code to be redefined by user");
420
- # }
421
- # }
422
- #Example 2: initial mode is reverse
423
- # mtk_writeSession('file1.java') {
424
- # write("Package .... ;")
425
- # mtk_protected(REVERSE) {
426
- # write("default code to be redefined by user");
427
- # }
428
- # }
429
- #Example 3: initial mode is noreverse
430
- # mtk_writeSession('file1.java') {
431
- # write("Package .... ;")
432
- # mtk_protected(NOREVERSE) {
433
- # write("default code to be redefined by user");
434
- # }
435
- # }
436
- #Example 4: multiple-protected zone for a single object
437
- # mtk_writeSession('file1.java') {
438
- # write("Package .... ;")
439
- # a.mtk_protected(REVERSE,"a") {
440
- # write("default code to be redefined by user");
441
- # }
442
- # a.mtk_protected(REVERSE,"b") {
443
- # write("default code to be redefined by user");
444
- # }
445
- # }
446
- def mtk_protected(initialReverseMode=false,zoneId='0',&block)
447
- #mbu=mtk_block_uri
448
- mbu="#{rdf_uri}__#{zoneId}"
449
- qualified_uri=rdf_model.mtk_qualifyBlockURI(mbu)
450
-
451
- fileType=context[:protectedReverse].fileType
452
- str=context[:protectedReverse][qualified_uri]
453
-
454
- reverse= (!str.nil?) || initialReverseMode
455
-
456
- write(fileType.beginMarker(mbu,reverse))
457
-
458
- if str.nil?
459
- #log.debug "!!yield block_uri=#{mbu}"
460
- yield
461
- else
462
- write(str)
463
- end
464
- write(fileType.endMarker(mbu))
465
- end
466
-
467
- #Stream to String Session
468
- def mtk_stss(&block)
469
- #@rdf_model.mtk_stringWriteSession(&block)
470
- mtk_stringWriteSession(&block)
471
- end
472
-
473
- #internal method.
474
- #
475
- #Returns file descriptor currently used by mtk_writeSession.
476
- def mtk_out
477
- return context[:mtk_out]
478
- end
479
-
480
- end
481
-
482
- #Internal use.
483
- #
484
- #Used by mtk_stringWriteSession.
485
- class StringOutputStream
486
- def initialize
487
- @str=nil
488
- end
489
-
490
- # Internal use.
491
- #
492
- # Simulates file open
493
- def open ; end
494
-
495
- # Internal use.
496
- #
497
- # Simulates file open
498
- def close ; end
499
-
500
- # Internal use.
501
- #
502
- # Appends str to internal steam buffer
503
- def write (str)
504
- #log.debug "Ajout #{str.to_s} !!"
505
- if @str
506
- @str="#{@str}#{str.to_s}"
507
- else
508
- @str=str.to_s
509
- end
510
- end
511
-
512
- # Internal use.
513
- # returns the internal stream buffer
514
- def to_s
515
- return @str
516
- end
517
- end
518
-
519
-
520
-
521
- module Mcore_Product
522
- end
523
-
524
- class Ccore_Product < Crdfs_Class
525
- include Mcore_Product
526
- def generate
527
- end
528
-
529
- end
530
-
531
- # a file writer that writes nowhere
532
- class NullFileWriter
533
- include Singleton
534
- def write(str)
535
- # does nothing !
536
- end
537
- end
538
-
1
+ require 'fileutils'
2
+
3
+ class WarningReverseBadOrMissingEnd < Warning
4
+ end
5
+
6
+ #Internal use.
7
+ class LoadModelLazyWriter
8
+
9
+ #Internal use.
10
+ def initialize (fn,ft)
11
+ @fileName=fn
12
+ @fileType=ft
13
+ @model=nil
14
+ @usedResources=nil
15
+ end
16
+ def fileType
17
+ if @fileType.nil?
18
+ @fileType=FileType.getFileType(@fileName)
19
+ end
20
+ return @fileType
21
+ end
22
+
23
+ #Internal use.
24
+ def protectedMode?
25
+ return !@model.nil?
26
+ end
27
+
28
+ def [](key)
29
+ if @model.nil?
30
+ @model=Crdf_Model.new
31
+ @model.mtk_retrieveProtected(@fileName,fileType)
32
+ end
33
+ if @usedResources.nil?
34
+ @usedResources=Array.new
35
+ end
36
+ ret=@model[key]
37
+ @usedResources << key unless ret.nil?
38
+ return ret
39
+ end
40
+
41
+ def unusedData
42
+ return nil if @model.nil?
43
+ ret=nil
44
+ @model.each { |k,c|
45
+ next if @usedResources.include?(k)
46
+ # c is either a String or a bootstrap element.
47
+ next if c.kind_of?(Mrdf_Resource) && c.ext_isBootstrap?
48
+ ret=Array.new if ret.nil?
49
+ ret << k
50
+ }
51
+ return ret
52
+ end
53
+
54
+ end
55
+ module Mmtk_helper
56
+
57
+ end
58
+
59
+ module Mrdf_Resource
60
+ include Mmtk_helper
61
+ end
62
+
63
+ class Crdf_Model
64
+ include Mmtk_helper
65
+ end
66
+ class Crdf_Resource
67
+ include Mmtk_helper
68
+ end
69
+
70
+ module Mrdf_Model
71
+ include Mmtk_helper
72
+ end
73
+ module Mmtk_helper
74
+ # Internal use.
75
+ #
76
+ # Used primarily by mtk server
77
+ def mtk_stringWriteSession()
78
+ fileName=context[:mtk_fileName,'string-file']
79
+ file=StringOutputStream.new
80
+
81
+ ret=nil
82
+ mtk_context(:mtk_out=>file,:mtk_fileName=>fileName) {
83
+ @@mtk_out=context[:mtk_out] # perf
84
+ yield
85
+ ret=@@mtk_out.to_s
86
+ }
87
+ @@mtk_out=context.get(:mtk_out) # perf
88
+ return ret
89
+ end
90
+
91
+ #mtk_writeSession temporary file suffix.
92
+ TEMP_FILE_SUFFIX=".xmda_toolkit_temporary"
93
+
94
+ @@max_file_logged=30
95
+
96
+ #le fichier fileName a ete genere pour la resource res
97
+ attr_reader :fileGenerated
98
+ #@fileGenerated=Array.new
99
+ def notifyFileGenerated(fileName,res)
100
+ #@fileGenerated << [ fileName , res ]
101
+ end
102
+
103
+ #Opens a file for writing.
104
+ #Note:
105
+ # Existing file is deleted
106
+ # Directory are automatically created
107
+ # Write is atomic. In case of failure existing file is not affected.
108
+ # The name of the current file is available in context: context[:mtk_fileName]
109
+ #
110
+ # if context[:dryRun] is true, file writes will be skipped.
111
+ # Note that reverse (file read) **will** be performed however.
112
+ #Example:
113
+ #mtk_writeSession('file1.java') {
114
+ # write('this goes into file1.java')
115
+ # mtk_writeSession('file2.java') {
116
+ # write('this goes into file2.java')
117
+ # puts context[:mtk_fileName]
118
+ # }
119
+ # write('this goes into file1.java')
120
+ # }
121
+ MTK_WRITE_SESSION_FILE_NAMES=Set.new
122
+ def mtk_writeSession(fileName,fileType=nil)
123
+ # Open or create session
124
+ mtk_writeSessionNameClashErrorDetection(fileName.to_s)
125
+
126
+ protectedReverse=LoadModelLazyWriter.new(fileName,fileType)
127
+ FileUtils.mkdir_p(File.dirname(fileName))
128
+ notifyFileGenerated(File.expand_path(fileName),self)
129
+
130
+ doNotOverwrite=mtk_autoNewFileCreationCheck(fileName)
131
+ if context[:dryRun,false]
132
+ file=NullFileWriter.instance
133
+ #log.debug { "Simulating Write to #{fileName} (because context[:dryRun]==true)" }
134
+ mtk_context(:mtk_out=>file,:mtk_fileName=>fileName,:protectedReverse=>protectedReverse) {
135
+ @@mtk_out=context[:mtk_out] # perf
136
+ yield
137
+ }
138
+ @@mtk_out=context.get(:mtk_out) # perf
139
+ return
140
+ end
141
+ File.open(fileName+TEMP_FILE_SUFFIX,File::CREAT|File::TRUNC|File::RDWR, 0644) {
142
+ |file|
143
+ mtk_context(:mtk_out=>file,:mtk_fileName=>fileName,:protectedReverse=>protectedReverse) {
144
+ #log.debug { "Writing #{fileName}" }
145
+ @@mtk_out=context[:mtk_out] # perf
146
+ yield
147
+ }
148
+ @@mtk_out=context.get(:mtk_out) # perf
149
+ }
150
+ #Le fichier temporaire a bien �t� g�n�r�.
151
+ unusedData=protectedReverse.unusedData
152
+ if(!unusedData.nil?)
153
+ log.info { "warning: saved code appended to #{fileName}.mtk_save" }
154
+ msg=""
155
+ File.open(fileName+".mtk_save",File::CREAT|File::APPEND|File::RDWR, 0644) { |file|
156
+ unusedData.each {|k|
157
+ msg=msg+%{\n ** uri="#{k}"}
158
+ file.write <<END
159
+ //***********************
160
+ //XMDA BEGIN SAVED DATA : uri="#{k}"
161
+ //***********************
162
+ #{protectedReverse[k]}
163
+ //***********************
164
+ //END SAVED DATA
165
+ //***********************
166
+
167
+ END
168
+
169
+ }
170
+ }
171
+ if !context[:allowAutomaticCodeDeletion,false]
172
+ doNotOverwrite=true
173
+ log.error { %{
174
+ ***************************************************************
175
+ Code generation has been *halted* to prevent code loss in
176
+ #{fileName}
177
+
178
+ Code to be deleted is stored in
179
+ #{fileName}.mtk_save
180
+
181
+ You must take the appropriate actions before re-running generator.
182
+ * fix your model for unwanted deletion.
183
+ * manually delete unused code for #{msg}
184
+ * rename
185
+ #{fileName+TEMP_FILE_SUFFIX}
186
+ to
187
+ #{fileName}
188
+ #
189
+ ***************************************************************
190
+ }}
191
+ #exit(1)
192
+ raise Exception.new("potential code loss detected")
193
+ end
194
+
195
+ end
196
+
197
+ puts "Writing: #{fileName}" if context[:logFileWrite,false]
198
+ retryCount=0
199
+ while true
200
+ begin
201
+ # On some windows machine,
202
+ # file is sometimes locked by some management
203
+ # daemon (probably some corporate audit daemon)
204
+ # This cause code generation to fail.
205
+ # This loop gives the daemon a chance to
206
+ # unlock the file.
207
+ # We just wait a few seconds and try again.
208
+ #raise IOException.new(),"KO" if retryCount<2
209
+ File.rename(fileName+TEMP_FILE_SUFFIX,fileName)
210
+ puts "Retry succeeded." if retryCount>0
211
+ break # exit while
212
+ rescue => e
213
+ retryCount=retryCount+1
214
+ #log.warn "#{e}"
215
+ raise e if retryCount > 3
216
+ puts "Rename failed. Retrying (#{retryCount})"
217
+ sleep(2) #
218
+ end
219
+ end
220
+ return nil
221
+ end
222
+
223
+ #checks if fileName already exists
224
+ def mtk_autoNewFileCreationCheck(fileName)
225
+ doNotOverwrite=!context[:autoNewFileCreation,true] && !File.exists?(fileName)
226
+ if doNotOverwrite
227
+ # xmda is not allowed to create new file
228
+ log.error { %{
229
+ ********* NEW FILE DETECTED **********
230
+ ** A new file needs to be added to your project:
231
+ ** "#{fileName}"
232
+ **
233
+ ** Generator has been halted to let
234
+ ** you take proper actions such as:
235
+ **
236
+ ** * Refactor your code if this new file is a renamed file
237
+ ** * Create a blank file and Add this file to version control
238
+ **
239
+ ** Model Element being processed is:
240
+ ** #{mtk_object_message}
241
+ **
242
+ ** Model element being processed is related to:
243
+ ** #{mtk_related_message}
244
+ ********* NEW FILE DETECTED **********
245
+ }}
246
+ #exit(1)
247
+ end
248
+ return doNotOverwrite
249
+ end
250
+
251
+ #detects if fileName has already been used.
252
+ #Logs an error if a clash is detected.
253
+ def mtk_writeSessionNameClashErrorDetection(fileName)
254
+ if(MTK_WRITE_SESSION_FILE_NAMES.include?(fileName.to_s))
255
+ log.error{ %{********* NAME CLASH DETECTED ********** #{fileName}
256
+ ********* NAME CLASH DETECTED **********
257
+ ** This software has detected that a generated file
258
+ ** is being overwritten in the same code generation session.
259
+ ** This most likely is caused by a name clash in the source model.
260
+ **
261
+ ** Filename being overwritten is
262
+ ** "#{fileName}"
263
+ ** Model Element being processed is:
264
+ ** #{mtk_object_message}
265
+ **
266
+ ** Model element being processed is related to:
267
+ ** #{mtk_related_message}
268
+ ********* NAME CLASH DETECTED **********
269
+ }}
270
+ else
271
+ MTK_WRITE_SESSION_FILE_NAMES<< fileName.to_s
272
+ end
273
+ end
274
+
275
+ #writes before string,
276
+ #yield block and then writes after.
277
+ #
278
+ #EXAMPLE.
279
+ # encloseWrite("<title>","</title>") { write "Today news" }
280
+ def encloseWrite(beforeStr,afterStr,&middleBlock)
281
+ write(beforeStr.to_s)
282
+ yield
283
+ write(afterStr.to_s)
284
+ end
285
+
286
+ # Write string to the current file opened by mtk_writeSession.
287
+ def write(str)
288
+ if !@@mtk_out.nil?
289
+ @@mtk_out.write(str)
290
+ return
291
+ end
292
+ raise Warning.new(), <<END
293
+ There is no file currently opened.
294
+ Please use mtk_writeSession prior to using any write method.
295
+ Example:
296
+ # mtk_writeSession('file1.java') {
297
+ # write("Package .... ;")
298
+ # }
299
+ # }
300
+ END
301
+ end
302
+
303
+ # Internal use.
304
+ #
305
+ # Transforms a uri to a uri qualified by the current file name
306
+ def mtk_qualifyBlockURI(_uri)
307
+ return "#{_uri}__#{context[:mtk_fileName]}"
308
+ end
309
+
310
+ #def mtk_fileType
311
+ # fileType=nil
312
+ # puts "fileType1=#{fileType}"
313
+ # fileType=context.get(:mtk_fileType)
314
+ # puts "fileType2=#{fileType}"
315
+ # fileType=FileType.get(fileName) if fileType.nil?
316
+ # puts "fileType3=#{fileType}"
317
+ #
318
+ # #fileType=FileTypeJava.instance
319
+ # return fileType
320
+ #end
321
+
322
+ #
323
+ # Internal use.
324
+ #
325
+ # Reverse the file currently being written by mtk_writeSession.
326
+ # This method is automaticaly called
327
+ def mtk_retrieveProtected(fileName,fileType)
328
+ return false unless File.exists?(fileName)
329
+
330
+ mtk_context(:mtk_fileName=>fileName) {
331
+ File.open(fileName,'r') { |aFile|
332
+ i=0
333
+ reading=false
334
+ block_uri=nil
335
+ buffer=''
336
+ reverseMode=nil
337
+
338
+ aFile.each_line { |line|
339
+ i=i+1
340
+ if !reading
341
+ #return if !line.include?("PROTECTED REGION XMDA BEGIN") # optimisation ?
342
+ m=fileType.re_begin.match(line)
343
+ #log.debug {"beg match_ok=#{!m.nil?} line=#{line}"}
344
+ next if m.nil?
345
+ #raise Warning.new,"Error Reading Protected region header\n#{fileName}:line #{i}: #{line}" if m.nil?
346
+ reading=true
347
+ buffer=''
348
+ linesep=''
349
+ block_uri=fileType.unescape(m[2].to_s)
350
+ #log.debug { "ma: #{m[0]} block_uri=#{block_uri}" }
351
+ raise Warning.new,'Error Reading Protected region header nil uri' if block_uri.nil?
352
+ case m[1]
353
+ when 'yes' then reverseMode=true
354
+ when 'no' then reverseMode=false
355
+ else raise Warning.new,%{Bad reverseMode value in file #{fileName}. reverse="yes" or reverse="no" expected (got "#{m[1]}" line ##{i}).}
356
+ end
357
+ raise Warning.new,'Error Reading Protected region header nil uri' if reverseMode.nil?
358
+ #log.debug { "!!!!!! block_ri=--#{block_uri}--" }
359
+ else
360
+ #log.debug "#{reading} line=#{line}"
361
+ m=fileType.re_end.match(line)
362
+ #log.debug "end match_ok=#{!m.nil?} line=#{line}"
363
+ if m.nil?
364
+ buffer=buffer.nil? ? line : "#{buffer}#{line}"
365
+ next
366
+ end
367
+ block_uri_end=fileType.unescape(m[1].to_s)
368
+ if block_uri_end!=block_uri
369
+ raise WarningReverseBadOrMissingEnd.new, <<ENDERRORMSG
370
+ Bad non matching END tag in #{fileName}
371
+ expected uri="#{block_uri}"
372
+ and got uri="#{block_uri_end}"
373
+ line ##{i})
374
+ ENDERRORMSG
375
+ end
376
+ reading=false
377
+ #log.debug "block_uri=#{block_uri} protected ->xxxxxxx\n#{buffer}xxxxxxxxxx"
378
+ qualified_block_uri=mtk_qualifyBlockURI(block_uri)
379
+ if reverseMode
380
+ self[qualified_block_uri]=buffer[0,buffer.size-1]
381
+ open("reverse.log","a") {|r|
382
+ r.write("\n### reverse #{qualified_block_uri}\n")
383
+ r.write( "#{self[qualified_block_uri]} #{self[qualified_block_uri].length}")
384
+ } #unless context[:logFileReverse].nil?
385
+ else
386
+ #log.debug "Reverse ignored #{context[:mtk_fileName]}!"
387
+ end
388
+ end
389
+
390
+ }
391
+ }}
392
+ return true # un fichier a ete retro
393
+ end
394
+ end
395
+
396
+ #module Mrdf_Resource
397
+ #end
398
+ module Mmtk_helper #_Resource
399
+ REVERSE=true
400
+ NOREVERSE=false
401
+
402
+ # mtk_protected is used when generated code can be modified by user and preserved by subsequent generation.
403
+ # The code generated in the block passed as parameter will be generated encolosed between identifiable tags.
404
+ #
405
+ # NOTE:
406
+ # The block is identified by the current rdf resource URI.
407
+ # If more than one block is to be generated in one file, zoneId must be used.
408
+ #
409
+ #
410
+ #
411
+ #
412
+ #Example 1: default
413
+ # mtk_writeSession('file1.java') {
414
+ # write("Package .... ;")
415
+ # a.mtk_protected() {
416
+ # write("default code to be redefined by user");
417
+ # }
418
+ # b.mtk_protected() {
419
+ # write("default code to be redefined by user");
420
+ # }
421
+ # }
422
+ #Example 2: initial mode is reverse
423
+ # mtk_writeSession('file1.java') {
424
+ # write("Package .... ;")
425
+ # mtk_protected(REVERSE) {
426
+ # write("default code to be redefined by user");
427
+ # }
428
+ # }
429
+ #Example 3: initial mode is noreverse
430
+ # mtk_writeSession('file1.java') {
431
+ # write("Package .... ;")
432
+ # mtk_protected(NOREVERSE) {
433
+ # write("default code to be redefined by user");
434
+ # }
435
+ # }
436
+ #Example 4: multiple-protected zone for a single object
437
+ # mtk_writeSession('file1.java') {
438
+ # write("Package .... ;")
439
+ # a.mtk_protected(REVERSE,"a") {
440
+ # write("default code to be redefined by user");
441
+ # }
442
+ # a.mtk_protected(REVERSE,"b") {
443
+ # write("default code to be redefined by user");
444
+ # }
445
+ # }
446
+ def mtk_protected(initialReverseMode=false,zoneId='0',&block)
447
+ #mbu=mtk_block_uri
448
+ raise Exception.new("Bad parameter") if initialReverseMode!=false && initialReverseMode!=true
449
+ mbu="#{rdf_uri}__#{zoneId}"
450
+ qualified_uri=rdf_model.mtk_qualifyBlockURI(mbu)
451
+
452
+ fileType=context[:protectedReverse].fileType
453
+ str=context[:protectedReverse][qualified_uri]
454
+
455
+ reverse= (!str.nil?) || initialReverseMode
456
+
457
+ if (!reverse) && context[:skipNoReverseMarker,false]
458
+ write(fileType.beginMarkerSkip(mbu,reverse))
459
+ else
460
+ write(fileType.beginMarker(mbu,reverse))
461
+ end
462
+
463
+ if str.nil?
464
+ #log.debug "!!yield block_uri=#{mbu}"
465
+ yield
466
+ else
467
+ write(str)
468
+ end
469
+ if (!reverse) && context[:skipNoReverseMarker,false]
470
+ write(fileType.endMarkerSkip(mbu))
471
+ else
472
+ write(fileType.endMarker(mbu))
473
+ end
474
+ end
475
+
476
+ #Stream to String Session
477
+ def mtk_stss(&block)
478
+ #@rdf_model.mtk_stringWriteSession(&block)
479
+ mtk_stringWriteSession(&block)
480
+ end
481
+
482
+ #internal method.
483
+ #
484
+ #Returns file descriptor currently used by mtk_writeSession.
485
+ def mtk_out
486
+ return context[:mtk_out]
487
+ end
488
+
489
+ end
490
+
491
+ #Internal use.
492
+ #
493
+ #Used by mtk_stringWriteSession.
494
+ class StringOutputStream
495
+ def initialize
496
+ @str=nil
497
+ end
498
+
499
+ # Internal use.
500
+ #
501
+ # Simulates file open
502
+ def open ; end
503
+
504
+ # Internal use.
505
+ #
506
+ # Simulates file open
507
+ def close ; end
508
+
509
+ # Internal use.
510
+ #
511
+ # Appends str to internal steam buffer
512
+ def write (str)
513
+ #log.debug "Ajout #{str.to_s} !!"
514
+ if @str
515
+ @str="#{@str}#{str.to_s}"
516
+ else
517
+ @str=str.to_s
518
+ end
519
+ end
520
+
521
+ # Internal use.
522
+ # returns the internal stream buffer
523
+ def to_s
524
+ return @str
525
+ end
526
+ end
527
+
528
+
529
+
530
+ module Mcore_Product
531
+ end
532
+
533
+ class Ccore_Product < Crdfs_Class
534
+ include Mcore_Product
535
+ def generate
536
+ end
537
+
538
+ end
539
+
540
+ # a file writer that writes nowhere
541
+ class NullFileWriter
542
+ include Singleton
543
+ def write(str)
544
+ # does nothing !
545
+ end
546
+ end
547
+