1
2
3
4
5
6
7
8
9 package org.astrogrid.adql;
10
11 import org.apache.commons.logging.Log ;
12 import org.apache.commons.logging.LogFactory ;
13 import java.io.* ;
14 import java.util.*;
15 import java.text.MessageFormat;
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 public class BnfExtractor {
50
51 private static Log log = LogFactory.getLog( BnfExtractor.class ) ;
52
53 private static StringBuffer logIndent = new StringBuffer() ;
54
55 private static final String USAGE =
56 "Usage: BnfExtractor {Parameters}\n" +
57 "Parameters:\n" +
58 " -input=file-path\n" +
59 " -output=file-path\n" +
60 " -text=text-header-path\n" +
61 " -html=html-header-path\n" +
62 " -conditional=condition-tag\n" +
63 "Notes:\n" +
64 " (1) All parameter triggers can be shortened to the first letter; ie: -i,-o,-t,-h,-c.\n" +
65 " (2) The input parameter is the only mandatory one.\n" +
66 " (3) If the output file-path parameter is omitted, output is directed to standard out.\n" +
67 " (4) The text and html parameters are mutually exclusive: either text or html is produced.\n" +
68 " The path given must be to a file containing suitable header data for the BNF diagrams.\n" +
69 " (5) The conditional parameter is for selecting between various possible sets of BNF defined\n" +
70 " within the base parser's AdqlStoX.jjt file. At present, only two condition tags are\n" +
71 " available: v20+RFC and v20-AG, where v20+RFC will produce BNF at the v2.0 plus changes\n" +
72 " associated with the RFC stage, and v20-AG will produce BNF at the projected level for\n" +
73 " AstroGrid's first support of v2.0. So, a conditional parameter could be:\n" +
74 " -c=v20+RFC\n" +
75 " If no conditional parameter is present, v20+RFC is assumed.\n" +
76 " (6) Ouput files must not already exist. If you wish to overwrite,\n" +
77 " omit the output file parameter and pipe standard out." ;
78
79 private static final String TEXT_FOOTINGS =
80 "" ;
81
82 private static final String HTML_FOOTINGS =
83 "\n" +
84 "</pre>" +
85 "</body>" +
86 "</html>" ;
87
88 private static final String HTML_KEY_TEMPLATE =
89 "<a name=\"{0}\"><{0}></a>" ;
90
91 private static final String HTML_DETAIL_TEMPLATE =
92 "<<a href=\"#{0}\">{0}</a>>" ;
93
94 private static final String BNF_SINGLE = " * bnf-single" ;
95 private static final String BNF_START = " * bnf-start" ;
96 private static final String BNF_END = " * bnf-end" ;
97 private static final String BNF_TRIGGER = "bnf-" ;
98 private static final String V20_PLUS_RFC = "v20+RFC" ;
99
100 private static String formatOption = null ;
101 private static String inFilePath = null ;
102 private static String outFilePath = null ;
103 private static String headerFilePath = null ;
104 private static boolean overwrite = false ;
105 private static String[] aConditionals = null ;
106
107 private String iFormatOption = null ;
108 private boolean iOverWriteOption = false ;
109 private File inputFile ;
110 private File outputFile ;
111 private File headerFile ;
112 private FileReader reader = null ;
113 private FileReader headerReader = null ;
114 private MessageFormat keyFormat = new MessageFormat( HTML_KEY_TEMPLATE ) ;
115 private MessageFormat detailFormat = new MessageFormat( HTML_DETAIL_TEMPLATE ) ;
116 private OutputStream outputStream = null ;
117
118 private StringBuffer lineBuffer = new StringBuffer( 100 ) ;
119 private boolean inputEOF = false ;
120 private ArrayList list = new ArrayList( 256 ) ;
121 private BnfStatementFactory statementFactory = new BnfStatementFactory() ;
122
123
124
125
126 public static void main( String[] args ) {
127 if( log.isTraceEnabled() ) enterTrace ( "BnfExtractor.main" ) ;
128
129 if( retrieveArgs( args ) == false ) {
130 System.out.println() ;
131 System.out.print( USAGE ) ;
132 return ;
133 }
134
135 File inputFile = new File( inFilePath ) ;
136 File outputFile = null ;
137 File headerFile = null ;
138
139 if( inputFile.exists() == false ) {
140 System.out.println( "Input file does not exist:\n" +
141 " " + inFilePath
142 ) ;
143 return ;
144 }
145
146 if( outFilePath != null ) {
147 outputFile = new File( outFilePath ) ;
148 if( outputFile.exists() == true ) {
149 System.out.println( "Output file already exists:\n" +
150 " " + outFilePath
151 ) ;
152 return ;
153 }
154 }
155
156 if( headerFilePath != null ) {
157 headerFile = new File( headerFilePath ) ;
158 if( headerFile.exists() == false ) {
159 System.out.println( "Header file does not exist:\n"
160 + " " + headerFilePath ) ;
161 return ;
162 }
163 }
164
165 if( BnfExtractor.formatOption == null ) {
166 BnfExtractor.formatOption = "t" ;
167 }
168
169 BnfExtractor extractor = new BnfExtractor( inputFile, outputFile, formatOption, headerFile ) ;
170
171 extractor.exec() ;
172 System.out.println( "BNF extraction complete." ) ;
173 if( log.isTraceEnabled() ) exitTrace ( "BnfExtractor.main" ) ;
174 }
175
176 private static boolean retrieveArgs( String[] args ) {
177 boolean retVal = false ;
178 if( args != null && args.length > 0 ) {
179
180 for( int i=0; i<args.length; i++ ) {
181
182 if( args[i].startsWith( "-text" ) ) {
183 BnfExtractor.formatOption = "t" ;
184 if( args[i].startsWith( "-text=") ) {
185 BnfExtractor.headerFilePath = args[i].substring(6) ;
186 }
187 }
188 else if( args[i].startsWith( "-t" ) ) {
189 BnfExtractor.formatOption = "t" ;
190 if( args[i].startsWith( "-t=") ) {
191 BnfExtractor.headerFilePath = args[i].substring(3) ;
192 }
193 }
194 else if( args[i].startsWith( "-html" ) ) {
195 BnfExtractor.formatOption = "h" ;
196 if( args[i].startsWith( "-html=") ) {
197 BnfExtractor.headerFilePath = args[i].substring(6) ;
198 }
199 }
200 else if( args[i].startsWith( "-h" ) ) {
201 BnfExtractor.formatOption = "h" ;
202 if( args[i].startsWith( "-h=") ) {
203 BnfExtractor.headerFilePath = args[i].substring(3) ;
204 }
205 }
206 else if( args[i].startsWith( "-input=" ) ) {
207 BnfExtractor.inFilePath = args[i].substring(7) ;
208 }
209 else if( args[i].startsWith( "-i=" ) ) {
210 BnfExtractor.inFilePath = args[i].substring(2) ;
211 }
212 else if( args[i].startsWith( "-output=" ) ) {
213 BnfExtractor.outFilePath = args[i].substring(8) ;
214 }
215 else if( args[i].startsWith( "-o=" ) ) {
216 BnfExtractor.outFilePath = args[i].substring(3) ;
217 if( log.isDebugEnabled() ){
218 log.debug( "o=" + BnfExtractor.outFilePath ) ;
219 }
220 }
221 else if( args[i].startsWith( "-conditional=") ) {
222 extractConditionals( args[i].substring(13) ) ;
223 }
224 else if( args[i].startsWith( "-c=") ) {
225 extractConditionals( args[i].substring(3) ) ;
226 }
227
228 }
229 if( BnfExtractor.inFilePath != null ) {
230 retVal = true ;
231 if( aConditionals == null ) {
232 aConditionals = new String[] { V20_PLUS_RFC } ;
233 }
234 else if( aConditionals.length == 0 ) {
235 aConditionals = new String[] { V20_PLUS_RFC } ;
236 }
237 }
238 }
239 return retVal ;
240 }
241
242 private static void extractConditionals( String conditionals ) {
243 if( conditionals == null ) {
244 aConditionals = new String[0] ;
245 }
246 else if( conditionals.length() == 0 ) {
247 aConditionals = new String[0] ;
248 }
249 else {
250 aConditionals = conditionals.split( "," ) ;
251 }
252 if( log.isDebugEnabled() ) {
253 StringBuffer b = new StringBuffer() ;
254 b.append( "Conditionals: " ) ;
255 for( int i=0; i<aConditionals.length; i++ ) {
256 b.append( aConditionals[i] ).append( ' ' ) ;
257 }
258 }
259 }
260
261 private static boolean isConditional( String c ) {
262 String[] ac = c.split( "," ) ;
263 for( int i=0; i<aConditionals.length; i++ ) {
264 for( int j=0; j<ac.length; j++ ) {
265 if( aConditionals[i].equalsIgnoreCase( ac[j]) )
266 return true ;
267 }
268 }
269 return false ;
270 }
271
272 public BnfExtractor( File inputFile, File outputFile, String format, File headerFile ) {
273 if( log.isTraceEnabled() ) enterTrace ( "BnfExtractor(File, File, String)" ) ;
274 this.inputFile = inputFile ;
275 this.outputFile = outputFile ;
276 if( this.outputFile != null ) {
277 try {
278 this.outputStream = new FileOutputStream( outputFile ) ;
279 }
280 catch( FileNotFoundException fnfex ) {
281 fnfex.printStackTrace() ;
282 }
283 }
284 else {
285 this.outputStream = System.out ;
286 }
287 this.iFormatOption = format ;
288 this.headerFile = headerFile ;
289 if( log.isTraceEnabled() ) exitTrace ( "BnfExtractor(File, File, String)" ) ;
290 }
291
292 public BnfExtractor( File inputFile, String format ) {
293 this( inputFile, null, format, null ) ;
294 }
295
296 public void exec() {
297 if( log.isTraceEnabled() ) enterTrace ( "BnfExtractor.exec()" ) ;
298 openFiles() ;
299 consumeInputFile() ;
300 produceOutput() ;
301 if( log.isTraceEnabled() ) exitTrace ( "BnfExtractor.exec()" ) ;
302 }
303
304 private void openFiles() {
305 if( log.isTraceEnabled() ) enterTrace ( "BnfExtractor.openFiles()" ) ;
306 try {
307 reader = new FileReader( inputFile ) ;
308 headerReader = new FileReader( headerFile ) ;
309 }
310 catch( Exception iox ) {
311 System.out.println( iox.getLocalizedMessage() ) ;
312 }
313 finally {
314 if( log.isTraceEnabled() ) exitTrace ( "BnfExtractor.openFiles()" ) ;
315 }
316 }
317
318 private void consumeInputFile() {
319 if( log.isTraceEnabled() ) enterTrace ( "BnfExtractor.consumeInputFile()" ) ;
320 while( isInputEOF() == false ) {
321 processOneStatement() ;
322 }
323 validateInputFile() ;
324
325
326
327
328
329
330 if( log.isTraceEnabled() ) exitTrace ( "BnfExtractor.consumeInputFile()" ) ;
331 }
332
333 private void validateInputFile() {
334 HashMap map = new HashMap() ;
335 HashSet errors = new HashSet() ;
336 ListIterator it = list.listIterator() ;
337 while( it.hasNext() ) {
338 BnfStatement bnf = (BnfStatement)it.next() ;
339 map.put( bnf.key, bnf ) ;
340 }
341 it = list.listIterator() ;
342 while( it.hasNext() ) {
343 BnfStatement bnf = (BnfStatement)it.next() ;
344 checkStatement( bnf, map, errors ) ;
345 }
346 if( errors.size() > 0 ) {
347 String[] errArray = new String[ errors.size() ] ;
348 errArray = (String[])errors.toArray( errArray ) ;
349 Arrays.sort( errArray ) ;
350 for( int i=0; i<errArray.length; i++ ) {
351 log.error( errArray[i] ) ;
352 }
353 }
354 }
355
356 private void checkStatement( BnfStatement bnf, HashMap map, HashSet errors ) {
357 String[] rKeys = bnf.getKeysOfReferencedElements() ;
358 for( int i=0; i<rKeys.length; i++ ) {
359 if( !map.containsKey( rKeys[i] ) ) {
360 errors.add( "BNF Statement missing from input: <" + rKeys[i] + ">" ) ;
361 }
362 }
363 }
364
365 private void produceOutput() {
366 try {
367 if( iFormatOption.equals( "t" ) ) {
368 produceText() ;
369 }
370 else {
371 produceHtml() ;
372 }
373 }
374 catch( IOException iox ) {
375 iox.printStackTrace() ;
376 }
377
378 }
379
380 private void processOneStatement() {
381 if( log.isTraceEnabled() ) enterTrace ( "BnfExtractor.processOneStatement()" ) ;
382 String line = readAheadToStatement() ;
383 String debugLine = line ;
384 try {
385 if( isBnfSingle( line ) ) {
386 list.add( statementFactory.newInstance( line.substring( BNF_SINGLE.length() ) ) ) ;
387 }
388 else if( isBnfStart( line ) ) {
389 ArrayList lineArray= new ArrayList() ;
390 line = readLine() ;
391 while( !isInputEOF() && !isBnfEnd( line ) ) {
392 lineArray.add( line.substring(2) ) ;
393 line = readLine() ;
394 }
395 if( lineArray.size() > 0 ) {
396 list.add( statementFactory.newInstance( (String[])lineArray.toArray( new String[ lineArray.size() ] ) ) ) ;
397 }
398 }
399 }
400 catch( InvalidBnfStatementException ibsex ) {
401 System.out.println( ibsex.getLocalizedMessage() ) ;
402 }
403 catch( Throwable ex ) {
404 log.error( "debugLine: " + debugLine, ex ) ;
405 }
406 finally {
407 if( log.isTraceEnabled() ) exitTrace ( "BnfExtractor.processOneStatement()" ) ;
408 }
409 }
410
411 private String readAheadToStatement() {
412 if( log.isTraceEnabled() ) enterTrace ( "BnfExtractor.readAheadToStatement()" ) ;
413 String line = readLine() ;
414 while( !isInputEOF() && !isBnfTrigger( line ) ) {
415 line = readLine() ;
416 }
417 if( log.isTraceEnabled() ) exitTrace ( "BnfExtractor.readAheadToStatement()" ) ;
418 return line ;
419 }
420
421 private boolean isBnfTrigger( String line ) {
422
423
424 if( line.startsWith( BNF_SINGLE ) ) {
425 return true ;
426 }
427
428
429 else if( line.startsWith( BNF_START ) ) {
430
431
432 if( BnfExtractor.aConditionals.length > 0 ) {
433 String line2 = line.trim() ;
434
435
436 if( !BNF_START.endsWith( line2 ) ) {
437 if( isConditional( line2.substring( BNF_START.length()-1 ).trim() ) ) {
438 return true ;
439 }
440 return false ;
441 }
442 return true ;
443 }
444 return true ;
445 }
446 return false ;
447
448 }
449
450 private String readLine() {
451
452 emptyLineBuffer() ;
453 try {
454 int ch = reader.read() ;
455 readLoop : {
456 while( ch != -1 ) {
457 lineBuffer.append( (char)ch ) ;
458 if( ch == '\n' ) {
459 break readLoop ;
460 }
461 ch = reader.read() ;
462 }
463 setInputEOF() ;
464 }
465 }
466 catch( IOException iox ) {
467 System.out.println( iox.getLocalizedMessage() ) ;
468 }
469 finally {
470
471
472
473
474
475
476 }
477 return lineBuffer.toString() ;
478 }
479
480 private void produceText() throws IOException {
481 writeHeader() ;
482 BnfStatement[] sArray = getSortedStatementArray() ;
483 for( int i=0; i<sArray.length; i++ ) {
484 outputStream.write( sArray[i].toText().getBytes() ) ;
485 outputStream.write( '\n' ) ;
486 }
487 outputStream.write( TEXT_FOOTINGS.getBytes() ) ;
488 }
489
490 private void produceHtml() throws IOException {
491 writeHeader() ;
492 BnfStatement[] sArray = getSortedStatementArray() ;
493 for( int i=0; i<sArray.length; i++ ) {
494 outputStream.write( sArray[i].toHtml().getBytes() ) ;
495 outputStream.write( '\n' ) ;
496 }
497 outputStream.write( HTML_FOOTINGS.getBytes() ) ;
498 }
499
500 private void writeHeader() {
501 try {
502 int ch = headerReader.read() ;
503 while( ch != -1 ) {
504 outputStream.write( ch ) ;
505 ch = headerReader.read();
506 }
507 }
508 catch( IOException iox ) {
509 System.out.println( iox.getLocalizedMessage() ) ;
510 }
511 finally {
512
513 }
514 }
515
516 private void emptyLineBuffer() {
517 if( lineBuffer.length() > 0 ) {
518 lineBuffer.delete( 0, lineBuffer.length() ) ;
519 }
520 }
521
522 private void setInputEOF() {
523 this.inputEOF = true ;
524 }
525
526 private boolean isInputEOF() {
527 return this.inputEOF ;
528 }
529
530 private boolean isBnfSingle( String line ) {
531 if( line.indexOf( BNF_SINGLE ) != -1 )
532 return true ;
533 return false ;
534 }
535
536 private boolean isBnfStart( String line ) {
537 if( line.indexOf( BNF_START ) != -1 ) {
538 return true ;
539 }
540 return false ;
541 }
542
543 private boolean isBnfEnd( String line ) {
544 if( line.indexOf( BNF_END ) != -1 )
545 return true ;
546 return false ;
547 }
548
549 private BnfStatement[] getSortedStatementArray() {
550 BnfStatement[] arrayStatement = new BnfStatement[ list.size() ] ;
551 arrayStatement = (BnfStatement[])list.toArray( arrayStatement ) ;
552 Arrays.sort( arrayStatement
553 , new Comparator() {
554 public int compare( Object o1, Object o2 ) {
555 return ((BnfStatement)o1).compare((BnfStatement)o2) ;
556 }
557 } ) ;
558 return arrayStatement ;
559 }
560
561 class BnfStatement {
562
563 String statementsAsString ;
564 String key ;
565
566 BnfStatement( String[] statements, String key ) {
567 if( log.isDebugEnabled() ) {
568 log.debug( "BnfStatement.key: " + key ) ;
569 }
570 this.key = key ;
571 StringBuffer buffer = new StringBuffer() ;
572 for( int i=0; i<statements.length; i++ ) {
573 buffer.append( statements[i] ) ;
574 }
575 this.statementsAsString = buffer.toString() ;
576 }
577
578 private BnfStatement() {}
579
580
581
582
583 public boolean equals( Object that ) {
584 if( that instanceof BnfStatement ) {
585 BnfStatement arg = (BnfStatement)that ;
586 if( this.key.equals( arg.key ) )
587 return true ;
588 }
589 return false ;
590 }
591
592 public int compare( BnfStatement s ) {
593 return this.key.compareTo( s.key ) ;
594 }
595
596 public String toString() {
597 return statementsAsString ;
598 }
599
600 public String toText() {
601 return toString() ;
602 }
603
604 public String[] getKeysOfReferencedElements() {
605 ArrayList elements = new ArrayList() ;
606 ArrayList psList = getMatchedPairsAndSingletons() ;
607 ListIterator it = psList.listIterator() ;
608
609
610 it.next() ;
611 while( it.hasNext() ) {
612 Object o = it.next() ;
613 if( o instanceof Pair ) {
614 Pair p = (Pair)o ;
615 String elementName = statementsAsString.substring( p.x+1, p.y ) ;
616 elements.add( elementName ) ;
617 }
618 }
619 String[] elementArray = new String[ elements.size() ] ;
620 elementArray = (String[])elements.toArray( elementArray ) ;
621 return elementArray ;
622 }
623
624 public String toHtml() {
625 String s = statementsAsString ;
626 StringBuffer buffer = new StringBuffer() ;
627 ArrayList psList = getMatchedPairsAndSingletons() ;
628 ListIterator it = psList.listIterator() ;
629
630
631
632 Pair p = (Pair)it.next() ;
633
634
635 buffer.append( s.substring( 0, p.x ) ) ;
636
637
638 String elementName = s.substring( p.x+1, p.y ) ;
639 String htmlizedElement =
640 keyFormat.format( new String[]{elementName}, new StringBuffer(), null ).toString() ;
641 buffer.append( htmlizedElement ) ;
642
643
644
645 int current = p.y + 1 ;
646 while( it.hasNext() ) {
647 Object o = it.next() ;
648 if( o instanceof Pair ) {
649 p = (Pair)o ;
650
651 buffer.append( s.substring( current, p.x ) ) ;
652
653 elementName = s.substring( p.x+1, p.y ) ;
654 htmlizedElement =
655 detailFormat.format( new String[]{elementName}, new StringBuffer(), null ).toString() ;
656 buffer.append( htmlizedElement ) ;
657 current = p.y + 1 ;
658 }
659 else {
660 int i = ((Integer)o).intValue() ;
661
662 if( current < i ) {
663 buffer.append( s.substring( current, i ) ) ;
664 current = i ;
665 }
666 if( s.charAt(i) == '>' ) {
667 buffer.append( ">" ) ;
668 }
669 else {
670 buffer.append( "<" ) ;
671 }
672 current++ ;
673 }
674 }
675
676
677
678 if( current != s.length() ) {
679 String remainder = s.substring( current ) ;
680 if( log.isDebugEnabled() ) {
681 log.debug( "Remainder: " + remainder ) ;
682 }
683 remainder = remainder.replaceAll( "<", "<" ) ;
684 remainder = remainder.replaceAll( ">", ">" ) ;
685 buffer.append( remainder ) ;
686 }
687 return buffer.toString() ;
688 }
689
690 private ArrayList getMatchedPairsAndSingletons() {
691 ArrayList psList = new ArrayList() ;
692 ArrayList indices = getIndicesOfLtGt() ;
693 Integer[] x = new Integer[ indices.size() ] ;
694 String s = statementsAsString ;
695 x = (Integer[])indices.toArray( x ) ;
696 Integer candidateLt = null ;
697 Integer candidateGt = null ;
698 for( int i=0; i<x.length; i++ ) {
699 if( s.charAt(x[i].intValue() ) == '<' ) {
700 if( candidateLt == null ) {
701 candidateLt = x[i] ;
702 }
703 else {
704 psList.add( candidateLt ) ;
705 candidateLt = x[i] ;
706 }
707 }
708 else if( s.charAt(x[i].intValue() ) == '>' ){
709 if( candidateGt == null ) {
710 candidateGt = x[i] ;
711 }
712 else {
713 psList.add( x[i] ) ;
714 }
715 }
716 if( candidateLt != null && candidateGt != null ) {
717 if( candidateLt.intValue()+1 == candidateGt.intValue() ) {
718 psList.add( candidateLt ) ;
719 psList.add( candidateGt ) ;
720 }
721 else {
722 psList.add( new Pair( candidateLt, candidateGt ) ) ;
723 }
724 candidateLt = candidateGt = null ;
725 }
726 }
727 return psList ;
728 }
729
730 private ArrayList getIndicesOfLtGt() {
731 ArrayList listLtGt = new ArrayList() ;
732 for( int i=0; i<statementsAsString.length(); i++ ) {
733 char c = statementsAsString.charAt(i) ;
734 if( c == '!' && statementsAsString.charAt(i+1) == '!' ) {
735 break ;
736 }
737 if( c == '<' || c == '>' )
738 listLtGt.add( new Integer(i) ) ;
739 }
740 return listLtGt ;
741 }
742
743 }
744
745 class BnfStatementFactory {
746
747 BnfStatement newInstance( String statement ) throws InvalidBnfStatementException {
748 return new BnfStatement( new String[] { statement }, extractKey( statement ) ) ;
749 }
750
751 BnfStatement newInstance( String[] statementArray ) throws InvalidBnfStatementException {
752 return new BnfStatement( statementArray, extractKey( statementArray[0] ) ) ;
753 }
754
755 private String extractKey( String firstLine ) throws InvalidBnfStatementException {
756 int indexFrom = firstLine.indexOf( '<' ) ;
757 int indexTo = firstLine.indexOf( '>', indexFrom ) ;
758 int indexOfDefinitionOp = firstLine.indexOf( "::=", indexTo ) ;
759
760 if( indexFrom == -1 || indexTo == -1 || indexOfDefinitionOp == -1 ) {
761 String message =
762 "InvalidBnfStatementException:\n" +
763 " " + firstLine ;
764 throw new InvalidBnfStatementException( message ) ;
765 }
766
767 return firstLine.substring( indexFrom+1, indexTo ) ;
768 }
769
770 }
771
772 class InvalidBnfStatementException extends Exception {
773 public InvalidBnfStatementException(String message) {
774 super(message);
775 }
776 }
777
778 class Pair {
779 public int x ;
780 public int y ;
781
782 Pair( Integer X, Integer Y ) {
783 x = X.intValue() ;
784 y = Y.intValue() ;
785 }
786 }
787
788 private static void enterTrace( String entry ) {
789 log.debug( logIndent.toString() + "enter: " + entry ) ;
790 indentPlus() ;
791 }
792
793 private static void exitTrace( String entry ) {
794 indentMinus() ;
795 log.debug( logIndent.toString() + "exit : " + entry ) ;
796 }
797
798 private static void indentPlus() {
799 logIndent.append( ' ' ) ;
800 }
801
802 private static void indentMinus() {
803 logIndent.deleteCharAt( logIndent.length()-1 ) ;
804 }
805
806 }
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899