You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jd...@apache.org on 2010/04/12 21:44:12 UTC

svn commit: r933380 [2/3] - in /maven/plugins/trunk/maven-javadoc-plugin: ./ src/it/MJAVADOC-280-2/MJAVADOC-280-2-distro/ src/it/MJAVADOC-280-3/ src/it/MJAVADOC-280-3/MJAVADOC-280-3-distro/ src/it/MJAVADOC-280-3/MJAVADOC-280-3-modA/ src/it/MJAVADOC-280...

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/AbstractJavadocMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/AbstractJavadocMojo.java?rev=933380&r1=933379&r2=933380&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/AbstractJavadocMojo.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/AbstractJavadocMojo.java Mon Apr 12 19:44:10 2010
@@ -19,7 +19,13 @@ package org.apache.maven.plugin.javadoc;
  * under the License.
  */
 
+import static org.codehaus.plexus.util.IOUtil.close;
+import static org.apache.maven.plugin.javadoc.JavadocUtil.toList;
+import static org.apache.maven.plugin.javadoc.JavadocUtil.toRelative;
+import static org.apache.maven.plugin.javadoc.JavadocUtil.*;
+
 import java.io.File;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
@@ -35,6 +41,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
@@ -63,15 +70,19 @@ import org.apache.maven.model.Dependency
 import org.apache.maven.model.Plugin;
 import org.apache.maven.model.Resource;
 import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.javadoc.options.BootclasspathArtifact;
 import org.apache.maven.plugin.javadoc.options.DocletArtifact;
 import org.apache.maven.plugin.javadoc.options.Group;
+import org.apache.maven.plugin.javadoc.options.JavadocOptions;
 import org.apache.maven.plugin.javadoc.options.JavadocPathArtifact;
 import org.apache.maven.plugin.javadoc.options.OfflineLink;
 import org.apache.maven.plugin.javadoc.options.ResourcesArtifact;
 import org.apache.maven.plugin.javadoc.options.Tag;
 import org.apache.maven.plugin.javadoc.options.Taglet;
 import org.apache.maven.plugin.javadoc.options.TagletArtifact;
+import org.apache.maven.plugin.javadoc.options.io.xpp3.JavadocOptionsXpp3Writer;
+import org.apache.maven.plugin.javadoc.resolver.JavadocBundle;
 import org.apache.maven.plugin.javadoc.resolver.ResourceResolver;
 import org.apache.maven.plugin.javadoc.resolver.SourceResolverConfig;
 import org.apache.maven.project.MavenProject;
@@ -116,6 +127,24 @@ public abstract class AbstractJavadocMoj
     extends AbstractMojo
 {
     /**
+     * Classifier used in the name of the javadoc-options XML file, and in the resources bundle 
+     * artifact that gets attached to the project. This one is used for non-test javadocs.
+     * 
+     * @since 2.6.2
+     * @see #TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER
+     */
+    public static final String JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER = "javadoc-resources";
+    
+    /**
+     * Classifier used in the name of the javadoc-options XML file, and in the resources bundle 
+     * artifact that gets attached to the project. This one is used for test-javadocs.
+     * 
+     * @since 2.6.2
+     * @see #JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER
+     */
+    public static final String TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER = "test-javadoc-resources";
+
+    /**
      * The default Javadoc API urls according the
      * <a href="http://java.sun.com/reference/api/index.html">Sun API Specifications</a>:
      * <pre>
@@ -1072,7 +1101,7 @@ public abstract class AbstractJavadocMoj
      * @see #detectLinks
      * @see #detectJavaApiLink
      */
-    protected ArrayList links;
+    protected ArrayList<String> links;
 
     /**
      * Creates an HTML version of each source file (with line numbers) and adds links to them from the standard
@@ -1598,6 +1627,24 @@ public abstract class AbstractJavadocMoj
      */
     private List<String> dependencySourceExcludes;
     
+    /**
+     * Directory into which assembled {@link JavadocOptions} instances will be written before they
+     * are added to javadoc resources bundles.
+     * 
+     * @parameter default-value="${project.build.directory}/javadoc-bundle-options"
+     * @readonly
+     * @since 2.6.2
+     */
+    private File javadocOptionsDir;
+
+    /**
+     * Transient variable to allow lazy-resolution of javadoc bundles from dependencies, so they can
+     * be used at various points in the javadoc generation process.
+     * 
+     * @since 2.6.2
+     */
+    private transient List<JavadocBundle> dependencyJavadocBundles;
+    
     // ----------------------------------------------------------------------
     // static
     // ----------------------------------------------------------------------
@@ -1633,6 +1680,11 @@ public abstract class AbstractJavadocMoj
     {
         return outputDirectory.getAbsoluteFile().toString();
     }
+    
+    protected MavenProject getProject()
+    {
+        return project;
+    }
 
     /**
      * @param p not null maven project
@@ -1771,6 +1823,17 @@ public abstract class AbstractJavadocMoj
             this.debug = true;
         }
 
+        // NOTE: Always generate this file, to allow javadocs from modules to be aggregated via
+        // useDependencySources in a distro module build.
+        try
+        {
+            buildJavadocOptions();
+        }
+        catch ( IOException e )
+        {
+            throw new MavenReportException( "Failed to generate javadoc options file: " + e.getMessage(), e );
+        }
+        
         List sourcePaths = getSourcePaths();
         List files = getFiles( sourcePaths );
         if ( !canGenerateReport( files ) )
@@ -1932,8 +1995,10 @@ public abstract class AbstractJavadocMoj
      *
      * @param sourcePaths a List that contains the paths to the source files
      * @return a List that contains the specific path for every source file
+     * @throws MavenReportException 
      */
     protected List getFiles( List sourcePaths )
+        throws MavenReportException
     {
         List files = new ArrayList();
         if ( StringUtils.isEmpty( subpackages ) )
@@ -2075,11 +2140,7 @@ public abstract class AbstractJavadocMoj
             throw new MavenReportException( "Failed to delete cache directory: " + sourceDependencyCacheDir + "\nReason: " + e.getMessage(), e );
         }
         
-        final SourceResolverConfig config =
-            new SourceResolverConfig( project, localRepository, sourceDependencyCacheDir, resolver, factory,
-                                      artifactMetadataSource, archiverManager ).withReactorProjects( reactorProjects );
-
-        configureDependencySourceResolution( config );
+        final SourceResolverConfig config = getDependencySourceResolverConfig();
 
         final AndArtifactFilter andFilter = new AndArtifactFilter();
 
@@ -2105,7 +2166,7 @@ public abstract class AbstractJavadocMoj
 
         try
         {
-            return ResourceResolver.resolveSourceDirs( config );
+            return ResourceResolver.resolveDependencySourcePaths( config );
         }
         catch ( final ArtifactResolutionException e )
         {
@@ -2120,13 +2181,19 @@ public abstract class AbstractJavadocMoj
     }
 
     /**
-     * Convenience method to determine that a collection is not empty or null.
+     * Construct a SourceResolverConfig for resolving dependency sources and resources in a consistent
+     * way, so it can be reused for both source and resource resolution.
+     * 
+     * @since 2.6.2
      */
-    protected final boolean isNotEmpty( final List<?> collection )
+    private SourceResolverConfig getDependencySourceResolverConfig()
     {
-        return collection != null && !collection.isEmpty();
+        return configureDependencySourceResolution( new SourceResolverConfig( getLog(), project, localRepository,
+                                                                              sourceDependencyCacheDir, resolver,
+                                                                              factory, artifactMetadataSource,
+                                                                              archiverManager ).withReactorProjects( reactorProjects ) );
     }
-    
+
     /**
      * Method that indicates whether the javadoc can be generated or not. If the project does not contain any source
      * files and no subpackages are specified, the plugin will terminate.
@@ -2166,8 +2233,10 @@ public abstract class AbstractJavadocMoj
      *
      * @param sourcePaths the list of paths to the source files
      * @return a String that contains the exclude argument that will be used by javadoc
+     * @throws MavenReportException 
      */
     private String getExcludedPackages( List sourcePaths )
+        throws MavenReportException
     {
         List excludedNames = null;
 
@@ -2223,22 +2292,55 @@ public abstract class AbstractJavadocMoj
      * with ',', ':', or ';' and then formatted.
      *
      * @return an array of String objects that contain the package names
+     * @throws MavenReportException 
      */
     private String[] getExcludedPackages()
+        throws MavenReportException
     {
-        String[] excludePackages = {};
-
+        Set<String> excluded = new LinkedHashSet<String>();
+        
+        if ( includeDependencySources )
+        {
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
+            }
+            
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
+                {
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getExcludePackageNames() ) )
+                    {
+                        excluded.addAll( options.getExcludePackageNames() );
+                    }
+                }
+            }
+        }
+        
         // for the specified excludePackageNames
