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