Project

General

Profile

annotations.xml

Constantin Asofiei, 01/21/2013 09:35 AM

Download (26.3 KB)

 
1
<?xml version="1.0"?>
2

    
3
<!-- 
4
/*
5
** Module   : annotations.xml
6
** Abstract : analyzes Progress source trees and leaves information behind
7
**            to ease conversion later
8
**
9
** Copyright (c) 2005-2013, Golden Code Development Corporation.
10
** ALL RIGHTS RESERVED. Use is subject to license terms.
11
**
12
**           Golden Code Development Corporation
13
**                      CONFIDENTIAL
14
**
15
** _#_ _I_ __Date__ __JPRM__ ________________Description_________________
16
** 001 GES 20050721   @21753 Added a header to an already working version  
17
**                           which supports the following:
18
**                           1. variable name conversion and wrapper class
19
**                              determination
20
**                           2. determination of the correct Java method
21
**                              name for the length builtin function
22
**                              depending on parameters
23
**                           3. user-defined function name conversion
24
**                           4. user-defined procedure name conversion
25
**                           5. cross-references for procedure definitions
26
**                              and their matching define_parameter stmts
27
**                           6. recording loop increments
28
**                           7. mark variable definitions for promotion
29
**                              to a class member (instead of being 
30
**                              local)
31
**                           8. mark return statements as to whether
32
**                              they are being executed from a function
33
**                              or a procedure
34
**                           9. detect non-integral/non-constant case 
35
**                              statements for conversion to 
36
**                              if/elseif/else form instead of a switch
37
**                           10. stream cross-references (refs to defs)
38
**                           11. stream name conversion
39
**                           12. reorder put_field children and certain
40
**                               children of kw_through in an input_thru,
41
**                               output_thru, input_output_thru
42
**                           13. cross-reference seek function parm to
43
**                               the correct stream def
44
**                           14. mark the first init of a stream such
45
**                               that an extra close can be avoided
46
**                           15. rewrite COMMAND_TOKENS children to merge
47
**                               into the least number of tokens (which
48
**                               reassembles the commands the way that
49
**                               Progress executes them, versus how we
50
**                               lex them)
51
**                           16. convert assignment style language stmts
52
**                               to method call friendly form
53
**                           17. remove unnecessary nodes or unreachable
54
**                               from the tree
55
** 002 GES 20050728   @21901 Added support for format string processing.
56
** 003 GES 20050729   @21916 Added processing for extent().
57
** 004 GES 20050731   @21929 Added processing for shared resource
58
**                           definitions (variables and streams).
59
** 005 SIY 20050808   @22043 Added processing of the LEAVE inside CASE
60
**                           statement. This processing is then moved into
61
**                           labeling.rules. Unreachable code removal is 
62
**                           moved into remove_unreachable.rules.
63
** 006 GES 20050815   @22137 Modified processing for the return stmt,
64
**                           save off return types in functions and to
65
**                           remove the error keyword when it is bogus.
66
**                           Added support for generic label name
67
**                           conversion and cross-referencing. Changed
68
**                           previous "labeling" to "leave_fixups".
69
**                           Refactored some rulesets into separate
70
**                           files to modularize and simplify maint.
71
** 007 GES 20050816   @22141 Added support for block properties and
72
**                           transactions.  Also refactored more content
73
**                           into modular rules files.
74
** 008 SIY 20050818   @22165 Changes necessary to help properly collect
75
**                           name mappings.
76
** 009 GES 20050907   @22595 Moved function processing and assignment
77
**                           style stmt rewriting to separate files.
78
** 010 GES 20050919   @22790 Moved all remaining rule sets to external
79
**                           files and added new rule sets for record
80
**                           scoping.
81
** 011 GES 20051013   @23069 Added support for index selection and where/
82
**                           by clause processing.
83
** 012 SIY 20051024   @23093 Added frame scoping rule set into list.
84
** 013 GES 20051025   @23121 Added where clause processing.
85
** 014 GES 20051102   @23188 Added screen buffer processing.
86
** 015 SIY 20051103   @23187 Added naming rule set.
87
** 016 GES 20051103   @23225 Added record field expansion processing.
88
** 017 GES 20051107   @23270 Added sorting and rewriting of UI related
89
**                           tree structures.
90
** 018 GES 20051114   @23325 Added assign stmt bracketing.
91
** 019 GES 20051116   @23351 Added buffer name conflict resolution.
92
** 020 GES 20051119   @23408 Added validation preparation.
93
** 021 GES 20051119   @23428 Moved validation core to seperate rule set
94
**                           and put implicit field validation processing
95
**                           in the prep step.
96
** 022 GES 20051122   @23441 Added embedded attribute assign rewrite.
97
** 023 GES 20051123   @23444 Added implicit array field expansion.
98
** 024 GES 20051123   @23447 Added when clause and embedded assignment
99
**                           processing.
100
** 025 GES 20051127   @23517 Dynamic UI field index support.
101
** 026 ECF 20051127   @23522 Added preselect processing. Encapsulated in
102
**                           preselect_prep.rules, preselect_post.rules.
103
** 027 ECF 20051129   @23583 Added query_associations.rules. Used during
104
**                           database annotations to associate define and
105
**                           open query statements.
106
** 028 ECF 20051207   @23766 Moved command_tokens back to fixups phase.
107
**                           Added database_general ruleset.
108
** 029 ECF 20060107   @23873 Added accumulate ruleset. Supports ACCUMULATE
109
**                           family of features.
110
** 030 ECF 20060118   @23992 Removed break_groups.rules. Replaced with
111
**                           presort.rules.
112
** 031 GES 20060201   @24177 Moved Progress procedure/function to Java
113
**                           class/method name mapping collection here
114
**                           from core conversion.
115
** 032 ECF 20060206   @24317 Swapped order of record_field_expansion and
116
**                           database_general rulesets. This dependency
117
**                           was introduced by the addition of fieldname
118
**                           annotation to database_general.
119
** 033 ECF 20060219   @24695 Added client where clause support. Added two
120
**                           new rulesets: where_clause_prep2 and
121
**                           where_clause_post2.
122
** 034 ECF 20060228   @24826 Added field-level validation support. Added
123
**                           validation_post ruleset.
124
** 035 GES 20060301   @24844 Made persistence of the AST, unconditional.
125
**                           All access to fileMatch can be removed over
126
**                           time from the included rules. Once all refs
127
**                           are gone, the var can be deleted here. It
128
**                           is completely vestigal now.
129
** 036 GES 20060306   @24913 Added customer specific prep step.
130
** 037 GES 20060311   @24978 Moved variable scope promotion near the end
131
**                           so that client side where clauses can be
132
**                           detected as promotion triggers.
133
** 038 SIY 20060313   @25007 Added second unreachable removal step.
134
** 039 GES 20060313   @25042 Moved file index for name collection into a
135
**                           top level global var to allow it to properly
136
**                           increment.
137
** 040 GES 20060313   @25045 Read name caching data back in to allow an
138
**                           incremental conversion of files rather than
139
**                           forcing all files to be converted at once.
140
** 041 GES 20060319   @25107 Added parameter signature collection.
141
** 042 NVS 20060320   @25152 Added another rule set, validate_post2.
142
** 043 GES 20060404   @25341 Added text clause reparenting.
143
** 044 ECF 20060409   @25440 Moved buffer_name_conflicts to earlier in the
144
**                           pipeline. Various downstream annotations
145
**                           rulesets needed to be aware of the changes
146
**                           made by this ruleset.
147
** 045 GES 20060411   @25466 Moved return_statements to follow
148
**                           block_properties since unlabeled next
149
**                           can be converted to a return when not 
150
**                           enclosed in a loop.
151
** 046 NVS 20060503   @25973 Added another rule set, frame_title.
152
** 047 GES 20060507   @26005 Added copying of VIEW-AS from the schema.
153
** 048 ECF 20060627   @27632 Added where_clause_normalize ruleset.
154
** 049 ECF 20060730   @28246 Added adaptive_query ruleset. Also made
155
**                           queryNum a global variable so that the
156
**                           query naming function which uses it could be
157
**                           moved to a public function library within the
158
**                           database_general ruleset.
159
** 050 ECF 20060812   @28682 Added where_clause_pre_prep.rules. Yet
160
**                           another where clause preprocessing step.
161
** 051 ECF 20060915   @29637 Added temp_table_buffers.rules. Associates
162
**                           temp-table buffers with their backing temp
163
**                           table definition.
164
** 052 ECF 20060925   @29907 Moved accumulate rules after block_properties
165
**                           to accommodate new dependency. Accumulute
166
**                           rules relies on 'transLevel' annotation added
167
**                           to inner_block node by block_properties.
168
** 053 GES 20070221   @32204 Support fixups for named events.
169
** 054 ECF 20070821   @34911 Added support for temporary silent error
170
**                           mode. This allows query substitution parms to
171
**                           be processed safely during initialization of
172
**                           a query. Added query_subst_silent.rules.
173
** 055 ECF 20070906   @34988 Added database_late.rules. Persistence
174
**                           related annotations with dependencies on
175
**                           earlier annotations.
176
** 056 GES 20080403   @37802 Added scope_promotion_fields and
177
**                           cross_namespace_conflicts.
178
** 057 GES 20080623   @38943 Changed ruleset names for clarity.
179
** 058 GES 20080722   @39161 Split file system cfg into a separate import
180
**                           XML file. Simplified the name_map.xml format.
181
**                           Added copying of the name map to the build
182
**                           area so it will get JAR'd up automatically.
183
** 059 GES 20080814   @39421 Added unmanaged_enclosing_blocks rule-set.
184
** 060 GES 20080903   @39684 Moved loop_control to follow block_properties
185
**                           which it is now dependent upon.
186
** 061 GES 20080905   @39725 Added deferred_logical_evaluation rules.
187
** 062 GES 20080930   @39968 Added variable_definitions_undo rules.
188
** 063 GES 20090816   @43657 Added output_parameters.rules.
189
** 064 CA  20100121   @44544 Added support for merging the manually maintained
190
**                           cfg/name_map_merge.xml file with the main 
191
**                           name_map.xml.
192
** 065 SVL 20100606   @44903 Added support for using statements like
193
**                           "run some-merged-function.p.".
194
** 066 GES 20100819          Eliminated unnecessary var.
195
** 067 EVL 20121102          Adding quoteReplacement() usage to support multi
196
**                           OS conversion support. Fixing the filename file
197
**                           separator value for map creation in Windows OS
198
**                           conversion environment.
199
** 068 CA  20130119          Collect the return types for each function 
200
**                           in a separate map definition.
201
*/
202
 -->
