Module: Mmtk_helper

Included in:
Crdf_Repository, Crdf_Resource, Mrdf_Repository, Mrdf_Resource
Defined in:
lib/ontomde-core/helper.rb,
lib/ontomde-core/helper.rb,
lib/ontomde-core/helper.rb

Overview

module Mrdf_Resource end

Constant Summary collapse

TEMP_FILE_SUFFIX =

mtk_writeSession temporary file suffix.

'.xmda_toolkit_temporary'
MTK_WRITE_SESSION_FILE_NAMES =

Opens a file for writing. Note:

Existing file is deleted
Directory are automatically created
Write is atomic. In case of failure existing file is not affected.
The name of the current file is available in context: context[:mtk_fileName]

if context is true, file writes will be skipped. Note that reverse (file read) will be performed however. Example: mtk_writeSession(‘file1.java’) { write(‘this goes into file1.java’) mtk_writeSession(‘file2.java’) { write(‘this goes into file2.java’) puts context } write(‘this goes into file1.java’) }

Set.new
REVERSE =

_Resource

true
NOREVERSE =
false
WITHOUT_MARKER =
true
@@max_file_logged =
30

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#fileGeneratedObject (readonly)

le fichier fileName a ete genere pour la resource res



97
98
99
# File 'lib/ontomde-core/helper.rb', line 97

def fileGenerated
  @fileGenerated
end

Instance Method Details

#encloseWrite(beforeStr, afterStr, stealth = false, &middleBlock) ⇒ Object

writes before string, yield block and then writes after.

EXAMPLE. encloseWrite(“<title>”,“</title>”) { write “Today news” }



289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/ontomde-core/helper.rb', line 289

def encloseWrite(beforeStr,afterStr,stealth=false,&middleBlock)
  if(stealth)
    s=mtk_stss { yield }
    return false if s.nil? || s.empty?
    write(beforeStr.to_s)
    write(s)
    write(afterStr.to_s)
    return true
  else
    write(beforeStr.to_s)
    yield
    write(afterStr.to_s)
    return nil
  end
end

#mtk_annotation(initialReverseMode = false, zonesId = ['annotations'], noMarker = false) ⇒ Object

Raises:

  • (Exception)


580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
# File 'lib/ontomde-core/helper.rb', line 580

def mtk_annotation(initialReverseMode=false,zonesId=['annotations'],noMarker=false)
  #mbu=mtk_block_uri
  raise Exception.new('Bad parameter') if initialReverseMode!=false && initialReverseMode!=true

  if !noMarker
    revAnno=''
    del=''
    
    nothingReverse = true
    
    zonesId.each{ |zone|
      mbu="#{rdf_uri}__#{zone}"
      qualified_uri=rdf_Repository.mtk_qualifyBlockURI(mbu)
      if !context[:hasGlobalReverse,false]
        str=context[:protectedReverse][qualified_uri]
      else
        str=context[:reverseGlobalMap][qualified_uri]
      end


      reverse= (!str.nil?) || initialReverseMode
      
      if reverse
        nothingReverse = false
        revAnno+=del
        del=', '
        if zone=='0'
          revAnno+='code'
        else
          if zone=='annoparam0'
            revAnno+='anno_param'
          else
            if zone=='custom_code'
              revAnno+='custom'
            else
              revAnno+=zone
            end
          end
        end
      end
    }
    
    if nothingReverse then
      revAnno = 'nothing'
    end
    write("\t") # good for methods and attributes 
    write("@OntoMDE(reverse = { #{revAnno} }, uri = \"#{rdf_uri}\")\n")
  end
end

#mtk_autoNewFileCreationCheck(fileName) ⇒ Object

checks if fileName already exists



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/ontomde-core/helper.rb', line 233

