Save This Page
Home » maven-ant-tasks-2.1.0-src » org.apache » maven » artifact » ant » [javadoc | source]
    1   package org.apache.maven.artifact.ant;
    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 org.apache.maven.artifact.Artifact;
   23   import org.apache.maven.artifact.ant.util.AntBuildWriter;
   24   import org.apache.maven.artifact.ant.util.AntTaskModified;
   25   import org.apache.maven.artifact.ant.util.AntUtil;
   26   import org.apache.maven.artifact.factory.ArtifactFactory;
   27   import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
   28   import org.apache.maven.artifact.repository.ArtifactRepository;
   29   import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
   30   import org.apache.maven.artifact.resolver.ArtifactResolutionException;
   31   import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
   32   import org.apache.maven.artifact.resolver.ArtifactResolver;
   33   import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
   34   import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
   35   import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
   36   import org.apache.maven.model.Dependency;
   37   import org.apache.maven.project.artifact.InvalidDependencyVersionException;
   38   import org.apache.maven.project.artifact.MavenMetadataSource;
   39   import org.apache.tools.ant.BuildException;
   40   import org.apache.tools.ant.Project;
   41   import org.apache.tools.ant.types.FileSet;
   42   import org.apache.tools.ant.types.Path;
   43   import org.codehaus.plexus.util.StringUtils;
   44   
   45   import java.io.File;
   46   import java.io.IOException;
   47   import java.util.ArrayList;
   48   import java.util.Collections;
   49   import java.util.HashSet;
   50   import java.util.Iterator;
   51   import java.util.List;
   52   import java.util.Map;
   53   import java.util.Set;
   54   
   55   /**
   56    * Dependencies task, using maven-artifact.
   57    *
   58    * @author <a href="mailto:brett@apache.org">Brett Porter</a>
   59    * @author <a href="mailto:hboutemy@apache.org">Herve Boutemy</a>
   60    * @version $Id: DependenciesTask.java 884311 2009-11-25 22:32:12Z pgier $
   61    */
   62   public class DependenciesTask
   63       extends AbstractArtifactWithRepositoryTask
   64   {
   65       
   66       public static final String DEFAULT_ANT_BUILD_FILE = "target/build-dependencies.xml";
   67       
   68       private List dependencies = new ArrayList();
   69   
   70       /**
   71        * The id of the path object containing a list of all dependencies.
   72        */
   73       private String pathId;
   74   
   75       /**
   76        * The id of the fileset object containing a list of all dependencies.
   77        */
   78       private String filesetId;
   79   
   80       /**
   81        * The id of the fileset object containing all resolved source jars for the list of dependencies.
   82        */
   83       private String sourcesFilesetId;
   84       
   85       /**
   86        * The id of the fileset object containing all resolved javadoc jars for the list of dependencies.
   87        */
   88       private String javadocFilesetId;
   89       
   90       /**
   91        * The id of the object containing a list of all artifact versions.
   92        * This is used for things like removing the version from the dependency filenames.
   93        */
   94       private String versionsId;
   95   
   96       /**
   97        * A specific maven scope used to determine which dependencies are resolved.
   98        * This takes only a single scope and uses the standard maven ScopeArtifactFilter.
   99        */
  100       private String useScope;
  101   
  102       /**
  103        * A comma separated list of dependency scopes to include, in the resulting path and fileset.
  104        */
  105       private String scopes;
  106   
  107       /**
  108        * A comma separated list of dependency types to include in the resulting set of artifacts.
  109        */
  110       private String type;
  111   
  112       /**
  113        * The file name to use for the generated Ant build that contains dependency properties and references.
  114        */
  115       private String dependencyRefsBuildFile;
  116   
  117       /**
  118        * Whether to use a generated Ant build file to cache the list of dependency properties and references.
  119        */
  120       private boolean cacheDependencyRefs;
  121   
  122       /**
  123        * Main task execution.  Called by parent execute().
  124        */
  125       protected void doExecute()
  126       {
  127           
  128           if ( useScope != null && scopes != null )
  129           {
  130               throw new BuildException( "You cannot specify both useScope and scopes in the dependencies task." );
  131           }
  132                   
  133           if ( getPom() != null && !this.dependencies.isEmpty() )
  134           {
  135               throw new BuildException( "You cannot specify both dependencies and a pom in the dependencies task" );
  136           }
  137           
  138           // Try to load dependency refs from an exsiting Ant cache file
  139           if ( isCacheDependencyRefs() )
  140           {
  141               if ( getDependencyRefsBuildFile() == null )
  142               {
  143                   setDependencyRefsBuildFile( DEFAULT_ANT_BUILD_FILE );
  144               }
  145               if ( checkCachedDependencies() )
  146               {
  147                   log( "Dependency refs loaded from file: " + getDependencyRefsBuildFile(), Project.MSG_VERBOSE );
  148                   return;
  149               }
  150           }
  151           
  152           ArtifactRepository localRepo = createLocalArtifactRepository();
  153           log( "Using local repository: " + localRepo.getBasedir(), Project.MSG_VERBOSE );
  154   
  155           // Look up required resources from the plexus container
  156           ArtifactResolver resolver = (ArtifactResolver) lookup( ArtifactResolver.ROLE );
  157           ArtifactFactory artifactFactory = (ArtifactFactory) lookup( ArtifactFactory.ROLE );
  158           MavenMetadataSource metadataSource = (MavenMetadataSource) lookup( ArtifactMetadataSource.ROLE );
  159   
  160           Pom pom = initializePom( localRepo );
  161           if ( pom != null )
  162           {
  163               dependencies = pom.getDependencies();
  164           }
  165           else
  166           {
  167               // we have to have some sort of Pom object in order to satisfy the requirements for building the
  168               // originating Artifact below...
  169               pom = createDummyPom( localRepo );
  170           }
  171   
  172           if ( dependencies.isEmpty() )
  173           {
  174               log( "There were no dependencies specified", Project.MSG_WARN );
  175           }
  176   
  177           log( "Resolving dependencies...", Project.MSG_VERBOSE );
  178   
  179           ArtifactResolutionResult result;
  180           Set artifacts;
  181   
  182           List remoteArtifactRepositories = createRemoteArtifactRepositories( pom.getRepositories() );
  183   
  184           try
  185           {
  186               artifacts = MavenMetadataSource.createArtifacts( artifactFactory, dependencies, null, null, null );
  187   
  188               Artifact pomArtifact = artifactFactory.createBuildArtifact( pom.getGroupId(), pom.getArtifactId(), 
  189                   pom.getVersion(), pom.getPackaging() );
  190   
  191               List listeners = Collections.singletonList( new AntResolutionListener( getProject() ) );
  192   
  193               Map managedDependencies = pom.getMavenProject().getManagedVersionMap();
  194   
  195               ArtifactFilter filter = null;
  196               if ( useScope != null )
  197               {
  198                   filter = new ScopeArtifactFilter( useScope );
  199               }
  200               if ( scopes != null )
  201               {
  202                   filter = new SpecificScopesArtifactFilter( scopes );
  203               }
  204               if ( type != null )
  205               {
  206                   ArtifactFilter typeArtifactFilter = new TypesArtifactFilter( type );
  207                   if ( filter != null )
  208                   {
  209                       AndArtifactFilter andFilter = new AndArtifactFilter();
  210                       andFilter.add( filter );
  211                       andFilter.add( typeArtifactFilter );
  212                       filter = andFilter;
  213                   }
  214                   else
  215                   {
  216                       filter = typeArtifactFilter;
  217                   }
  218               }
  219   
  220               result = resolver.resolveTransitively( artifacts, pomArtifact, managedDependencies, localRepo,
  221                                                      remoteArtifactRepositories, metadataSource, filter, listeners );
  222           }
  223           catch ( ArtifactResolutionException e )
  224           {
  225               throw new BuildException( "Unable to resolve artifact: " + e.getMessage(), e );
  226           }
  227           catch ( ArtifactNotFoundException e )
  228           {
  229               throw new BuildException( "Dependency not found: " + e.getMessage(), e );
  230           }
  231           catch ( InvalidDependencyVersionException e )
  232           {
  233               throw new BuildException( "Invalid dependency version: " + e.getMessage(), e );
  234           }
  235   
  236           FileSet dependencyFileSet = createFileSet();
  237   
  238           FileSet sourcesFileSet = createFileSet();
  239   
  240           FileSet javadocsFileSet = createFileSet();
  241   
  242           Path dependencyPath = new Path( getProject() );
  243           
  244           Set versions = new HashSet();
  245           
  246           for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); )
  247           {
  248               Artifact artifact = (Artifact) i.next();
  249   
  250               addArtifactToResult( localRepo, artifact, dependencyFileSet, dependencyPath );
  251   
  252               versions.add( artifact.getVersion() );
  253   
  254               if ( sourcesFilesetId != null )
  255               {
  256                   resolveSource( artifactFactory, resolver, remoteArtifactRepositories, localRepo,
  257                                  artifact, "sources", sourcesFileSet );
  258               }
  259   
  260               if ( javadocFilesetId != null )
  261               {
  262                   resolveSource( artifactFactory, resolver, remoteArtifactRepositories, localRepo,
  263                                  artifact, "javadoc", javadocsFileSet );
  264               }
  265   
  266           }
  267   
  268           defineFilesetReference( filesetId, dependencyFileSet );
  269   
  270           defineFilesetReference( sourcesFilesetId, sourcesFileSet );
  271           
  272           defineFilesetReference( javadocFilesetId, javadocsFileSet );
  273           
  274           if ( pathId != null )
  275           {
  276               getProject().addReference( pathId, dependencyPath );
  277           }
  278           
  279           if ( versionsId != null )
  280           {
  281               String versionsValue = StringUtils.join( versions.iterator(), File.pathSeparator );
  282               getProject().setNewProperty( versionsId, versionsValue );
  283           }
  284           
  285           // Write the dependency information to an Ant build file.
  286           if ( getDependencyRefsBuildFile() != null || this.isCacheDependencyRefs() )
  287           {
  288               if ( getDependencyRefsBuildFile() == null || getDependencyRefsBuildFile().equals( "default" ) )
  289               {
  290                   setDependencyRefsBuildFile( DEFAULT_ANT_BUILD_FILE );
  291               }
  292               log( "Building ant file: " + getDependencyRefsBuildFile());
  293               AntBuildWriter antBuildWriter = new AntBuildWriter();
  294               File antBuildFile = new File( getProject().getBaseDir(), getDependencyRefsBuildFile() );
  295               try 
  296               {
  297                   antBuildWriter.openAntBuild( antBuildFile, "maven-dependencies", "init-dependencies" );
  298                   antBuildWriter.openTarget( "init-dependencies" );
  299                   antBuildWriter.writeEcho( "Loading dependency paths from file: " + antBuildFile.getAbsolutePath() );
  300                   
  301                   Iterator i = result.getArtifacts().iterator();
  302                   while (  i.hasNext() )
  303                   {
  304                       Artifact artifact = (Artifact) i.next();
  305                       String conflictId = artifact.getDependencyConflictId();
  306                       antBuildWriter.writeProperty( conflictId, artifact.getFile().getAbsolutePath() );
  307                       FileSet singleArtifactFileSet = (FileSet)getProject().getReference( conflictId );
  308                       antBuildWriter.writeFileSet( singleArtifactFileSet, conflictId );
  309                   }
  310                   
  311                   if ( pathId != null )
  312                   {
  313                       Path thePath = (Path)getProject().getReference( pathId );
  314                       antBuildWriter.writePath( thePath, pathId );
  315                   }
  316                   
  317                   if ( filesetId != null )
  318                   {
  319                       antBuildWriter.writeFileSet( dependencyFileSet, filesetId );
  320                   }
  321                   if ( sourcesFilesetId != null )
  322                   {
  323                       antBuildWriter.writeFileSet( sourcesFileSet, sourcesFilesetId );
  324                   }
  325                   if ( javadocFilesetId != null )
  326                   {
  327                       antBuildWriter.writeFileSet( sourcesFileSet, javadocFilesetId );
  328                   }
  329                   
  330                   String versionsList = getProject().getProperty( versionsId );
  331                   antBuildWriter.writeProperty( versionsId, versionsList );
  332                   
  333                   antBuildWriter.closeTarget();
  334                   antBuildWriter.closeAntBuild();
  335               }
  336               catch ( IOException e )
  337               {
  338                   throw new BuildException ( "Unable to write ant build: " + e);
  339               }
  340           }
  341       }
  342       
  343       /**
  344        * Check if the cache needs to be updated.
  345        * 
  346        * @return true if the dependency refs were successfully loaded, false otherwise
  347        */
  348       private boolean checkCachedDependencies()
  349       {
  350           File cacheBuildFile = new File( getProject().getBaseDir(), getDependencyRefsBuildFile() );
  351           if ( ! cacheBuildFile.exists() )
  352           {
  353               return false;
  354           }
  355           
  356           File antBuildFile = new File( getProject().getProperty( "ant.file" ) );
  357           if ( antBuildFile.lastModified() > cacheBuildFile.lastModified() )
  358           {
  359               return false;
  360           }
  361           
  362           Pom pom = getPom();
  363           if ( pom != null )
  364           {
  365               File pomFile = pom.getFile();
  366               if ( pomFile == null || ( pomFile.lastModified() > cacheBuildFile.lastModified() ) )
  367               {
  368                   return false;
  369               }
  370           }
  371           
  372           return loadDependenciesFromAntBuildFile();
  373       }
  374       
  375       /**
  376        * Load the dependency references from the generated ant build file.
  377        * 
  378        * @return True if the dependency refs were successfully loaded.
  379        */
  380       private boolean loadDependenciesFromAntBuildFile()
  381       {
  382           Project currentAntProject = getProject();
  383           
  384           // Run the ant build with the dependency refs
  385           AntTaskModified dependenciesAntBuild = new AntTaskModified();
  386           dependenciesAntBuild.setAntfile( getDependencyRefsBuildFile() );
  387           dependenciesAntBuild.setProject( currentAntProject );
  388           dependenciesAntBuild.execute();
  389           
  390           // Copy the properties and refs to the current project
  391           Project cachedDepsProject = dependenciesAntBuild.getSavedNewProject();
  392           AntUtil.copyProperties( cachedDepsProject, currentAntProject );
  393           AntUtil.copyReferences( cachedDepsProject, currentAntProject );
  394           
  395           return true;
  396       }
  397           
  398       private FileSet createFileSet()
  399       {
  400           FileSet fileSet = new FileSet();
  401           fileSet.setProject( getProject() );
  402           fileSet.setDir( getLocalRepository().getPath() );
  403           return fileSet;
  404       }
  405   
  406       private void defineFilesetReference( String id, FileSet fileSet )
  407       {
  408           if ( id != null )
  409           {
  410               if ( !fileSet.hasPatterns() )
  411               {
  412                   fileSet.createExclude().setName( "**/**" );
  413               }
  414               getProject().addReference( id, fileSet );
  415           }
  416       }
  417   
  418       private void addArtifactToResult( ArtifactRepository localRepo, Artifact artifact, 
  419                                         FileSet toFileSet )
  420       {
  421           addArtifactToResult( localRepo, artifact, toFileSet, null );
  422       }
  423       
  424       private void addArtifactToResult( ArtifactRepository localRepo, Artifact artifact, 
  425                                         FileSet toFileSet, Path path )
  426       {
  427           String filename = localRepo.pathOf( artifact );
  428   
  429           toFileSet.createInclude().setName( filename );
  430   
  431           getProject().setProperty( artifact.getDependencyConflictId(), artifact.getFile().getAbsolutePath() );
  432           
  433           FileSet artifactFileSet = new FileSet();
  434           artifactFileSet.setProject( getProject() );
  435           artifactFileSet.setFile( artifact.getFile() );
  436           getProject().addReference( artifact.getDependencyConflictId(), artifactFileSet );
  437           
  438           if ( path != null )
  439           {
  440               path.addFileset( artifactFileSet );
  441           }
  442       }
  443   
  444       private void resolveSource( ArtifactFactory artifactFactory, ArtifactResolver resolver,
  445                                   List remoteArtifactRepositories, ArtifactRepository localRepo,
  446                                   Artifact artifact, String classifier, FileSet sourcesFileSet )
  447       {
  448           Artifact sourceArtifact =
  449               artifactFactory.createArtifactWithClassifier( artifact.getGroupId(), artifact.getArtifactId(),
  450                                                             artifact.getVersion(), "java-source", classifier );
  451           try
  452           {
  453               resolver.resolve( sourceArtifact, remoteArtifactRepositories, localRepo );
  454   
  455               addArtifactToResult( localRepo, sourceArtifact, sourcesFileSet );
  456           }
  457           catch ( ArtifactResolutionException e )
  458           {
  459               throw new BuildException( "Unable to resolve artifact: " + e.getMessage(), e );
  460           }
  461           catch ( ArtifactNotFoundException e )
  462           {
  463               // no source available: no problem, it's optional
  464           }
  465       }
  466   
  467       public List getDependencies()
  468       {
  469           return dependencies;
  470       }
  471   
  472       public void addDependency( Dependency dependency )
  473       {
  474           dependencies.add( dependency );
  475       }
  476   
  477       public String getPathId()
  478       {
  479           return pathId;
  480       }
  481   
  482       public void setPathId( String pathId )
  483       {
  484           this.pathId = pathId;
  485       }
  486   
  487       public String getFilesetId()
  488       {
  489           return filesetId;
  490       }
  491   
  492       public void setSourcesFilesetId( String filesetId )
  493       {
  494           this.sourcesFilesetId = filesetId;
  495       }
  496   
  497       public String getSourcesFilesetId()
  498       {
  499           return sourcesFilesetId;
  500       }
  501   
  502       public void setJavadocFilesetId( String filesetId )
  503       {
  504           this.javadocFilesetId = filesetId;
  505       }
  506   
  507       public String getJavadocFilesetId()
  508       {
  509           return javadocFilesetId;
  510       }
  511   
  512       public void setFilesetId( String filesetId )
  513       {
  514           this.filesetId = filesetId;
  515       }
  516   
  517       public String getVersionsId()
  518       {
  519           return versionsId;
  520       }
  521   
  522       public void setVersionsId( String versionsId )
  523       {
  524           this.versionsId = versionsId;
  525       }
  526   
  527       public void setVerbose( boolean verbose )
  528       {
  529           getProject().log( "Option \"verbose\" is deprecated.  Please use the standard Ant -v option.",
  530                             Project.MSG_WARN );
  531       }
  532   
  533       /**
  534        * Use the maven artifact filtering for a particular scope.  This
  535        * uses the standard maven ScopeArtifactFilter.
  536        * 
  537        * @param useScope
  538        */
  539       public void setUseScope( String useScope )
  540       {
  541           this.useScope = useScope;
  542       }
  543   
  544       public void setType( String type )
  545       {
  546           this.type = type;
  547       }
  548   
  549       public String getScopes()
  550       {
  551           return scopes;
  552       }
  553   
  554       /**
  555        * Only include artifacts that fall under one of the specified scopes.
  556        * 
  557        * @return
  558        */
  559       public void setScopes( String scopes )
  560       {
  561           this.scopes = scopes;
  562       }
  563   
  564       /**
  565        * @deprecated
  566        * @param addArtifactFileSetRefs
  567        */
  568       public void setAddArtifactFileSetRefs( boolean addArtifactFileSetRefs )
  569       {
  570           this.log( "Parameter addArtifactFileSetRefs is deprecated.  A fileset ref is always created" +
  571           		"for each dependency.", Project.MSG_WARN );
  572       }
  573   
  574       public String getDependencyRefsBuildFile()
  575       {
  576           return dependencyRefsBuildFile;
  577       }
  578   
  579       public void setDependencyRefsBuildFile( String dependencyRefsBuildFile )
  580       {
  581           this.dependencyRefsBuildFile = dependencyRefsBuildFile;
  582       }
  583   
  584       public boolean isCacheDependencyRefs()
  585       {
  586           return cacheDependencyRefs;
  587       }
  588   
  589       public void setCacheDependencyRefs( boolean cacheDependencyRefs )
  590       {
  591           this.cacheDependencyRefs = cacheDependencyRefs;
  592       }
  593   }

Save This Page
Home » maven-ant-tasks-2.1.0-src » org.apache » maven » artifact » ant » [javadoc | source]