1 package org.apache.maven.jxr;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 import org.apache.commons.lang.StringUtils;
34 import org.apache.maven.jxr.pacman.ClassType;
35 import org.apache.maven.jxr.pacman.FileManager;
36 import org.apache.maven.jxr.pacman.ImportType;
37 import org.apache.maven.jxr.pacman.JavaFile;
38 import org.apache.maven.jxr.pacman.PackageManager;
39 import org.apache.maven.jxr.pacman.PackageType;
40 import org.apache.maven.jxr.util.SimpleWordTokenizer;
41 import org.apache.maven.jxr.util.StringEntry;
42
43 import java.io.BufferedReader;
44 import java.io.File;
45 import java.io.FileInputStream;
46 import java.io.FileOutputStream;
47 import java.io.FileReader;
48 import java.io.FileWriter;
49 import java.io.IOException;
50 import java.io.InputStreamReader;
51 import java.io.ObjectInputStream;
52 import java.io.ObjectOutputStream;
53 import java.io.OutputStreamWriter;
54 import java.io.PrintWriter;
55 import java.io.Reader;
56 import java.io.Serializable;
57 import java.io.Writer;
58 import java.util.Hashtable;
59 import java.util.Locale;
60 import java.util.Vector;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 public class JavaCodeTransform
91 implements Serializable
92 {
93
94
95
96
97
98
99
100 public static final boolean LINE_NUMBERS = true;
101
102
103
104
105 public static final String COMMENT_START = "<em class=\"jxr_comment\">";
106
107
108
109
110 public static final String COMMENT_END = "</em>";
111
112
113
114
115 public static final String JAVADOC_COMMENT_START = "<em class=\"jxr_javadoccomment\">";
116
117
118
119
120 public static final String JAVADOC_COMMENT_END = "</em>";
121
122
123
124
125 public static final String STRING_START = "<span class=\"jxr_string\">";
126
127
128
129
130 public static final String STRING_END = "</span>";
131
132
133
134
135 public static final String RESERVED_WORD_START = "<strong class=\"jxr_keyword\">";
136
137
138
139
140 public static final String RESERVED_WORD_END = "</strong>";
141
142
143
144
145 public static final String STYLESHEET_FILENAME = "stylesheet.css";
146
147
148
149
150 public static final String[] VALID_URI_SCHEMES = {"http://", "mailto:"};
151
152
153
154
155
156 public static final char[] VALID_URI_CHARS = {'?', '+', '%', '&', ':', '/', '.', '@', '_', ';', '=', '$', ',', '-',
157 '!', '~', '*', '\'', '(', ')'};
158
159
160
161
162
163
164
165
166 private Hashtable reservedWords = new Hashtable();
167
168
169
170
171 private boolean inMultiLineComment = false;
172
173
174
175
176 private boolean inJavadocComment = false;
177
178
179
180
181 private String currentFilename = null;
182
183
184
185
186 private String revision = null;
187
188
189
190
191 private String sourcefile = null;
192
193
194
195
196 private String destfile = null;
197
198
199
200
201 private String sourcedir = null;
202
203
204
205
206 private String inputEncoding = null;
207
208
209
210
211 private String outputEncoding = null;
212
213
214
215
216 private Locale locale = null;
217
218
219
220
221 private String javadocLinkDir;
222
223
224
225
226 private PackageManager packageManager;
227
228
229
230
231 private FileManager fileManager;
232
233
234
235
236
237
238
239
240
241
242 public JavaCodeTransform( PackageManager packageManager )
243 {
244 this.packageManager = packageManager;
245 loadHash();
246 this.fileManager = packageManager.getFileManager();
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260 public final String syntaxHighlight( String line )
261 {
262 return htmlFilter( line );
263 }
264
265
266
267
268
269
270
271 public void appendHeader( PrintWriter out )
272 {
273 String outputEncoding = this.outputEncoding;
274 if ( outputEncoding == null )
275 {
276 outputEncoding = "ISO-8859-1";
277 }
278
279
280 out.println(
281 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" );
282 out.print( "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"" );
283 out.print( locale );
284 out.print( "\" lang=\"" );
285 out.print( locale );
286 out.println( "\">" );
287 out.print( "<head>" );
288 out.print( "<meta http-equiv=\"content-type\" content=\"text/html; charset=" );
289 out.print( outputEncoding );
290 out.println( "\" />" );
291
292
293 out.print( "<title>" );
294 try
295 {
296 JavaFile javaFile = fileManager.getFile( this.getCurrentFilename() );
297
298 if ( javaFile.getClassType() != null && javaFile.getClassType().getFilename() != null )
299 {
300 out.print( javaFile.getClassType().getFilename() );
301 }
302 else
303 {
304 out.print( this.getCurrentFilename() );
305 }
306 out.print( " " );
307 }
308 catch ( IOException e )
309 {
310 e.printStackTrace();
311 }
312 finally
313 {
314 out.println( "xref</title>" );
315 }
316
317
318 out.print( "<link type=\"text/css\" rel=\"stylesheet\" href=\"" );
319 out.print( this.getPackageRoot() );
320 out.print( STYLESHEET_FILENAME );
321 out.println( "\" />" );
322
323 out.println( "</head>" );
324 out.println( "<body>" );
325 out.print( this.getFileOverview() );
326
327
328 out.println( "<pre>" );
329 }
330
331
332
333
334
335
336
337 public final void appendFooter( PrintWriter out, String bottom )
338 {
339 out.println( "</pre>" );
340 out.println( "<hr/>" );
341 out.print( "<div id=\"footer\">" );
342 out.print( bottom );
343 out.println( "</div>" );
344 out.println( "</body>" );
345 out.println( "</html>" );
346 }
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361 public final void transform( Reader sourceReader, Writer destWriter, Locale locale, String inputEncoding,
362 String outputEncoding, String javadocLinkDir, String revision, String bottom )
363 throws IOException
364 {
365 this.locale = locale;
366 this.inputEncoding = inputEncoding;
367 this.outputEncoding = outputEncoding;
368 this.javadocLinkDir = javadocLinkDir;
369 this.revision = revision;
370
371 BufferedReader in = new BufferedReader( sourceReader );
372
373 PrintWriter out = new PrintWriter( destWriter );
374
375 String line = "";
376
377 appendHeader( out );
378
379 int linenumber = 1;
380 while ( ( line = in.readLine() ) != null )
381 {
382 if ( LINE_NUMBERS )
383 {
384 out.print( "<a class=\"jxr_linenumber\" name=\"L" + linenumber + "\" " + "href=\"#L" + linenumber + "\">" + linenumber
385 + "</a>" + getLineWidth( linenumber ) );
386 }
387
388 out.println( this.syntaxHighlight( line ) );
389
390 ++linenumber;
391 }
392
393 appendFooter( out, bottom );
394
395 out.flush();
396 }
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411 public final void transform( String sourcefile, String destfile, Locale locale, String inputEncoding,
412 String outputEncoding, String javadocLinkDir, String revision, String bottom )
413 throws IOException
414 {
415 this.setCurrentFilename( sourcefile );
416
417 this.sourcefile = sourcefile;
418 this.destfile = destfile;
419
420
421 new File( new File( destfile ).getParent() ).mkdirs();
422
423 Reader fr = null;
424 Writer fw = null;
425 try
426 {
427 if ( inputEncoding != null )
428 {
429 fr = new InputStreamReader( new FileInputStream( sourcefile ), inputEncoding );
430 }
431 else
432 {
433 fr = new FileReader( sourcefile );
434 }
435 if ( outputEncoding != null )
436 {
437 fw = new OutputStreamWriter( new FileOutputStream( destfile ), outputEncoding );
438 }
439 else
440 {
441 fw = new FileWriter( destfile );
442 }
443
444 transform( fr, fw, locale, inputEncoding, outputEncoding, javadocLinkDir, revision, bottom );
445 }
446 catch ( RuntimeException e )
447 {
448 System.out.println( "Unable to processPath " + sourcefile + " => " + destfile );
449 throw e;
450 }
451 finally
452 {
453 if ( fr != null )
454 {
455 try
456 {
457 fr.close();
458 }
459 catch ( Exception ex )
460 {
461 ex.printStackTrace();
462 }
463 }
464 if ( fw != null )
465 {
466 try
467 {
468 fw.close();
469 }
470 catch ( Exception ex )
471 {
472 ex.printStackTrace();
473 }
474 }
475 }
476 }
477
478
479
480
481
482
483 public final String getCurrentFilename()
484 {
485 return this.currentFilename;
486 }
487
488
489
490
491
492
493 public final void setCurrentFilename( String filename )
494 {
495 this.currentFilename = filename;
496 }
497
498
499
500
501
502
503
504 public final String getPackageRoot()
505 {
506 StringBuffer buff = new StringBuffer();
507
508 JavaFile jf = null;
509
510 try
511 {
512 jf = fileManager.getFile( this.getCurrentFilename() );
513 }
514 catch ( IOException e )
515 {
516 e.printStackTrace();
517 return null;
518 }
519
520 String current = jf.getPackageType().getName();
521
522 int count = this.getPackageCount( current );
523
524 for ( int i = 0; i < count; ++i )
525 {
526 buff.append( "../" );
527 }
528
529 return buff.toString();
530 }
531
532
533
534
535
536
537
538 public final String uriFilter( String line )
539 {
540 for ( int i = 0; i < VALID_URI_SCHEMES.length; ++i )
541 {
542 String scheme = VALID_URI_SCHEMES[i];
543
544 int index = line.indexOf( scheme );
545
546 if ( index != -1 )
547 {
548 int start = index;
549 int end = -1;
550
551 for ( int j = start; j < line.length(); ++j )
552 {
553 char current = line.charAt( j );
554
555 if ( !Character.isLetterOrDigit( current ) && isInvalidURICharacter( current ) )
556 {
557 end = j;
558 break;
559 }
560
561 end = j;
562 }
563
564
565
566
567 if ( end != -1 )
568 {
569 String uri = line.substring( start, end );
570
571 line = StringUtils.replace( line, uri,
572 "<a href=\"" + uri + "\" target=\"alexandria_uri\">" + uri + "</a>" );
573 }
574 }
575 }
576
577
578 if ( !inMultiLineComment && !inJavadocComment )
579 {
580 return jxrFilter( line );
581 }
582
583 return line;
584 }
585
586
587
588
589
590
591 public final String getRevision()
592 {
593 return this.revision;
594 }
595
596
597
598
599
600
601 public final String getSourcefile()
602 {
603 return this.sourcefile;
604 }
605
606
607
608
609
610
611 public final String getDestfile()
612 {
613 return this.destfile;
614 }
615
616
617
618
619
620
621 public final String getSourceDirectory()
622 {
623 return this.sourcedir;
624 }
625
626
627
628
629
630
631
632
633
634 public final String xrLine( String line, String packageName, ClassType classType )
635 {
636 StringBuffer buff = new StringBuffer( line );
637
638 String link = null;
639 String find = null;
640 String href = null;
641
642 if ( classType != null )
643 {
644 href = this.getHREF( packageName, classType );
645 find = classType.getName();
646 }
647 else
648 {
649 href = this.getHREF( packageName );
650 find = packageName;
651 }
652
653
654 link = "<a href=\"" + href + "\">" + find + "</a>";
655
656
657
658
659
660
661 String replace = link;
662 StringEntry[] tokens = SimpleWordTokenizer.tokenize( buff.toString(), find );
663
664 for ( int l = 0; l < tokens.length; ++l )
665 {
666
667 int start = tokens[l].getIndex();
668 int end = tokens[l].getIndex() + find.length();
669
670 buff.replace( start, end, replace );
671
672 }
673
674 return buff.toString();
675 }
676
677
678
679
680
681
682
683
684 public final String xrLine( String line, String packageName )
685 {
686 String href = this.getHREF( packageName );
687
688 String find = packageName;
689
690
691 String link = "<a href=\"" + href + "\">" + find + "</a>";
692
693 return StringUtils.replace( line, find, link );
694 }
695
696
697
698
699
700
701
702
703
704
705
706 private final String htmlFilter( String line )
707 {
708 if ( line == null || line.equals( "" ) )
709 {
710 return "";
711 }
712 line = replace( line, "&", "&" );
713 line = replace( line, "<", "<" );
714 line = replace( line, ">", ">" );
715 line = replace( line, "\\\\", "\\" );
716 line = replace( line, "\\\"", "\\"" );
717 line = replace( line, "'\"'", "'"'" );
718 return ongoingMultiLineCommentFilter( line );
719 }
720
721
722
723
724
725
726
727
728
729 private final String ongoingMultiLineCommentFilter( String line )
730 {
731 if ( line == null || line.equals( "" ) )
732 {
733 return "";
734 }
735 final String[] tags =
736 inJavadocComment
737 ? new String[] { JAVADOC_COMMENT_START, JAVADOC_COMMENT_END } :
738 inMultiLineComment
739 ? new String[] { COMMENT_START, COMMENT_END } :
740 null;
741
742 if ( tags == null )
743 {
744
745 return inlineCommentFilter( line );
746 }
747
748 int index = line.indexOf( "*/" );
749
750
751 String comment = uriFilter( index < 0 ? line : line.substring( 0, index ) );
752 if ( index >= 0 )
753 {
754 inJavadocComment = false;
755 inMultiLineComment = false;
756 }
757 StringBuilder buf = new StringBuilder( tags[0] ).append(
758 comment );
759
760 if ( index >= 0 )
761 {
762 buf.append( "*/" );
763 }
764 buf.append( tags[1] );
765
766 if ( index >= 0 && line.length() > index + 2 )
767 {
768 buf.append( inlineCommentFilter( line.substring( index + 2 ) ) );
769 }
770 return buf.toString();
771 }
772
773
774
775
776
777
778
779
780
781
782
783
784 private final String inlineCommentFilter( String line )
785 {
786
787
788
789 if ( line == null || line.equals( "" ) )
790 {
791 return "";
792 }
793 int index;
794 if ( ( index = line.indexOf( "//" ) ) >= 0 && !isInsideString( line, index ) )
795 {
796 return new StringBuffer(
797 beginMultiLineCommentFilter( line.substring( 0, index ) ) )
798 .append( COMMENT_START )
799 .append( line.substring( index ) )
800 .append( COMMENT_END )
801 .toString();
802 }
803
804 return beginMultiLineCommentFilter( line );
805 }
806
807
808
809
810
811
812
813
814
815 private final String beginMultiLineCommentFilter( String line )
816 {
817
818
819
820 if ( line == null || line.equals( "" ) )
821 {
822 return "";
823 }
824
825 int index;
826
827 if ( ( index = line.indexOf( "/*" ) ) > -1 && !isInsideString( line, index ) )
828 {
829 String fromIndex = line.substring( index );
830 if ( fromIndex.startsWith( "/**" )
831 && !( fromIndex.startsWith( "/**/" ) ) )
832 {
833 inJavadocComment = true;
834 } else {
835 inMultiLineComment = true;
836 }
837
838
839
840
841 return new StringBuilder(
842 stringFilter( line.substring( 0, index ) ) ).append(
843 ongoingMultiLineCommentFilter( fromIndex ) ).toString();
844 }
845
846
847
848 else
849 {
850 return stringFilter( line );
851 }
852 }
853
854
855
856
857
858
859
860 private final String stringFilter( String line )
861 {
862 if ( line == null || line.equals( "" ) )
863 {
864 return "";
865 }
866 StringBuffer buf = new StringBuffer();
867 if ( line.indexOf( "\"" ) <= -1 )
868 {
869 return keywordFilter( line );
870 }
871 int start = 0;
872 int startStringIndex = -1;
873 int endStringIndex = -1;
874 int tempIndex;
875
876 while ( ( tempIndex = line.indexOf( "\"" ) ) > -1 )
877 {
878
879 if ( startStringIndex == -1 )
880 {
881 startStringIndex = 0;
882 buf.append( stringFilter( line.substring( start, tempIndex ) ) );
883 buf.append( STRING_START ).append( "\"" );
884 line = line.substring( tempIndex + 1 );
885 }
886
887 else
888 {
889 startStringIndex = -1;
890 endStringIndex = tempIndex;
891 buf.append( line.substring( 0, endStringIndex + 1 ) );
892 buf.append( STRING_END );
893 line = line.substring( endStringIndex + 1 );
894 }
895 }
896
897 buf.append( keywordFilter( line ) );
898
899 return buf.toString();
900 }
901
902
903
904
905
906
907
908 private final String keywordFilter( String line )
909 {
910 final String CLASS_KEYWORD = "class";
911
912 if ( line == null || line.equals( "" ) )
913 {
914 return "";
915 }
916 StringBuffer buf = new StringBuffer();
917 int i = 0;
918 char ch;
919 StringBuffer temp = new StringBuffer();
920 while ( i < line.length() )
921 {
922 temp.setLength( 0 );
923 ch = line.charAt( i );
924 while ( i < line.length() && ( ( ch >= 65 && ch <= 90 ) || ( ch >= 97 && ch <= 122 ) ) )
925 {
926 temp.append( ch );
927 i++;
928 if ( i < line.length() )
929 {
930 ch = line.charAt( i );
931 }
932 }
933 String tempString = temp.toString();
934
935
936 if ( CLASS_KEYWORD.equals( tempString ) && ch == '=' )
937 {
938 i++;
939 }
940 else if ( reservedWords.containsKey( tempString ) )
941 {
942 StringBuffer newLine = new StringBuffer( line.substring( 0, i - tempString.length() ) );
943 newLine.append( RESERVED_WORD_START );
944 newLine.append( tempString );
945 newLine.append( RESERVED_WORD_END );
946 newLine.append( line.substring( i ) );
947 line = newLine.toString();
948 i += ( RESERVED_WORD_START.length() + RESERVED_WORD_END.length() );
949 }
950 else
951 {
952 i++;
953 }
954 }
955 buf.append( line );
956
957 return uriFilter( buf.toString() );
958 }
959
960
961
962
963
964
965
966
967
968 private final String replace( String line, String oldString, String newString )
969 {
970 int i = 0;
971 while ( ( i = line.indexOf( oldString, i ) ) >= 0 )
972 {
973 line = ( new StringBuffer().append( line.substring( 0, i ) ).append( newString ).append(
974 line.substring( i + oldString.length() ) ) ).toString();
975 i += newString.length();
976 }
977 return line;
978 }
979
980
981
982
983
984
985
986
987
988 private final boolean isInsideString( String line, int position )
989 {
990 if ( line.indexOf( '"' ) < 0 )
991 {
992 return false;
993 }
994 int index;
995 String left = line.substring( 0, position );
996 String right = line.substring( position );
997 int leftCount = 0;
998 int rightCount = 0;
999 while ( ( index = left.indexOf( '"' ) ) > -1 )
1000 {
1001 leftCount++;
1002 left = left.substring( index + 1 );
1003 }
1004 while ( ( index = right.indexOf( '"' ) ) > -1 )
1005 {
1006 rightCount++;
1007 right = right.substring( index + 1 );
1008 }
1009 return ( rightCount % 2 != 0 && leftCount % 2 != 0 );
1010 }
1011
1012
1013
1014
1015 private final void loadHash()
1016 {
1017 reservedWords.put( "abstract", "abstract" );
1018 reservedWords.put( "do", "do" );
1019 reservedWords.put( "inner", "inner" );
1020 reservedWords.put( "public", "public" );
1021 reservedWords.put( "var", "var" );
1022 reservedWords.put( "boolean", "boolean" );
1023 reservedWords.put( "continue", "continue" );
1024 reservedWords.put( "int", "int" );
1025 reservedWords.put( "return", "return" );
1026 reservedWords.put( "void", "void" );
1027 reservedWords.put( "break", "break" );
1028 reservedWords.put( "else", "else" );
1029 reservedWords.put( "interface", "interface" );
1030 reservedWords.put( "short", "short" );
1031 reservedWords.put( "volatile", "volatile" );
1032 reservedWords.put( "byvalue", "byvalue" );
1033 reservedWords.put( "extends", "extends" );
1034 reservedWords.put( "long", "long" );
1035 reservedWords.put( "static", "static" );
1036 reservedWords.put( "while", "while" );
1037 reservedWords.put( "case", "case" );
1038 reservedWords.put( "final", "final" );
1039 reservedWords.put( "native", "native" );
1040 reservedWords.put( "super", "super" );
1041 reservedWords.put( "transient", "transient" );
1042 reservedWords.put( "cast", "cast" );
1043 reservedWords.put( "float", "float" );
1044 reservedWords.put( "new", "new" );
1045 reservedWords.put( "rest", "rest" );
1046 reservedWords.put( "catch", "catch" );
1047 reservedWords.put( "for", "for" );
1048 reservedWords.put( "null", "null" );
1049 reservedWords.put( "synchronized", "synchronized" );
1050 reservedWords.put( "char", "char" );
1051 reservedWords.put( "finally", "finally" );
1052 reservedWords.put( "operator", "operator" );
1053 reservedWords.put( "this", "this" );
1054 reservedWords.put( "class", "class" );
1055 reservedWords.put( "generic", "generic" );
1056 reservedWords.put( "outer", "outer" );
1057 reservedWords.put( "switch", "switch" );
1058 reservedWords.put( "const", "const" );
1059 reservedWords.put( "goto", "goto" );
1060 reservedWords.put( "package", "package" );
1061 reservedWords.put( "throw", "throw" );
1062 reservedWords.put( "double", "double" );
1063 reservedWords.put( "if", "if" );
1064 reservedWords.put( "private", "private" );
1065 reservedWords.put( "true", "true" );
1066 reservedWords.put( "default", "default" );
1067 reservedWords.put( "import", "import" );
1068 reservedWords.put( "protected", "protected" );
1069 reservedWords.put( "try", "try" );
1070 reservedWords.put( "throws", "throws" );
1071 reservedWords.put( "implements", "implements" );
1072 }
1073
1074
1075
1076
1077
1078
1079
1080 final void writeObject( ObjectOutputStream oos )
1081 throws IOException
1082 {
1083 oos.defaultWriteObject();
1084 }
1085
1086
1087
1088
1089
1090
1091
1092
1093 final void readObject( ObjectInputStream ois )
1094 throws ClassNotFoundException, IOException
1095 {
1096 ois.defaultReadObject();
1097 }
1098
1099
1100
1101
1102
1103
1104 private final String getFileOverview()
1105 {
1106 StringBuffer overview = new StringBuffer();
1107
1108
1109 if ( javadocLinkDir != null )
1110 {
1111 overview.append( "<div id=\"overview\">" );
1112
1113 StringBuffer javadocURI = new StringBuffer().append( javadocLinkDir );
1114
1115 try
1116 {
1117 JavaFile jf = fileManager.getFile( this.getCurrentFilename() );
1118
1119 javadocURI.append( StringUtils.replace( jf.getPackageType().getName(), ".", "/" ) );
1120 javadocURI.append( "/" );
1121
1122 if ( jf.getClassType() != null && jf.getClassType().getFilename() != null )
1123 {
1124 javadocURI.append( jf.getClassType().getFilename() );
1125 }
1126 else
1127 {
1128 return "";
1129 }
1130 javadocURI.append( ".html" );
1131
1132 }
1133 catch ( IOException e )
1134 {
1135 e.printStackTrace();
1136 }
1137
1138 String javadocHREF = "<a href=\"" + javadocURI + "\">View Javadoc</a>";
1139
1140
1141 overview.append( javadocHREF );
1142
1143 overview.append( "</div>" );
1144 }
1145
1146 return overview.toString();
1147 }
1148
1149
1150
1151
1152
1153
1154
1155
1156 private final String getLineWidth( int linenumber )
1157 {
1158 if ( linenumber < 10 )
1159 {
1160 return " ";
1161 }
1162 else if ( linenumber < 100 )
1163 {
1164 return " ";
1165 }
1166 else
1167 {
1168 return " ";
1169 }
1170 }
1171
1172
1173
1174
1175
1176
1177
1178
1179 private final String jxrFilter( String line )
1180 {
1181 JavaFile jf = null;
1182
1183 try
1184 {
1185
1186 if ( this.getCurrentFilename() == null )
1187 {
1188 return line;
1189 }
1190
1191 jf = fileManager.getFile( this.getCurrentFilename() );
1192 }
1193 catch ( IOException e )
1194 {
1195 e.printStackTrace();
1196 return line;
1197 }
1198
1199 Vector v = new Vector();
1200
1201
1202 ImportType[] imports = jf.getImportTypes();
1203 for ( int j = 0; j < imports.length; ++j )
1204 {
1205 v.addElement( imports[j].getPackage() );
1206 }
1207
1208
1209 v.addElement( jf.getPackageType().getName() );
1210
1211 String[] packages = new String[v.size()];
1212 v.copyInto( packages );
1213
1214 StringEntry[] words = SimpleWordTokenizer.tokenize( line );
1215
1216
1217 for ( int i = 0; i < words.length; ++i )
1218 {
1219
1220 StringEntry word = words[i];
1221
1222 for ( int j = 0; j < packages.length; ++j )
1223 {
1224
1225
1226
1227 PackageType currentImport = packageManager.getPackageType( packages[j] );
1228
1229
1230
1231
1232
1233 if ( currentImport == null )
1234 {
1235 continue;
1236 }
1237
1238
1239
1240
1241
1242
1243 String wordName = word.toString();
1244
1245 if ( wordName.indexOf( "." ) != -1 )
1246 {
1247
1248
1249
1250 String fqpn_package = null;
1251 String fqpn_class = null;
1252
1253 fqpn_package = wordName.substring( 0, wordName.lastIndexOf( "." ) );
1254 fqpn_class = wordName.substring( wordName.lastIndexOf( "." ) + 1, wordName.length() );
1255
1256
1257
1258
1259
1260 PackageType pt = packageManager.getPackageType( fqpn_package );
1261
1262 if ( pt != null )
1263 {
1264 ClassType ct = pt.getClassType( fqpn_class );
1265
1266 if ( ct != null )
1267 {
1268
1269
1270
1271
1272 line = xrLine( line, pt.getName(), ct );
1273 }
1274 }
1275
1276 if ( fqpn_package.equals( currentImport.getName() )
1277 && currentImport.getClassType( fqpn_class ) != null )
1278 {
1279
1280
1281 line = xrLine( line, packages[j], currentImport.getClassType( fqpn_class ) );
1282 }
1283 }
1284 else if ( currentImport.getClassType( wordName ) != null )
1285 {
1286 line = xrLine( line, packages[j], currentImport.getClassType( wordName ) );
1287 }
1288 }
1289 }
1290
1291 return importFilter( line );
1292 }
1293
1294
1295
1296
1297
1298
1299
1300
1301 private final String getHREF( String dest, ClassType jc )
1302 {
1303 StringBuffer href = new StringBuffer();
1304
1305
1306 href.append( this.getPackageRoot() );
1307
1308
1309 dest = StringUtils.replace( dest, ".*", "" );
1310 dest = StringUtils.replace( dest, ".", "/" );
1311
1312 href.append( dest );
1313
1314
1315 if ( jc != null )
1316 {
1317 href.append( "/" );
1318 href.append( jc.getFilename() );
1319 href.append( ".html" );
1320 }
1321
1322 return href.toString();
1323 }
1324
1325
1326
1327
1328
1329
1330
1331 private final String getHREF( String dest )
1332 {
1333 return getHREF( dest, null );
1334 }
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344 private final int getPackageCount( String packageName )
1345 {
1346 if ( packageName == null )
1347 {
1348 return 0;
1349 }
1350
1351 int count = 0;
1352 int index = 0;
1353
1354 while ( true )
1355 {
1356 index = packageName.indexOf( '.', index );
1357
1358 if ( index == -1 )
1359 {
1360 break;
1361 }
1362 ++index;
1363 ++count;
1364 }
1365
1366
1367 ++count;
1368
1369 return count;
1370 }
1371
1372
1373
1374
1375
1376
1377
1378
1379 private final String importFilter( String line )
1380 {
1381 int start = -1;
1382
1383
1384
1385
1386
1387
1388
1389
1390 boolean isPackage = line.trim().startsWith( "package " );
1391 boolean isImport = line.trim().startsWith( "import " );
1392
1393 if ( isImport || isPackage )
1394 {
1395 start = line.trim().indexOf( " " );
1396 }
1397
1398 if ( start != -1 )
1399 {
1400
1401 String pkg = line.substring( start, line.length() ).trim();
1402
1403
1404 String classname = null;
1405
1406 if ( pkg.indexOf( ".*" ) != -1 )
1407 {
1408 pkg = StringUtils.replace( pkg, ".*", "" );
1409 }
1410 else if ( !isPackage )
1411 {
1412
1413
1414 String packageLine = pkg.toString();
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424 int a = packageLine.lastIndexOf( "." ) + 1;
1425 int b = packageLine.length() - 1;
1426
1427 if ( a > b + 1 )
1428 {
1429 classname = packageLine.substring( packageLine.lastIndexOf( "." ) + 1, packageLine.length() - 1 );
1430
1431 int end = pkg.lastIndexOf( "." );
1432 if ( end == -1 )
1433 {
1434 end = pkg.length() - 1;
1435 }
1436
1437 pkg = pkg.substring( 0, end );
1438 }
1439 }
1440
1441 pkg = StringUtils.replace( pkg, ";", "" );
1442 String pkgHREF = getHREF( pkg );
1443
1444
1445 if ( packageManager.getPackageType( pkg ) != null || isPackage )
1446 {
1447
1448 if ( classname != null )
1449 {
1450 line = StringUtils.replace( line, classname, "<a href=\"" + pkgHREF + "/" + classname + ".html"
1451 + "\">" + classname + "</a>" );
1452 }
1453
1454
1455 line = StringUtils.replace( line, pkg, "<a href=\"" + pkgHREF + "/" + DirectoryIndexer.INDEX + "\">"
1456 + pkg + "</a>" );
1457 }
1458
1459 }
1460
1461 return line;
1462 }
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472 private final boolean isInvalidURICharacter( char c )
1473 {
1474 for ( int i = 0; i < VALID_URI_CHARS.length; ++i )
1475 {
1476 if ( VALID_URI_CHARS[i] == c )
1477 {
1478 return false;
1479 }
1480 }
1481
1482 return true;
1483 }
1484 }