1 package org.apache.maven.plugin.javadoc;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.io.FileOutputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.URI;
27 import java.net.URISyntaxException;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.Calendar;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.HashSet;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.Locale;
38 import java.util.Map;
39 import java.util.Properties;
40 import java.util.Set;
41 import java.util.StringTokenizer;
42
43 import org.apache.commons.lang.ClassUtils;
44 import org.apache.commons.lang.SystemUtils;
45 import org.apache.maven.artifact.Artifact;
46 import org.apache.maven.artifact.factory.ArtifactFactory;
47 import org.apache.maven.artifact.handler.ArtifactHandler;
48 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
49 import org.apache.maven.artifact.repository.ArtifactRepository;
50 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
51 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
52 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
53 import org.apache.maven.artifact.resolver.ArtifactResolver;
54 import org.apache.maven.artifact.resolver.MultipleArtifactsNotFoundException;
55 import org.apache.maven.artifact.versioning.ArtifactVersion;
56 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
57 import org.apache.maven.execution.MavenSession;
58 import org.apache.maven.plugin.AbstractMojo;
59 import org.apache.maven.plugin.javadoc.options.BootclasspathArtifact;
60 import org.apache.maven.plugin.javadoc.options.DocletArtifact;
61 import org.apache.maven.plugin.javadoc.options.Group;
62 import org.apache.maven.plugin.javadoc.options.JavadocPathArtifact;
63 import org.apache.maven.plugin.javadoc.options.OfflineLink;
64 import org.apache.maven.plugin.javadoc.options.ResourcesArtifact;
65 import org.apache.maven.plugin.javadoc.options.Tag;
66 import org.apache.maven.plugin.javadoc.options.Taglet;
67 import org.apache.maven.plugin.javadoc.options.TagletArtifact;
68 import org.apache.maven.project.MavenProject;
69 import org.apache.maven.project.MavenProjectBuilder;
70 import org.apache.maven.project.ProjectBuildingException;
71 import org.apache.maven.project.artifact.InvalidDependencyVersionException;
72 import org.apache.maven.reporting.MavenReportException;
73 import org.apache.maven.settings.Proxy;
74 import org.apache.maven.settings.Settings;
75 import org.apache.maven.toolchain.Toolchain;
76 import org.apache.maven.toolchain.ToolchainManager;
77 import org.apache.maven.wagon.PathUtils;
78 import org.codehaus.plexus.archiver.ArchiverException;
79 import org.codehaus.plexus.archiver.UnArchiver;
80 import org.codehaus.plexus.archiver.manager.ArchiverManager;
81 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
82 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
83 import org.codehaus.plexus.util.FileUtils;
84 import org.codehaus.plexus.util.IOUtil;
85 import org.codehaus.plexus.util.ReaderFactory;
86 import org.codehaus.plexus.util.StringUtils;
87 import org.codehaus.plexus.util.cli.CommandLineException;
88 import org.codehaus.plexus.util.cli.CommandLineUtils;
89 import org.codehaus.plexus.util.cli.Commandline;
90 import org.codehaus.plexus.util.cli.DefaultConsumer;
91
92
93
94
95
96
97
98
99
100
101 public abstract class AbstractJavadocMojo
102 extends AbstractMojo
103 {
104
105 protected static final String DEBUG_JAVADOC_SCRIPT_NAME =
106 "javadoc." + ( SystemUtils.IS_OS_WINDOWS ? "bat" : "sh" );
107
108
109
110 protected static final String OPTIONS_FILE_NAME = "options";
111
112
113
114 protected static final String PACKAGES_FILE_NAME = "packages";
115
116
117
118 protected static final String ARGFILE_FILE_NAME = "argfile";
119
120
121
122 protected static final String FILES_FILE_NAME = "files";
123
124
125 private static final String RESOURCE_DIR = ClassUtils.getPackageName( JavadocReport.class ).replace( '.', '/' );
126
127
128 private static final String DEFAULT_CSS_NAME = "stylesheet.css";
129
130
131 private static final String RESOURCE_CSS_DIR = RESOURCE_DIR + "/css";
132
133
134
135
136
137
138
139 private static final float SINCE_JAVADOC_1_4 = 1.4f;
140
141
142
143
144
145
146
147 private static final float SINCE_JAVADOC_1_4_2 = 1.42f;
148
149
150
151
152
153
154
155 private static final float SINCE_JAVADOC_1_5 = 1.5f;
156
157
158
159
160
161
162
163 private static final float SINCE_JAVADOC_1_6 = 1.6f;
164
165
166
167
168
169
170
171
172
173
174
175 private ArchiverManager archiverManager;
176
177
178
179
180
181
182 private ArtifactFactory factory;
183
184
185
186
187
188
189
190 private ArtifactMetadataSource artifactMetadataSource;
191
192
193
194
195
196
197 private ArtifactResolver resolver;
198
199
200
201
202
203
204
205 private MavenProjectBuilder mavenProjectBuilder;
206
207
208
209
210
211
212
213
214
215
216
217
218
219 private MavenSession session;
220
221
222
223
224
225
226
227
228
229 private Settings settings;
230
231
232
233
234
235
236
237
238 protected MavenProject project;
239
240
241
242
243
244
245
246
247 private boolean isOffline;
248
249
250
251
252
253
254
255
256
257
258
259
260 private File javadocDirectory;
261
262
263
264
265
266
267
268 private String additionalparam;
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283 private String additionalJOption;
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306 private ResourcesArtifact[] resourcesArtifacts;
307
308
309
310
311
312
313 private ArtifactRepository localRepository;
314
315
316
317
318
319
320 private List remoteRepositories;
321
322
323
324
325
326
327
328 private List reactorProjects;
329
330
331
332
333
334
335
336
337 protected boolean aggregate;
338
339
340
341
342
343
344
345
346 private boolean debug;
347
348
349
350
351
352
353
354
355 private String javadocExecutable;
356
357
358
359
360
361
362
363 private String javadocVersion;
364
365
366
367
368 private float fJavadocVersion = 0.0f;
369
370
371
372
373
374
375
376 protected boolean skip;
377
378
379
380
381
382
383
384 protected boolean failOnError;
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405 protected boolean useStandardDocletOptions;
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420 private String bootclasspath;
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444 private BootclasspathArtifact[] bootclasspathArtifacts;
445
446
447
448
449
450
451
452
453
454
455
456 private boolean breakiterator;
457
458
459
460
461
462
463
464
465 private String doclet;
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486 private DocletArtifact docletArtifact;
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511 private DocletArtifact[] docletArtifacts;
512
513
514
515
516
517
518
519
520
521
522 private String docletPath;
523
524
525
526
527
528
529
530
531
532
533
534
535
536 private String encoding;
537
538
539
540
541
542
543
544
545
546
547
548 private String excludePackageNames;
549
550
551
552
553
554
555
556
557
558 private String extdirs;
559
560
561
562
563
564
565
566
567 private String locale;
568
569
570
571
572
573
574
575
576
577
578 private String maxmemory;
579
580
581
582
583
584
585
586
587
588
589 private String minmemory;
590
591
592
593
594
595
596
597
598
599
600 private boolean old;
601
602
603
604
605
606
607
608
609
610
611
612
613 private File overview;
614
615
616
617
618
619
620
621
622
623
624 private String proxyHost;
625
626
627
628
629
630
631
632
633
634
635 private int proxyPort;
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651 private boolean quiet;
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670 private String show;
671
672
673
674
675
676
677
678
679
680
681 private String source;
682
683
684
685
686
687
688
689
690
691 private String sourcepath;
692
693
694
695
696
697
698
699
700
701
702
703 private String subpackages;
704
705
706
707
708
709
710
711
712
713 private boolean verbose;
714
715
716
717
718
719
720
721
722
723
724
725
726
727 private boolean author;
728
729
730
731
732
733
734
735
736
737
738
739
740 private String bottom;
741
742
743
744
745
746
747
748
749
750
751 private String charset;
752
753
754
755
756
757
758
759
760
761 private String docencoding;
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778 private boolean docfilessubdirs;
779
780
781
782
783
784
785
786
787
788 private String doctitle;
789
790
791
792
793
794
795
796
797
798
799
800
801
802 private String excludedocfilessubdir;
803
804
805
806
807
808
809
810
811 private String footer;
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836 private Group[] groups;
837
838
839
840
841
842
843
844
845 private String header;
846
847
848
849
850
851
852
853
854
855
856
857 private String helpfile;
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874 private boolean keywords;
875
876
877
878
879
880
881
882
883 protected ArrayList links;
884
885
886
887
888
889
890
891
892
893
894
895
896 private boolean linksource;
897
898
899
900
901
902
903
904
905
906
907
908 private boolean nocomment;
909
910
911
912
913
914
915
916
917
918 private boolean nodeprecated;
919
920
921
922
923
924
925
926
927
928
929
930 private boolean nodeprecatedlist;
931
932
933
934
935
936
937
938
939
940
941
942 private boolean nohelp;
943
944
945
946
947
948
949
950
951
952
953
954 private boolean noindex;
955
956
957
958
959
960
961
962
963
964 private boolean nonavbar;
965
966
967
968
969
970
971
972
973
974
975
976
977 private boolean nooverview;
978
979
980
981
982
983
984
985
986
987
988 private String noqualifier;
989
990
991
992
993
994
995
996
997
998 private boolean nosince;
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012 private boolean notimestamp;
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022 private boolean notree;
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045 private OfflineLink[] offlineLinks;
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 protected File outputDirectory;
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 private String packagesheader;
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 private boolean serialwarn;
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094 private int sourcetab;
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107 private boolean splitindex;
1108
1109
1110
1111
1112
1113
1114
1115
1116 private String stylesheet;
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126 private String stylesheetfile;
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137 private String taglet;
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168 private TagletArtifact tagletArtifact;
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196 private TagletArtifact[] tagletArtifacts;
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209 private String tagletpath;
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239 private Taglet[] taglets;
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264 private Tag[] tags;
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276 private String top;
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286 private boolean use;
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296 private boolean version;
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306 private String windowtitle;
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319 protected boolean isAggregator()
1320 {
1321 return false;
1322 }
1323
1324
1325
1326
1327 protected String getOutputDirectory()
1328 {
1329 return outputDirectory.getAbsoluteFile().toString();
1330 }
1331
1332
1333
1334
1335
1336
1337 protected List getProjectBuildOutputDirs( MavenProject p )
1338 {
1339 if ( StringUtils.isEmpty( p.getBuild().getOutputDirectory() ) )
1340 {
1341 return Collections.EMPTY_LIST;
1342 }
1343
1344 return Collections.singletonList( p.getBuild().getOutputDirectory() );
1345 }
1346
1347
1348
1349
1350
1351 protected List getProjectSourceRoots( MavenProject p )
1352 {
1353 if ( "pom".equals( p.getPackaging().toLowerCase() ) )
1354 {
1355 return Collections.EMPTY_LIST;
1356 }
1357
1358 return p.getCompileSourceRoots();
1359 }
1360
1361
1362
1363
1364
1365 protected List getExecutionProjectSourceRoots( MavenProject p )
1366 {
1367 if ( "pom".equals( p.getExecutionProject().getPackaging().toLowerCase() ) )
1368 {
1369 return Collections.EMPTY_LIST;
1370 }
1371
1372 return p.getExecutionProject().getCompileSourceRoots();
1373 }
1374
1375
1376
1377
1378
1379 protected List getProjectArtifacts( MavenProject p )
1380 {
1381 return p.getCompileArtifacts();
1382 }
1383
1384
1385
1386
1387 protected File getJavadocDirectory()
1388 {
1389 return javadocDirectory;
1390 }
1391
1392
1393
1394
1395 protected String getDoctitle()
1396 {
1397 return doctitle;
1398 }
1399
1400
1401
1402
1403 protected File getOverview()
1404 {
1405 return overview;
1406 }
1407
1408
1409
1410
1411 protected String getWindowtitle()
1412 {
1413 return windowtitle;
1414 }
1415
1416
1417
1418
1419 private String getCharset()
1420 {
1421 return ( StringUtils.isEmpty( charset ) ) ? getDocencoding() : charset;
1422 }
1423
1424
1425
1426
1427 private String getDocencoding()
1428 {
1429 return ( StringUtils.isEmpty( docencoding ) ) ? ReaderFactory.UTF_8 : docencoding;
1430 }
1431
1432
1433
1434
1435 private String getEncoding()
1436 {
1437 return ( StringUtils.isEmpty( encoding ) ) ? ReaderFactory.FILE_ENCODING : encoding;
1438 }
1439
1440
1441
1442
1443
1444
1445
1446
1447 protected void executeReport( Locale unusedLocale )
1448 throws MavenReportException
1449 {
1450 if ( skip )
1451 {
1452 getLog().info( "Skipping javadoc generation" );
1453 return;
1454 }
1455
1456 if ( isAggregator() && !project.isExecutionRoot() )
1457 {
1458 return;
1459 }
1460
1461 if ( getLog().isDebugEnabled() )
1462 {
1463 this.debug = true;
1464 }
1465
1466 List sourcePaths = getSourcePaths();
1467 List files = getFiles( sourcePaths );
1468 if ( !canGenerateReport( files ) )
1469 {
1470 return;
1471 }
1472
1473 List packageNames = getPackageNames( sourcePaths, files );
1474 List filesWithUnnamedPackages = getFilesWithUnnamedPackages( sourcePaths, files );
1475
1476
1477
1478
1479
1480 String jExecutable;
1481 try
1482 {
1483 jExecutable = getJavadocExecutable();
1484 }
1485 catch ( IOException e )
1486 {
1487 throw new MavenReportException( "Unable to find javadoc command: " + e.getMessage(), e );
1488 }
1489 setFJavadocVersion( new File( jExecutable ) );
1490
1491
1492
1493
1494
1495 File javadocOutputDirectory = new File( getOutputDirectory() );
1496 if ( javadocOutputDirectory.exists() && !javadocOutputDirectory.isDirectory() )
1497 {
1498 throw new MavenReportException( "IOException: " + getOutputDirectory() + " is not a directory." );
1499 }
1500 if ( javadocOutputDirectory.exists() && !javadocOutputDirectory.canWrite() )
1501 {
1502 throw new MavenReportException( "IOException: " + getOutputDirectory() + " is not writable." );
1503 }
1504 javadocOutputDirectory.mkdirs();
1505
1506
1507
1508
1509
1510 copyAllResources( javadocOutputDirectory );
1511
1512
1513
1514
1515
1516 Commandline cmd = new Commandline();
1517 cmd.getShell().setQuotedArgumentsEnabled( false );
1518 cmd.setWorkingDirectory( javadocOutputDirectory.getAbsolutePath() );
1519 cmd.setExecutable( jExecutable );
1520
1521
1522
1523
1524
1525 addMemoryArg( cmd, "-Xmx", this.maxmemory );
1526 addMemoryArg( cmd, "-Xms", this.minmemory );
1527 addProxyArg( cmd );
1528
1529 if ( StringUtils.isNotEmpty( additionalJOption ) )
1530 {
1531 cmd.createArg().setValue( additionalJOption );
1532 }
1533
1534 List arguments = new ArrayList();
1535
1536
1537
1538
1539
1540 addJavadocOptions( arguments, sourcePaths );
1541
1542
1543
1544
1545
1546 if ( StringUtils.isEmpty( doclet ) || useStandardDocletOptions )
1547 {
1548 addStandardDocletOptions( javadocOutputDirectory, arguments );
1549 }
1550
1551
1552
1553
1554
1555 if ( arguments.size() > 0 )
1556 {
1557 addCommandLineOptions( cmd, arguments, javadocOutputDirectory );
1558 }
1559
1560
1561
1562
1563
1564 if ( !packageNames.isEmpty() )
1565 {
1566 addCommandLinePackages( cmd, javadocOutputDirectory, packageNames );
1567
1568
1569
1570
1571
1572 if ( !filesWithUnnamedPackages.isEmpty() )
1573 {
1574 addCommandLineArgFile( cmd, javadocOutputDirectory, filesWithUnnamedPackages );
1575 }
1576 }
1577 else
1578 {
1579
1580
1581
1582
1583 if ( !files.isEmpty() )
1584 {
1585 addCommandLineArgFile( cmd, javadocOutputDirectory, files );
1586 }
1587 }
1588
1589
1590
1591
1592
1593 executeJavadocCommandLine( cmd, javadocOutputDirectory );
1594 }
1595
1596
1597
1598
1599
1600
1601
1602 protected List getFiles( List sourcePaths )
1603 {
1604 List files = new ArrayList();
1605 if ( StringUtils.isEmpty( subpackages ) )
1606 {
1607 String[] excludedPackages = getExcludedPackages();
1608
1609 for ( Iterator i = sourcePaths.iterator(); i.hasNext(); )
1610 {
1611 File sourceDirectory = new File( (String) i.next() );
1612 JavadocUtil.addFilesFromSource( files, sourceDirectory, excludedPackages );
1613 }
1614 }
1615
1616 return files;
1617 }
1618
1619
1620
1621
1622
1623
1624
1625
1626 protected List getSourcePaths()
1627 {
1628 List sourcePaths;
1629
1630 if ( StringUtils.isEmpty( sourcepath ) )
1631 {
1632 sourcePaths = new ArrayList( JavadocUtil.pruneDirs( project, getProjectSourceRoots( project ) ) );
1633
1634 if ( project.getExecutionProject() != null )
1635 {
1636 sourcePaths.addAll( JavadocUtil.pruneDirs( project, getExecutionProjectSourceRoots( project ) ) );
1637 }
1638
1639
1640
1641
1642
1643
1644 if ( getJavadocDirectory() != null )
1645 {
1646 File javadocDir = getJavadocDirectory();
1647 if ( javadocDir.exists() && javadocDir.isDirectory() )
1648 {
1649 List l =
1650 JavadocUtil.pruneDirs( project,
1651 Collections.singletonList( getJavadocDirectory().getAbsolutePath() ) );
1652 sourcePaths.addAll( l );
1653 }
1654 }
1655
1656 if ( isAggregator() && project.isExecutionRoot() )
1657 {
1658 for ( Iterator i = reactorProjects.iterator(); i.hasNext(); )
1659 {
1660 MavenProject subProject = (MavenProject) i.next();
1661
1662 if ( subProject != project )
1663 {
1664 List sourceRoots = getProjectSourceRoots( subProject );
1665
1666 if ( subProject.getExecutionProject() != null )
1667 {
1668 sourceRoots.addAll( getExecutionProjectSourceRoots( subProject ) );
1669 }
1670
1671 ArtifactHandler artifactHandler = subProject.getArtifact().getArtifactHandler();
1672 if ( "java".equals( artifactHandler.getLanguage() ) )
1673 {
1674 sourcePaths.addAll( JavadocUtil.pruneDirs( subProject, sourceRoots ) );
1675 }
1676
1677 String javadocDirRelative =
1678 PathUtils.toRelative( project.getBasedir(), getJavadocDirectory().getAbsolutePath() );
1679 File javadocDir = new File( subProject.getBasedir(), javadocDirRelative );
1680 if ( javadocDir.exists() && javadocDir.isDirectory() )
1681 {
1682 List l =
1683 JavadocUtil.pruneDirs( subProject,
1684 Collections.singletonList( javadocDir.getAbsolutePath() ) );
1685 sourcePaths.addAll( l );
1686 }
1687 }
1688 }
1689 }
1690 }
1691 else
1692 {
1693 sourcePaths = new ArrayList( Arrays.asList( sourcepath.split( "[;]" ) ) );
1694 sourcePaths = JavadocUtil.pruneDirs( project, sourcePaths );
1695 if ( getJavadocDirectory() != null )
1696 {
1697 List l =
1698 JavadocUtil.pruneDirs( project,
1699 Collections.singletonList( getJavadocDirectory().getAbsolutePath() ) );
1700 sourcePaths.addAll( l );
1701 }
1702 }
1703
1704 sourcePaths = JavadocUtil.pruneDirs( project, sourcePaths );
1705
1706 return sourcePaths;
1707 }
1708
1709
1710
1711
1712
1713
1714
1715
1716 protected boolean canGenerateReport( List files )
1717 {
1718 boolean canGenerate = true;
1719
1720 if ( files.isEmpty() && StringUtils.isEmpty( subpackages ) )
1721 {
1722 canGenerate = false;
1723 }
1724
1725 return canGenerate;
1726 }
1727
1728
1729
1730
1731
1732
1733 protected List getCompileArtifacts( ArtifactResolutionResult result )
1734 {
1735 return JavadocUtil.getCompileArtifacts( result.getArtifacts(), false );
1736 }
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749 private String getExcludedPackages( List sourcePaths )
1750 {
1751 List excludedNames = null;
1752
1753 if ( StringUtils.isNotEmpty( sourcepath ) && StringUtils.isNotEmpty( subpackages ) )
1754 {
1755 String[] excludedPackages = getExcludedPackages();
1756 String[] subpackagesList = subpackages.split( "[:]" );
1757
1758 excludedNames = JavadocUtil.getExcludedNames( sourcePaths, subpackagesList, excludedPackages );
1759 }
1760
1761 String excludeArg = "";
1762 if ( StringUtils.isNotEmpty( subpackages ) && excludedNames != null )
1763 {
1764
1765 for ( Iterator it = excludedNames.iterator(); it.hasNext(); )
1766 {
1767 String str = (String) it.next();
1768 excludeArg = excludeArg + str;
1769
1770 if ( it.hasNext() )
1771 {
1772 excludeArg = excludeArg + ":";
1773 }
1774 }
1775 }
1776
1777 return excludeArg;
1778 }
1779
1780
1781
1782
1783
1784
1785
1786 private String getSourcePath( List sourcePaths )
1787 {
1788 String sourcePath = null;
1789
1790 if ( StringUtils.isEmpty( subpackages ) || StringUtils.isNotEmpty( sourcepath ) )
1791 {
1792 sourcePath = StringUtils.join( sourcePaths.iterator(), File.pathSeparator );
1793 }
1794
1795 return sourcePath;
1796 }
1797
1798
1799
1800
1801
1802
1803
1804 private String[] getExcludedPackages()
1805 {
1806 String[] excludePackages = {};
1807
1808
1809 if ( excludePackageNames != null )
1810 {
1811 excludePackages = excludePackageNames.split( "[ ,:;]" );
1812 }
1813 for ( int i = 0; i < excludePackages.length; i++ )
1814 {
1815 excludePackages[i] = excludePackages[i].replace( '.', File.separatorChar );
1816 }
1817
1818 return excludePackages;
1819 }
1820
1821
1822
1823
1824
1825
1826
1827 private String getClasspath()
1828 throws MavenReportException
1829 {
1830 List classpathElements = new ArrayList();
1831 Map compileArtifactMap = new HashMap();
1832
1833 classpathElements.addAll( getProjectBuildOutputDirs( project ) );
1834
1835 populateCompileArtifactMap( compileArtifactMap, getProjectArtifacts( project ) );
1836
1837 if ( isAggregator() && project.isExecutionRoot() )
1838 {
1839 try
1840 {
1841 for ( Iterator i = reactorProjects.iterator(); i.hasNext(); )
1842 {
1843 MavenProject subProject = (MavenProject) i.next();
1844
1845 if ( subProject != project )
1846 {
1847 classpathElements.addAll( getProjectBuildOutputDirs( subProject ) );
1848
1849 Set dependencyArtifacts = subProject.createArtifacts( factory, null, null );
1850 if ( !dependencyArtifacts.isEmpty() )
1851 {
1852 ArtifactResolutionResult result = null;
1853 try
1854 {
1855 result =
1856 resolver.resolveTransitively( dependencyArtifacts, subProject.getArtifact(),
1857 subProject.getManagedVersionMap(),
1858 localRepository,
1859 subProject.getRemoteArtifactRepositories(),
1860 artifactMetadataSource );
1861 }
1862 catch ( MultipleArtifactsNotFoundException e )
1863 {
1864 if ( checkMissingArtifactsInReactor( dependencyArtifacts, e.getMissingArtifacts() ) )
1865 {
1866 getLog().warn( "IGNORED to add some artifacts in the classpath. See above." );
1867 }
1868 else
1869 {
1870
1871 throw new MavenReportException( e.getMessage(), e );
1872 }
1873 }
1874 catch ( ArtifactNotFoundException e )
1875 {
1876 throw new MavenReportException( e.getMessage(), e );
1877 }
1878 catch ( ArtifactResolutionException e )
1879 {
1880 throw new MavenReportException( e.getMessage(), e );
1881 }
1882
1883 if ( result == null )
1884 {
1885 continue;
1886 }
1887
1888 populateCompileArtifactMap( compileArtifactMap, getCompileArtifacts( result ) );
1889
1890 if ( getLog().isDebugEnabled() )
1891 {
1892 StringBuffer sb = new StringBuffer();
1893
1894 sb.append( "Compiled artifacts for " );
1895 sb.append( subProject.getGroupId() ).append( ":" );
1896 sb.append( subProject.getArtifactId() ).append( ":" );
1897 sb.append( subProject.getVersion() ).append( '\n' );
1898 for ( Iterator it = compileArtifactMap.keySet().iterator(); it.hasNext(); )
1899 {
1900 String key = it.next().toString();
1901
1902 Artifact a = (Artifact) compileArtifactMap.get( key );
1903 sb.append( a.getFile() ).append( '\n' );
1904 }
1905
1906 getLog().debug( sb.toString() );
1907 }
1908 }
1909 }
1910 }
1911 }
1912 catch ( InvalidDependencyVersionException e )
1913 {
1914 throw new MavenReportException( e.getMessage(), e );
1915 }
1916 }
1917
1918 for ( Iterator it = compileArtifactMap.keySet().iterator(); it.hasNext(); )
1919 {
1920 String key = it.next().toString();
1921
1922 Artifact a = (Artifact) compileArtifactMap.get( key );
1923 classpathElements.add( a.getFile() );
1924 }
1925
1926 return StringUtils.join( classpathElements.iterator(), File.pathSeparator );
1927 }
1928
1929
1930
1931
1932
1933
1934
1935 private Toolchain getToolchain()
1936 {
1937 Toolchain tc = null;
1938 try
1939 {
1940 if ( session != null )
1941 {
1942 ToolchainManager toolchainManager =
1943 (ToolchainManager) session.getContainer().lookup( ToolchainManager.ROLE );
1944 if ( toolchainManager != null )
1945 {
1946 tc = toolchainManager.getToolchainFromBuildContext( "jdk", session );
1947 }
1948 }
1949 }
1950 catch ( ComponentLookupException componentLookupException )
1951 {
1952
1953 }
1954
1955 return tc;
1956 }
1957
1958
1959
1960
1961
1962
1963
1964
1965 private void populateCompileArtifactMap( Map compileArtifactMap, Collection artifactList )
1966 throws MavenReportException
1967 {
1968 if ( artifactList != null )
1969 {
1970 for ( Iterator i = artifactList.iterator(); i.hasNext(); )
1971 {
1972 Artifact newArtifact = (Artifact) i.next();
1973
1974 File file = newArtifact.getFile();
1975
1976 if ( file == null )
1977 {
1978 throw new MavenReportException( "Error in plugin descriptor - "
1979 + "dependency was not resolved for artifact: " + newArtifact.getGroupId() + ":"
1980 + newArtifact.getArtifactId() + ":" + newArtifact.getVersion() );
1981 }
1982
1983 if ( compileArtifactMap.get( newArtifact.getDependencyConflictId() ) != null )
1984 {
1985 Artifact oldArtifact =
1986 (Artifact) compileArtifactMap.get( newArtifact.getDependencyConflictId() );
1987
1988 ArtifactVersion oldVersion = new DefaultArtifactVersion( oldArtifact.getVersion() );
1989 ArtifactVersion newVersion = new DefaultArtifactVersion( newArtifact.getVersion() );
1990 if ( newVersion.compareTo( oldVersion ) > 0 )
1991 {
1992 compileArtifactMap.put( newArtifact.getDependencyConflictId(), newArtifact );
1993 }
1994 }
1995 else
1996 {
1997 compileArtifactMap.put( newArtifact.getDependencyConflictId(), newArtifact );
1998 }
1999 }
2000 }
2001 }
2002
2003
2004
2005
2006
2007
2008
2009 private String getBottomText()
2010 {
2011 int actualYear = Calendar.getInstance().get( Calendar.YEAR );
2012 String year = String.valueOf( actualYear );
2013
2014 String inceptionYear = project.getInceptionYear();
2015
2016 String theBottom = StringUtils.replace( this.bottom, "{currentYear}", year );
2017
2018 if ( inceptionYear != null )
2019 {
2020 if ( inceptionYear.equals( year ) )
2021 {
2022 theBottom = StringUtils.replace( theBottom, "{inceptionYear}-", "" );
2023 }
2024 else
2025 {
2026 theBottom = StringUtils.replace( theBottom, "{inceptionYear}", inceptionYear );
2027 }
2028 }
2029 else
2030 {
2031 theBottom = StringUtils.replace( theBottom, "{inceptionYear}-", "" );
2032 }
2033
2034 if ( project.getOrganization() == null )
2035 {
2036 theBottom = StringUtils.replace( theBottom, " {organizationName}", "" );
2037 }
2038 else
2039 {
2040 if ( StringUtils.isNotEmpty( project.getOrganization().getName() ) )
2041 {
2042 if ( StringUtils.isNotEmpty( project.getOrganization().getUrl() ) )
2043 {
2044 theBottom =
2045 StringUtils.replace( theBottom, "{organizationName}", "<a href=\""
2046 + project.getOrganization().getUrl() + "\">" + project.getOrganization().getName()
2047 + "</a>" );
2048 }
2049 else
2050 {
2051 theBottom =
2052 StringUtils.replace( theBottom, "{organizationName}", project.getOrganization().getName() );
2053 }
2054 }
2055 else
2056 {
2057 theBottom = StringUtils.replace( theBottom, " {organizationName}", "" );
2058 }
2059 }
2060
2061 return theBottom;
2062 }
2063
2064
2065
2066
2067
2068
2069
2070
2071 private String getStylesheetFile( File javadocOutputDirectory )
2072 {
2073 String stylesheetfilePath = this.stylesheetfile;
2074 if ( StringUtils.isEmpty( stylesheetfilePath ) && "maven".equals( stylesheet ) )
2075 {
2076 stylesheetfilePath = javadocOutputDirectory + File.separator + DEFAULT_CSS_NAME;
2077 }
2078
2079 return stylesheetfilePath;
2080 }
2081
2082
2083
2084
2085
2086
2087
2088
2089 private String getAccessLevel()
2090 {
2091 String accessLevel;
2092 if ( "public".equalsIgnoreCase( show ) || "protected".equalsIgnoreCase( show )
2093 || "package".equalsIgnoreCase( show ) || "private".equalsIgnoreCase( show ) )
2094 {
2095 accessLevel = "-" + show;
2096 }
2097 else
2098 {
2099 if ( getLog().isErrorEnabled() )
2100 {
2101 getLog().error( "Unrecognized access level to show '" + show + "'. Defaulting to protected." );
2102 }
2103 accessLevel = "-protected";
2104 }
2105
2106 return accessLevel;
2107 }
2108
2109
2110
2111
2112
2113
2114
2115
2116 private String getBootclassPath()
2117 throws MavenReportException
2118 {
2119 StringBuffer path = new StringBuffer();
2120
2121 if ( bootclasspathArtifacts != null )
2122 {
2123 List bootclassPath = new ArrayList();
2124 for ( int i = 0; i < bootclasspathArtifacts.length; i++ )
2125 {
2126 BootclasspathArtifact aBootclasspathArtifact = bootclasspathArtifacts[i];
2127
2128 if ( ( StringUtils.isNotEmpty( aBootclasspathArtifact.getGroupId() ) )
2129 && ( StringUtils.isNotEmpty( aBootclasspathArtifact.getArtifactId() ) )
2130 && ( StringUtils.isNotEmpty( aBootclasspathArtifact.getVersion() ) ) )
2131 {
2132 bootclassPath.addAll( getArtifactsAbsolutePath( aBootclasspathArtifact ) );
2133 }
2134 }
2135
2136 bootclassPath = JavadocUtil.pruneFiles( bootclassPath );
2137
2138 path.append( StringUtils.join( bootclassPath.iterator(), File.pathSeparator ) );
2139 }
2140
2141 if ( StringUtils.isNotEmpty( bootclasspath ) )
2142 {
2143 path.append( bootclasspath );
2144 }
2145
2146 return path.toString();
2147 }
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160 private String getDocletPath()
2161 throws MavenReportException
2162 {
2163 StringBuffer path = new StringBuffer();
2164 if ( !isDocletArtifactEmpty( docletArtifact ) )
2165 {
2166 path.append( StringUtils.join( getArtifactsAbsolutePath( docletArtifact ).iterator(),
2167 File.pathSeparator ) );
2168 }
2169 else if ( docletArtifacts != null )
2170 {
2171 for ( int i = 0; i < docletArtifacts.length; i++ )
2172 {
2173 if ( !isDocletArtifactEmpty( docletArtifacts[i] ) )
2174 {
2175 path.append( StringUtils.join( getArtifactsAbsolutePath( docletArtifacts[i] ).iterator(),
2176 File.pathSeparator ) );
2177
2178 if ( i < docletArtifacts.length - 1 )
2179 {
2180 path.append( File.pathSeparator );
2181 }
2182 }
2183 }
2184 }
2185
2186 if ( !StringUtils.isEmpty( docletPath ) )
2187 {
2188 path.append( docletPath );
2189 }
2190
2191 if ( StringUtils.isEmpty( path.toString() ) && getLog().isWarnEnabled() )
2192 {
2193 getLog().warn(
2194 "No docletpath option was found. Please review <docletpath/> or <docletArtifact/>"
2195 + " or <doclets/>." );
2196 }
2197
2198 return path.toString();
2199 }
2200
2201
2202
2203
2204
2205
2206
2207
2208 private boolean isDocletArtifactEmpty( DocletArtifact aDocletArtifact )
2209 {
2210 if ( aDocletArtifact == null )
2211 {
2212 return true;
2213 }
2214
2215 return StringUtils.isEmpty( aDocletArtifact.getGroupId() )
2216 && StringUtils.isEmpty( aDocletArtifact.getArtifactId() )
2217 && StringUtils.isEmpty( aDocletArtifact.getVersion() );
2218 }
2219
2220
2221
2222
2223
2224
2225
2226
2227 private String getTagletPath()
2228 throws MavenReportException
2229 {
2230 StringBuffer path = new StringBuffer();
2231
2232 if ( ( tagletArtifact != null ) && ( StringUtils.isNotEmpty( tagletArtifact.getGroupId() ) )
2233 && ( StringUtils.isNotEmpty( tagletArtifact.getArtifactId() ) )
2234 && ( StringUtils.isNotEmpty( tagletArtifact.getVersion() ) ) )
2235 {
2236 path.append( StringUtils.join( getArtifactsAbsolutePath( tagletArtifact ).iterator(),
2237 File.pathSeparator ) );
2238 }
2239
2240 if ( tagletArtifacts != null )
2241 {
2242 List tagletsPath = new ArrayList();
2243 for ( int i = 0; i < tagletArtifacts.length; i++ )
2244 {
2245 TagletArtifact aTagletArtifact = tagletArtifacts[i];
2246
2247 if ( ( StringUtils.isNotEmpty( aTagletArtifact.getGroupId() ) )
2248 && ( StringUtils.isNotEmpty( aTagletArtifact.getArtifactId() ) )
2249 && ( StringUtils.isNotEmpty( aTagletArtifact.getVersion() ) ) )
2250 {
2251 tagletsPath.addAll( getArtifactsAbsolutePath( aTagletArtifact ) );
2252 }
2253 }
2254
2255 tagletsPath = JavadocUtil.pruneFiles( tagletsPath );
2256
2257 path.append( StringUtils.join( tagletsPath.iterator(), File.pathSeparator ) );
2258 }
2259
2260 if ( taglets != null )
2261 {
2262 List tagletsPath = new ArrayList();
2263 for ( int i = 0; i < taglets.length; i++ )
2264 {
2265 Taglet current = taglets[i];
2266
2267 if ( current == null )
2268 {
2269 continue;
2270 }
2271
2272 if ( ( current.getTagletArtifact() != null )
2273 && ( StringUtils.isNotEmpty( current.getTagletArtifact().getGroupId() ) )
2274 && ( StringUtils.isNotEmpty( current.getTagletArtifact().getArtifactId() ) )
2275 && ( StringUtils.isNotEmpty( current.getTagletArtifact().getVersion() ) ) )
2276 {
2277 tagletsPath.addAll( getArtifactsAbsolutePath( current.getTagletArtifact() ) );
2278 }
2279 else if ( StringUtils.isNotEmpty( current.getTagletpath() ) )
2280 {
2281 tagletsPath.add( current.getTagletpath() );
2282 }
2283 }
2284
2285 tagletsPath = JavadocUtil.pruneFiles( tagletsPath );
2286
2287 path.append( StringUtils.join( tagletsPath.iterator(), File.pathSeparator ) );
2288 }
2289
2290 if ( StringUtils.isNotEmpty( tagletpath ) )
2291 {
2292 path.append( tagletpath );
2293 }
2294
2295 return path.toString();
2296 }
2297
2298
2299
2300
2301
2302
2303
2304
2305 private List getArtifactsAbsolutePath( JavadocPathArtifact javadocArtifact )
2306 throws MavenReportException
2307 {
2308 if ( ( StringUtils.isEmpty( javadocArtifact.getGroupId() ) )
2309 && ( StringUtils.isEmpty( javadocArtifact.getArtifactId() ) )
2310 && ( StringUtils.isEmpty( javadocArtifact.getVersion() ) ) )
2311 {
2312 return Collections.EMPTY_LIST;
2313 }
2314
2315 List path = new ArrayList();
2316
2317 try
2318 {
2319 Artifact artifact = createAndResolveArtifact( javadocArtifact );
2320 path.add( artifact.getFile().getAbsolutePath() );
2321
2322
2323 MavenProject artifactProject =
2324 mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories, localRepository );
2325 Set dependencyArtifacts = artifactProject.createArtifacts( factory, null, null );
2326 if ( !dependencyArtifacts.isEmpty() )
2327 {
2328 ArtifactResolutionResult result =
2329 resolver.resolveTransitively( dependencyArtifacts, artifactProject.getArtifact(),
2330 artifactProject.getRemoteArtifactRepositories(),
2331 localRepository, artifactMetadataSource );
2332 Set artifacts = result.getArtifacts();
2333
2334 Map compileArtifactMap = new HashMap();
2335 populateCompileArtifactMap( compileArtifactMap, artifacts );
2336
2337 for ( Iterator it = compileArtifactMap.keySet().iterator(); it.hasNext(); )
2338 {
2339 String key = it.next().toString();
2340
2341 Artifact a = (Artifact) compileArtifactMap.get( key );
2342 path.add( a.getFile().getAbsolutePath() );
2343 }
2344 }
2345
2346 return path;
2347 }
2348 catch ( ArtifactResolutionException e )
2349 {
2350 throw new MavenReportException( "Unable to resolve artifact:" + javadocArtifact, e );
2351 }
2352 catch ( ArtifactNotFoundException e )
2353 {
2354 throw new MavenReportException( "Unable to find artifact:" + javadocArtifact, e );
2355 }
2356 catch ( ProjectBuildingException e )
2357 {
2358 throw new MavenReportException( "Unable to build the Maven project for the artifact:"
2359 + javadocArtifact, e );
2360 }
2361 catch ( InvalidDependencyVersionException e )
2362 {
2363 throw new MavenReportException( "Unable to resolve artifact:" + javadocArtifact, e );
2364 }
2365 }
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376 private Artifact createAndResolveArtifact( JavadocPathArtifact javadocArtifact )
2377 throws ArtifactResolutionException, ArtifactNotFoundException, ProjectBuildingException
2378 {
2379 Artifact artifact =
2380 factory.createProjectArtifact( javadocArtifact.getGroupId(), javadocArtifact.getArtifactId(),
2381 javadocArtifact.getVersion(), Artifact.SCOPE_COMPILE );
2382
2383 if ( artifact.getFile() == null )
2384 {
2385 MavenProject pluginProject =
2386 mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories, localRepository );
2387 artifact = pluginProject.getArtifact();
2388
2389 resolver.resolve( artifact, remoteRepositories, localRepository );
2390 }
2391
2392 return artifact;
2393 }
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403 private void addMemoryArg( Commandline cmd, String arg, String memory )
2404 {
2405 if ( StringUtils.isNotEmpty( memory ) )
2406 {
2407 try
2408 {
2409 cmd.createArg().setValue( "-J" + arg + JavadocUtil.parseJavadocMemory( memory ) );
2410 }
2411 catch ( IllegalArgumentException e )
2412 {
2413 if ( getLog().isErrorEnabled() )
2414 {
2415 getLog().error( "Malformed memory pattern for '" + arg + memory + "'. Ignore this option." );
2416 }
2417 }
2418 }
2419 }
2420
2421
2422
2423
2424
2425
2426 private void addProxyArg( Commandline cmd )
2427 {
2428
2429 if ( StringUtils.isNotEmpty( proxyHost ) )
2430 {
2431 if ( getLog().isWarnEnabled() )
2432 {
2433 getLog().warn(
2434 "The Javadoc plugin parameter 'proxyHost' is deprecated since 2.4. "
2435 + "Please configure an active proxy in your settings.xml." );
2436 }
2437 cmd.createArg().setValue( "-J-DproxyHost=" + proxyHost );
2438
2439 if ( proxyPort > 0 )
2440 {
2441 if ( getLog().isWarnEnabled() )
2442 {
2443 getLog().warn(
2444 "The Javadoc plugin parameter 'proxyPort' is deprecated since 2.4. "
2445 + "Please configure an active proxy in your settings.xml." );
2446 }
2447 cmd.createArg().setValue( "-J-DproxyPort=" + proxyPort );
2448 }
2449 }
2450
2451 if ( settings == null )
2452 {
2453 return;
2454 }
2455
2456 Proxy activeProxy = settings.getActiveProxy();
2457 if ( activeProxy != null )
2458 {
2459 String protocol =
2460 StringUtils.isNotEmpty( activeProxy.getProtocol() ) ? activeProxy.getProtocol() + "." : "";
2461
2462 if ( StringUtils.isNotEmpty( activeProxy.getHost() ) )
2463 {
2464 cmd.createArg().setValue( "-J-D" + protocol + "proxySet=true" );
2465 cmd.createArg().setValue( "-J-D" + protocol + "proxyHost=" + activeProxy.getHost() );
2466
2467 if ( activeProxy.getPort() > 0 )
2468 {
2469 cmd.createArg().setValue( "-J-D" + protocol + "proxyPort=" + activeProxy.getPort() );
2470 }
2471
2472 if ( StringUtils.isNotEmpty( activeProxy.getNonProxyHosts() ) )
2473 {
2474 cmd.createArg().setValue(
2475 "-J-D" + protocol + "nonProxyHosts=\""
2476 + activeProxy.getNonProxyHosts() + "\"" );
2477 }
2478
2479 if ( StringUtils.isNotEmpty( activeProxy.getUsername() ) )
2480 {
2481 cmd.createArg().setValue( "-J-Dhttp.proxyUser=\"" + activeProxy.getUsername() + "\"" );
2482
2483 if ( StringUtils.isNotEmpty( activeProxy.getPassword() ) )
2484 {
2485 cmd.createArg().setValue( "-J-Dhttp.proxyPassword=\"" + activeProxy.getPassword() + "\"" );
2486 }
2487 }
2488 }
2489 }
2490 }
2491
2492
2493
2494
2495
2496
2497
2498
2499 private String getJavadocExecutable()
2500 throws IOException
2501 {
2502 Toolchain tc = getToolchain();
2503
2504 if ( tc != null )
2505 {
2506 getLog().info( "Toolchain in javadoc-plugin: " + tc );
2507 if ( javadocExecutable != null )
2508 {
2509 getLog().warn(
2510 "Toolchains are ignored, 'javadocExecutable' parameter is set to "
2511 + javadocExecutable );
2512 }
2513 else
2514 {
2515 javadocExecutable = tc.findTool( "javadoc" );
2516 }
2517 }
2518
2519 String javadocCommand = "javadoc" + ( SystemUtils.IS_OS_WINDOWS ? ".exe" : "" );
2520
2521 File javadocExe;
2522
2523
2524
2525
2526 if ( StringUtils.isNotEmpty( javadocExecutable ) )
2527 {
2528 javadocExe = new File( javadocExecutable );
2529
2530 if ( javadocExe.isDirectory() )
2531 {
2532 javadocExe = new File( javadocExe, javadocCommand );
2533 }
2534
2535 if ( SystemUtils.IS_OS_WINDOWS && javadocExe.getName().indexOf( '.' ) < 0 )
2536 {
2537 javadocExe = new File( javadocExe.getPath() + ".exe" );
2538 }
2539
2540 if ( !javadocExe.isFile() )
2541 {
2542 throw new IOException( "The javadoc executable '" + javadocExe
2543 + "' doesn't exist or is not a file. Verify the <javadocExecutable/> parameter." );
2544 }
2545
2546 return javadocExe.getAbsolutePath();
2547 }
2548
2549
2550
2551
2552
2553
2554
2555 if ( SystemUtils.IS_OS_AIX )
2556 {
2557 javadocExe =
2558 new File( SystemUtils.getJavaHome() + File.separator + ".." + File.separator + "sh",
2559 javadocCommand );
2560 }
2561 else if ( SystemUtils.IS_OS_MAC_OSX )
2562 {
2563 javadocExe = new File( SystemUtils.getJavaHome() + File.separator + "bin", javadocCommand );
2564 }
2565 else
2566 {
2567 javadocExe =
2568 new File( SystemUtils.getJavaHome() + File.separator + ".." + File.separator + "bin",
2569 javadocCommand );
2570 }
2571
2572
2573
2574
2575 if ( !javadocExe.exists() || !javadocExe.isFile() )
2576 {
2577 Properties env = CommandLineUtils.getSystemEnvVars();
2578 String javaHome = env.getProperty( "JAVA_HOME" );
2579 if ( StringUtils.isEmpty( javaHome ) )
2580 {
2581 throw new IOException( "The environment variable JAVA_HOME is not correctly set." );
2582 }
2583 if ( ( !new File( javaHome ).exists() ) || ( !new File( javaHome ).isDirectory() ) )
2584 {
2585 throw new IOException( "The environment variable JAVA_HOME=" + javaHome
2586 + " doesn't exist or is not a valid directory." );
2587 }
2588
2589 javadocExe = new File( env.getProperty( "JAVA_HOME" ) + File.separator + "bin", javadocCommand );
2590 }
2591
2592 if ( !javadocExe.exists() || !javadocExe.isFile() )
2593 {
2594 throw new IOException( "The javadoc executable '" + javadocExe
2595 + "' doesn't exist or is not a file. Verify the JAVA_HOME environment variable." );
2596 }
2597
2598 return javadocExe.getAbsolutePath();
2599 }
2600
2601
2602
2603
2604
2605
2606
2607
2608 private void setFJavadocVersion( File jExecutable )
2609 throws MavenReportException
2610 {
2611 float jVersion;
2612 try
2613 {
2614 jVersion = JavadocUtil.getJavadocVersion( jExecutable );
2615 }
2616 catch ( IOException e )
2617 {
2618 if ( getLog().isWarnEnabled() )
2619 {
2620 getLog().warn( "Unable to find the javadoc version: " + e.getMessage() );
2621 getLog().warn( "Using the Java version instead of, i.e. " + SystemUtils.JAVA_VERSION_FLOAT );
2622 }
2623 jVersion = SystemUtils.JAVA_VERSION_FLOAT;
2624 }
2625 catch ( CommandLineException e )
2626 {
2627 if ( getLog().isWarnEnabled() )
2628 {
2629 getLog().warn( "Unable to find the javadoc version: " + e.getMessage() );
2630 getLog().warn( "Using the Java the version instead of, i.e. " + SystemUtils.JAVA_VERSION_FLOAT );
2631 }
2632 jVersion = SystemUtils.JAVA_VERSION_FLOAT;
2633 }
2634 catch ( IllegalArgumentException e )
2635 {
2636 if ( getLog().isWarnEnabled() )
2637 {
2638 getLog().warn( "Unable to find the javadoc version: " + e.getMessage() );
2639 getLog().warn( "Using the Java the version instead of, i.e. " + SystemUtils.JAVA_VERSION_FLOAT );
2640 }
2641 jVersion = SystemUtils.JAVA_VERSION_FLOAT;
2642 }
2643
2644 if ( StringUtils.isNotEmpty( javadocVersion ) )
2645 {
2646 try
2647 {
2648 fJavadocVersion = Float.parseFloat( javadocVersion );
2649 }
2650 catch ( NumberFormatException e )
2651 {
2652 throw new MavenReportException( "Unable to parse javadoc version: " + e.getMessage(), e );
2653 }
2654
2655 if ( fJavadocVersion != jVersion && getLog().isWarnEnabled() )
2656 {
2657 getLog().warn( "Are you sure about the <javadocVersion/> parameter? It seems to be " + jVersion );
2658 }
2659 }
2660 else
2661 {
2662 fJavadocVersion = jVersion;
2663 }
2664 }
2665
2666
2667
2668
2669
2670
2671
2672
2673 private boolean isJavaDocVersionAtLeast( float requiredVersion )
2674 {
2675 return fJavadocVersion >= requiredVersion;
2676 }
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686 private void addArgIf( List arguments, boolean b, String value )
2687 {
2688 if ( b )
2689 {
2690 arguments.add( value );
2691 }
2692 }
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705 private void addArgIf( List arguments, boolean b, String value, float requiredJavaVersion )
2706 {
2707 if ( b )
2708 {
2709 if ( isJavaDocVersionAtLeast( requiredJavaVersion ) )
2710 {
2711 addArgIf( arguments, b, value );
2712 }
2713 else
2714 {
2715 if ( getLog().isWarnEnabled() )
2716 {
2717 getLog().warn(
2718 value + " option is not supported on Java version < " + requiredJavaVersion
2719 + ". Ignore this option." );
2720 }
2721 }
2722 }
2723 }
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736 private void addArgIfNotEmpty( List arguments, String key, String value )
2737 {
2738 addArgIfNotEmpty( arguments, key, value, false );
2739 }
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756 private void addArgIfNotEmpty( List arguments, String key, String value, boolean repeatKey,
2757 boolean splitValue, float requiredJavaVersion )
2758 {
2759 if ( StringUtils.isNotEmpty( value ) )
2760 {
2761 if ( isJavaDocVersionAtLeast( requiredJavaVersion ) )
2762 {
2763 addArgIfNotEmpty( arguments, key, value, repeatKey, splitValue );
2764 }
2765 else
2766 {
2767 if ( getLog().isWarnEnabled() )
2768 {
2769 getLog().warn(
2770 key + " option is not supported on Java version < " + requiredJavaVersion
2771 + ". Ignore this option." );
2772 }
2773 }
2774 }
2775 }
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789 private void addArgIfNotEmpty( List arguments, String key, String value, boolean repeatKey, boolean splitValue )
2790 {
2791 if ( StringUtils.isNotEmpty( value ) )
2792 {
2793 if ( StringUtils.isNotEmpty( key ) )
2794 {
2795 arguments.add( key );
2796 }
2797
2798 if ( splitValue )
2799 {
2800 StringTokenizer token = new StringTokenizer( value, "," );
2801 while ( token.hasMoreTokens() )
2802 {
2803 String current = token.nextToken().trim();
2804
2805 if ( StringUtils.isNotEmpty( current ) )
2806 {
2807 arguments.add( current );
2808
2809 if ( token.hasMoreTokens() && repeatKey )
2810 {
2811 arguments.add( key );
2812 }
2813 }
2814 }
2815 }
2816 else
2817 {
2818 arguments.add( value );
2819 }
2820 }
2821 }
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834 private void addArgIfNotEmpty( List arguments, String key, String value, boolean repeatKey )
2835 {
2836 addArgIfNotEmpty( arguments, key, value, repeatKey, true );
2837 }
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849 private void addArgIfNotEmpty( List arguments, String key, String value, float requiredJavaVersion )
2850 {
2851 addArgIfNotEmpty( arguments, key, value, requiredJavaVersion, false );
2852 }
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866 private void addArgIfNotEmpty( List arguments, String key, String value, float requiredJavaVersion,
2867 boolean repeatKey )
2868 {
2869 if ( StringUtils.isNotEmpty( value ) )
2870 {
2871 if ( isJavaDocVersionAtLeast( requiredJavaVersion ) )
2872 {
2873 addArgIfNotEmpty( arguments, key, value, repeatKey );
2874 }
2875 else
2876 {
2877 if ( getLog().isWarnEnabled() )
2878 {
2879 getLog().warn( key + " option is not supported on Java version < " + requiredJavaVersion );
2880 }
2881 }
2882 }
2883 }
2884
2885
2886
2887
2888
2889
2890 private void addLinkofflineArguments( List arguments )
2891 {
2892 List offlineLinksList =
2893 ( offlineLinks != null ? new ArrayList( Arrays.asList( offlineLinks ) ) : new ArrayList() );
2894
2895 if ( !isAggregator() && reactorProjects != null )
2896 {
2897 String javadocDirRelative = PathUtils.toRelative( project.getBasedir(), getOutputDirectory() );
2898
2899 for ( Iterator it = reactorProjects.iterator(); it.hasNext(); )
2900 {
2901 MavenProject p = (MavenProject) it.next();
2902
2903
2904 if ( p.getId().equals( project.getId() ) )
2905 {
2906 break;
2907 }
2908
2909 if ( p.getUrl() != null )
2910 {
2911 String url = p.getUrl() + "/apidocs";
2912 File location = new File( p.getBasedir(), javadocDirRelative );
2913
2914 if ( location.exists() )
2915 {
2916 OfflineLink ol = new OfflineLink();
2917 ol.setUrl( url );
2918 ol.setLocation( location.getAbsolutePath() );
2919
2920 offlineLinksList.add( ol );
2921 }
2922 }
2923 }
2924 }
2925
2926 if ( offlineLinksList != null )
2927 {
2928 for ( int i = 0; i < offlineLinksList.size(); i++ )
2929 {
2930 OfflineLink offlineLink = (OfflineLink) offlineLinksList.get( i );
2931 addArgIfNotEmpty( arguments, "-linkoffline", JavadocUtil.quotedPathArgument( offlineLink.getUrl() )
2932 + " " + JavadocUtil.quotedPathArgument( offlineLink.getLocation() ), true );
2933 }
2934 }
2935 }
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949 private void addLinkArguments( List arguments )
2950 {
2951 if ( links != null )
2952 {
2953 for ( int i = 0; i < links.size(); i++ )
2954 {
2955 String link = (String) links.get( i );
2956
2957 if ( StringUtils.isEmpty( link ) )
2958 {
2959 continue;
2960 }
2961
2962 if ( link.endsWith( "/" ) )
2963 {
2964 link = link.substring( 0, link.length() - 1 );
2965 }
2966
2967 try
2968 {
2969 URI linkUri;
2970 if ( link.trim().toLowerCase( Locale.ENGLISH ).startsWith( "http" )
2971 || link.trim().toLowerCase( Locale.ENGLISH ).startsWith( "https" )
2972 || link.trim().toLowerCase( Locale.ENGLISH ).startsWith( "ftp" )
2973 || link.trim().toLowerCase( Locale.ENGLISH ).startsWith( "file" ) )
2974 {
2975 linkUri = new URI( link + "/package-list" );
2976 }
2977 else
2978 {
2979
2980 linkUri = new File( getOutputDirectory(), link + "/package-list" ).toURI();
2981 }
2982 JavadocUtil.fetchURL( settings, linkUri.toURL() );
2983 addArgIfNotEmpty( arguments, "-link", JavadocUtil.quotedPathArgument( link ), true );
2984 }
2985 catch ( URISyntaxException e )
2986 {
2987 if ( getLog().isErrorEnabled() )
2988 {
2989 getLog().error( "Malformed link: " + link + "/package-list. Ignored it." );
2990 }
2991 }
2992 catch ( IOException e )
2993 {
2994 if ( getLog().isErrorEnabled() )
2995 {
2996 getLog().error( "Error fetching link: " + link + "/package-list. Ignored it." );
2997 }
2998 }
2999 }
3000 }
3001 }
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011 private InputStream getStream( String resource )
3012 {
3013 return getClass().getClassLoader().getResourceAsStream( resource );
3014 }
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025 private void copyAllResources( File javadocOutputDirectory )
3026 throws MavenReportException
3027 {
3028
3029
3030
3031
3032 try
3033 {
3034 copyDefaultStylesheet( javadocOutputDirectory );
3035 }
3036 catch ( IOException e )
3037 {
3038 throw new MavenReportException( "Unable to copy default stylesheet: " + e.getMessage(), e );
3039 }
3040
3041
3042
3043
3044
3045 if ( docfilessubdirs )
3046 {
3047
3048
3049
3050
3051 try
3052 {
3053 copyJavadocResources( javadocOutputDirectory );
3054 }
3055 catch ( IOException e )
3056 {
3057 throw new MavenReportException( "Unable to copy javadoc resources: " + e.getMessage(), e );
3058 }
3059 }
3060
3061
3062
3063
3064
3065 copyAdditionalJavadocResources( javadocOutputDirectory );
3066 }
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076 private void copyDefaultStylesheet( File anOutputDirectory )
3077 throws IOException
3078 {
3079 if ( anOutputDirectory == null || !anOutputDirectory.exists() )
3080 {
3081 throw new IOException( "The outputDirectory " + anOutputDirectory + " doesn't exists." );
3082 }
3083
3084 InputStream is = getStream( RESOURCE_CSS_DIR + "/" + DEFAULT_CSS_NAME );
3085
3086 if ( is == null )
3087 {
3088 throw new IOException( "The resource " + DEFAULT_CSS_NAME + " doesn't exists." );
3089 }
3090
3091 File outputFile = new File( anOutputDirectory, DEFAULT_CSS_NAME );
3092
3093 if ( !outputFile.getParentFile().exists() )
3094 {
3095 outputFile.getParentFile().mkdirs();
3096 }
3097
3098 FileOutputStream w = new FileOutputStream( outputFile );
3099
3100 IOUtil.copy( is, w );
3101
3102 IOUtil.close( is );
3103
3104 IOUtil.close( w );
3105 }
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118 private void copyJavadocResources( File anOutputDirectory )
3119 throws IOException
3120 {
3121 if ( anOutputDirectory == null || !anOutputDirectory.exists() )
3122 {
3123 throw new IOException( "The outputDirectory " + anOutputDirectory + " doesn't exists." );
3124 }
3125
3126 if ( getJavadocDirectory() != null )
3127 {
3128 JavadocUtil.copyJavadocResources( anOutputDirectory, getJavadocDirectory(), excludedocfilessubdir );
3129 }
3130
3131 if ( isAggregator() && project.isExecutionRoot() )
3132 {
3133 for ( Iterator i = reactorProjects.iterator(); i.hasNext(); )
3134 {
3135 MavenProject subProject = (MavenProject) i.next();
3136
3137 if ( subProject != project )
3138 {
3139 String javadocDirRelative =
3140 PathUtils.toRelative( project.getBasedir(), getJavadocDirectory().getAbsolutePath() );
3141 File javadocDir = new File( subProject.getBasedir(), javadocDirRelative );
3142 JavadocUtil.copyJavadocResources( anOutputDirectory, javadocDir, excludedocfilessubdir );
3143 }
3144 }
3145 }
3146 }
3147
3148
3149
3150
3151
3152
3153
3154
3155 private void copyAdditionalJavadocResources( File anOutputDirectory )
3156 throws MavenReportException
3157 {
3158 if ( resourcesArtifacts != null && resourcesArtifacts.length > 0 )
3159 {
3160 UnArchiver unArchiver;
3161 try
3162 {
3163 unArchiver = archiverManager.getUnArchiver( "jar" );
3164 }
3165 catch ( NoSuchArchiverException e )
3166 {
3167 throw new MavenReportException( "Unable to extract resources artifact. "
3168 + "No archiver for 'jar' available.", e );
3169 }
3170
3171 for ( int i = 0; i < resourcesArtifacts.length; i++ )
3172 {
3173 ResourcesArtifact item = resourcesArtifacts[i];
3174
3175 Artifact artifact;
3176 try
3177 {
3178 artifact = createAndResolveArtifact( item );
3179 }
3180 catch ( ArtifactResolutionException e )
3181 {
3182 throw new MavenReportException( "Unable to resolve artifact:" + item, e );
3183 }
3184 catch ( ArtifactNotFoundException e )
3185 {
3186 throw new MavenReportException( "Unable to find artifact:" + item, e );
3187 }
3188 catch ( ProjectBuildingException e )
3189 {
3190 throw new MavenReportException( "Unable to build the Maven project for the artifact:" + item,
3191 e );
3192 }
3193
3194 unArchiver.setSourceFile( artifact.getFile() );
3195 unArchiver.setDestDirectory( anOutputDirectory );
3196
3197 getLog().info( "Extracting contents of resources artifact: " + artifact.getArtifactId() );
3198 try
3199 {
3200 unArchiver.extract();
3201 }
3202 catch ( ArchiverException e )
3203 {
3204 throw new MavenReportException( "Extraction of resources failed. Artifact that failed was: "
3205 + artifact.getArtifactId(), e );
3206 }
3207 }
3208 }
3209 }
3210
3211
3212
3213
3214
3215
3216 private List getPackageNames( List sourcePaths, List files )
3217 {
3218 return getPackageNamesOrFilesWithUnnamedPackages( sourcePaths, files, true );
3219 }
3220
3221
3222
3223
3224
3225
3226 private List getFilesWithUnnamedPackages( List sourcePaths, List files )
3227 {
3228 return getPackageNamesOrFilesWithUnnamedPackages( sourcePaths, files, false );
3229 }
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239 private List getPackageNamesOrFilesWithUnnamedPackages( List sourcePaths, List files, boolean onlyPackageName )
3240 {
3241 List returnList = new ArrayList();
3242
3243 if ( !StringUtils.isEmpty( sourcepath ) )
3244 {
3245 return returnList;
3246 }
3247
3248 for ( Iterator it = files.iterator(); it.hasNext(); )
3249 {
3250 String currentFile = (String) it.next();
3251 currentFile = currentFile.replace( '\\', '/' );
3252
3253 for ( Iterator it2 = sourcePaths.iterator(); it2.hasNext(); )
3254 {
3255 String currentSourcePath = (String) it2.next();
3256 currentSourcePath = currentSourcePath.replace( '\\', '/' );
3257
3258 if ( !currentSourcePath.endsWith( "/" ) )
3259 {
3260 currentSourcePath += "/";
3261 }
3262
3263 if ( currentFile.indexOf( currentSourcePath ) != -1 )
3264 {
3265 String packagename = currentFile.substring( currentSourcePath.length() + 1 );
3266 if ( onlyPackageName && packagename.lastIndexOf( "/" ) != -1 )
3267 {
3268 packagename = packagename.substring( 0, packagename.lastIndexOf( "/" ) );
3269 packagename = packagename.replace( '/', '.' );
3270
3271 if ( !returnList.contains( packagename ) )
3272 {
3273 returnList.add( packagename );
3274 }
3275 }
3276 if ( !onlyPackageName && packagename.lastIndexOf( "/" ) == -1 )
3277 {
3278 returnList.add( currentFile );
3279 }
3280 }
3281 }
3282 }
3283
3284 return returnList;
3285 }
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300 private void addCommandLineOptions( Commandline cmd, List arguments, File javadocOutputDirectory )
3301 throws MavenReportException
3302 {
3303 File optionsFile = new File( javadocOutputDirectory, OPTIONS_FILE_NAME );
3304
3305 StringBuffer options = new StringBuffer();
3306 options.append( StringUtils.join( arguments.toArray( new String[0] ), SystemUtils.LINE_SEPARATOR ) );
3307
3308 try
3309 {
3310 FileUtils.fileWrite( optionsFile.getAbsolutePath(), options.toString() );
3311 }
3312 catch ( IOException e )
3313 {
3314 throw new MavenReportException( "Unable to write '" + optionsFile.getName()
3315 + "' temporary file for command execution", e );
3316 }
3317
3318 cmd.createArg().setValue( "@" + OPTIONS_FILE_NAME );
3319
3320 if ( !debug )
3321 {
3322 optionsFile.deleteOnExit();
3323 }
3324 }
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345 private void addCommandLineArgFile( Commandline cmd, File javadocOutputDirectory, List files )
3346 throws MavenReportException
3347 {
3348 File argfileFile;
3349 if ( isJavaDocVersionAtLeast( SINCE_JAVADOC_1_4 ) )
3350 {
3351 argfileFile = new File( javadocOutputDirectory, ARGFILE_FILE_NAME );
3352 }
3353 else
3354 {
3355 argfileFile = new File( javadocOutputDirectory, FILES_FILE_NAME );
3356 }
3357
3358 try
3359 {
3360 FileUtils.fileWrite( argfileFile.getAbsolutePath(), StringUtils.join( files.iterator(),
3361 SystemUtils.LINE_SEPARATOR ) );
3362 }
3363 catch ( IOException e )
3364 {
3365 throw new MavenReportException( "Unable to write '" + argfileFile.getName()
3366 + "' temporary file for command execution", e );
3367 }
3368
3369 if ( isJavaDocVersionAtLeast( SINCE_JAVADOC_1_4 ) )
3370 {
3371 cmd.createArg().setValue( "@" + ARGFILE_FILE_NAME );
3372 }
3373 else
3374 {
3375 cmd.createArg().setValue( "@" + FILES_FILE_NAME );
3376 }
3377
3378 if ( !debug )
3379 {
3380 argfileFile.deleteOnExit();
3381 }
3382 }
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397 private void addCommandLinePackages( Commandline cmd, File javadocOutputDirectory, List packageNames )
3398 throws MavenReportException
3399 {
3400 File packagesFile = new File( javadocOutputDirectory, PACKAGES_FILE_NAME );
3401
3402 try
3403 {
3404 FileUtils.fileWrite( packagesFile.getAbsolutePath(),
3405 StringUtils.join( packageNames.toArray( new String[0] ),
3406 SystemUtils.LINE_SEPARATOR ) );
3407 }
3408 catch ( IOException e )
3409 {
3410 throw new MavenReportException( "Unable to write '" + packagesFile.getName()
3411 + "' temporary file for command execution", e );
3412 }
3413
3414 cmd.createArg().setValue( "@" + PACKAGES_FILE_NAME );
3415
3416 if ( !debug )
3417 {
3418 packagesFile.deleteOnExit();
3419 }
3420 }
3421
3422
3423
3424
3425
3426
3427 private void validateJavadocOptions()
3428 throws MavenReportException
3429 {
3430
3431 if ( StringUtils.isNotEmpty( getEncoding() ) && !JavadocUtil.validateEncoding( getEncoding() ) )
3432 {
3433 throw new MavenReportException( "Encoding not supported: " + getEncoding() );
3434 }
3435 }
3436
3437
3438
3439
3440
3441
3442
3443
3444 private void validateStandardDocletOptions()
3445 throws MavenReportException
3446 {
3447
3448 if ( StringUtils.isNotEmpty( getDocencoding() ) && !JavadocUtil.validateEncoding( getDocencoding() ) )
3449 {
3450 throw new MavenReportException( "Encoding not supported: " + getDocencoding() );
3451 }
3452
3453
3454 if ( StringUtils.isNotEmpty( helpfile ) && nohelp )
3455 {
3456 throw new MavenReportException( "Option <nohelp/> conflicts with <helpfile/>" );
3457 }
3458 if ( ( StringUtils.isNotEmpty( helpfile ) ) && ( !new File( helpfile ).exists() ) )
3459 {
3460 throw new MavenReportException( "File not found: " + helpfile );
3461 }
3462
3463
3464 if ( ( getOverview() != null ) && nooverview )
3465 {
3466 throw new MavenReportException( "Option <nooverview/> conflicts with <overview/>" );
3467 }
3468
3469
3470 if ( splitindex && noindex )
3471 {
3472 throw new MavenReportException( "Option <noindex/> conflicts with <splitindex/>" );
3473 }
3474 }
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486 private boolean checkMissingArtifactsInReactor( Collection dependencyArtifacts, Collection missing )
3487 {
3488 Set foundInReactor = new HashSet();
3489 Iterator iter = missing.iterator();
3490 while ( iter.hasNext() )
3491 {
3492 Artifact mArtifact = (Artifact) iter.next();
3493 Iterator pIter = reactorProjects.iterator();
3494 while ( pIter.hasNext() )
3495 {
3496 MavenProject p = (MavenProject) pIter.next();
3497 if ( p.getArtifactId().equals( mArtifact.getArtifactId() )
3498 && p.getGroupId().equals( mArtifact.getGroupId() )
3499 && p.getVersion().equals( mArtifact.getVersion() ) )
3500 {
3501 getLog().warn(
3502 "The dependency: ["
3503 + p.getId()
3504 + "] can't be resolved but has been found in the reactor (probably snapshots).\n"
3505 + "This dependency has been excluded from the Javadoc classpath. "
3506 + "You should rerun javadoc after executing mvn install." );
3507
3508
3509 foundInReactor.add( p );
3510 break;
3511 }
3512 }
3513 }
3514
3515
3516 return foundInReactor.size() == missing.size();
3517 }
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531 private void addJavadocOptions( List arguments, List sourcePaths )
3532 throws MavenReportException
3533 {
3534 validateJavadocOptions();
3535
3536
3537 addArgIfNotEmpty( arguments, "-locale", JavadocUtil.quotedArgument( this.locale ) );
3538
3539
3540
3541 if ( old && isJavaDocVersionAtLeast( SINCE_JAVADOC_1_4 ) )
3542 {
3543 if ( getLog().isWarnEnabled() )
3544 {
3545 getLog().warn( "Javadoc 1.4+ doesn't support the -1.1 switch anymore. Ignore this option." );
3546 }
3547 }
3548 else
3549 {
3550 addArgIf( arguments, old, "-1.1" );
3551 }
3552
3553 addArgIfNotEmpty( arguments, "-bootclasspath", JavadocUtil.quotedPathArgument( getBootclassPath() ) );
3554
3555 if ( isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
3556 {
3557 addArgIf( arguments, breakiterator, "-breakiterator", SINCE_JAVADOC_1_5 );
3558 }
3559
3560 addArgIfNotEmpty( arguments, "-classpath", JavadocUtil.quotedPathArgument( getClasspath() ) );
3561
3562 if ( StringUtils.isNotEmpty( doclet ) )
3563 {
3564 addArgIfNotEmpty( arguments, "-doclet", JavadocUtil.quotedArgument( doclet ) );
3565 addArgIfNotEmpty( arguments, "-docletpath", JavadocUtil.quotedPathArgument( getDocletPath() ) );
3566 }
3567
3568 if ( StringUtils.isEmpty( encoding ) )
3569 {
3570 getLog().warn(
3571 "Source files encoding has not been set, using platform encoding "
3572 + ReaderFactory.FILE_ENCODING + ", i.e. build is platform dependent!" );
3573 }
3574 addArgIfNotEmpty( arguments, "-encoding", JavadocUtil.quotedArgument( getEncoding() ) );
3575
3576 addArgIfNotEmpty( arguments, "-exclude", getExcludedPackages( sourcePaths ), SINCE_JAVADOC_1_4 );
3577
3578 addArgIfNotEmpty( arguments, "-extdirs", JavadocUtil.quotedPathArgument( extdirs ) );
3579
3580 if ( ( getOverview() != null ) && ( getOverview().exists() ) )
3581 {
3582 addArgIfNotEmpty( arguments, "-overview",
3583 JavadocUtil.quotedPathArgument( getOverview().getAbsolutePath() ) );
3584 }
3585
3586 arguments.add( getAccessLevel() );
3587
3588 if ( isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
3589 {
3590 addArgIf( arguments, quiet, "-quiet", SINCE_JAVADOC_1_5 );
3591 }
3592
3593 addArgIfNotEmpty( arguments, "-source", JavadocUtil.quotedArgument( source ), SINCE_JAVADOC_1_4 );
3594
3595 if ( ( StringUtils.isEmpty( sourcepath ) ) && ( StringUtils.isNotEmpty( subpackages ) ) )
3596 {
3597 sourcepath = StringUtils.join( sourcePaths.iterator(), File.pathSeparator );
3598 }
3599 addArgIfNotEmpty( arguments, "-sourcepath", JavadocUtil.quotedPathArgument( getSourcePath( sourcePaths ) ) );
3600
3601 if ( StringUtils.isNotEmpty( sourcepath ) && isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
3602 {
3603 addArgIfNotEmpty( arguments, "-subpackages", subpackages, SINCE_JAVADOC_1_5 );
3604 }
3605
3606 addArgIf( arguments, verbose, "-verbose" );
3607
3608 addArgIfNotEmpty( arguments, null, additionalparam );
3609 }
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623 private void addStandardDocletOptions( File javadocOutputDirectory, List arguments )
3624 throws MavenReportException
3625 {
3626 validateStandardDocletOptions();
3627
3628
3629
3630 addArgIf( arguments, author, "-author" );
3631
3632 addArgIfNotEmpty( arguments, "-bottom", JavadocUtil.quotedArgument( getBottomText() ), false, false );
3633
3634 if ( !isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
3635 {
3636 addArgIf( arguments, breakiterator, "-breakiterator", SINCE_JAVADOC_1_4 );
3637 }
3638
3639 addArgIfNotEmpty( arguments, "-charset", JavadocUtil.quotedArgument( getCharset() ) );
3640
3641 addArgIfNotEmpty( arguments, "-d", JavadocUtil.quotedPathArgument( javadocOutputDirectory.toString() ) );
3642
3643 addArgIfNotEmpty( arguments, "-docencoding", JavadocUtil.quotedArgument( getDocencoding() ) );
3644
3645 addArgIf( arguments, docfilessubdirs, "-docfilessubdirs", SINCE_JAVADOC_1_4 );
3646
3647 addArgIfNotEmpty( arguments, "-doctitle", JavadocUtil.quotedArgument( getDoctitle() ), false, false );
3648
3649 if ( docfilessubdirs )
3650 {
3651 addArgIfNotEmpty( arguments, "-excludedocfilessubdir",
3652 JavadocUtil.quotedPathArgument( excludedocfilessubdir ), SINCE_JAVADOC_1_4 );
3653 }
3654
3655 addArgIfNotEmpty( arguments, "-footer", JavadocUtil.quotedArgument( footer ), false, false );
3656
3657 addGroups( arguments );
3658
3659 addArgIfNotEmpty( arguments, "-header", JavadocUtil.quotedArgument( header ), false, false );
3660
3661 addArgIfNotEmpty( arguments, "-helpfile", JavadocUtil.quotedPathArgument( helpfile ) );
3662
3663 addArgIf( arguments, keywords, "-keywords", SINCE_JAVADOC_1_4_2 );
3664
3665 if ( !isOffline )
3666 {
3667 addLinkArguments( arguments );
3668 }
3669
3670 addLinkofflineArguments( arguments );
3671
3672 addArgIf( arguments, linksource, "-linksource", SINCE_JAVADOC_1_4 );
3673
3674 if ( sourcetab > 0 )
3675 {
3676 if ( fJavadocVersion == SINCE_JAVADOC_1_4_2 )
3677 {
3678 addArgIfNotEmpty( arguments, "-linksourcetab", String.valueOf( sourcetab ) );
3679 }
3680 addArgIfNotEmpty( arguments, "-sourcetab", String.valueOf( sourcetab ), SINCE_JAVADOC_1_5 );
3681 }
3682
3683 addArgIf( arguments, nocomment, "-nocomment", SINCE_JAVADOC_1_4 );
3684
3685 addArgIf( arguments, nodeprecated, "-nodeprecated" );
3686
3687 addArgIf( arguments, nodeprecatedlist, "-nodeprecatedlist" );
3688
3689 addArgIf( arguments, nohelp, "-nohelp" );
3690
3691 addArgIf( arguments, noindex, "-noindex" );
3692
3693 addArgIf( arguments, nonavbar, "-nonavbar" );
3694
3695 addArgIf( arguments, nooverview, "-nooverview" );
3696
3697 addArgIfNotEmpty( arguments, "-noqualifier", JavadocUtil.quotedArgument( noqualifier ), SINCE_JAVADOC_1_4 );
3698
3699 addArgIf( arguments, nosince, "-nosince" );
3700
3701 addArgIf( arguments, notimestamp, "-notimestamp", SINCE_JAVADOC_1_5 );
3702
3703 addArgIf( arguments, notree, "-notree" );
3704
3705 addArgIfNotEmpty( arguments, "-packagesheader", JavadocUtil.quotedArgument( packagesheader ),
3706 SINCE_JAVADOC_1_4_2 );
3707
3708 if ( !isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
3709 {
3710 addArgIf( arguments, quiet, "-quiet", SINCE_JAVADOC_1_4 );
3711 }
3712
3713 addArgIf( arguments, serialwarn, "-serialwarn" );
3714
3715 addArgIf( arguments, splitindex, "-splitindex" );
3716
3717 addArgIfNotEmpty( arguments, "-stylesheetfile",
3718 JavadocUtil.quotedPathArgument( getStylesheetFile( javadocOutputDirectory ) ) );
3719
3720 if ( StringUtils.isNotEmpty( sourcepath ) && !isJavaDocVersionAtLeast( SINCE_JAVADOC_1_5 ) )
3721 {
3722 addArgIfNotEmpty( arguments, "-subpackages", subpackages, SINCE_JAVADOC_1_4 );
3723 }
3724
3725 addArgIfNotEmpty( arguments, "-taglet", JavadocUtil.quotedArgument( taglet ), SINCE_JAVADOC_1_4 );
3726 addTaglets( arguments );
3727 addTagletsFromTagletArtifacts( arguments );
3728 addArgIfNotEmpty( arguments, "-tagletpath", JavadocUtil.quotedPathArgument( getTagletPath() ),
3729 SINCE_JAVADOC_1_4 );
3730
3731 addTags( arguments );
3732
3733 addArgIfNotEmpty( arguments, "-top", JavadocUtil.quotedArgument( top ), false, false, SINCE_JAVADOC_1_6 );
3734
3735 addArgIf( arguments, use, "-use" );
3736
3737 addArgIf( arguments, version, "-version" );
3738
3739 addArgIfNotEmpty( arguments, "-windowtitle", JavadocUtil.quotedArgument( getWindowtitle() ), false, false );
3740 }
3741
3742
3743
3744
3745
3746
3747 private void addGroups( List arguments )
3748 {
3749 if ( groups == null )
3750 {
3751 return;
3752
3753 }
3754
3755 for ( int i = 0; i < groups.length; i++ )
3756 {
3757 if ( groups[i] == null || StringUtils.isEmpty( groups[i].getTitle() )
3758 || StringUtils.isEmpty( groups[i].getPackages() ) )
3759 {
3760 if ( getLog().isWarnEnabled() )
3761 {
3762 getLog().warn( "A group option is empty. Ignore this option." );
3763 }
3764 }
3765 else
3766 {
3767 String groupTitle = StringUtils.replace( groups[i].getTitle(), ",", "," );
3768 addArgIfNotEmpty( arguments, "-group", JavadocUtil.quotedArgument( groupTitle ) + " "
3769 + JavadocUtil.quotedArgument( groups[i].getPackages() ), true );
3770 }
3771 }
3772 }
3773
3774
3775
3776
3777
3778
3779 private void addTags( List arguments )
3780 {
3781 if ( tags == null )
3782 {
3783 return;
3784 }
3785
3786 for ( int i = 0; i < tags.length; i++ )
3787 {
3788 if ( StringUtils.isEmpty( tags[i].getName() ) )
3789 {
3790 if ( getLog().isWarnEnabled() )
3791 {
3792 getLog().warn( "A tag name is empty. Ignore this option." );
3793 }
3794 }
3795 else
3796 {
3797 String value = "\"" + tags[i].getName();
3798 if ( StringUtils.isNotEmpty( tags[i].getPlacement() ) )
3799 {
3800 value += ":" + tags[i].getPlacement();
3801 if ( StringUtils.isNotEmpty( tags[i].getHead() ) )
3802 {
3803 value += ":" + tags[i].getHead();
3804 }
3805 }
3806 value += "\"";
3807 addArgIfNotEmpty( arguments, "-tag", value, SINCE_JAVADOC_1_4 );
3808 }
3809 }
3810 }
3811
3812
3813
3814
3815
3816
3817 private void addTaglets( List arguments )
3818 {
3819 if ( taglets == null )
3820 {
3821 return;
3822 }
3823
3824 for ( int i = 0; i < taglets.length; i++ )
3825 {
3826 if ( ( taglets[i] == null ) || ( StringUtils.isEmpty( taglets[i].getTagletClass() ) ) )
3827 {
3828 if ( getLog().isWarnEnabled() )
3829 {
3830 getLog().warn( "A taglet option is empty. Ignore this option." );
3831 }
3832 }
3833 else
3834 {
3835 addArgIfNotEmpty( arguments, "-taglet", JavadocUtil.quotedArgument( taglets[i].getTagletClass() ),
3836 SINCE_JAVADOC_1_4 );
3837 }
3838 }
3839 }
3840
3841
3842
3843
3844
3845
3846
3847
3848 private void addTagletsFromTagletArtifacts( List arguments )
3849 throws MavenReportException
3850 {
3851 if ( tagletArtifacts == null )
3852 {
3853 return;
3854 }
3855
3856 List tagletsPath = new ArrayList();
3857 for ( int i = 0; i < tagletArtifacts.length; i++ )
3858 {
3859 TagletArtifact aTagletArtifact = tagletArtifacts[i];
3860
3861 if ( ( StringUtils.isNotEmpty( aTagletArtifact.getGroupId() ) )
3862 && ( StringUtils.isNotEmpty( aTagletArtifact.getArtifactId() ) )
3863 && ( StringUtils.isNotEmpty( aTagletArtifact.getVersion() ) ) )
3864 {
3865 Artifact artifact;
3866 try
3867 {
3868 artifact = createAndResolveArtifact( aTagletArtifact );
3869 }
3870 catch ( ArtifactResolutionException e )
3871 {
3872 throw new MavenReportException( "Unable to resolve artifact:" + aTagletArtifact, e );
3873 }
3874 catch ( ArtifactNotFoundException e )
3875 {
3876 throw new MavenReportException( "Unable to find artifact:" + aTagletArtifact, e );
3877 }
3878 catch ( ProjectBuildingException e )
3879 {
3880 throw new MavenReportException( "Unable to build the Maven project for the artifact:"
3881 + aTagletArtifact, e );
3882 }
3883
3884 tagletsPath.add( artifact.getFile().getAbsolutePath() );
3885 }
3886 }
3887
3888 tagletsPath = JavadocUtil.pruneFiles( tagletsPath );
3889
3890 for ( Iterator it = tagletsPath.iterator(); it.hasNext(); )
3891 {
3892 String tagletJar = (String) it.next();
3893
3894 if ( !tagletJar.toLowerCase( Locale.ENGLISH ).endsWith( ".jar" ) )
3895 {
3896 continue;
3897 }
3898
3899 List tagletClasses;
3900 try
3901 {
3902 tagletClasses = JavadocUtil.getTagletClassNames( new File( tagletJar ) );
3903 }
3904 catch ( IOException e )
3905 {
3906 if ( getLog().isWarnEnabled() )
3907 {
3908 getLog().warn(
3909 "Unable to auto-detect Taglet class names from '" + tagletJar
3910 + "'. Try to specify them with <taglets/>." );
3911 }
3912 if ( getLog().isDebugEnabled() )
3913 {
3914 getLog().debug( "IOException: " + e.getMessage(), e );
3915 }
3916 continue;
3917 }
3918 catch ( ClassNotFoundException e )
3919 {
3920 if ( getLog().isWarnEnabled() )
3921 {
3922 getLog().warn(
3923 "Unable to auto-detect Taglet class names from '" + tagletJar
3924 + "'. Try to specify them with <taglets/>." );
3925 }
3926 if ( getLog().isDebugEnabled() )
3927 {
3928 getLog().debug( "ClassNotFoundException: " + e.getMessage(), e );
3929 }
3930 continue;
3931 }
3932 catch ( NoClassDefFoundError e )
3933 {
3934 if ( getLog().isWarnEnabled() )
3935 {
3936 getLog().warn(
3937 "Unable to auto-detect Taglet class names from '" + tagletJar
3938 + "'. Try to specify them with <taglets/>." );
3939 }
3940 if ( getLog().isDebugEnabled() )
3941 {
3942 getLog().debug( "NoClassDefFoundError: " + e.getMessage(), e );
3943 }
3944 continue;
3945 }
3946
3947 if ( tagletClasses != null && !tagletClasses.isEmpty() )
3948 {
3949 for ( Iterator it2 = tagletClasses.iterator(); it2.hasNext(); )
3950 {
3951 String tagletClass = (String) it2.next();
3952
3953 addArgIfNotEmpty( arguments, "-taglet", JavadocUtil.quotedArgument( tagletClass ),
3954 SINCE_JAVADOC_1_4 );
3955 }
3956 }
3957 }
3958 }
3959
3960
3961
3962
3963
3964
3965
3966
3967 private void executeJavadocCommandLine( Commandline cmd, File javadocOutputDirectory )
3968 throws MavenReportException
3969 {
3970 if ( getLog().isDebugEnabled() )
3971 {
3972
3973 getLog().debug( CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" ) );
3974 }
3975
3976 if ( debug )
3977 {
3978 File commandLineFile =
3979 new File( javadocOutputDirectory, DEBUG_JAVADOC_SCRIPT_NAME );
3980
3981 try
3982 {
3983 FileUtils.fileWrite( commandLineFile.getAbsolutePath(),
3984 CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" ) );
3985
3986 if ( !SystemUtils.IS_OS_WINDOWS )
3987 {
3988 Runtime.getRuntime().exec( new String[] { "chmod", "a+x", commandLineFile.getAbsolutePath() } );
3989 }
3990 }
3991 catch ( IOException e )
3992 {
3993 if ( getLog().isWarnEnabled() )
3994 {
3995 getLog().warn( "Unable to write '" + commandLineFile.getName() + "' debug script file", e );
3996 }
3997 }
3998 }
3999
4000 CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
4001 try
4002 {
4003 int exitCode = CommandLineUtils.executeCommandLine( cmd, new DefaultConsumer(), err );
4004
4005 if ( exitCode != 0 )
4006 {
4007 String cmdLine = CommandLineUtils.toString( cmd.getCommandline() ).replaceAll( "'", "" );
4008 cmdLine = JavadocUtil.hideProxyPassword( cmdLine, settings );
4009
4010 StringBuffer msg = new StringBuffer( "Exit code: " + exitCode + " - " + err.getOutput() );
4011 msg.append( '\n' );
4012 msg.append( "Command line was:" + cmdLine );
4013 throw new MavenReportException( msg.toString() );
4014 }
4015 }
4016 catch ( CommandLineException e )
4017 {
4018 throw new MavenReportException( "Unable to execute javadoc command: " + e.getMessage(), e );
4019 }
4020
4021
4022
4023
4024
4025 if ( StringUtils.isNotEmpty( err.getOutput() ) && getLog().isWarnEnabled() )
4026 {
4027 getLog().warn( "Javadoc Warnings" );
4028
4029 StringTokenizer token = new StringTokenizer( err.getOutput(), "\n" );
4030 while ( token.hasMoreTokens() )
4031 {
4032 String current = token.nextToken().trim();
4033
4034 getLog().warn( current );
4035 }
4036 }
4037 }
4038 }