Coverage Report - org.apache.maven.plugin.javadoc.resolver.ResourceResolver
 
Classes in this File Line Coverage Branch Coverage Complexity
ResourceResolver
0%
0/151
0%
0/82
6.1
 
 1  
 package org.apache.maven.plugin.javadoc.resolver;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *   http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import static org.codehaus.plexus.util.IOUtil.close;
 23  
 
 24  
 import org.apache.maven.artifact.Artifact;
 25  
 import org.apache.maven.artifact.DefaultArtifact;
 26  
 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
 27  
 import org.apache.maven.artifact.repository.ArtifactRepository;
 28  
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 29  
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 30  
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 31  
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 32  
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 33  
 import org.apache.maven.plugin.javadoc.AbstractJavadocMojo;
 34  
 import org.apache.maven.plugin.javadoc.JavadocUtil;
 35  
 import org.apache.maven.plugin.javadoc.ResourcesBundleMojo;
 36  
 import org.apache.maven.plugin.javadoc.options.JavadocOptions;
 37  
 import org.apache.maven.plugin.javadoc.options.io.xpp3.JavadocOptionsXpp3Reader;
 38  
 import org.apache.maven.project.MavenProject;
 39  
 import org.codehaus.plexus.archiver.ArchiverException;
 40  
 import org.codehaus.plexus.archiver.UnArchiver;
 41  
 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
 42  
 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 43  
 
 44  
 import java.io.File;
 45  
 import java.io.FileInputStream;
 46  
 import java.io.IOException;
 47  
 import java.util.ArrayList;
 48  
 import java.util.Arrays;
 49  
 import java.util.Collection;
 50  
 import java.util.HashMap;
 51  
 import java.util.LinkedHashSet;
 52  
 import java.util.List;
 53  
 import java.util.Map;
 54  
 import java.util.Set;
 55  
 
 56  
 public final class ResourceResolver
 57  
 {
 58  
 
 59  
     public static final String SOURCES_CLASSIFIER = "sources";
 60  
 
 61  
     public static final String TEST_SOURCES_CLASSIFIER = "test-sources";
 62  
 
 63  0
     private static final List<String> SOURCE_VALID_CLASSIFIERS =
 64  
         Arrays.asList( new String[] { SOURCES_CLASSIFIER, TEST_SOURCES_CLASSIFIER } );
 65  
 
 66  0
     private static final List<String> RESOURCE_VALID_CLASSIFIERS =
 67  
         Arrays.asList( new String[] { AbstractJavadocMojo.JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER,
 68  
             AbstractJavadocMojo.TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER } );
 69  
 
 70  
     private ResourceResolver()
 71  0
     {
 72  0
     }
 73  
 
 74  
     @SuppressWarnings( "unchecked" )
 75  
     public static List<JavadocBundle> resolveDependencyJavadocBundles( final SourceResolverConfig config )
 76  
         throws IOException
 77  
     {
 78  0
         final List<JavadocBundle> bundles = new ArrayList<JavadocBundle>();
 79  
 
 80  0
         final Map<String, MavenProject> projectMap = new HashMap<String, MavenProject>();
 81  0
         if ( config.reactorProjects() != null )
 82  
         {
 83  0
             for ( final MavenProject p : config.reactorProjects() )
 84  
             {
 85  0
                 projectMap.put( key( p.getGroupId(), p.getArtifactId() ), p );
 86  
             }
 87  
         }
 88  
 
 89  0
         final List<Artifact> artifacts = config.project().getTestArtifacts();
 90  
 
 91  0
         final List<Artifact> forResourceResolution = new ArrayList<Artifact>( artifacts.size() );
 92  0
         for ( final Artifact artifact : artifacts )
 93  
         {
 94  0
             final String key = key( artifact.getGroupId(), artifact.getArtifactId() );
 95  0
             final MavenProject p = projectMap.get( key );
 96  0
             if ( p != null )
 97  
             {
 98  0
                 bundles.addAll( resolveBundleFromProject( config, p, artifact ) );
 99  
             }
 100  
             else
 101  
             {
 102  0
                 forResourceResolution.add( artifact );
 103  
             }
 104  0
         }
 105  
 
 106  0
         bundles.addAll( resolveBundlesFromArtifacts( config, forResourceResolution ) );
 107  
 
 108  0
         return bundles;
 109  
     }
 110  
 
 111  
     @SuppressWarnings( "unchecked" )
 112  
     public static List<String> resolveDependencySourcePaths( final SourceResolverConfig config )
 113  
         throws ArtifactResolutionException, ArtifactNotFoundException
 114  
     {
 115  0
         final List<String> dirs = new ArrayList<String>();
 116  
 
 117  0
         final Map<String, MavenProject> projectMap = new HashMap<String, MavenProject>();
 118  0
         if ( config.reactorProjects() != null )
 119  
         {
 120  0
             for ( final MavenProject p : config.reactorProjects() )
 121  
             {
 122  0
                 projectMap.put( key( p.getGroupId(), p.getArtifactId() ), p );
 123  
             }
 124  
         }
 125  
 
 126  0
         final List<Artifact> artifacts = config.project().getTestArtifacts();
 127  
 
 128  0
         final List<Artifact> forResourceResolution = new ArrayList<Artifact>( artifacts.size() );
 129  0
         for ( final Artifact artifact : artifacts )
 130  
         {
 131  0
             final String key = key( artifact.getGroupId(), artifact.getArtifactId() );
 132  0
             final MavenProject p = projectMap.get( key );
 133  0
             if ( p != null )
 134  
             {
 135  0
                 dirs.addAll( resolveFromProject( config, p, artifact ) );
 136  
             }
 137  
             else
 138  
             {
 139  0
                 forResourceResolution.add( artifact );
 140  
             }
 141  0
         }
 142  
 
 143  0
         dirs.addAll( resolveFromArtifacts( config, forResourceResolution ) );
 144  
 
 145  0
         return dirs;
 146  
     }
 147  
 
 148  
     private static List<JavadocBundle> resolveBundleFromProject( SourceResolverConfig config, MavenProject project,
 149  
                                                            Artifact artifact ) throws IOException
 150  
     {
 151  0
         List<JavadocBundle> bundles = new ArrayList<JavadocBundle>();
 152  
         
 153  0
         List<String> classifiers = new ArrayList<String>();
 154  0
         if ( config.includeCompileSources() )
 155  
         {
 156  0
             classifiers.add( AbstractJavadocMojo.JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER );
 157  
         }
 158  
         
 159  0
         if ( config.includeTestSources() )
 160  
         {
 161  0
             classifiers.add( AbstractJavadocMojo.TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER );
 162  
         }
 163  
         
 164  0
         for ( String classifier : classifiers )
 165  
         {
 166  0
             File optionsFile = new File( project.getBuild().getDirectory(), "javadoc-bundle-options/javadoc-options-" + classifier + ".xml" );
 167  0
             if ( !optionsFile.exists() )
 168  
             {
 169  0
                 continue;
 170  
             }
 171  
             
 172  0
             FileInputStream stream = null;
 173  
             try
 174  
             {
 175  0
                 stream = new FileInputStream( optionsFile );
 176  0
                 JavadocOptions options = new JavadocOptionsXpp3Reader().read( stream );
 177  
                 
 178  0
                 bundles.add( new JavadocBundle( options, new File( project.getBasedir(), options.getJavadocResourcesDirectory() ) ) );
 179  
             }
 180  0
             catch ( XmlPullParserException e )
 181  
             {
 182  0
                 IOException error = new IOException( "Failed to read javadoc options from: " + optionsFile + "\nReason: " + e.getMessage() );
 183  0
                 error.initCause( e );
 184  
                 
 185  0
                 throw error;
 186  
             }
 187  
             finally
 188  
             {
 189  0
                 close( stream );
 190  0
             }
 191  0
         }
 192  
 
 193  0
         return bundles;
 194  
     }
 195  
 
 196  
     private static List<JavadocBundle> resolveBundlesFromArtifacts( final SourceResolverConfig config,
 197  
                                                                     final List<Artifact> artifacts )
 198  
         throws IOException
 199  
     {
 200  0
         final List<Artifact> toResolve = new ArrayList<Artifact>( artifacts.size() );
 201  
 
 202  0
         for ( final Artifact artifact : artifacts )
 203  
         {
 204  0
             if ( config.filter() != null && !config.filter().include( artifact ) )
 205  
             {
 206  0
                 continue;
 207  
             }
 208  
 
 209  0
             if ( config.includeCompileSources() )
 210  
             {
 211  0
                 toResolve.add( createResourceArtifact( artifact, AbstractJavadocMojo.JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER, config ) );
 212  
             }
 213  
 
 214  0
             if ( config.includeTestSources() )
 215  
             {
 216  0
                 toResolve.add( createResourceArtifact( artifact, AbstractJavadocMojo.TEST_JAVADOC_RESOURCES_ATTACHMENT_CLASSIFIER, config ) );
 217  
             }
 218  
         }
 219  
 
 220  0
         List<String> dirs = null;
 221  
         try
 222  
         {
 223  0
             dirs = resolveAndUnpack( toResolve, config, RESOURCE_VALID_CLASSIFIERS, false );
 224  
         }
 225  0
         catch ( ArtifactResolutionException e )
 226  
         {
 227  0
             if ( config.log().isDebugEnabled() )
 228  
             {
 229  0
                 config.log().debug( e.getMessage(), e );
 230  
             }
 231  
         }
 232  0
         catch ( ArtifactNotFoundException e )
 233  
         {
 234  0
             if ( config.log().isDebugEnabled() )
 235  
             {
 236  0
                 config.log().debug( e.getMessage(), e );
 237  
             }
 238  0
         }
 239  
         
 240  0
         List<JavadocBundle> result = new ArrayList<JavadocBundle>();
 241  
 
 242  0
         if ( dirs != null )
 243  
         {
 244  0
             for ( String d : dirs )
 245  
             {
 246  0
                 File dir = new File( d );
 247  0
                 File resources = new File( dir, ResourcesBundleMojo.RESOURCES_DIR_PATH );
 248  0
                 JavadocOptions options = null;
 249  
 
 250  0
                 File javadocOptions = new File( dir, ResourcesBundleMojo.BUNDLE_OPTIONS_PATH );
 251  0
                 if ( javadocOptions.exists() )
 252  
                 {
 253  0
                     FileInputStream reader = null;
 254  
                     try
 255  
                     {
 256  0
                         reader = new FileInputStream( javadocOptions );
 257  0
                         options = new JavadocOptionsXpp3Reader().read( reader );
 258  
                     }
 259  0
                     catch ( XmlPullParserException e )
 260  
                     {
 261  0
                         IOException error = new IOException( "Failed to parse javadoc options: " + e.getMessage() );
 262  0
                         error.initCause( e );
 263  
                         
 264  0
                         throw error;
 265  
                     }
 266  
                     finally
 267  
                     {
 268  0
                         close( reader );
 269  0
                     }
 270  
                 }
 271  
                 
 272  0
                 result.add( new JavadocBundle( options, resources ) );
 273  0
             }
 274  
         }
 275  
         
 276  0
         return result;
 277  
     }
 278  
 
 279  
     private static List<String> resolveFromArtifacts( final SourceResolverConfig config, final List<Artifact> artifacts )
 280  
         throws ArtifactResolutionException, ArtifactNotFoundException
 281  
     {
 282  0
         final List<Artifact> toResolve = new ArrayList<Artifact>( artifacts.size() );
 283  
 
 284  0
         for ( final Artifact artifact : artifacts )
 285  
         {
 286  0
             if ( config.filter() != null && !config.filter().include( artifact ) )
 287  
             {
 288  0
                 continue;
 289  
             }
 290  
 
 291  0
             if ( config.includeCompileSources() )
 292  
             {
 293  0
                 toResolve.add( createResourceArtifact( artifact, SOURCES_CLASSIFIER, config ) );
 294  
             }
 295  
 
 296  0
             if ( config.includeTestSources() )
 297  
             {
 298  0
                 toResolve.add( createResourceArtifact( artifact, TEST_SOURCES_CLASSIFIER, config ) );
 299  
             }
 300  
         }
 301  
 
 302  0
         return resolveAndUnpack( toResolve, config, SOURCE_VALID_CLASSIFIERS, true );
 303  
     }
 304  
 
 305  
     private static Artifact createResourceArtifact( final Artifact artifact, final String classifier,
 306  
                                                     final SourceResolverConfig config )
 307  
     {
 308  0
         final DefaultArtifact a =
 309  
             (DefaultArtifact) config.artifactFactory().createArtifactWithClassifier( artifact.getGroupId(),
 310  
                                                                                      artifact.getArtifactId(),
 311  
                                                                                      artifact.getVersion(), "jar",
 312  
                                                                                      classifier );
 313  
 
 314  0
         a.setRepository( artifact.getRepository() );
 315  
 
 316  0
         return a;
 317  
     }
 318  
 
 319  
     @SuppressWarnings( "unchecked" )
 320  
     private static List<String> resolveAndUnpack( final List<Artifact> artifacts, final SourceResolverConfig config,
 321  
                                                   final List<String> validClassifiers, final boolean propagateErrors )
 322  
         throws ArtifactResolutionException, ArtifactNotFoundException
 323  
     {
 324  
         // NOTE: Since these are '-sources' and '-test-sources' artifacts, they won't actually 
 325  
         // resolve transitively...this is just used to aggregate resolution failures into a single 
 326  
         // exception.
 327  0
         final Set<Artifact> artifactSet = new LinkedHashSet<Artifact>( artifacts );
 328  0
         final Artifact pomArtifact = config.project().getArtifact();
 329  0
         final ArtifactRepository localRepo = config.localRepository();
 330  0
         final List<ArtifactRepository> remoteRepos = config.project().getRemoteArtifactRepositories();
 331  0
         final ArtifactMetadataSource metadataSource = config.artifactMetadataSource();
 332  
 
 333  0
         final ArtifactFilter filter = config.filter();
 334  0
         ArtifactFilter resolutionFilter = null;
 335  0
         if ( filter != null )
 336  
         {
 337  
             // Wrap the filter in a ProjectArtifactFilter in order to always include the pomArtifact for resolution.
 338  
             // NOTE that this is necessary, b/c the -sources artifacts are added dynamically to the pomArtifact
 339  
             // and the resolver also checks the dependency trail with the given filter, thus the pomArtifact has
 340  
             // to be explicitly included by the filter, otherwise the -sources artifacts won't be resolved.
 341  0
             resolutionFilter = new ProjectArtifactFilter(pomArtifact, filter);
 342  
         }
 343  
 
 344  0
         final ArtifactResolver resolver = config.artifactResolver();
 345  
 
 346  0
         final ArtifactResolutionResult resolutionResult = resolver.resolveTransitively(
 347  
                 artifactSet, pomArtifact, localRepo, remoteRepos, metadataSource, resolutionFilter );
 348  
 
 349  0
         final List<String> result = new ArrayList<String>( artifacts.size() );
 350  0
         for ( final Artifact a : (Collection<Artifact>) resolutionResult.getArtifacts() )
 351  
         {
 352  0
             if ( !validClassifiers.contains( a.getClassifier() ) || ( filter != null && !filter.include( a ) ) )
 353  
             {
 354  0
                 continue;
 355  
             }
 356  
 
 357  0
             final File d =
 358  
                 new File( config.outputBasedir(), a.getArtifactId() + "-" + a.getVersion() + "-" + a.getClassifier() );
 359  
 
 360  0
             if ( !d.exists() )
 361  
             {
 362  0
                 d.mkdirs();
 363  
             }
 364  
 
 365  
             try
 366  
             {
 367  0
                 final UnArchiver unArchiver = config.archiverManager().getUnArchiver( a.getType() );
 368  
 
 369  0
                 unArchiver.setDestDirectory( d );
 370  0
                 unArchiver.setSourceFile( a.getFile() );
 371  
 
 372  0
                 unArchiver.extract();
 373  
 
 374  0
                 result.add( d.getAbsolutePath() );
 375  
             }
 376  0
             catch ( final NoSuchArchiverException e )
 377  
             {
 378  0
                 if ( propagateErrors )
 379  
                 {
 380  0
                     throw new ArtifactResolutionException( "Failed to retrieve valid un-archiver component: "
 381  
                         + a.getType(), a, e );
 382  
                 }
 383  
             }
 384  0
             catch ( final ArchiverException e )
 385  
             {
 386  0
                 if ( propagateErrors )
 387  
                 {
 388  0
                     throw new ArtifactResolutionException( "Failed to unpack: " + a.getId(), a, e );
 389  
                 }
 390  0
             }
 391  0
         }
 392  
 
 393  0
         return result;
 394  
     }
 395  
 
 396  
     @SuppressWarnings( "unchecked" )
 397  
     private static List<String> resolveFromProject( final SourceResolverConfig config,
 398  
                                                     final MavenProject reactorProject, final Artifact artifact )
 399  
     {
 400  0
         final List<String> dirs = new ArrayList<String>();
 401  
 
 402  0
         if ( config.filter() == null || config.filter().include( artifact ) )
 403  
         {
 404  0
             if ( config.includeCompileSources() )
 405  
             {
 406  0
                 final List<String> srcRoots = reactorProject.getCompileSourceRoots();
 407  0
                 for ( final String root : srcRoots )
 408  
                 {
 409  0
                     dirs.add( root );
 410  
                 }
 411  
             }
 412  
 
 413  0
             if ( config.includeTestSources() )
 414  
             {
 415  0
                 final List<String> srcRoots = reactorProject.getTestCompileSourceRoots();
 416  0
                 for ( final String root : srcRoots )
 417  
                 {
 418  0
                     dirs.add( root );
 419  
                 }
 420  
             }
 421  
         }
 422  
 
 423  0
         return JavadocUtil.pruneDirs( reactorProject, dirs );
 424  
     }
 425  
 
 426  
     private static String key( final String gid, final String aid )
 427  
     {
 428  0
         return gid + ":" + aid;
 429  
     }
 430  
 
 431  
 }