View Javadoc
1   package org.codehaus.mojo.wagon.shared;
2   
3   import org.apache.maven.settings.Proxy;
4   import org.apache.maven.settings.Server;
5   import org.apache.maven.settings.Settings;
6   import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
7   import org.apache.maven.settings.crypto.SettingsDecrypter;
8   import org.apache.maven.settings.crypto.SettingsDecryptionResult;
9   import org.apache.maven.wagon.TransferFailedException;
10  import org.apache.maven.wagon.UnsupportedProtocolException;
11  import org.apache.maven.wagon.Wagon;
12  import org.apache.maven.wagon.WagonException;
13  import org.apache.maven.wagon.authentication.AuthenticationInfo;
14  import org.apache.maven.wagon.observers.Debug;
15  import org.apache.maven.wagon.proxy.ProxyInfo;
16  import org.apache.maven.wagon.repository.Repository;
17  import org.apache.maven.wagon.repository.RepositoryPermissions;
18  import org.codehaus.plexus.PlexusConstants;
19  import org.codehaus.plexus.PlexusContainer;
20  import org.codehaus.plexus.classworlds.realm.ClassRealm;
21  import org.codehaus.plexus.component.configurator.BasicComponentConfigurator;
22  import org.codehaus.plexus.component.annotations.Component;
23  import org.codehaus.plexus.component.annotations.Requirement;
24  import org.codehaus.plexus.component.configurator.ComponentConfigurationException;
25  import org.codehaus.plexus.component.configurator.ComponentConfigurator;
26  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
27  import org.codehaus.plexus.configuration.PlexusConfiguration;
28  import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
29  import org.codehaus.plexus.context.Context;
30  import org.codehaus.plexus.context.ContextException;
31  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
32  import org.codehaus.plexus.util.StringUtils;
33  import org.codehaus.plexus.util.xml.Xpp3Dom;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  import java.util.List;
38  @Component(role = WagonFactory.class, hint = "default")
39  public class DefaultWagonFactory
40      implements WagonFactory, Contextualizable
41  {
42  
43      private final Logger logger = LoggerFactory.getLogger( this.getClass() );
44  
45      @Requirement
46      private SettingsDecrypter settingsDecrypter;
47  
48      @Requirement(hint = "basic")
49      private ComponentConfigurator componentConfigurator;
50  
51      @Requirement(hint = "map-oriented")
52      private ComponentConfigurator mapComponentConfigurator;
53  
54      ////////////////////////////////////////////////////////////////////
55      private PlexusContainer container;
56  
57      @Override
58      public Wagon create( String url, String serverId, Settings settings )
59          throws WagonException
60      {
61          final Repository repository = new Repository( serverId, url == null ? "" : url );
62          repository.setPermissions( getPermissions( serverId, settings ) );
63          Wagon wagon;
64          if ( url == null )
65          {
66              wagon = createAndConfigureWagon( serverId, settings, repository );
67          }
68          else
69          {
70              wagon = getWagon( repository.getProtocol() );
71  
72              configureWagon( wagon, serverId, settings );
73          }
74  
75  
76  
77          if ( logger.isDebugEnabled() )
78          {
79              Debug debug = new Debug();
80              wagon.addSessionListener( debug );
81              wagon.addTransferListener( debug );
82          }
83  
84          AuthenticationInfo authInfo = getAuthenticationInfo( serverId, settings );
85          ProxyInfo proxyInfo = getProxyInfo( settings );
86          wagon.connect( repository, authInfo, proxyInfo );
87  
88          return wagon;
89      }
90  
91      private Wagon createAndConfigureWagon( String repositoryId, Settings settings, Repository repository )
92              throws WagonException
93      {
94          Wagon wagon = null;
95          for ( Server server : settings.getServers() )
96          {
97              String id = server.getId();
98  
99              if ( id != null && id.equals( repositoryId ) )
100             {
101                 Xpp3Dom configuration = (Xpp3Dom) server.getConfiguration();
102                 String url = configuration == null ? null : configuration.getAttribute( "url" );
103                 if ( StringUtils.isBlank( url ) )
104                 {
105                     throw new NullPointerException( "url cannot be null" );
106                 }
107                 repository.setUrl( url );
108 
109                 wagon = getWagon( repository.getProtocol() );
110                 configureWagon( wagon, repositoryId, server );
111 
112                 break;
113 
114             }
115         }
116 
117         return wagon;
118     }
119 
120     ///////////////////////////////////////////////////////////////////////////////////
121     //////////////////////////////////////////////////////////////////////////////////////////////
122 
123     private Wagon getWagon( String protocol )
124         throws UnsupportedProtocolException
125     {
126         if ( protocol == null )
127         {
128             throw new UnsupportedProtocolException( "Unspecified protocol" );
129         }
130 
131         try
132         {
133             return container.lookup( Wagon.class, protocol.toLowerCase( java.util.Locale.ENGLISH ) );
134         }
135         catch ( ComponentLookupException e )
136         {
137             throw new UnsupportedProtocolException( "Cannot find wagon which supports the requested protocol: "
138                 + protocol, e );
139         }
140     }
141 
142     private static RepositoryPermissions getPermissions( String id, Settings settings )
143     {
144         // May not have an id
145         if ( StringUtils.isBlank( id ) )
146         {
147             return null;
148         }
149 
150         // May not be a server matching that id
151         Server server = settings.getServer( id );
152         if ( server == null )
153         {
154             return null;
155         }
156 
157         // Extract perms (if there are any)
158         String filePerms = server.getFilePermissions();
159         String dirPerms = server.getDirectoryPermissions();
160 
161         // Check to see if custom permissions were supplied
162         if ( StringUtils.isBlank( filePerms ) && StringUtils.isBlank( dirPerms ) )
163         {
164             return null;
165         }
166 
167         // There are custom permissions specified in settings.xml for this server
168         RepositoryPermissions permissions = new RepositoryPermissions();
169         permissions.setFileMode( filePerms );
170         permissions.setDirectoryMode( dirPerms );
171         return permissions;
172     }
173 
174     /**
175      * Convenience method to map a <code>Proxy</code> object from the user system settings to a <code>ProxyInfo</code>
176      * object.
177      *
178      * @return a proxyInfo object or null if no active proxy is define in the settings.xml
179      */
180     private ProxyInfo getProxyInfo( Settings settings )
181     {
182         ProxyInfo proxyInfo = null;
183         if ( settings != null && settings.getActiveProxy() != null )
184         {
185             SettingsDecryptionResult result =
186                     settingsDecrypter.decrypt( new DefaultSettingsDecryptionRequest( settings.getActiveProxy() ) );
187             Proxy settingsProxy = result.getProxy();
188 
189             proxyInfo = new ProxyInfo();
190             proxyInfo.setHost( settingsProxy.getHost() );
191             proxyInfo.setType( settingsProxy.getProtocol() );
192             proxyInfo.setPort( settingsProxy.getPort() );
193             proxyInfo.setNonProxyHosts( settingsProxy.getNonProxyHosts() );
194             proxyInfo.setUserName( settingsProxy.getUsername() );
195             proxyInfo.setPassword( settingsProxy.getPassword() );
196         }
197 
198         return proxyInfo;
199     }
200 
201     private Wagon configureWagon( Wagon wagon, String repositoryId, Settings settings )
202         throws TransferFailedException
203     {
204         for ( Server server : settings.getServers() )
205         {
206             String id = server.getId();
207 
208             if ( id != null && id.equals( repositoryId ) && ( server.getConfiguration() != null ) )
209             {
210 
211                 configureWagon( wagon, repositoryId, server);
212                 break;
213 
214             }
215         }
216 
217         return wagon;
218     }
219 
220     private Wagon configureWagon( Wagon wagon, String repositoryId, Server server)
221             throws TransferFailedException
222     {
223         final PlexusConfiguration plexusConf =
224                 new XmlPlexusConfiguration( (Xpp3Dom) server.getConfiguration() );
225         try
226         {
227             if ( !( componentConfigurator instanceof BasicComponentConfigurator ) ) {
228                 componentConfigurator = new BasicComponentConfigurator();
229             }
230             componentConfigurator.configureComponent( wagon, plexusConf,
231                     (ClassRealm) this.getClass().getClassLoader() );
232         }
233         catch ( ComponentConfigurationException e )
234         {
235             throw new TransferFailedException( "While configuring wagon for \'" + repositoryId
236                     + "\': Unable to apply wagon configuration.", e );
237         }
238         return wagon;
239     }
240 
241     public AuthenticationInfo getAuthenticationInfo( String id, Settings settings )
242     {
243         List<Server> servers = settings.getServers();
244 
245         if ( servers != null )
246         {
247             for ( Server server : servers )
248             {
249                 if ( id.equalsIgnoreCase( server.getId() ) )
250                 {
251                     SettingsDecryptionResult result =
252                         settingsDecrypter.decrypt( new DefaultSettingsDecryptionRequest( server ) );
253                     server = result.getServer();
254 
255                     AuthenticationInfo authInfo = new AuthenticationInfo();
256                     authInfo.setUserName( server.getUsername() );
257                     authInfo.setPassword( server.getPassword() );
258                     authInfo.setPrivateKey( server.getPrivateKey() );
259                     authInfo.setPassphrase( server.getPassphrase() );
260 
261                     return authInfo;
262                 }
263             }
264 
265         }
266 
267         // empty one to prevent NPE
268         return new AuthenticationInfo();
269     }
270 
271     @Override
272     public void contextualize( Context context )
273         throws ContextException
274     {
275         container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
276     }
277 
278 }