203

    
204
<cfg>
205

    
206
   <!-- Makes decisions needed by multiple downstream rules.  The results
207
        are stored as annotations so that they will be easily available
208
        later. -->
209
        
210
   <!-- register worker objects -->
211
   <worker class="com.goldencode.p2j.uast.ProgressPatternWorker"
212
           namespace="prog" />
213
   <worker class="com.goldencode.p2j.convert.ExpressionConversionWorker"
214
           namespace="ecw" />
215
   <worker class="com.goldencode.p2j.pattern.TemplateWorker"
216
           namespace="tw" />
217
   <worker class="com.goldencode.p2j.xml.XmlPatternWorker" 
218
           namespace="xml" />
219
   <worker class="com.goldencode.p2j.convert.NameMappingWorker" 
220
           namespace="nmap" />
221
  
222
   <!-- expression libraries -->
223
   <include name="common-progress" />
224
   <include name="annotations/name_map_helpers" />
225
  
226
   <!-- variables -->
227
   <variable name="xmlRoot"   type="com.goldencode.p2j.xml.XmlAst" />
228
   <variable name="xmlAst"    type="com.goldencode.p2j.xml.XmlAst" />
229
   <variable name="xmlfile"   type="java.lang.String" />
230
   <variable name="outroot"   type="java.lang.String" />
