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