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