231
   <variable name="pkgroot"   type="java.lang.String" />
232
   <variable name="outfile"   type="java.lang.String" />
233
   <variable name="cachefile" type="java.lang.String" />
234
   <variable name="queryNum"  type="java.lang.Integer" />
235

    
236
   <variable name="mergeRoot"  type="com.goldencode.p2j.xml.XmlAst" />
237
   <variable name="mergeIndex" type="com.goldencode.p2j.xml.XmlAst" />
238
   <variable name="mergefile"  type="java.lang.String" />
239
   <variable name="jname"      type="java.lang.String" />
240
   <variable name="pname"      type="java.lang.String" />
241
   <variable name="mergeMap"   type="java.util.Map" />
242
   <variable name="ftypesByName" type="java.util.Map" />
243
   <variable name="iter"       type="java.util.Iterator" />
244

    
245
   <!-- pipeline of rule-sets to process -->
246
  
247
   <!-- global initialization (once per pipeline) -->
248
   <init-rules>
249
      
250
      <rule>xmlfile = "name_map.xml"</rule>
251
      <rule>cachefile = "name_map.cache"</rule>
252
      <rule>mergefile = getConfigParameter("name_map_merge")</rule>
253
      <rule>ftypesByName = create("java.util.HashMap")</rule>
254
      