def mtk_autoNewFileCreationCheck(fileName)
  doNotOverwrite=!context[:autoNewFileCreation,true] && !File.exists?(fileName)
  if doNotOverwrite
    # xmda is not allowed to create new file
    log.error { %{
********* NEW FILE DETECTED **********
** A new file needs to be added to your project:
** "#{fileName}"
**
** Generator has been halted to let
** you take proper actions such as:
**
**  * Refactor your code if this new file is a renamed file
**  * Create a blank file and Add this file to version control
**
** Model Element being processed is:
** #{mtk_object_message}
**
** Model element being processed is related to:
** #{mtk_related_message}
********* NEW FILE DETECTED **********
      }}
    #exit(1)
  end
  return doNotOverwrite
end

#mtk_outObject

internal method.

Returns file descriptor currently used by mtk_writeSession.



575
576
577
# File 'lib/ontomde-core/helper.rb', line 575

def mtk_out
  return context[:mtk_out]
end

#mtk_protected(initialReverseMode = false, zoneId = '0', noMarker = false, &block) ⇒ Object

mtk_protected is used when generated code can be modified by user and preserved by subsequent generation. The code generated in the block passed as parameter will be generated encolosed between identifiable tags.

NOTE:

The block is identified by the current rdf resource URI.
If more than one block is to be generated in one file, zoneId must be used.

Example 1: default

mtk_writeSession('file1.java') {
  write("Package .... ;")
  a.mtk_protected() {
     write("default code to be redefined by user");
     }
  b.mtk_protected() {
     write("default code to be redefined by user");
     }
}

Example 2: initial mode is reverse

mtk_writeSession('file1.java') {
  write("Package .... ;")
  mtk_protected(REVERSE) {
     write("default code to be redefined by user");
     }
}

Example 3: initial mode is noreverse

mtk_writeSession('file1.java') {
  write("Package .... ;")
  mtk_protected(NOREVERSE) {
    write("default code to be redefined by user");
    }
}

Example 4: multiple-protected zone for a single object

mtk_writeSession('file1.java') {
  write("Package .... ;")
  a.mtk_protected(REVERSE,"a") {
     write("default code to be redefined by user");
     }
  a.mtk_protected(REVERSE,"b") {
     write("default code to be redefined by user");
     }
}

Raises:

  • (Exception)


515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
# File 'lib/ontomde-core/helper.rb', line 515

def mtk_protected(initialReverseMode=false,zoneId='0',noMarker=false, &block)
  #mbu=mtk_block_uri
  raise Exception.new('Bad parameter') if initialReverseMode!=false && initialReverseMode!=true
  mbu="#{rdf_uri}__#{zoneId}"
  qualified_uri=rdf_Repository.mtk_qualifyBlockURI(mbu)

  fileType=context[:protectedReverse].fileType

  str=nil
  if context[:hasGlobalReverse,false]
    str=context[:reverseGlobalMap][qualified_uri]
  else
    str=context[:protectedReverse][qualified_uri]
  end

  reverse= (!str.nil?) || initialReverseMode

  if noMarker
    # do not use marker for this item
  elsif(!reverse) && context[:skipNoReverseMarker,false]
    write(fileType.beginMarkerSkip(mbu,reverse))
  else
    write(fileType.beginMarker(mbu,reverse))
  end
  if str.nil?
    #log.debug "!!yield block_uri=#{mbu}"
    ret=yield
    write(ret) if ret.kind_of?(String)
  else
    write(str)
  end
  if noMarker
    write("\n") if !str.nil? && str!=""
    # do not use marker for this item
  elsif (!reverse) && context[:skipNoReverseMarker,false]
    write(fileType.endMarkerSkip(mbu))
  else
    write(fileType.endMarker(mbu))
  end
end

#mtk_qualifyBlockURI(_uri) ⇒ Object

Internal use.

Transforms a uri to a uri qualified by the current file name



326
327
328
# File 'lib/ontomde-core/helper.rb', line 326

def mtk_qualifyBlockURI(_uri)
  return "#{_uri}__#{context[:mtk_fileName]}"
