View Javadoc

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 java.math.BigInteger;
23  import java.security.MessageDigest;
24  import java.util.ArrayList;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.Set;
28  
29  import org.apache.maven.artifact.repository.ArtifactRepository;
30  import org.apache.maven.model.Repository;
31  import org.apache.tools.ant.BuildException;
32  import org.apache.tools.ant.Project;
33  
34  /**
35   * Base class for artifact tasks that are able to download artifact from remote repositories.
36   * @version $Id: AbstractArtifactWithRepositoryTask.html 806929 2012-03-01 18:57:40Z hboutemy $
37   */
38  public abstract class AbstractArtifactWithRepositoryTask
39      extends AbstractArtifactTask
40  {
41      /**
42       * List of Ant Tasks RemoteRepository-ies
43       */
44      private List<RemoteRepository> remoteRepositories = new ArrayList<RemoteRepository>();
45  
46      /**
47       * Get the default remote repository.
48       * @return central repository
49       */
50      private static RemoteRepository getDefaultRemoteRepository()
51      {
52          // TODO: could we utilize the super POM for this?
53          RemoteRepository remoteRepository = new RemoteRepository();
54          remoteRepository.setId( "central" );
55          remoteRepository.setUrl( "http://repo1.maven.org/maven2" );
56          RepositoryPolicy snapshots = new RepositoryPolicy();
57          snapshots.setEnabled( false );
58          remoteRepository.addSnapshots( snapshots );
59          return remoteRepository;
60      }
61  
62      private static String statusAsString( RepositoryPolicy policy )
63      {
64          return ( policy == null ) || policy.isEnabled() ? "enabled" : "disabled";
65      }
66  
67      protected List<ArtifactRepository> createRemoteArtifactRepositories()
68      {
69          return createRemoteArtifactRepositories( null );
70      }
71  
72      /**
73       * Create the list of ArtifactRepository-ies where artifacts can be downloaded. If
74       * no remote repository has been configured, adds central repository.
75       * 
76       * @param pomRepositories additional repositories defined in pom (or null if none)
77       * @return the list of ArtifactRepository-ies
78       * @see #createRemoteArtifactRepository(RemoteRepository)
79       */
80      protected List<ArtifactRepository> createRemoteArtifactRepositories( List<Repository> pomRepositories )
81      {
82          List<RemoteRepository> remoteRepositories = new ArrayList<RemoteRepository>();
83  
84          // First, add repositories configured in Ant
85          remoteRepositories.addAll( getRemoteRepositories() );
86  
87          // Add repositories configured in POM
88          if ( pomRepositories != null )
89          {
90              for ( Repository pomRepository : pomRepositories )
91              {
92                  remoteRepositories.add( createAntRemoteRepository( pomRepository ) );
93              }
94          }
95  
96          // Only add default repository if no repositories were configured otherwise
97          if ( remoteRepositories.isEmpty() )
98          {
99              remoteRepositories.add( getDefaultRemoteRepository() );
100         }
101 
102         log( "Using remote repositories:", Project.MSG_VERBOSE );
103         List<ArtifactRepository> list = new ArrayList<ArtifactRepository>();
104         Set<String> ids = new HashSet<String>();
105         for ( RemoteRepository remoteRepository : remoteRepositories )
106         {
107             if ( !ids.add( remoteRepository.getId() ) )
108             {
109                 // repository id already added to the list: ignore it, since it has been overridden
110                 continue;
111             }
112             updateRepositoryWithSettings( remoteRepository );
113 
114             StringBuffer msg = new StringBuffer();
115             msg.append( "  - id=" + remoteRepository.getId() );
116             msg.append( ", url=" + remoteRepository.getUrl() );
117             msg.append( ", releases=" + statusAsString( remoteRepository.getReleases() ) );
118             msg.append( ", snapshots=" + statusAsString( remoteRepository.getSnapshots() ) );
119             if ( remoteRepository.getAuthentication() != null )
120             {
121                 msg.append( ", authentication=" + remoteRepository.getAuthentication().getUserName() );
122             }
123             if ( remoteRepository.getProxy() != null )
124             {
125                 msg.append( ", proxy=" + remoteRepository.getProxy().getHost() );
126             }
127             getProject().log( msg.toString(), Project.MSG_VERBOSE );
128 
129             list.add( createRemoteArtifactRepository( remoteRepository ) );
130         }
131         return list;
132     }
133 
134     /**
135      * The repositories configured in the Ant task
136      * 
137      * @return The list of repositories
138      */
139     public List<RemoteRepository> getRemoteRepositories()
140     {
141         return remoteRepositories;
142     }
143 
144     /**
145      * This is called automatically by ant when the task is initialized.
146      * Need to use "addConfigured..." instead of "add..." because the
147      * repository Id and URL need to be set before the method is called.
148      *
149      * @param remoteRepository
150      */
151     public void addConfiguredRemoteRepository( RemoteRepository remoteRepository )
152     {
153         if ( remoteRepository.getRefid() != null )
154         {
155             // check that the refid points to a repository that is properly defined
156             String refid = remoteRepository.getRefid();
157             if ( getProject().getReference( refid ) == null )
158             {
159                 throw new BuildException( "Unknown remote repository refid='" + refid + "'." );
160             }
161         }
162         // Validate the url and id parameters before adding the repository
163         if ( remoteRepository.getUrl() == null )
164         {
165             throw new BuildException( "Each remote repository must specify a url." );
166         }
167         if ( remoteRepository.getId() == null || remoteRepository.getId().equals( remoteRepository.getUrl() ) )
168         {
169             log( "Each remote repository must specify a unique id. For backward-compatibility, "
170                  + "a default id will be used. In future releases, a missing repository id will raise an error.",
171                   Project.MSG_WARN );
172             remoteRepository.setId( generateDefaultRepositoryId( remoteRepository ) );
173         }
174         remoteRepositories.add( remoteRepository );
175     }
176 
177     public final String MD5_ALGO_NAME = "MD5";
178 
179     public final String UTF_ENC_NAME = "UTF-8";
180 
181     /**
182      * Generates an MD5 digest based on the url of the repository.
183      * This is safer to use for the id than the url.
184      * MANTTASKS-142
185      *
186      * @param repository
187      * @return
188      */
189     public String generateDefaultRepositoryId( RemoteRepository repository )
190     {
191         try
192         {
193             MessageDigest md = MessageDigest.getInstance( MD5_ALGO_NAME );
194             md.update( repository.getUrl().getBytes( UTF_ENC_NAME ) );
195             BigInteger digest = new BigInteger( md.digest() );
196             return digest.toString( 16 );
197         }
198         catch ( Exception e )
199         {
200             log( "Unable to generate unique repository Id: " + e, Project.MSG_WARN );
201             return "default";
202         }
203     }
204 }