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