View Javadoc

1   package org.apache.maven.shared.io.download;
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.io.File;
23  import java.io.IOException;
24  import java.net.MalformedURLException;
25  import java.net.URL;
26  import java.util.Collections;
27  import java.util.HashMap;
28  import java.util.Iterator;
29  import java.util.List;
30  import java.util.Map;
31  
32  import org.apache.maven.artifact.manager.WagonManager;
33  import org.apache.maven.shared.io.logging.MessageHolder;
34  import org.apache.maven.wagon.ConnectionException;
35  import org.apache.maven.wagon.ResourceDoesNotExistException;
36  import org.apache.maven.wagon.TransferFailedException;
37  import org.apache.maven.wagon.UnsupportedProtocolException;
38  import org.apache.maven.wagon.Wagon;
39  import org.apache.maven.wagon.authentication.AuthenticationException;
40  import org.apache.maven.wagon.authorization.AuthorizationException;
41  import org.apache.maven.wagon.events.TransferListener;
42  import org.apache.maven.wagon.repository.Repository;
43  
44  public class DefaultDownloadManager
45      implements DownloadManager
46  {
47  
48      public static final String ROLE_HINT = "default";
49  
50      private WagonManager wagonManager;
51  
52      private Map cache = new HashMap();
53  
54      public DefaultDownloadManager()
55      {
56      }
57  
58      public DefaultDownloadManager( WagonManager wagonManager )
59      {
60          this.wagonManager = wagonManager;
61      }
62  
63      public File download( String url, MessageHolder messageHolder )
64          throws DownloadFailedException
65      {
66          return download( url, Collections.EMPTY_LIST, messageHolder );
67      }
68  
69      public File download( String url, List transferListeners, MessageHolder messageHolder )
70          throws DownloadFailedException
71      {
72          File downloaded = (File) cache.get( url );
73  
74          if ( downloaded != null && downloaded.exists() )
75          {
76              messageHolder.addMessage( "Using cached download: " + downloaded.getAbsolutePath() );
77  
78              return downloaded;
79          }
80  
81          URL sourceUrl;
82          try
83          {
84              sourceUrl = new URL( url );
85          }
86          catch ( MalformedURLException e )
87          {
88              throw new DownloadFailedException( url, "Download failed due to invalid URL. Reason: " + e.getMessage(), e );
89          }
90  
91          Wagon wagon = null;
92  
93          // Retrieve the correct Wagon instance used to download the remote archive
94          try
95          {
96              wagon = wagonManager.getWagon( sourceUrl.getProtocol() );
97          }
98          catch ( UnsupportedProtocolException e )
99          {
100             throw new DownloadFailedException( url, "Download failed. Reason: " + e.getMessage(), e );
101         }
102 
103         messageHolder.addMessage( "Using wagon: " + wagon + " to download: " + url );
104 
105         try
106         {
107             // create the landing file in /tmp for the downloaded source archive
108             downloaded = File.createTempFile( "download-", null );
109 
110             // delete when the JVM exits, to avoid polluting the temp dir...
111             downloaded.deleteOnExit();
112         }
113         catch ( IOException e )
114         {
115             throw new DownloadFailedException( url, "Failed to create temporary file target for download. Reason: "
116                 + e.getMessage(), e );
117         }
118 
119         messageHolder.addMessage( "Download target is: " + downloaded.getAbsolutePath() );
120 
121         // split the download URL into base URL and remote path for connecting, then retrieving.
122         String remotePath = sourceUrl.getPath();
123         String baseUrl = url.substring( 0, url.length() - remotePath.length() );
124 
125         for ( Iterator it = transferListeners.iterator(); it.hasNext(); )
126         {
127             TransferListener listener = (TransferListener) it.next();
128             wagon.addTransferListener( listener );
129         }
130 
131         // connect to the remote site, and retrieve the archive. Note the separate methods in which
132         // base URL and remote path are used.
133         Repository repo = new Repository( sourceUrl.getHost(), baseUrl );
134 
135         messageHolder.addMessage( "Connecting to: " + repo.getHost() + "(baseUrl: " + repo.getUrl() + ")" );
136 
137         try
138         {
139             wagon.connect( repo, wagonManager.getAuthenticationInfo( repo.getId() ), wagonManager.getProxy( sourceUrl
140                 .getProtocol() ) );
141         }
142         catch ( ConnectionException e )
143         {
144             throw new DownloadFailedException( url, "Download failed. Reason: " + e.getMessage(), e );
145         }
146         catch ( AuthenticationException e )
147         {
148             throw new DownloadFailedException( url, "Download failed. Reason: " + e.getMessage(), e );
149         }
150 
151         messageHolder.addMessage( "Getting: " + remotePath );
152 
153         try
154         {
155             wagon.get( remotePath, downloaded );
156 
157             // cache this for later download requests to the same instance...
158             cache.put( url, downloaded );
159 
160             return downloaded;
161         }
162         catch ( TransferFailedException e )
163         {
164             throw new DownloadFailedException( url, "Download failed. Reason: " + e.getMessage(), e );
165         }
166         catch ( ResourceDoesNotExistException e )
167         {
168             throw new DownloadFailedException( url, "Download failed. Reason: " + e.getMessage(), e );
169         }
170         catch ( AuthorizationException e )
171         {
172             throw new DownloadFailedException( url, "Download failed. Reason: " + e.getMessage(), e );
173         }
174         finally
175         {
176             // ensure the Wagon instance is closed out properly.
177             if ( wagon != null )
178             {
179                 try
180                 {
181                     messageHolder.addMessage( "Disconnecting." );
182 
183                     wagon.disconnect();
184                 }
185                 catch ( ConnectionException e )
186                 {
187                     messageHolder.addMessage( "Failed to disconnect wagon for: " + url, e );
188                 }
189 
190                 for ( Iterator it = transferListeners.iterator(); it.hasNext(); )
191                 {
192                     TransferListener listener = (TransferListener) it.next();
193                     wagon.removeTransferListener( listener );
194                 }
195             }
196         }
197     }
198 
199 }