View Javadoc
1   package org.apache.maven.index.updater;
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 com.google.inject.Injector;
23  import com.google.inject.Key;
24  import com.google.inject.name.Names;
25  import org.apache.maven.wagon.ConnectionException;
26  import org.apache.maven.wagon.ResourceDoesNotExistException;
27  import org.apache.maven.wagon.Wagon;
28  import org.apache.maven.wagon.WagonException;
29  import org.apache.maven.wagon.authentication.AuthenticationException;
30  import org.apache.maven.wagon.authentication.AuthenticationInfo;
31  import org.apache.maven.wagon.authorization.AuthorizationException;
32  import org.apache.maven.wagon.events.TransferListener;
33  import org.apache.maven.wagon.proxy.ProxyInfo;
34  import org.apache.maven.wagon.repository.Repository;
35  
36  import java.io.File;
37  import java.io.FileInputStream;
38  import java.io.FileNotFoundException;
39  import java.io.IOException;
40  import java.io.InputStream;
41  import java.nio.file.Files;
42  
43  /**
44   * This is a helper for obtaining Wagon based ResourceFetchers. Some Indexer integrations does have access to Wagon
45   * already, so this is here just to help them. Since Wagon (et al) is just optional dependency, looking up this
46   * component in integrations where Wagon is not present, should be avoided. This helper is rather limited, as it offers
47   * only "HTTP" wagons! This is not made a Plexus component since SISU would crack in CLI, while trying to load up this
48   * class, because of lacking Wagon classes from classpath!
49   *
50   * @author cstamas
51   */
52  public class WagonHelper
53  {
54      private final Injector injector;
55  
56      public WagonHelper( final Injector injector )
57      {
58          this.injector = injector;
59      }
60  
61      public WagonFetcher getWagonResourceFetcher( final TransferListener listener )
62      {
63          return getWagonResourceFetcher( listener, null, null );
64      }
65  
66      /**
67       * @param listener
68       * @param authenticationInfo
69       * @param proxyInfo
70       * @return
71       * @deprecated use getWagonResourceFetcher with protocol argument
72       */
73      public WagonFetcher getWagonResourceFetcher( final TransferListener listener,
74                                                   final AuthenticationInfo authenticationInfo,
75                                                   final ProxyInfo proxyInfo )
76      {
77          // we limit ourselves to HTTP only
78          return new WagonFetcher( injector.getInstance( Key.get( Wagon.class, Names.named( "http" ) ) ),
79                  listener, authenticationInfo, proxyInfo );
80      }
81  
82      /**
83       * @param listener
84       * @param authenticationInfo
85       * @param proxyInfo
86       * @param protocol           protocol supported by wagon http/https
87       * @return
88       * @since 4.1.3
89       */
90      public WagonFetcher getWagonResourceFetcher( final TransferListener listener,
91                                                   final AuthenticationInfo authenticationInfo,
92                                                   final ProxyInfo proxyInfo,
93                                                   final String protocol )
94      {
95          return new WagonFetcher( injector.getInstance( Key.get( Wagon.class, Names.named( protocol ) ) ),
96                  listener, authenticationInfo, proxyInfo );
97      }
98  
99      public static class WagonFetcher
100         implements ResourceFetcher
101     {
102         private final TransferListener listener;
103 
104         private final AuthenticationInfo authenticationInfo;
105 
106         private final ProxyInfo proxyInfo;
107 
108         private final Wagon wagon;
109 
110         public WagonFetcher( final Wagon wagon, final TransferListener listener,
111                              final AuthenticationInfo authenticationInfo, final ProxyInfo proxyInfo )
112         {
113             this.wagon = wagon;
114             this.listener = listener;
115             this.authenticationInfo = authenticationInfo;
116             this.proxyInfo = proxyInfo;
117         }
118 
119         public void connect( final String id, final String url )
120             throws IOException
121         {
122             Repository repository = new Repository( id, url );
123 
124             try
125             {
126                 // wagon = wagonManager.getWagon( repository );
127 
128                 if ( listener != null )
129                 {
130                     wagon.addTransferListener( listener );
131                 }
132 
133                 // when working in the context of Maven, the WagonManager is already
134                 // populated with proxy information from the Maven environment
135 
136                 if ( authenticationInfo != null )
137                 {
138                     if ( proxyInfo != null )
139                     {
140                         wagon.connect( repository, authenticationInfo, proxyInfo );
141                     }
142                     else
143                     {
144                         wagon.connect( repository, authenticationInfo );
145                     }
146                 }
147                 else
148                 {
149                     if ( proxyInfo != null )
150                     {
151                         wagon.connect( repository, proxyInfo );
152                     }
153                     else
154                     {
155                         wagon.connect( repository );
156                     }
157                 }
158             }
159             catch ( AuthenticationException ex )
160             {
161                 String msg = "Authentication exception connecting to " + repository;
162                 logError( msg, ex );
163                 throw new IOException( msg, ex );
164             }
165             catch ( WagonException ex )
166             {
167                 String msg = "Wagon exception connecting to " + repository;
168                 logError( msg, ex );
169                 throw new IOException( msg, ex );
170             }
171         }
172 
173         public void disconnect()
174             throws IOException
175         {
176             if ( wagon != null )
177             {
178                 try
179                 {
180                     wagon.disconnect();
181                 }
182                 catch ( ConnectionException ex )
183                 {
184                     throw new IOException( ex.toString(), ex );
185                 }
186             }
187         }
188 
189         public InputStream retrieve( String name )
190             throws IOException, FileNotFoundException
191         {
192             final File target = Files.createTempFile( name, "tmp" ).toFile();
193             target.deleteOnExit();
194             retrieve( name, target );
195             return new FileInputStream( target )
196             {
197                 @Override
198                 public void close()
199                     throws IOException
200                 {
201                     super.close();
202                     target.delete();
203                 }
204             };
205         }
206 
207         public void retrieve( final String name, final File targetFile )
208             throws IOException, FileNotFoundException
209         {
210             try
211             {
212                 wagon.get( name, targetFile );
213             }
214             catch ( AuthorizationException e )
215             {
216                 targetFile.delete();
217                 String msg = "Authorization exception retrieving " + name;
218                 logError( msg, e );
219                 throw new IOException( msg, e );
220             }
221             catch ( ResourceDoesNotExistException e )
222             {
223                 targetFile.delete();
224                 String msg = "Resource " + name + " does not exist";
225                 logError( msg, e );
226                 FileNotFoundException fileNotFoundException = new FileNotFoundException( msg );
227                 fileNotFoundException.initCause( e );
228                 throw fileNotFoundException;
229             }
230             catch ( WagonException e )
231             {
232                 targetFile.delete();
233                 String msg = "Transfer for " + name + " failed";
234                 logError( msg, e );
235                 throw new IOException( msg + "; " + e.getMessage(), e );
236             }
237         }
238 
239         private void logError( final String msg, final Exception ex )
240         {
241             if ( listener != null )
242             {
243                 listener.debug( msg + "; " + ex.getMessage() );
244             }
245         }
246     }
247 }