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