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( javaFile.getFilename() );
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 beginMultiLineCommentFilter( line.substring( 0, index ) ) + COMMENT_START + line.substring( index )
760 + COMMENT_END;
761 }
762
763 return beginMultiLineCommentFilter( line );
764 }
765
766
767
768
769
770
771
772
773 private String beginMultiLineCommentFilter( String line )
774 {
775
776
777
778 if ( line == null || line.equals( "" ) )
779 {
780 return "";
781 }
782
783 int index = line.indexOf( "/*" );
784
785 if ( ( index > -1 ) && !isInsideString( line, index ) )
786 {
787 String fromIndex = line.substring( index );
788 if ( fromIndex.startsWith( "/**" ) && !( fromIndex.startsWith( "/**/" ) ) )
789 {
790 inJavadocComment = true;
791 }
792 else
793 {
794 inMultiLineComment = true;
795 }
796
797
798
799
800 return stringFilter( line.substring( 0, index ) ) + ongoingMultiLineCommentFilter( fromIndex );
801 }
802
803
804
805 else
806 {
807 return stringFilter( line );
808 }
809 }
810
811
812
813
814
815
816
817 private String stringFilter( String line )
818 {
819 if ( line == null || line.equals( "" ) )
820 {
821 return "";
822 }
823 StringBuilder buf = new StringBuilder();
824 if ( line.indexOf( '"' ) <= -1 )
825 {
826 return keywordFilter( line );
827 }
828 int start = 0;
829 int startStringIndex = -1;
830 int endStringIndex = -1;
831 int tempIndex;
832
833 while ( ( tempIndex = line.indexOf( '"' ) ) > -1 )
834 {
835
836 if ( startStringIndex == -1 )
837 {
838 startStringIndex = 0;
839 buf.append( stringFilter( line.substring( start, tempIndex ) ) );
840 buf.append( STRING_START ).append( '"' );
841 line = line.substring( tempIndex + 1 );
842 }
843
844 else
845 {
846 startStringIndex = -1;
847 endStringIndex = tempIndex;
848 buf.append( line, 0, endStringIndex + 1 );
849 buf.append( STRING_END );
850 line = line.substring( endStringIndex + 1 );
851 }
852 }
853
854 buf.append( keywordFilter( line ) );
855
856 return buf.toString();
857 }
858
859
860
861
862
863
864
865 private String keywordFilter( String line )
866 {
867 final String classKeyword = "class";
868
869 if ( line == null || line.equals( "" ) )
870 {
871 return "";
872 }
873 StringBuilder buf = new StringBuilder();
874 int i = 0;
875 char ch;
876 StringBuilder temp = new StringBuilder();
877 while ( i < line.length() )
878 {
879 temp.setLength( 0 );
880 ch = line.charAt( i );
881 while ( i < line.length() && ( ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) ) )
882 {
883 temp.append( ch );
884 i++;
885 if ( i < line.length() )
886 {
887 ch = line.charAt( i );
888 }
889 }
890 String tempString = temp.toString();
891
892
893 if ( classKeyword.equals( tempString ) && ch == '=' )
894 {
895 i++;
896 }
897 else if ( reservedWords.containsKey( tempString ) )
898 {
899 line = line.substring( 0, i - tempString.length() ) + RESERVED_WORD_START
900 + tempString
901 + RESERVED_WORD_END
902 + line.substring( i );
903 i += ( RESERVED_WORD_START.length() + RESERVED_WORD_END.length() );
904 }
905 else
906 {
907 i++;
908 }
909 }
910 buf.append( line );
911
912 return uriFilter( buf.toString() );
913 }
914
915
916
917
918
919
920
921
922
923 private boolean isInsideString( String line, int position )
924 {
925 if ( line.indexOf( '"' ) < 0 )
926 {
927 return false;
928 }
929 int index;
930 String left = line.substring( 0, position );
931 String right = line.substring( position );
932 int leftCount = 0;
933 int rightCount = 0;
934 while ( ( index = left.indexOf( '"' ) ) > -1 )
935 {
936 leftCount++;
937 left = left.substring( index + 1 );
938 }
939 while ( ( index = right.indexOf( '"' ) ) > -1 )
940 {
941 rightCount++;
942 right = right.substring( index + 1 );
943 }
944 return ( rightCount % 2 != 0 && leftCount % 2 != 0 );
945 }
946
947
948
949
950
951
952
953 final void writeObject( ObjectOutputStream oos )
954 throws IOException
955 {
956 oos.defaultWriteObject();
957 }
958
959
960
961
962
963
964
965
966 final void readObject( ObjectInputStream ois )
967 throws ClassNotFoundException, IOException
968 {
969 ois.defaultReadObject();
970 }
971
972
973
974
975
976
977 private String getFileOverview()
978 {
979 StringBuilder overview = new StringBuilder();
980
981
982 if ( javadocLinkDir != null )
983 {
984 overview.append( "<div id=\"overview\">" );
985
986 Path javadocURI;
987
988 try
989 {
990 JavaFile jf = fileManager.getFile( this.getCurrentFilename() );
991
992 javadocURI = javadocLinkDir.resolve( jf.getPackageType().getName().replace( '.', '/' ) )
993 ;
994
995 String fileName;
996 if ( jf.getClassType() != null && jf.getClassType().getFilename() != null )
997 {
998 fileName = jf.getClassType().getFilename();
999 }
1000 else
1001 {
1002 fileName = jf.getFilename();
1003 }
1004 javadocURI = javadocURI.resolve( fileName + ".html" );
1005
1006 String javadocHREF = "<a href=\"" + javadocURI.toString().replace( '\\', '/' ) + "\">View Javadoc</a>";
1007
1008
1009 overview.append( javadocHREF );
1010 }
1011 catch ( IOException e )
1012 {
1013 e.printStackTrace();
1014 }
1015
1016 overview.append( "</div>" );
1017 }
1018
1019 return overview.toString();
1020 }
1021
1022
1023
1024
1025
1026
1027
1028 private String getLineWidth( int linenumber )
1029 {
1030 if ( linenumber < 10 )
1031 {
1032 return " ";
1033 }
1034 else if ( linenumber < 100 )
1035 {
1036 return " ";
1037 }
1038 else
1039 {
1040 return " ";
1041 }
1042 }
1043
1044
1045
1046
1047
1048
1049
1050 private String jxrFilter( String line )
1051 {
1052 JavaFile jf;
1053
1054 try
1055 {
1056
1057 if ( this.getCurrentFilename() == null )
1058 {
1059 return line;
1060 }
1061
1062 jf = fileManager.getFile( this.getCurrentFilename() );
1063 }
1064 catch ( IOException e )
1065 {
1066 e.printStackTrace();
1067 return line;
1068 }
1069
1070 Set<String> packages = new HashSet<>();
1071
1072
1073 for ( ImportType importType : jf.getImportTypes() )
1074 {
1075 packages.add( importType.getPackage() );
1076 }
1077
1078
1079 packages.add( jf.getPackageType().getName() );
1080
1081 List<StringEntry> words = SimpleWordTokenizer.tokenize( line );
1082
1083
1084 for ( StringEntry word : words )
1085 {
1086 for ( String pkg : packages )
1087 {
1088
1089
1090
1091 PackageType currentImport = packageManager.getPackageType( pkg );
1092
1093
1094
1095
1096
1097 if ( currentImport == null )
1098 {
1099 continue;
1100 }
1101
1102
1103
1104
1105
1106
1107 String wordName = word.toString();
1108
1109 if ( wordName.indexOf( '.' ) != -1 )
1110 {
1111
1112
1113
1114 String fqpnPackage = wordName.substring( 0, wordName.lastIndexOf( '.' ) );
1115 String fqpnClass = wordName.substring( wordName.lastIndexOf( '.' ) + 1 );
1116
1117
1118
1119
1120
1121 PackageType pt = packageManager.getPackageType( fqpnPackage );
1122
1123 if ( pt != null )
1124 {
1125 ClassType ct = pt.getClassType( fqpnClass );
1126
1127 if ( ct != null )
1128 {
1129
1130
1131
1132
1133 line = xrLine( line, pt.getName(), ct );
1134 }
1135 }
1136
1137 if ( fqpnPackage.equals( currentImport.getName() )
1138 && currentImport.getClassType( fqpnClass ) != null )
1139 {
1140
1141
1142 line = xrLine( line, pkg, currentImport.getClassType( fqpnClass ) );
1143 }
1144 }
1145 else if ( currentImport.getClassType( wordName ) != null )
1146 {
1147 line = xrLine( line, pkg, currentImport.getClassType( wordName ) );
1148 }
1149 }
1150 }
1151
1152 return importFilter( line );
1153 }
1154
1155
1156
1157
1158
1159
1160
1161
1162 private String getHREF( String dest, ClassType jc )
1163 {
1164 StringBuilder href = new StringBuilder();
1165
1166
1167 href.append( this.getPackageRoot() );
1168
1169
1170 dest = StringUtils.replace( dest, ".*", "" ).replace( '.', '/' );
1171
1172 href.append( dest );
1173
1174
1175 if ( jc != null )
1176 {
1177 href.append( '/' );
1178 href.append( jc.getFilename() );
1179 href.append( ".html" );
1180 href.append( '#' );
1181 href.append( jc.getName() );
1182 }
1183
1184 return href.toString();
1185 }
1186
1187
1188
1189
1190
1191
1192
1193 private String getHREF( String dest )
1194 {
1195 return getHREF( dest, null );
1196 }
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209 private int getPackageCount( String packageName )
1210 {
1211 if ( packageName == null )
1212 {
1213 return 0;
1214 }
1215
1216 int count = 0;
1217 int index = 0;
1218
1219 while ( true )
1220 {
1221 index = packageName.indexOf( '.', index );
1222
1223 if ( index == -1 )
1224 {
1225 break;
1226 }
1227 ++index;
1228 ++count;
1229 }
1230
1231
1232 ++count;
1233
1234 return count;
1235 }
1236
1237
1238
1239
1240
1241
1242
1243 private String importFilter( String line )
1244 {
1245 int start = -1;
1246
1247
1248
1249
1250
1251
1252 boolean isPackage = line.trim().startsWith( "package " );
1253 boolean isImport = line.trim().startsWith( "import " );
1254
1255 if ( isImport || isPackage )
1256 {
1257 start = line.trim().indexOf( ' ' );
1258 }
1259
1260 if ( start != -1 )
1261 {
1262
1263 String pkg = line.substring( start ).trim();
1264
1265
1266 String classname = null;
1267
1268 if (pkg.contains(".*"))
1269 {
1270 pkg = StringUtils.replace( pkg, ".*", "" );
1271 }
1272 else if ( !isPackage )
1273 {
1274
1275
1276 String packageLine = pkg;
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286 int a = packageLine.lastIndexOf( '.' ) + 1;
1287 int b = packageLine.length() - 1;
1288
1289 if ( a > b + 1 )
1290 {
1291 classname = packageLine.substring( packageLine.lastIndexOf( '.' ) + 1, packageLine.length() - 1 );
1292
1293 int end = pkg.lastIndexOf( '.' );
1294 if ( end == -1 )
1295 {
1296 end = pkg.length() - 1;
1297 }
1298
1299 pkg = pkg.substring( 0, end );
1300 }
1301 }
1302
1303 pkg = StringUtils.replace( pkg, ";", "" );
1304 String pkgHREF = getHREF( pkg );
1305
1306
1307 if ( packageManager.getPackageType( pkg ) != null || isPackage )
1308 {
1309
1310 if ( classname != null )
1311 {
1312 line =
1313 StringUtils.replace( line, classname, "<a href=\"" + pkgHREF + '/' + classname + ".html"
1314 + "\">" + classname + "</a>" );
1315 }
1316
1317
1318 line =
1319 StringUtils.replace( line, pkg, "<a href=\"" + pkgHREF + '/' + DirectoryIndexer.INDEX + "\">" + pkg
1320 + "</a>" );
1321 }
1322
1323 }
1324
1325 return line;
1326 }
1327
1328
1329
1330
1331
1332
1333
1334 private boolean isInvalidURICharacter( char c )
1335 {
1336 for ( char validUriChar : VALID_URI_CHARS )
1337 {
1338 if ( validUriChar == c )
1339 {
1340 return false;
1341 }
1342 }
1343
1344 return true;
1345 }
1346 }