-        if ( excludePackageNames != null )
+        if ( StringUtils.isNotEmpty( excludePackageNames ) )
         {
-            excludePackages = excludePackageNames.split( "[,:;]" );
+            excluded.addAll( Arrays.asList( excludePackageNames.split( "[,:;]" ) ) );
         }
-        for ( int i = 0; i < excludePackages.length; i++ )
+        
+        String[] result = new String[excluded.size()];
+        if ( isNotEmpty( excluded ) )
         {
-            excludePackages[i] = excludePackages[i].replace( '.', File.separatorChar );
+            int idx = 0;
+            for ( String exclude : excluded )
+            {
+                result[idx] = exclude.replace( '.', File.separatorChar );
+                idx++;
+            }
         }
 
-        return excludePackages;
+        return result;
     }
 
     /**
@@ -2577,27 +2679,23 @@ public abstract class AbstractJavadocMoj
     private String getBootclassPath()
         throws MavenReportException
     {
-        StringBuffer path = new StringBuffer();
-
-        if ( bootclasspathArtifacts != null )
+        Set<BootclasspathArtifact> bootclasspathArtifacts = collectBootClasspathArtifacts();
+        
+        List<String> bootclassPath = new ArrayList<String>();
+        for ( BootclasspathArtifact aBootclasspathArtifact : bootclasspathArtifacts )
         {
-            List bootclassPath = new ArrayList();
-            for ( int i = 0; i < bootclasspathArtifacts.length; i++ )
+            if ( ( StringUtils.isNotEmpty( aBootclasspathArtifact.getGroupId() ) )
+                && ( StringUtils.isNotEmpty( aBootclasspathArtifact.getArtifactId() ) )
+                && ( StringUtils.isNotEmpty( aBootclasspathArtifact.getVersion() ) ) )
             {
-                BootclasspathArtifact aBootclasspathArtifact = bootclasspathArtifacts[i];
-
-                if ( ( StringUtils.isNotEmpty( aBootclasspathArtifact.getGroupId() ) )
-                    && ( StringUtils.isNotEmpty( aBootclasspathArtifact.getArtifactId() ) )
-                    && ( StringUtils.isNotEmpty( aBootclasspathArtifact.getVersion() ) ) )
-                {
-                    bootclassPath.addAll( getArtifactsAbsolutePath( aBootclasspathArtifact ) );
-                }
+                bootclassPath.addAll( getArtifactsAbsolutePath( aBootclasspathArtifact ) );
             }
+        }
 
-            bootclassPath = JavadocUtil.pruneFiles( bootclassPath );
+        bootclassPath = JavadocUtil.pruneFiles( bootclassPath );
 
-            path.append( StringUtils.join( bootclassPath.iterator(), File.pathSeparator ) );
-        }
+        StringBuffer path = new StringBuffer();
+        path.append( StringUtils.join( bootclassPath.iterator(), File.pathSeparator ) );
 
         if ( StringUtils.isNotEmpty( bootclasspath ) )
         {
@@ -2622,28 +2720,19 @@ public abstract class AbstractJavadocMoj
     private String getDocletPath()
         throws MavenReportException
     {
-        StringBuffer path = new StringBuffer();
-        if ( !isDocletArtifactEmpty( docletArtifact ) )
-        {
-            path.append( StringUtils.join( getArtifactsAbsolutePath( docletArtifact ).iterator(),
-                                           File.pathSeparator ) );
-        }
-        else if ( docletArtifacts != null )
+        Set<DocletArtifact> docletArtifacts = collectDocletArtifacts();
+        List<String> pathParts = new ArrayList<String>();
+        
+        for ( DocletArtifact docletArtifact : docletArtifacts )
         {
-            for ( int i = 0; i < docletArtifacts.length; i++ )
+            if ( !isDocletArtifactEmpty( docletArtifact ) )
             {
-                if ( !isDocletArtifactEmpty( docletArtifacts[i] ) )
-                {
-                    path.append( StringUtils.join( getArtifactsAbsolutePath( docletArtifacts[i] ).iterator(),
-                                                   File.pathSeparator ) );
-
-                    if ( i < docletArtifacts.length - 1 )
-                    {
-                        path.append( File.pathSeparator );
-                    }
-                }
+                pathParts.addAll( getArtifactsAbsolutePath( docletArtifact ) );
             }
         }
+        
+        StringBuffer path = new StringBuffer();
+        path.append( StringUtils.join( pathParts.iterator(), File.pathSeparator ) );
 
         if ( !StringUtils.isEmpty( docletPath ) )
         {
@@ -2690,74 +2779,411 @@ public abstract class AbstractJavadocMoj
     private String getTagletPath()
         throws MavenReportException
     {
+        Set<TagletArtifact> tArtifacts = collectTagletArtifacts();
+        List<String> pathParts = new ArrayList<String>();
+        
+        for ( TagletArtifact tagletArtifact : tArtifacts )
+        {
+            if ( ( tagletArtifact != null ) && ( StringUtils.isNotEmpty( tagletArtifact.getGroupId() ) )
+                && ( StringUtils.isNotEmpty( tagletArtifact.getArtifactId() ) )
+                && ( StringUtils.isNotEmpty( tagletArtifact.getVersion() ) ) )
+            {
+                pathParts.addAll( getArtifactsAbsolutePath( tagletArtifact ) );
+            }
+        }
+
+        
+        Set<Taglet> taglets = collectTaglets();
+        for ( Taglet taglet : taglets )
+        {
+            if ( taglet == null )
+            {
+                continue;
+            }
+
+            if ( ( taglet.getTagletArtifact() != null )
+                && ( StringUtils.isNotEmpty( taglet.getTagletArtifact().getGroupId() ) )
+                && ( StringUtils.isNotEmpty( taglet.getTagletArtifact().getArtifactId() ) )
+                && ( StringUtils.isNotEmpty( taglet.getTagletArtifact().getVersion() ) ) )
+            {
+                pathParts.addAll( getArtifactsAbsolutePath( taglet.getTagletArtifact() ) );
+
+                pathParts = JavadocUtil.pruneFiles( pathParts );
+            }
+            else if ( StringUtils.isNotEmpty( taglet.getTagletpath() ) )
+            {
+                pathParts.add( taglet.getTagletpath() );
+
+                pathParts = JavadocUtil.pruneDirs( project, pathParts );
+            }
+        }
+        
         StringBuffer path = new StringBuffer();
+        path.append( StringUtils.join( pathParts.iterator(), File.pathSeparator ) );
 
-        if ( ( tagletArtifact != null ) && ( StringUtils.isNotEmpty( tagletArtifact.getGroupId() ) )
-            && ( StringUtils.isNotEmpty( tagletArtifact.getArtifactId() ) )
-            && ( StringUtils.isNotEmpty( tagletArtifact.getVersion() ) ) )
+        if ( StringUtils.isNotEmpty( tagletpath ) )
         {
-            path.append( StringUtils.join( getArtifactsAbsolutePath( tagletArtifact ).iterator(),
-                                           File.pathSeparator ) );
+            path.append( JavadocUtil.unifyPathSeparator( tagletpath ) );
         }
 
-        if ( tagletArtifacts != null )
+        return path.toString();
+    }
+    
+    private Set<String> collectLinks()
+        throws MavenReportException
+    {
+        Set<String> links = new LinkedHashSet<String>();
+        
+        if ( includeDependencySources )
         {
-            List tagletsPath = new ArrayList();
-            for ( int i = 0; i < tagletArtifacts.length; i++ )
+            try
             {
-                TagletArtifact aTagletArtifact = tagletArtifacts[i];
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
+            }
+            
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
+                {
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getLinks() ) )
+                    {
+                        links.addAll( options.getLinks() );
+                    }
+                }
+            }
+        }
+        
+        if ( isNotEmpty( this.links ) )
+        {
+            links.addAll( this.links );
+        }
+        
+        String javaApiLink = getDefaultJavadocApiLink();
+        if ( javaApiLink != null )
+        {
+            links.add( javaApiLink );
+        }
 
-                if ( ( StringUtils.isNotEmpty( aTagletArtifact.getGroupId() ) )
-                    && ( StringUtils.isNotEmpty( aTagletArtifact.getArtifactId() ) )
-                    && ( StringUtils.isNotEmpty( aTagletArtifact.getVersion() ) ) )
+        links.addAll( getDependenciesLinks() );
+        
+        return links;
+    }
+    
+    private Set<Group> collectGroups()
+        throws MavenReportException
+    {
+        Set<Group> groups = new LinkedHashSet<Group>();
+        
+        if ( includeDependencySources )
+        {
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
+            }
+            
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
                 {
-                    tagletsPath.addAll( getArtifactsAbsolutePath( aTagletArtifact ) );
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getGroups() ) )
+                    {
+                        groups.addAll( options.getGroups() );
+                    }
                 }
             }
+        }
+        
+        if ( this.groups != null && this.groups.length > 0 )
+        {
+            groups.addAll( Arrays.asList( this.groups ) );
+        }
+        
+        return groups;
+    }
+
+    private Set<ResourcesArtifact> collectResourcesArtifacts()
+        throws MavenReportException
+    {
+        Set<ResourcesArtifact> result = new LinkedHashSet<ResourcesArtifact>();
+
+        if ( includeDependencySources )
+        {
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: "
+                    + e.getMessage(), e );
+            }
 
-            tagletsPath = JavadocUtil.pruneFiles( tagletsPath );
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
+                {
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getResourcesArtifacts() ) )
+                    {
+                        result.addAll( options.getResourcesArtifacts() );
+                    }
+                }
+            }
+        }
 
-            path.append( StringUtils.join( tagletsPath.iterator(), File.pathSeparator ) );
+        if ( this.resourcesArtifacts != null && this.resourcesArtifacts.length > 0 )
+        {
+            result.addAll( Arrays.asList( this.resourcesArtifacts ) );
         }
 
-        if ( taglets != null )
+        return result;
+    }
+
+    private Set<BootclasspathArtifact> collectBootClasspathArtifacts()
+        throws MavenReportException
+    {
+        Set<BootclasspathArtifact> result = new LinkedHashSet<BootclasspathArtifact>();
+
+        if ( includeDependencySources )
         {
-            List tagletsPath = new ArrayList();
-            for ( int i = 0; i < taglets.length; i++ )
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
             {
-                Taglet current = taglets[i];
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: "
+                    + e.getMessage(), e );
+            }
 
-                if ( current == null )
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
                 {
-                    continue;
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getBootclasspathArtifacts() ) )
+                    {
+                        result.addAll( options.getBootclasspathArtifacts() );
+                    }
                 }
+            }
+        }
+
+        if ( this.bootclasspathArtifacts != null && this.bootclasspathArtifacts.length > 0 )
+        {
+            result.addAll( Arrays.asList( this.bootclasspathArtifacts ) );
+        }
+
+        return result;
+    }
 
-                if ( ( current.getTagletArtifact() != null )
-                    && ( StringUtils.isNotEmpty( current.getTagletArtifact().getGroupId() ) )
-                    && ( StringUtils.isNotEmpty( current.getTagletArtifact().getArtifactId() ) )
-                    && ( StringUtils.isNotEmpty( current.getTagletArtifact().getVersion() ) ) )
+    private Set<OfflineLink> collectOfflineLinks()
+        throws MavenReportException
+    {
+        Set<OfflineLink> result = new LinkedHashSet<OfflineLink>();
+
+        if ( includeDependencySources )
+        {
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: "
+                    + e.getMessage(), e );
+            }
+
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
                 {
-                    tagletsPath.addAll( getArtifactsAbsolutePath( current.getTagletArtifact() ) );
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getOfflineLinks() ) )
+                    {
+                        result.addAll( options.getOfflineLinks() );
+                    }
+                }
+            }
+        }
+
+        if ( this.offlineLinks != null && this.offlineLinks.length > 0 )
+        {
+            result.addAll( Arrays.asList( this.offlineLinks ) );
+        }
+
+        return result;
+    }
+
+    private Set<Tag> collectTags()
+        throws MavenReportException
+    {
+        Set<Tag> tags = new LinkedHashSet<Tag>();
+
+        if ( includeDependencySources )
+        {
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: "
+                    + e.getMessage(), e );
+            }
 
-                    tagletsPath = JavadocUtil.pruneFiles( tagletsPath );
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
+                {
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getTags() ) )
+                    {
+                        tags.addAll( options.getTags() );
+                    }
                 }
-                else if ( StringUtils.isNotEmpty( current.getTagletpath() ) )
+            }
+        }
+
+        if ( this.tags != null && this.tags.length > 0 )
+        {
+            tags.addAll( Arrays.asList( this.tags ) );
+        }
+
+        return tags;
+    }
+
+    private Set<TagletArtifact> collectTagletArtifacts()
+        throws MavenReportException
+    {
+        Set<TagletArtifact> tArtifacts = new LinkedHashSet<TagletArtifact>();
+        
+        if ( includeDependencySources )
+        {
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
+            }
+            
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
                 {
-                    tagletsPath.add( current.getTagletpath() );
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getTagletArtifacts() ) )
+                    {
+                        tArtifacts.addAll( options.getTagletArtifacts() );
+                    }
+                }
+            }
+        }
+        
+        if ( tagletArtifact != null )
+        {
+            tArtifacts.add( tagletArtifact );
+        }
+        
+        if ( tagletArtifacts != null && tagletArtifacts.length > 0 )
+        {
+            tArtifacts.addAll( Arrays.asList( tagletArtifacts ) );
+        }
+        
+        return tArtifacts;
+    }
+
+    private Set<DocletArtifact> collectDocletArtifacts()
+        throws MavenReportException
+    {
+        Set<DocletArtifact> dArtifacts = new LinkedHashSet<DocletArtifact>();
+
+        if ( includeDependencySources )
+        {
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: "
+                    + e.getMessage(), e );
+            }
 
-                    tagletsPath = JavadocUtil.pruneDirs( project, tagletsPath );
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
+                {
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getDocletArtifacts() ) )
+                    {
+                        dArtifacts.addAll( options.getDocletArtifacts() );
+                    }
                 }
             }
+        }
 
-            path.append( StringUtils.join( tagletsPath.iterator(), File.pathSeparator ) );
+        if ( docletArtifact != null )
+        {
+            dArtifacts.add( docletArtifact );
         }
 
-        if ( StringUtils.isNotEmpty( tagletpath ) )
+        if ( docletArtifacts != null && docletArtifacts.length > 0 )
         {
-            path.append( JavadocUtil.unifyPathSeparator( tagletpath ) );
+            dArtifacts.addAll( Arrays.asList( docletArtifacts ) );
         }
 
-        return path.toString();
+        return dArtifacts;
+    }
+
+    private Set<Taglet> collectTaglets()
+        throws MavenReportException
+    {
+        Set<Taglet> result = new LinkedHashSet<Taglet>();
+
+        if ( includeDependencySources )
+        {
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: "
+                    + e.getMessage(), e );
+            }
+
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
+                {
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getTaglets() ) )
+                    {
+                        result.addAll( options.getTaglets() );
+                    }
+                }
+            }
+        }
+
+        if ( taglet != null && taglets.length > 0 )
+        {
+            result.addAll( Arrays.asList( taglets ) );
+        }
+
+        return result;
     }
 
     /**
@@ -2767,17 +3193,17 @@ public abstract class AbstractJavadocMoj
      * @return a list of locale artifacts absolute path
      * @throws MavenReportException if any
      */