255
      <!-- name mapping must cross all files so it initialized once for the
256
           entire pipeline -->
257
      <rule>exists(xmlfile, true)
258
      
259
         <!-- read our cached name mapping file and initialize our data
260
              structures -->
261
         <rule>nmap.restoreMappings(cachefile)</rule>
262
         <rule>xmlRoot = xml.parse(xmlfile, false, null)</rule>
263
         
264
         <!-- find the name-map node -->
265
         <rule>
266
            xmlAst = xmlRoot.getImmediateChild(xml.element_node, null)
267
         </rule>
268
      
269
         <!-- initialize our project-wide XML name mapping file -->
270
         <rule on="false">
271
            xmlRoot = xml.createAst(xml.document_node, '#document', null)
272
         </rule>
273
         <rule on="false">
274
            xmlAst = xml.createAst(xml.element_node, "name-map", xmlRoot)
275
         </rule>
276
         
277
         <!-- initialize the directory import file for file system cfg -->
278
         <rule on="false">execLib("init_file_sys_cfg")</rule>
279
         
280
      </rule>
281
      
282
   </init-rules>
283
   
284
   <!-- collect all user-function definitions into a map and save its
285
        return type -->
286
   <rule-set>
287
      <variable name="cls"   type="java.lang.String" />
288
      <variable name="fname" type="java.lang.String" />
289
      <variable name="ftype" type="java.lang.Integer" />"
290
      
291
      <walk-rules>
292
      
293
         <rule>evalLib("function_defs")
294
            <action>fname = getNoteString("name")</action>
295
            <action>ftype = #(int) getNoteLong("type")</action>
296
            
297
            <rule>ftypesByName.containsKey(fname) and