end

#mtk_retrieveProtected(fileName, fileType) ⇒ Object

Internal use.

Reverse the file currently being written by mtk_writeSession. This method is automaticaly called



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
# File 'lib/ontomde-core/helper.rb', line 347

def mtk_retrieveProtected(fileName,fileType)    
  return false unless File.exists?(fileName)
  globalFile=false
  if context[:hasGlobalReverse,false]
    if context[:globalReverseFile]!=fileName
      return true if context[:reversedFiles].include?(File.basename(fileName))
	if mtk_shouldAlreadyBeenReversed(fileName)
msg=<<END

FILENAME="#{fileName}" File.exists?=#{File.exists?(fileName)}
$FILENAME should have been reversed by batch reverse process and it has not. 
This may be caused by an internal error or a platform limitation. 
You should know that there is a length limit for paths and your fileName is #{fileName.length} character long. You may consider reducing packages depths and shortening names for reducing global fileName length.
END
      	raise Warning.new,msg
	end
    else
      globalFile=true
      endFilesName=false
      endFilesExtension=false
    end
  end

  mtk_context(:mtk_fileName=>fileName) {
    File.open(fileName,'r') { |aFile|
      i=0
      reading=false
      block_uri=nil
      buffer=''
      reverseMode=nil

      aFile.each_line { |line|
        i=i+1

        if globalFile && !endFilesExtension
          if !endFilesName
            if line.include?('End_Files_Name')
              endFilesName=true
            else
              context[:reversedFiles].concat(line[0,line.size-1].split(','))
            end
          else
            if line.include?('End_Files_Extension')
              endFilesExtension=true
            else
              context[:requireReverseExtensions].concat(line[0,line.size-1].split(','))
            end
          end
          next
        end

        if !reading
          #return if !line.include?("PROTECTED REGION XMDA BEGIN") # optimisation ?
          m=fileType.re_begin.match(line)
          #log.debug {"beg match_ok=#{!m.nil?} line=#{line}"}
          next if m.nil?
          #raise Warning.new,"Error Reading Protected region header\n#{fileName}:line #{i}: #{line}" if m.nil?
          reading=true
          buffer=''
          linesep=''
          block_uri=fileType.unescape(m[2].to_s)
          #log.debug { "ma: #{m[0]} block_uri=#{block_uri}" }
          raise Warning.new,'Error Reading Protected region header nil uri' if block_uri.nil?
          case m[1]
          when 'yes' then reverseMode=true
          when 'no'  then reverseMode=false
          else raise Warning.new,%{Bad reverseMode value in file #{fileName}. reverse="yes" or reverse="no" expected (got "#{m[1]}" line ##{i}).}
          end
          raise Warning.new,'Error Reading Protected region header nil uri' if reverseMode.nil?
          #log.debug { "!!!!!! block_ri=--#{block_uri}--" }
        else
          #log.debug "#{reading} line=#{line}"
          m=fileType.re_end.match(line)
          #log.debug "end match_ok=#{!m.nil?} line=#{line}"
          if m.nil?
            buffer=buffer.nil? ?  line : "#{buffer}#{line}"
            next
          end
          block_uri_end=fileType.unescape(m[1].to_s)
          if block_uri_end!=block_uri
            raise WarningReverseBadOrMissingEnd.new, <<ENDERRORMSG
Bad non matching END tag in  #{fileName}
expected uri="#{block_uri}"
and got  uri="#{block_uri_end}"
line ##{i})
ENDERRORMSG
          end
          reading=false
          #log.debug "block_uri=#{block_uri} protected ->xxxxxxx\n#{buffer}xxxxxxxxxx"
          if reverseMode
            buffer=buffer[0,buffer.size-1] unless buffer==''
            if (!context[:hasGlobalReverse])
              qualified_block_uri=mtk_qualifyBlockURI(block_uri)
              self[qualified_block_uri]=buffer
            else
              qualified_block_uri=block_uri
              context[:reverseGlobalMap][qualified_block_uri]=buffer
            end
            open('reverse.log','a') {|r|
              r.write("\n### reverse #{qualified_block_uri}\n")
              r.write( "#{buffer} #{buffer.length}")
            } #unless context[:logFileReverse].nil?
          else
            #log.debug "Reverse ignored #{context[:mtk_fileName]}!"
          end
        end

      }
    }}
  return true # un fichier a ete retro
end

#mtk_shouldAlreadyBeenReversed(fileName) ⇒ Object



459
460
461
# File 'lib/ontomde-core/helper.rb', line 459

def mtk_shouldAlreadyBeenReversed(fileName)
  return context[:requireReverseExtensions].include?(File.extname(fileName))
end

#mtk_sprotected(initialReverseMode = false, zoneId = '0', &block) ⇒ Object

same as #mtk_protected but for string instead of writes.



568
569
570
571
# File 'lib/ontomde-core/helper.rb', line 568

def mtk_sprotected(initialReverseMode=false,zoneId='0',&block)
  return mtk_stss { mtk_protected(initialReverseMode,zoneId,&block)}
  
end

#mtk_stringWriteSessionObject

Internal use.

Used primarily by mtk server



77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/ontomde-core/helper.rb', line 77

def mtk_stringWriteSession()
  fileName=context[:mtk_fileName,'string-file']
  file=StringOutputStream.new

  ret=nil
  mtk_context(:mtk_out=>file,:mtk_fileName=>fileName) {
    #@@mtk_out=context[:mtk_out] # perf
    yield
    ret=context[:mtk_out].to_s
  }
  #@@mtk_out=context.get(:mtk_out) # perf
  return ret
end

#mtk_stss(&block) ⇒ Object

Stream to String Session



557
558
559
560
# File 'lib/ontomde-core/helper.rb', line 557

def mtk_stss(&block)
  #@rdf_Repository.mtk_stringWriteSession(&block)
  mtk_stringWriteSession(&block)
end

#mtk_wprotected(initialReverseMode = false, zoneId = '0', &block) ⇒ Object

same as #mtk_protected but for writes.



563
564
565
# File 'lib/ontomde-core/helper.rb', line 563

def mtk_wprotected(initialReverseMode=false,zoneId='0',&block)
  mtk_protected(initialReverseMode=false,zoneId='0',&block)
end

#mtk_writeSession(fileName, fileType = nil) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/ontomde-core/helper.rb', line 122

def mtk_writeSession(fileName,fileType=nil)
  
  #if a file exist named fileName.mda, then write to this
  #file instead of fileName
  divert=fileName+'.mda'
  if (File.exists?(divert))
    fileType=FileType.getFileType(fileName) if fileType.nil?
    fileName=divert      
  end
  
  # Open or create session
  mtk_writeSessionNameClashErrorDetection(fileName.to_s)

  protectedReverse=LoadModelLazyWriter.new(fileName,fileType)
  FileUtils.mkdir_p(File.dirname(fileName))
  notifyFileGenerated(File.expand_path(fileName),self)

  doNotOverwrite=mtk_autoNewFileCreationCheck(fileName)
  if context[:dryRun,false]
    file=NullFileWriter.instance
    #log.debug { "Simulating Write to #{fileName} (because context[:dryRun]==true)" }
    mtk_context(:mtk_out=>file,:mtk_fileName=>fileName,:protectedReverse=>protectedReverse) {
      #@@mtk_out=context[:mtk_out] # perf
      yield
    }
    #@@mtk_out=context.get(:mtk_out) # perf
    return
  end
  File.open(fileName+TEMP_FILE_SUFFIX,File::CREAT|File::TRUNC|File::RDWR, 0644) {
    |file|
    mtk_context(:mtk_out=>file,:mtk_fileName=>fileName,:protectedReverse=>protectedReverse) {
      #log.debug { "Writing #{fileName}" }
      #@@mtk_out=context[:mtk_out] # perf
      yield
    }
    #@@mtk_out=context.get(:mtk_out) # perf
  }
  #Temporary file has been corectly generated.
  unusedData=protectedReverse.unusedData
  if(!unusedData.nil?)
    log.info { "warning: saved code appended to #{fileName}.mtk_save" }
    msg=''
    File.open(fileName+'.mtk_save',File::CREAT|File::APPEND|File::RDWR, 0644) { |file|
      unusedData.each {|k|
        msg=msg+%{\n  ** uri="#{k}"}
        file.write <<END
//***********************
//XMDA BEGIN SAVED DATA : uri="#{k}"
//***********************
#{protectedReverse[k]}
//***********************
//END SAVED DATA
//***********************

END

      }
    }
    if !context[:allowAutomaticCodeDeletion,false]
      doNotOverwrite=true
      log.error { %{
***************************************************************
Code generation has been *halted* to prevent code loss in
   #{fileName}

Code to be deleted is stored in
   #{fileName}.mtk_save

You must take the appropriate actions before re-running generator.
* fix your model for unwanted deletion.
* manually delete unused code for #{msg}
* rename
   #{fileName+TEMP_FILE_SUFFIX}
to
   #{fileName}
#
***************************************************************
        }}
      #exit(1)
      raise Exception.new('potential code loss detected')
    end

  end

  puts "Writing: #{fileName}" if context[:logFileWrite,false]
  retryCount=0
  while true
    begin
      # On some windows machine,
      # file is sometimes locked by some management
      # daemon (probably some corporate audit daemon)
      # This cause code generation to fail.
      # This loop gives the daemon a chance to
      # unlock the file.
      # We just wait a few seconds and try again.
      #raise IOException.new(),"KO" if retryCount<2
      File.rename(fileName+TEMP_FILE_SUFFIX,fileName)
      puts 'Retry succeeded.' if retryCount>0
      break # exit while
    rescue   => e
      retryCount=retryCount+1
      #log.warn "#{e}"
      raise e if retryCount > 3
      puts "Rename failed. Retrying (#{retryCount})"
      sleep(2) #
    end
  end
  return nil
end

#mtk_writeSessionNameClashErrorDetection(fileName) ⇒ Object

detects if fileName has already been used. Logs an error if a clash is detected.



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/ontomde-core/helper.rb', line 262

def mtk_writeSessionNameClashErrorDetection(fileName)
  if(MTK_WRITE_SESSION_FILE_NAMES.include?(fileName.to_s))
    log.error{ %{********* NAME CLASH DETECTED ********** #{fileName}
********* NAME CLASH DETECTED **********
** This software has detected that a generated file
** is being overwritten in the same code generation session.
** This most likely is caused by a name clash in the source model.
**
** Filename being overwritten is
** "#{fileName}"
** Model Element being processed is:
** #{mtk_object_message}
**
** Model element being processed is related to:
** #{mtk_related_message}
********* NAME CLASH DETECTED **********
      }}
  else
    MTK_WRITE_SESSION_FILE_NAMES<< fileName.to_s
  end
end

#notifyFileGenerated(fileName, res) ⇒ Object

@fileGenerated=Array.new



99
100
101
# File 'lib/ontomde-core/helper.rb', line 99

def notifyFileGenerated(fileName,res)
  #@fileGenerated << [ fileName , res ]
end

#write(str) ⇒ Object

Write string to the current file opened by mtk_writeSession.

Raises:



306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/ontomde-core/helper.rb', line 306

def write(str)
  o=context[:mtk_out]
  if !o.nil?
    o.write(str)
    return
  end
  raise Warning.new(), <<END
There is no file currently opened.
Please use mtk_writeSession prior to using any write method.
Example:
#  mtk_writeSession('file1.java') {
#    write("Package .... ;")
#       }
#  }
END
end