-    private List getArtifactsAbsolutePath( JavadocPathArtifact javadocArtifact )
+    private List<String> getArtifactsAbsolutePath( JavadocPathArtifact javadocArtifact )
         throws MavenReportException
     {
         if ( ( StringUtils.isEmpty( javadocArtifact.getGroupId() ) )
             && ( StringUtils.isEmpty( javadocArtifact.getArtifactId() ) )
             && ( StringUtils.isEmpty( javadocArtifact.getVersion() ) ) )
         {
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
 
-        List path = new ArrayList();
+        List<String> path = new ArrayList<String>();
 
         try
         {
@@ -3357,37 +3783,31 @@ public abstract class AbstractJavadocMoj
      * @see #getModulesLinks()
      * @see <a href="http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javadoc.html#package-list">package-list spec</a>
      */
-    private void addLinkofflineArguments( List arguments )
+    private void addLinkofflineArguments( List<String> arguments )
         throws MavenReportException
     {
-        List offlineLinksList =
-            ( offlineLinks != null ? new ArrayList( Arrays.asList( offlineLinks ) ) : new ArrayList() );
+        Set<OfflineLink> offlineLinksList = collectOfflineLinks();
 
         offlineLinksList.addAll( getModulesLinks() );
 
-        if ( offlineLinksList != null )
+        for ( OfflineLink offlineLink : offlineLinksList )
         {
-            for ( int i = 0; i < offlineLinksList.size(); i++ )
+            String url = offlineLink.getUrl();
+            if ( StringUtils.isEmpty( url ) )
             {
-                OfflineLink offlineLink = (OfflineLink) offlineLinksList.get( i );
-
-                String url = offlineLink.getUrl();
-                if ( StringUtils.isEmpty( url ) )
-                {
-                    continue;
-                }
-                url = cleanUrl( url );
+                continue;
+            }
+            url = cleanUrl( url );
 
-                String location = offlineLink.getLocation();
-                if ( StringUtils.isEmpty( location ) )
-                {
-                    continue;
-                }
-                if ( isValidJavadocLink( location ) )
-                {
-                    addArgIfNotEmpty( arguments, "-linkoffline", JavadocUtil.quotedPathArgument( url )
-                                      + " " + JavadocUtil.quotedPathArgument( location ), true );
-                }
+            String location = offlineLink.getLocation();
+            if ( StringUtils.isEmpty( location ) )
+            {
+                continue;
+            }
+            if ( isValidJavadocLink( location ) )
+            {
+                addArgIfNotEmpty( arguments, "-linkoffline", JavadocUtil.quotedPathArgument( url ) + " "
+                    + JavadocUtil.quotedPathArgument( location ), true );
             }
         }
     }
@@ -3406,30 +3826,19 @@ public abstract class AbstractJavadocMoj
      * </ul>
      *
      * @param arguments a list of arguments, not null
+     * @throws MavenReportException 
      * @see #detectLinks
      * @see #getDependenciesLinks()
      * @see JavadocUtil#fetchURL(Settings, URL)
      * @see <a href="http://java.sun.com/j2se/1.4.2/docs/tooldocs/windows/javadoc.html#package-list">package-list spec</a>
      */
-    private void addLinkArguments( List arguments )
+    private void addLinkArguments( List<String> arguments )
+        throws MavenReportException
     {
-        if ( links == null )
-        {
-            links = new ArrayList();
-        }
+        Set<String> links = collectLinks();
 
-        String javaApiLink = getDefaultJavadocApiLink();
-        if ( javaApiLink != null )
+        for ( String link : links )
         {
-            links.add( javaApiLink );
-        }
-
-        links.addAll( getDependenciesLinks() );
-
-        for ( int i = 0; i < links.size(); i++ )
-        {
-            String link = (String) links.get( i );
-
             if ( StringUtils.isEmpty( link ) )
             {
                 continue;
@@ -3546,6 +3955,24 @@ public abstract class AbstractJavadocMoj
             throw new IOException( "The outputDirectory " + anOutputDirectory + " doesn't exists." );
         }
 
+        if ( includeDependencySources )
+        {
+            resolveDependencyBundles();
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
+                {
+                    File dir = bundle.getResourcesDirectory();
+                    JavadocOptions options = bundle.getOptions();
+                    if ( dir != null && dir.isDirectory() )
+                    {
+                        JavadocUtil.copyJavadocResources( anOutputDirectory, dir, options == null ? null
+                                        : options.getExcludedDocfilesSubdirs() );
+                    }
+                }
+            }
+        }
+        
         if ( getJavadocDirectory() != null )
         {
             JavadocUtil.copyJavadocResources( anOutputDirectory, getJavadocDirectory(), excludedocfilessubdir );
@@ -3568,6 +3995,19 @@ public abstract class AbstractJavadocMoj
         }
     }
 
+    private synchronized void resolveDependencyBundles()
+        throws IOException
+    {
+        if ( dependencyJavadocBundles == null )
+        {
+            dependencyJavadocBundles = ResourceResolver.resolveDependencyJavadocBundles( getDependencySourceResolverConfig() );
+            if ( dependencyJavadocBundles == null )
+            {
+                dependencyJavadocBundles = new ArrayList<JavadocBundle>();
+            }
+        }
+    }
+
     /**
      * Method that copy additional Javadoc resources from given artifacts.
      *
@@ -3578,7 +4018,8 @@ public abstract class AbstractJavadocMoj
     private void copyAdditionalJavadocResources( File anOutputDirectory )
         throws MavenReportException
     {
-        if ( resourcesArtifacts == null || resourcesArtifacts.length == 0 )
+        Set<ResourcesArtifact> resourcesArtifacts = collectResourcesArtifacts();
+        if ( isEmpty( resourcesArtifacts ) )
         {
             return;
         }
@@ -3594,10 +4035,8 @@ public abstract class AbstractJavadocMoj
                 + "No archiver for 'jar' available.", e );
         }
 
-        for ( int i = 0; i < resourcesArtifacts.length; i++ )
+        for ( ResourcesArtifact item : resourcesArtifacts )
         {
-            ResourcesArtifact item = resourcesArtifacts[i];
-
             Artifact artifact;
             try
             {
@@ -4254,19 +4693,21 @@ public abstract class AbstractJavadocMoj
      * Add <code>groups</code> parameter to arguments.
      *
      * @param arguments not null
+     * @throws MavenReportException 
      */
     private void addGroups( List arguments )
+        throws MavenReportException
     {
-        if ( groups == null )
+        Set<Group> groups = collectGroups();
+        if ( isEmpty( groups ) )
         {
             return;
-
         }
 
-        for ( int i = 0; i < groups.length; i++ )
+        for ( Group group : groups )
         {
-            if ( groups[i] == null || StringUtils.isEmpty( groups[i].getTitle() )
-                || StringUtils.isEmpty( groups[i].getPackages() ) )
+            if ( group == null || StringUtils.isEmpty( group.getTitle() )
+                || StringUtils.isEmpty( group.getPackages() ) )
             {
                 if ( getLog().isWarnEnabled() )
                 {
@@ -4275,9 +4716,9 @@ public abstract class AbstractJavadocMoj
             }
             else
             {
-                String groupTitle = StringUtils.replace( groups[i].getTitle(), ",", "&#44;" );
+                String groupTitle = StringUtils.replace( group.getTitle(), ",", "&#44;" );
                 addArgIfNotEmpty( arguments, "-group", JavadocUtil.quotedArgument( groupTitle ) + " "
-                    + JavadocUtil.quotedArgument( groups[i].getPackages() ), true );
+                    + JavadocUtil.quotedArgument( group.getPackages() ), true );
             }
         }
     }
@@ -4286,17 +4727,21 @@ public abstract class AbstractJavadocMoj
      * Add <code>tags</code> parameter to arguments.
      *
      * @param arguments not null
+     * @throws MavenReportException 
      */
     private void addTags( List arguments )
+        throws MavenReportException
     {
-        if ( tags == null )
+        Set<Tag> tags = collectTags();
+        
+        if ( isEmpty( tags ) )
         {
             return;
         }
 
-        for ( int i = 0; i < tags.length; i++ )
+        for ( Tag tag : tags )
         {
-            if ( StringUtils.isEmpty( tags[i].getName() ) )
+            if ( StringUtils.isEmpty( tag.getName() ) )
             {
                 if ( getLog().isWarnEnabled() )
                 {
@@ -4305,13 +4750,13 @@ public abstract class AbstractJavadocMoj
             }
             else
             {
-                String value = "\"" + tags[i].getName();
-                if ( StringUtils.isNotEmpty( tags[i].getPlacement() ) )
+                String value = "\"" + tag.getName();
+                if ( StringUtils.isNotEmpty( tag.getPlacement() ) )
                 {
-                    value += ":" + tags[i].getPlacement();
-                    if ( StringUtils.isNotEmpty( tags[i].getHead() ) )
+                    value += ":" + tag.getPlacement();
+                    if ( StringUtils.isNotEmpty( tag.getHead() ) )
                     {
-                        value += ":" + tags[i].getHead();
+                        value += ":" + tag.getHead();
                     }
                 }
                 value += "\"";
@@ -4359,16 +4804,45 @@ public abstract class AbstractJavadocMoj
     private void addTagletsFromTagletArtifacts( List arguments )
         throws MavenReportException
     {
-        if ( tagletArtifacts == null )
+        Set<TagletArtifact> tArtifacts = new LinkedHashSet<TagletArtifact>();
+        if ( tagletArtifacts != null && tagletArtifacts.length > 0 )
+        {
+            tArtifacts.addAll( Arrays.asList( tagletArtifacts ) );
+        }
+        
+        if ( includeDependencySources )
+        {
+            try
+            {
+                resolveDependencyBundles();
+            }
+            catch ( IOException e )
+            {
+                throw new MavenReportException( "Failed to resolve javadoc bundles from dependencies: " + e.getMessage(), e );
+            }
+            
+            if ( isNotEmpty( dependencyJavadocBundles ) )
+            {
+                for ( JavadocBundle bundle : dependencyJavadocBundles )
+                {
+                    JavadocOptions options = bundle.getOptions();
+                    if ( options != null && isNotEmpty( options.getTagletArtifacts() ) )
+                    {
+                        tArtifacts.addAll( options.getTagletArtifacts() );
+                    }
+                }
+            }
+        }
+        
+        if ( isEmpty( tArtifacts ) )
         {
             return;
         }
 
         List tagletsPath = new ArrayList();
-        for ( int i = 0; i < tagletArtifacts.length; i++ )
+        
+        for ( TagletArtifact aTagletArtifact: tArtifacts )
         {
-            TagletArtifact aTagletArtifact = tagletArtifacts[i];
-
             if ( ( StringUtils.isNotEmpty( aTagletArtifact.getGroupId() ) )
                 && ( StringUtils.isNotEmpty( aTagletArtifact.getArtifactId() ) )
                 && ( StringUtils.isNotEmpty( aTagletArtifact.getVersion() ) ) )
@@ -4784,7 +5258,7 @@ public abstract class AbstractJavadocMoj
      * @see #reactorProjects
      * @since 2.6
      */
-    private List getModulesLinks()
+    private List<OfflineLink> getModulesLinks()
         throws MavenReportException
     {
         if ( !( detectOfflineLinks && !isAggregator() && reactorProjects != null ) )
@@ -4885,7 +5359,7 @@ public abstract class AbstractJavadocMoj
      * @see #detectLinks
      * @since 2.6
      */
-    private List getDependenciesLinks()
+    private List<String> getDependenciesLinks()
     {
         if ( !detectLinks )
         {
@@ -5239,4 +5713,72 @@ public abstract class AbstractJavadocMoj
 
         return null;
     }
+    
+    /**
+     * Construct the output file for the generated javadoc-options XML file, after creating the 
+     * javadocOptionsDir if necessary. This method does NOT write to the file in question.
+     * 
+     * @since 2.6.2
+     */
+    protected final File getJavadocOptionsFile()
+    {
+        if ( !javadocOptionsDir.exists() )
+        {
+            javadocOptionsDir.mkdirs();
+        }
+        
+        return new File( javadocOptionsDir, "javadoc-options-" + getAttachmentClassifier() + ".xml" );
+    }
+    
+    /**
+     * Generate a javadoc-options XML file, for either bundling with a javadoc-resources artifact OR
+     * supplying to a distro module in a includeDependencySources configuration, so the javadoc options
+     * from this execution can be reconstructed and merged in the distro build.
+     * 
+     * @since 2.6.2
+     */
+    protected final JavadocOptions buildJavadocOptions()
+        throws IOException
+    {
+        JavadocOptions options = new JavadocOptions();
+        
+        options.setBootclasspathArtifacts( toList( bootclasspathArtifacts ) );
+        options.setDocfilesSubdirsUsed( docfilessubdirs );
+        options.setDocletArtifacts( toList( docletArtifact, docletArtifacts ) );
+        options.setExcludedDocfilesSubdirs( excludedocfilessubdir );
+        options.setExcludePackageNames( toList( excludePackageNames ) );
+        options.setGroups( toList( groups ) );
+        options.setLinks( links );
+        options.setOfflineLinks( toList( offlineLinks ) );
+        options.setResourcesArtifacts( toList( resourcesArtifacts ) );
+        options.setTagletArtifacts( toList( tagletArtifact, tagletArtifacts ) );
+        options.setTaglets( toList( taglets ) );
+        options.setTags( toList( tags ) );
+        
+        options.setJavadocResourcesDirectory( toRelative( project.getBasedir(), getJavadocDirectory().getAbsolutePath() ) );
+        
+        File optionsFile = getJavadocOptionsFile();
+        FileWriter writer = null;
+        try
+        {
+            writer = new FileWriter( optionsFile );
+            new JavadocOptionsXpp3Writer().write( writer, options );
+        }
+        finally
+        {
+            close( writer );
+        }
+        
+        return options;
+    }
+    
+    /**
+     * Override this if you need to provide a bundle attachment classifier, as in the case of test 
+     * javadocs.
+     */
+    protected String getAttachmentClassifier()
+    {
+        return JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER;
+    }
+    
 }

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/JavadocReport.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/JavadocReport.java?rev=933380&r1=933379&r2=933380&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/JavadocReport.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/JavadocReport.java Mon Apr 12 19:44:10 2010
@@ -207,9 +207,11 @@ public class JavadocReport
         if ( !this.isAggregator() || ( this.isAggregator() && this.project.isExecutionRoot() ) )
         {
             List sourcePaths;
+            List files;
             try
             {
                 sourcePaths = getSourcePaths();
+                files = getFiles( sourcePaths );
             }
             catch ( MavenReportException e )
             {
@@ -217,8 +219,6 @@ public class JavadocReport
                 return false;
             }
 
-            List files = getFiles( sourcePaths );
-
             canGenerate = canGenerateReport( files );
         }
         if ( getLog().isDebugEnabled() )

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/JavadocUtil.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/JavadocUtil.java?rev=933380&r1=933379&r2=933380&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/JavadocUtil.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/JavadocUtil.java Mon Apr 12 19:44:10 2010
@@ -19,6 +19,9 @@ package org.apache.maven.plugin.javadoc;
  * under the License.
  */
 
+import static org.codehaus.plexus.util.StringUtils.isEmpty;
+import static org.codehaus.plexus.util.StringUtils.isNotEmpty;
+
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -36,6 +39,7 @@ import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
@@ -108,13 +112,11 @@ public class JavadocUtil
      * @param dirs the list of <code>String</code> directories path that will be validated.
      * @return a List of valid <code>String</code> directories absolute paths.
      */
-    public static List pruneDirs( MavenProject project, List dirs )
+    public static List<String> pruneDirs( MavenProject project, List<String> dirs )
     {
-        List pruned = new ArrayList( dirs.size() );
-        for ( Iterator i = dirs.iterator(); i.hasNext(); )
+        List<String> pruned = new ArrayList<String>( dirs.size() );
+        for ( String dir : dirs )
         {
-            String dir = (String) i.next();
-
             if ( dir == null )
             {
                 continue;
@@ -142,26 +144,36 @@ public class JavadocUtil
      * @param files the list of <code>String</code> files paths that will be validated.
      * @return a List of valid <code>File</code> objects.
      */
-    protected static List pruneFiles( List files )
+    protected static List<String> pruneFiles( List<String> files )
     {
-        List pruned = new ArrayList( files.size() );
-        for ( Iterator i = files.iterator(); i.hasNext(); )
+        List<String> pruned = new ArrayList<String>( files.size() );
+        for ( String f : files )
         {
-            String f = (String) i.next();
-
-            if ( f == null )
+            if ( !shouldPruneFile( f, pruned ) )
             {
-                continue;
+                pruned.add( f );
             }
+        }
+ 
+        return pruned;
+    }
 
+    /**
+     * Determine whether a file should be excluded from the provided list of paths, based on whether
+     * it exists and is already present in the list.
+     */
+    public static boolean shouldPruneFile( String f, List<String> pruned )
+    {
+        if ( f != null )
+        {
             File file = new File( f );
-            if ( file.isFile() && !pruned.contains( f ) )
+            if ( file.isFile() && ( isEmpty( pruned ) || !pruned.contains( f ) ) )
             {
-                pruned.add( f );
+                return false;
             }
         }
-
-        return pruned;
+        
+        return true;
     }
 
     /**
@@ -1614,4 +1626,112 @@ public class JavadocUtil
             return token;
         }
     }
+    
+    static List<String> toList( String src )
+    {
+        return toList( src, null, null );
+    }
+    
+    static List<String> toList( String src, String elementPrefix, String elementSuffix )
+    {
+        if ( StringUtils.isEmpty( src ) )
+        {
+            return null;
+        }
+        
+        List<String> result = new ArrayList<String>();
+
+        StringTokenizer st = new StringTokenizer( src, "[,:;]" );
+        StringBuilder sb = new StringBuilder( 256 );
+        while ( st.hasMoreTokens() )
+        {
+            sb.setLength( 0 );
+            if ( StringUtils.isNotEmpty( elementPrefix ) )
+            {
+                sb.append( elementPrefix );
+            }
+            
+            sb.append( st.nextToken() );
+            
+            if ( StringUtils.isNotEmpty( elementSuffix ) )
+            {
+                sb.append( elementSuffix );
+            }
+            
+            result.add( sb.toString() );
+        }
+        
+        return result;
+    }
+    
+    static <T> List<T> toList( T[] multiple )
+    {
+        return toList( null, multiple );
+    }
+    
+    static <T> List<T> toList( T single, T[] multiple )
+    {
+        if ( single == null && ( multiple == null || multiple.length < 1 ) )
+        {
+            return null;
+        }
+        
+        List<T> result = new ArrayList<T>();
+        if ( single != null )
+        {
+            result.add( single );
+        }
+        
+        if ( multiple != null && multiple.length > 0 )
+        {
+            result.addAll( Arrays.asList( multiple ) );
+        }
+        
+        return result;
+    }
+    
+    // TODO: move to plexus-utils or use something appropriate from there
+    public static String toRelative( File basedir, String absolutePath )
+    {
+        String relative;
+
+        absolutePath = absolutePath.replace( '\\', '/' );
+        String basedirPath = basedir.getAbsolutePath().replace( '\\', '/' );
+
+        if ( absolutePath.startsWith( basedirPath ) )
+        {
+            relative = absolutePath.substring( basedirPath.length() );
+            if ( relative.startsWith( "/" ) )
+            {
+                relative = relative.substring( 1 );
+            }
+            if ( relative.length() <= 0 )
+            {
+                relative = ".";
+            }
+        }
+        else
+        {
+            relative = absolutePath;
+        }
+
+        return relative;
+    }
+    
+    /**
+     * Convenience method to determine that a collection is not empty or null.
+     */
+    public static boolean isNotEmpty( final Collection<?> collection )
+    {
+        return collection != null && !collection.isEmpty();
+    }
+    
+    /**
+     * Convenience method to determine that a collection is empty or null.
+     */
+    public static boolean isEmpty( final Collection<?> collection )
+    {
+        return collection == null || collection.isEmpty();
+    }
+    
 }

Added: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/ResourcesBundleMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/ResourcesBundleMojo.java?rev=933380&view=auto
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/ResourcesBundleMojo.java (added)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/ResourcesBundleMojo.java Mon Apr 12 19:44:10 2010
@@ -0,0 +1,135 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.plugin.javadoc;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.javadoc.options.JavadocOptions;
+import org.apache.maven.project.MavenProjectHelper;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.manager.ArchiverManager;
+import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Bundle {@link AbstractJavadocMojo#javadocDirectory}, along with javadoc configuration options such
+ * as taglet, doclet, and link information into a deployable artifact. This artifact can then be consumed
+ * by the javadoc plugin mojos when used by the <code>includeDependencySources</code> option, to generate
+ * javadocs that are somewhat consistent with those generated in the original project itself.
+ *  
+ * @goal resource-bundle
+ * @phase package
+ * @since 2.6.2
+ */
+public class ResourcesBundleMojo
+    extends AbstractJavadocMojo
+{
+    
+    public static final String BUNDLE_OPTIONS_PATH = "META-INF/maven/javadoc-options.xml";
+
+    public static final String RESOURCES_DIR_PATH = "resources";
+
+    /**
+     * Base name of artifacts produced by this project. This will be combined with 
+     * {@link ResourcesBundleMojo#getAttachmentClassifier()} to produce the name for this bundle 
+     * jar.
+     * 
+     * @parameter default-value="${project.build.finalName}"
+     * @readonly
+     */
+    private String finalName;
+    
+    /**
+     * Helper component to provide an easy mechanism for attaching an artifact to the project for 
+     * installation/deployment.
+     * 
+     * @component
+     */
+    private MavenProjectHelper projectHelper;
+    
+    /**
+     * Archiver manager, used to manage jar builder.
+     *
+     * @component
+     */
+    private ArchiverManager archiverManager;
+
+    /**
+     * Assemble a new {@link JavadocOptions} instance that contains the configuration options in this
+     * mojo, which are a subset of those provided in derivatives of the {@link AbstractJavadocMojo}
+     * class (most of the javadoc mojos, in other words). Then, bundle the contents of the 
+     * <code>javadocDirectory</code> along with the assembled JavadocOptions instance (serialized to
+     * META-INF/maven/javadoc-options.xml) into a project attachment for installation/deployment.
+     * 
+     * {@inheritDoc}
+     * @see org.apache.maven.plugin.Mojo#execute()
+     */
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+        try
+        {
+            buildJavadocOptions();
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "Failed to generate javadoc-options file: " + e.getMessage(), e );
+        }
+        
+        Archiver archiver;
+        try
+        {
+            archiver = archiverManager.getArchiver( "jar" );
+        }
+        catch ( NoSuchArchiverException e )
+        {
+            throw new MojoExecutionException( "Failed to retrieve jar archiver component from manager.", e );
+        }
+        
+        File optionsFile = getJavadocOptionsFile();
+        File bundleFile = new File( getProject().getBuild().getDirectory(), finalName + "-" + getAttachmentClassifier() + ".jar" );
+        try
+        {
+            archiver.addFile( optionsFile, BUNDLE_OPTIONS_PATH );
+            
+            File javadocDir = getJavadocDirectory();
+            if ( javadocDir.exists() && javadocDir.isDirectory() )
+            {
+                archiver.addDirectory( javadocDir, RESOURCES_DIR_PATH );
+            }
+            
+            archiver.setDestFile( bundleFile );
+            archiver.createArchive();
+        }
+        catch ( ArchiverException e )
+        {
+            throw new MojoExecutionException( "Failed to assemble javadoc-resources bundle archive. Reason: " + e.getMessage(), e );
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "Failed to assemble javadoc-resources bundle archive. Reason: " + e.getMessage(), e );
+        }
+        
+        projectHelper.attachArtifact( getProject(), bundleFile, getAttachmentClassifier() );
+    }
+}

Propchange: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/ResourcesBundleMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/TestJavadocReport.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/TestJavadocReport.java?rev=933380&r1=933379&r2=933380&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/TestJavadocReport.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/TestJavadocReport.java Mon Apr 12 19:44:10 2010
@@ -326,7 +326,7 @@ public class TestJavadocReport
     {
         if ( links == null )
         {
-            links = new ArrayList();
+            links = new ArrayList<String>();
         }
 
         // TODO the prerequisite is that the main report is in apidocs

Added: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/TestResourcesBundleMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/TestResourcesBundleMojo.java?rev=933380&view=auto
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/TestResourcesBundleMojo.java (added)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/TestResourcesBundleMojo.java Mon Apr 12 19:44:10 2010
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.plugin.javadoc;
+
+import java.io.File;
+
+/**
+ * Bundle {@link TestJavadocJar#testJavadocDirectory}, along with javadoc configuration options from 
+ * {@link AbstractJavadocMojo} such as taglet, doclet, and link information into a deployable 
+ * artifact. This artifact can then be consumed by the javadoc plugin mojos when used by the 
+ * <code>includeDependencySources</code> option, to generate javadocs that are somewhat consistent 
+ * with those generated in the original project itself.
+ *  
+ * @goal test-resource-bundle
+ * @phase package
+ * @since 2.6.2
+ */
+public class TestResourcesBundleMojo
+    extends ResourcesBundleMojo
+{
+    
+    /**
+     * Specifies the Test Javadoc resources directory to be included in the Javadoc (i.e. package.html, images...).
+     *
+     * @parameter default-value="${basedir}/src/test/javadoc" alias="javadocDirectory"
+     */
+    private File testJavadocDirectory;
+
+    @Override
+    protected String getAttachmentClassifier()
+    {
+        return TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER;
+    }
+
+    @Override
+    protected File getJavadocDirectory()
+    {
+        return testJavadocDirectory;
+    }
+    
+}

Propchange: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/TestResourcesBundleMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/JavadocBundle.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/JavadocBundle.java?rev=933380&view=auto
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/JavadocBundle.java (added)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/JavadocBundle.java Mon Apr 12 19:44:10 2010
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.plugin.javadoc.resolver;
+
+import org.apache.maven.plugin.javadoc.options.JavadocOptions;
+
+import java.io.File;
+
+public class JavadocBundle
+{
+    
+    private final File resourcesDirectory;
+    
+    private final JavadocOptions options;
+    
+    public JavadocBundle( final JavadocOptions options, final File resourcesDirectory )
+    {
+        this.options = options;
+        this.resourcesDirectory = resourcesDirectory;
+    }
+
+    public File getResourcesDirectory()
+    {
+        return resourcesDirectory;
+    }
+
+    public JavadocOptions getOptions()
+    {
+        return options;
+    }
+
+}

Propchange: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/JavadocBundle.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/ResourceResolver.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/ResourceResolver.java?rev=933380&r1=933379&r2=933380&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/ResourceResolver.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/ResourceResolver.java Mon Apr 12 19:44:10 2010
@@ -19,6 +19,8 @@ package org.apache.maven.plugin.javadoc.
  * under the License.
  */
 
+import static org.codehaus.plexus.util.IOUtil.close;
+
 import org.apache.maven.artifact.Artifact;
 import org.apache.maven.artifact.DefaultArtifact;
 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
@@ -28,14 +30,22 @@ import org.apache.maven.artifact.resolve
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.plugin.javadoc.AbstractJavadocMojo;
 import org.apache.maven.plugin.javadoc.JavadocUtil;
+import org.apache.maven.plugin.javadoc.ResourcesBundleMojo;
+import org.apache.maven.plugin.javadoc.options.JavadocOptions;
+import org.apache.maven.plugin.javadoc.options.io.xpp3.JavadocOptionsXpp3Reader;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.archiver.ArchiverException;
 import org.codehaus.plexus.archiver.UnArchiver;
 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedHashSet;
@@ -46,18 +56,64 @@ import java.util.Set;
 public final class ResourceResolver
 {
 
+    public static final String SOURCES_CLASSIFIER = "sources";
+
+    public static final String TEST_SOURCES_CLASSIFIER = "test-sources";
+
+    private static final List<String> SOURCE_VALID_CLASSIFIERS =
+        Arrays.asList( new String[] { SOURCES_CLASSIFIER, TEST_SOURCES_CLASSIFIER } );
+
+    private static final List<String> RESOURCE_VALID_CLASSIFIERS =
+        Arrays.asList( new String[] { AbstractJavadocMojo.JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER,
+            AbstractJavadocMojo.TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER } );
+
     private ResourceResolver()
     {
     }
 
     @SuppressWarnings( "unchecked" )
-    public static List<String> resolveSourceDirs( final SourceResolverConfig config )
+    public static List<JavadocBundle> resolveDependencyJavadocBundles( final SourceResolverConfig config )
+        throws IOException
+    {
+        final List<JavadocBundle> bundles = new ArrayList<JavadocBundle>();
+
+        final Map<String, MavenProject> projectMap = new HashMap<String, MavenProject>();
+        if ( config.reactorProjects() != null )
+        {
+            for ( final MavenProject p : config.reactorProjects() )
+            {
+                projectMap.put( key( p.getGroupId(), p.getArtifactId() ), p );
+            }
+        }
+
+        final List<Artifact> artifacts = config.project().getTestArtifacts();
+
+        final List<Artifact> forResourceResolution = new ArrayList<Artifact>( artifacts.size() );
+        for ( final Artifact artifact : artifacts )
+        {
+            final String key = key( artifact.getGroupId(), artifact.getArtifactId() );
+            final MavenProject p = projectMap.get( key );
+            if ( p != null )
+            {
+                bundles.addAll( resolveBundleFromProject( config, p, artifact ) );
+            }
+            else
+            {
+                forResourceResolution.add( artifact );
+            }
+        }
+
+        bundles.addAll( resolveBundlesFromArtifacts( config, forResourceResolution ) );
+
+        return bundles;
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public static List<String> resolveDependencySourcePaths( final SourceResolverConfig config )
         throws ArtifactResolutionException, ArtifactNotFoundException
     {
         final List<String> dirs = new ArrayList<String>();
 
-        //        dirs.addAll( resolveFromProject( config, config.project(), config.project().getArtifact() ) );
-
         final Map<String, MavenProject> projectMap = new HashMap<String, MavenProject>();
         if ( config.reactorProjects() != null )
         {
@@ -89,6 +145,137 @@ public final class ResourceResolver
         return dirs;
     }
 
+    private static List<JavadocBundle> resolveBundleFromProject( SourceResolverConfig config, MavenProject project,
+                                                           Artifact artifact ) throws IOException
+    {
+        List<JavadocBundle> bundles = new ArrayList<JavadocBundle>();
+        
+        List<String> classifiers = new ArrayList<String>();
+        if ( config.includeCompileSources() )
+        {
+            classifiers.add( AbstractJavadocMojo.JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER );
+        }
+        
+        if ( config.includeTestSources() )
+        {
+            classifiers.add( AbstractJavadocMojo.TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER );
+        }
+        
+        for ( String classifier : classifiers )
+        {
+            File optionsFile = new File( project.getBuild().getDirectory(), "javadoc-bundle-options/javadoc-options-" + classifier + ".xml" );
+            if ( !optionsFile.exists() )
+            {
+                continue;
+            }
+            
+            FileInputStream stream = null;
+            try
+            {
+                stream = new FileInputStream( optionsFile );
+                JavadocOptions options = new JavadocOptionsXpp3Reader().read( stream );
+                
+                bundles.add( new JavadocBundle( options, new File( project.getBasedir(), options.getJavadocResourcesDirectory() ) ) );
+            }
+            catch ( XmlPullParserException e )
+            {
+                IOException error = new IOException( "Failed to read javadoc options from: " + optionsFile + "\nReason: " + e.getMessage() );
+                error.initCause( e );
+                
+                throw error;
+            }
+            finally
+            {
+                close( stream );
+            }
+        }
+
+        return bundles;
+    }
+
+    private static List<JavadocBundle> resolveBundlesFromArtifacts( final SourceResolverConfig config,
+                                                                    final List<Artifact> artifacts )
+        throws IOException
+    {
+        final List<Artifact> toResolve = new ArrayList<Artifact>( artifacts.size() );
+
+        for ( final Artifact artifact : artifacts )
+        {
+            if ( config.filter() != null && !config.filter().include( artifact ) )
+            {
+                continue;
+            }
+
+            if ( config.includeCompileSources() )
+            {
+                toResolve.add( createResourceArtifact( artifact, AbstractJavadocMojo.JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER, config ) );
+            }
+
+            if ( config.includeTestSources() )
+            {
+                toResolve.add( createResourceArtifact( artifact, AbstractJavadocMojo.TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER, config ) );
+            }
+        }
+
+        List<String> dirs = null;
+        try
+        {
+            dirs = resolveAndUnpack( toResolve, config, RESOURCE_VALID_CLASSIFIERS, false );
+        }
+        catch ( ArtifactResolutionException e )
+        {
+            if ( config.log().isDebugEnabled() )
+            {
+                config.log().debug( e.getMessage(), e );
+            }
+        }
+        catch ( ArtifactNotFoundException e )
+        {
+            if ( config.log().isDebugEnabled() )
+            {
+                config.log().debug( e.getMessage(), e );
+            }
+        }
+        
+        List<JavadocBundle> result = new ArrayList<JavadocBundle>();
+
+        if ( dirs != null )
+        {
+            for ( String d : dirs )
+            {
+                File dir = new File( d );
+                File resources = new File( dir, ResourcesBundleMojo.RESOURCES_DIR_PATH );
+                JavadocOptions options = null;
+
+                File javadocOptions = new File( dir, ResourcesBundleMojo.BUNDLE_OPTIONS_PATH );
+                if ( javadocOptions.exists() )
+                {
+                    FileInputStream reader = null;
+                    try
+                    {
+                        reader = new FileInputStream( javadocOptions );
+                        options = new JavadocOptionsXpp3Reader().read( reader );
+                    }
+                    catch ( XmlPullParserException e )
+                    {
+                        IOException error = new IOException( "Failed to parse javadoc options: " + e.getMessage() );
+                        error.initCause( e );
+                        
+                        throw error;
+                    }
+                    finally
+                    {
+                        close( reader );
+                    }
+                }
+                
+                result.add( new JavadocBundle( options, resources ) );
+            }
+        }
+        
+        return result;
+    }
+
     private static List<String> resolveFromArtifacts( final SourceResolverConfig config, final List<Artifact> artifacts )
         throws ArtifactResolutionException, ArtifactNotFoundException
     {
@@ -103,20 +290,20 @@ public final class ResourceResolver
 
             if ( config.includeCompileSources() )
             {
-                toResolve.add( createSourceArtifact( artifact, "sources", config ) );
+                toResolve.add( createResourceArtifact( artifact, SOURCES_CLASSIFIER, config ) );
             }
 
             if ( config.includeTestSources() )
             {
-                toResolve.add( createSourceArtifact( artifact, "test-sources", config ) );
+                toResolve.add( createResourceArtifact( artifact, TEST_SOURCES_CLASSIFIER, config ) );
             }
         }
 
-        return resolveAndUnpack( toResolve, config );
+        return resolveAndUnpack( toResolve, config, SOURCE_VALID_CLASSIFIERS, true );
     }
 
-    public static Artifact createSourceArtifact( final Artifact artifact, final String classifier,
-                                                 final SourceResolverConfig config )
+    private static Artifact createResourceArtifact( final Artifact artifact, final String classifier,
+                                                    final SourceResolverConfig config )
     {
         final DefaultArtifact a =
             (DefaultArtifact) config.artifactFactory().createArtifactWithClassifier( artifact.getGroupId(),
@@ -130,7 +317,8 @@ public final class ResourceResolver
     }
 
     @SuppressWarnings( "unchecked" )
-    private static List<String> resolveAndUnpack( final List<Artifact> artifacts, final SourceResolverConfig config )
+    private static List<String> resolveAndUnpack( final List<Artifact> artifacts, final SourceResolverConfig config,
+                                                  final List<String> validClassifiers, final boolean propagateErrors )
         throws ArtifactResolutionException, ArtifactNotFoundException
     {
         // NOTE: Since these are '-sources' and '-test-sources' artifacts, they won't actually 
@@ -151,7 +339,7 @@ public final class ResourceResolver
         final List<String> result = new ArrayList<String>( artifacts.size() );
         for ( final Artifact a : (Collection<Artifact>) resolutionResult.getArtifacts() )
         {
-            if ( !"sources".equals( a.getClassifier() ) && !"test-sources".equals( a.getClassifier() ) )
+            if ( !validClassifiers.contains( a.getClassifier() ) || ( filter != null && !filter.include( a ) ) )
             {
                 continue;
             }
@@ -177,13 +365,18 @@ public final class ResourceResolver
             }
             catch ( final NoSuchArchiverException e )
             {
-                throw new ArtifactResolutionException(
-                                                       "Failed to retrieve valid un-archiver component: " + a.getType(),
-                                                       a, e );
+                if ( propagateErrors )
+                {
+                    throw new ArtifactResolutionException( "Failed to retrieve valid un-archiver component: "
+                        + a.getType(), a, e );
+                }
             }
             catch ( final ArchiverException e )
             {
-                throw new ArtifactResolutionException( "Failed to unpack: " + a.getId(), a, e );
+                if ( propagateErrors )
+                {
+                    throw new ArtifactResolutionException( "Failed to unpack: " + a.getId(), a, e );
+                }
             }
         }
 
@@ -208,7 +401,6 @@ public final class ResourceResolver
         if ( config.includeTestSources() )
         {
             final List<String> srcRoots = reactorProject.getTestCompileSourceRoots();
-            final File basedir = reactorProject.getBasedir();
             for ( final String root : srcRoots )
             {
                 dirs.add( root );

Modified: maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/SourceResolverConfig.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/SourceResolverConfig.java?rev=933380&r1=933379&r2=933380&view=diff
==============================================================================
--- maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/SourceResolverConfig.java (original)
+++ maven/plugins/trunk/maven-javadoc-plugin/src/main/java/org/apache/maven/plugin/javadoc/resolver/SourceResolverConfig.java Mon Apr 12 19:44:10 2010
@@ -24,6 +24,7 @@ import org.apache.maven.artifact.metadat
 import org.apache.maven.artifact.repository.ArtifactRepository;
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
+import org.apache.maven.plugin.logging.Log;
 import org.apache.maven.project.MavenProject;
 import org.codehaus.plexus.archiver.manager.ArchiverManager;
 
@@ -55,12 +56,15 @@ public class SourceResolverConfig
 
     private final ArtifactFactory artifactFactory;
 
-    public SourceResolverConfig( final MavenProject project, final ArtifactRepository localRepository,
+    private final Log log;
+
+    public SourceResolverConfig( final Log log, final MavenProject project, final ArtifactRepository localRepository,
                                  final File outputBasedir, final ArtifactResolver artifactResolver,
                                  final ArtifactFactory artifactFactory,
                                  final ArtifactMetadataSource artifactMetadataSource,
                                  final ArchiverManager archiverManager )
     {
+        this.log = log;
         this.project = project;
         this.localRepository = localRepository;
         this.outputBasedir = outputBasedir;
@@ -160,5 +164,10 @@ public class SourceResolverConfig
     {
         return artifactFactory;
     }
+    
+    public Log log()
+    {
+        return log;
+    }
 
 }