298
                  !ftype.equals(#(java.lang.String) ftypesByName.get(fname))
299
               <action>
300
                  printfln("WARNING: Duplicate function definition %s with different returns types: %s and %s",
301
                           fname,
302
                           ftype,
303
                           ftypesByName.get(fname))
304
               </action>
305
            </rule>
306
            
307
            <action>cls = execLib("get_function_return_class", ftype)</action>
308
            <action>ftypesByName.put(fname, cls)</action>
309
         </rule>
310
      </walk-rules>
311
      
312
      <post-rules>
313
         <rule>printfln("%s", ftypesByName.toString())</rule>
314
      </post-rules>
315
   </rule-set>
316
  
317
   <!-- main processing (once per tree) -->
318
   
319
   <!-- should be first in this file so that unreachable nodes aren't
320
        further processed downstream -->
321
   <!-- first pass: process dead THEN/ELSE blocks -->
322
   <!-- do this few times to reach deeply nested blocks -->
323
   <rule-set name="annotations/remove_unreachable" />
324
   <rule-set name="annotations/remove_unreachable" />
325
   <rule-set name="annotations/remove_unreachable" />
326
   <rule-set name="annotations/remove_unreachable" />
327
   <rule-set name="annotations/remove_unreachable" />
328
   <rule-set name="annotations/remove_unreachable" />
329
   
330
   <!-- second pass, finally remove unreachable code -->
331
   <rule-set name="annotations/remove_unreachable2" />
332
   
333
   <!-- customer-specific tree rewriting -->
334
   <rule-set name="customer_specific_annotations_prep" optional="true" />
335
   
336
   <!-- generate names for class/package/etc. -->
337
   <rule-set name="annotations/naming" />
338
   
339
   <!-- these next two rulesets are order dependent since label_manufacturing
340
        creates new label_def nodes which then must be processed by the
341
        label_xref ruleset (which cross-references label and label_def nodes)
342
        -->
343
   <rule-set name="annotations/label_manufacturing" />
344
   <rule-set name="annotations/label_xref" />
345
   
346
   <!-- these next two rulesets are order dependent since var_defs
347
        detects unreferenced vars and hides them -->
348
   <rule-set name="annotations/variable_definitions" />
349
   <rule-set name="annotations/variable_definitions_undo" />
350
   
351
   <rule-set name="annotations/functions" />
352
   <rule-set name="annotations/procedures" />      
353
   <rule-set name="annotations/case_statements" />
354
   <rule-set name="annotations/input_output" />
355
   <rule-set name="annotations/assignment_style_stmt_rewriting" />
356
   <rule-set name="annotations/embedded_attribute_assign_rewrite" />
357
   <rule-set name="annotations/format_string" />
358
   <rule-set name="annotations/shared_resources" />
359
   <rule-set name="annotations/named_events" />
360
   
361
   <!-- database support: this next group of rule sets is order dependent -->
362
   <rule-set name="annotations/record_field_expansion" />
363
   <rule-set name="annotations/database_general" />
364
   <rule-set name="annotations/array_expansion" />
365
   <rule-set name="annotations/implicit_where_clause" />
366
   <rule-set name="annotations/record_scoping_prep" />
367
   <rule-set name="annotations/record_scoping" />
368
   <rule-set name="annotations/record_scoping_post" />
369
   <rule-set name="annotations/buffer_name_conflicts" />
370
   <rule-set name="annotations/temp_table_buffers" />
371
   <rule-set name="annotations/index_selection" />
372
   <rule-set name="annotations/preselect_prep" />
373
   <rule-set name="annotations/where_clause_normalize" />
374
   <rule-set name="annotations/where_clause_pre_prep" />
375
   <rule-set name="annotations/where_clause_prep" />
376
   <rule-set name="annotations/where_clause_prep2" />
377
   <rule-set name="annotations/where_clause" />
378
   <rule-set name="annotations/where_clause_post" />
379
   <rule-set name="annotations/where_clause_post2" />
380
   <rule-set name="annotations/query_subst_silent" />
381
   <rule-set name="annotations/preselect_post" />
382
   <rule-set name="annotations/query_associations" />
383
   <rule-set name="annotations/database_late" />
384
   <rule-set name="annotations/assign_bracketing" />
385
   <rule-set name="annotations/output_parameters" />
386

    
387
   <!-- UI support: this next group of rule sets is order dependent -->
388
   <rule-set name="annotations/trigger_prep" />
389
   <rule-set name="annotations/set_update_embedded_assignments" />
390
   <rule-set name="annotations/text_clause_reparenting" />
391
   <rule-set name="annotations/copy_view_as_from_schema" />
392
   <rule-set name="annotations/frame_scoping" />
393
   <rule-set name="annotations/frame_title" />
394
   <rule-set name="annotations/screen_buffer" />
395
   <rule-set name="annotations/validation_prep" />
396
   <rule-set name="annotations/validation" />
397
   <rule-set name="annotations/validation_post" />
398
   <rule-set name="annotations/validation_post2" />
399
   <rule-set name="annotations/when_rewriting" />
400
   <rule-set name="annotations/dynamic_ui_indexes" />
401
   
402
   <rule-set name="annotations/deferred_logical_evaluation" />
403
   <rule-set name="annotations/presort" />
404
   <rule-set name="annotations/block_properties" />
405
   <rule-set name="annotations/accumulate" />
406
   <rule-set name="annotations/return_statements" />
407
   <rule-set name="annotations/scope_promotion" />
408
   <rule-set name="annotations/scope_promotion_fields" />
409
   <rule-set name="annotations/cross_namespace_conflicts" />
410
   <rule-set name="annotations/sorting" />
411
   <rule-set name="annotations/cleanup" />
412
   
413
   <!-- rules that rely upon annotations in block_properties -->
414
   <rule-set name="annotations/loop_control" />
415
   <rule-set name="annotations/adaptive_query" />
416
   <rule-set name="annotations/unmanaged_enclosing_blocks" />
417
   
418
   <!-- this must be at the end (in the following order) -->
419
   <rule-set name="annotations/collect_parameters" />
420
   <rule-set name="annotations/collect_names" />
421

    
422
   <!-- persist -->
423
   <rule-set>
424
      <post-rules>
425
         <rule>persist()</rule>
426
      </post-rules>
427
   </rule-set>   
428
  
429
   <!-- global termination (once per pipeline) -->
430
   <post-rules>
431
      <!-- go through the merge file and check for collisions; since the 
432
           name_map may have been read from a cache, we must do this against 
433
           the entire name_map file -->
434
      <rule>mergefile != null and exists(mergefile, true)
435

    
436
         <!-- read the merge file and save it into a map -->
437
         <action>mergeRoot = xml.parse(mergefile, false, null)</action>
438
         <action>
439
            mergeIndex = mergeRoot.getImmediateChild(xml.element_node, null)
440
         </action>
441
         
442
         <action>
443
            printfln("Reading name map merge file %s", 
444
                     mergefile.substring(getConfigParameter("P2J_HOME")
445
                              .length()))
446
         </action>
447
         
448
         <action>mergeMap = create("java.util.HashMap")</action>
449

    
450
         <!-- read all the children of the name-map node -->
451
         <action>mergeIndex = mergeIndex.getFirstChild()</action>
452
         <while>mergeIndex != null
453
            <rule>mergeIndex.type == xml.element_node and
454
                  mergeIndex.text.equals("class-mapping")
455

    
456
               <action>
457
                  jname = xml.getAttributeValue(mergeIndex, "jname")
458
               </action>
459
               <action>
460
                  pname = fixupFileName(xml.getAttributeValue(mergeIndex, "pname"))
461
               </action>
462
               
463
               <action>mergeMap.put(pname, jname)</action>
464
            </rule>
465

    
466
            <rule>mergeIndex = mergeIndex.getNextSibling()</rule>
467
         </while>
468

    
469
         <action>
470
            mergeIndex = xmlRoot.getImmediateChild(xml.element_node, null)
471
         </action>
472
         
473
         <!-- read all the children of the name-map node -->
474
         <action>mergeIndex = mergeIndex.getFirstChild()</action>
475
         <while>mergeIndex != null
476
            <rule>mergeIndex.type == xml.element_node and
477
                  mergeIndex.text.equals("class-mapping")
478

    
479
               <action>
480
                  jname = xml.getAttributeValue(mergeIndex, "jname")
481
               </action>
482
               <action>
483
                  pname = fixupFileName(xml.getAttributeValue(mergeIndex, "pname"))
484
               </action>
485

    
486
               <rule>mergeMap.containsKey(pname)
487
                  <action>
488
                     printfln(
489
          "WARNING: Can't add merged mapping %s to %s - already mapped to %s",
490
                              pname,
491
                              mergeMap.get(pname),
492
                              jname)
493
                  </action>
494
                  
495
                  <action>mergeMap.remove(pname)</action>
496
               </rule>
497
            </rule>
498

    
499
            <rule>mergeIndex = mergeIndex.getNextSibling()</rule>
500
         </while>
501
         
502
         <!-- map the remainder merged nodes -->
503
         <action>iter = mergeMap.keySet().iterator()</action>
504
         <while>iter.hasNext()
505
            <action>pname = iter.next()</action>
506
            <action>jname = mergeMap.get(pname)</action>
507
            
508
            <action>
509
               printfln("Adding merged mapping %s to %s", pname, jname)
510
            </action>
511

    
512
            <!-- required in order to use the statements like
513
                 "run some-merged-function.p." -->
514
            <action>nmap.addMapping(pname, jname)</action>
515

    
516
            <!-- required in order to use the statements like
517
                 "s = "some-merged-function.p". run value(s)." -->
518
            <action>
519
               execLib("createMappingNode",
520
                       xmlAst,
521
                       "class-mapping",
522
                       pname,
523
                       jname)
524
            </action>
525
         </while>
526
      </rule>
527

    
528
      <!-- persist our project-wide name mapping XML file -->
529
      <rule>xml.persistTarget(xmlRoot, xmlfile, false)</rule>
530
      
531
      <!-- copy our name mapping XML file into the proper project location -->
532
      <rule>outroot = getConfigParameter("output-root")</rule>
533
      <rule>pkgroot = getConfigParameter("pkgroot")</rule>
534
      <rule>
535
         outfile = sprintf("%s%s%s%s%s",
536
                           outroot,
537
                           fileSep,
538
                           pkgroot.replaceAll("\.", quoteReplacement(fileSep)),
539
                           fileSep,
540
                           xmlfile)
541
      </rule>
542
      <rule>println(outfile)</rule>
543
      <rule>copyFile(xmlfile, outfile, true, true)</rule>
544
      
545
      <!-- persist our project-wide name mapping cache file -->
546
      <rule>nmap.saveMappings("name_map.cache")</rule>
547
      
548
   </post-rules>
549

    
550
</cfg>