View Javadoc
1   package org.apache.maven.internal.aether;
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.RepositoryUtils;
23  import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
24  import org.apache.maven.bridge.MavenRepositorySystem;
25  import org.apache.maven.eventspy.internal.EventSpyDispatcher;
26  import org.apache.maven.execution.MavenExecutionRequest;
27  import org.apache.maven.model.Profile;
28  import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
29  import org.apache.maven.rtinfo.RuntimeInformation;
30  import org.apache.maven.settings.Mirror;
31  import org.apache.maven.settings.Proxy;
32  import org.apache.maven.settings.Server;
33  import org.apache.maven.settings.building.SettingsProblem;
34  import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
35  import org.apache.maven.settings.crypto.SettingsDecrypter;
36  import org.apache.maven.settings.crypto.SettingsDecryptionResult;
37  import org.codehaus.plexus.configuration.xml.XmlPlexusConfiguration;
38  import org.codehaus.plexus.logging.Logger;
39  import org.codehaus.plexus.util.xml.Xpp3Dom;
40  import org.eclipse.aether.ConfigurationProperties;
41  import org.eclipse.aether.DefaultRepositorySystemSession;
42  import org.eclipse.aether.RepositorySystem;
43  import org.eclipse.aether.repository.LocalRepository;
44  import org.eclipse.aether.repository.NoLocalRepositoryManagerException;
45  import org.eclipse.aether.repository.RepositoryPolicy;
46  import org.eclipse.aether.repository.WorkspaceReader;
47  import org.eclipse.aether.resolution.ResolutionErrorPolicy;
48  import org.eclipse.aether.spi.localrepo.LocalRepositoryManagerFactory;
49  import org.eclipse.aether.util.repository.AuthenticationBuilder;
50  import org.eclipse.aether.util.repository.DefaultAuthenticationSelector;
51  import org.eclipse.aether.util.repository.DefaultMirrorSelector;
52  import org.eclipse.aether.util.repository.DefaultProxySelector;
53  import org.eclipse.aether.util.repository.SimpleResolutionErrorPolicy;
54  import org.eclipse.sisu.Nullable;
55  
56  import javax.inject.Inject;
57  import javax.inject.Named;
58  
59  import java.util.HashMap;
60  import java.util.LinkedHashMap;
61  import java.util.List;
62  import java.util.Map;
63  
64  /**
65   * @since 3.3.0
66   */
67  @Named
68  public class DefaultRepositorySystemSessionFactory
69  {
70      @Inject
71      private Logger logger;
72  
73      @Inject
74      private ArtifactHandlerManager artifactHandlerManager;
75  
76      @Inject
77      private RepositorySystem repoSystem;
78  
79      @Inject
80      @Nullable
81      @Named( "simple" )
82      private LocalRepositoryManagerFactory simpleLocalRepoMgrFactory;
83  
84      @Inject
85      @Nullable
86      @Named( "ide" )
87      private WorkspaceReader workspaceRepository;
88  
89      @Inject
90      private SettingsDecrypter settingsDecrypter;
91  
92      @Inject
93      private EventSpyDispatcher eventSpyDispatcher;
94  
95      @Inject
96      MavenRepositorySystem mavenRepositorySystem;
97  
98      @Inject
99      private RuntimeInformation runtimeInformation;
100 
101     public DefaultRepositorySystemSession newRepositorySession( MavenExecutionRequest request )
102     {
103         DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
104 
105         session.setCache( request.getRepositoryCache() );
106 
107         Map<Object, Object> configProps = new LinkedHashMap<>();
108         configProps.put( ConfigurationProperties.USER_AGENT, getUserAgent() );
109         configProps.put( ConfigurationProperties.INTERACTIVE, request.isInteractiveMode() );
110         configProps.put( "maven.startTime", request.getStartTime() );
111         // First add properties populated from settings.xml
112         configProps.putAll( getPropertiesFromRequestedProfiles( request ) );
113         // Resolver's ConfigUtils solely rely on config properties, that is why we need to add both here as well.
114         configProps.putAll( request.getSystemProperties() );
115         configProps.putAll( request.getUserProperties() );
116 
117         session.setOffline( request.isOffline() );
118         session.setChecksumPolicy( request.getGlobalChecksumPolicy() );
119         if ( request.isNoSnapshotUpdates() )
120         {
121             session.setUpdatePolicy( RepositoryPolicy.UPDATE_POLICY_NEVER );
122         }
123         else if ( request.isUpdateSnapshots() )
124         {
125             session.setUpdatePolicy( RepositoryPolicy.UPDATE_POLICY_ALWAYS );
126         }
127         else
128         {
129             session.setUpdatePolicy( null );
130         }
131 
132         int errorPolicy = 0;
133         errorPolicy |= request.isCacheNotFound() ? ResolutionErrorPolicy.CACHE_NOT_FOUND
134             : ResolutionErrorPolicy.CACHE_DISABLED;
135         errorPolicy |= request.isCacheTransferError() ? ResolutionErrorPolicy.CACHE_TRANSFER_ERROR
136             : ResolutionErrorPolicy.CACHE_DISABLED;
137         session.setResolutionErrorPolicy(
138             new SimpleResolutionErrorPolicy( errorPolicy, errorPolicy | ResolutionErrorPolicy.CACHE_NOT_FOUND ) );
139 
140         session.setArtifactTypeRegistry( RepositoryUtils.newArtifactTypeRegistry( artifactHandlerManager ) );
141 
142         if ( request.getWorkspaceReader() != null )
143         {
144             session.setWorkspaceReader( request.getWorkspaceReader() );
145         }
146         else
147         {
148             session.setWorkspaceReader( workspaceRepository );
149         }
150 
151         DefaultSettingsDecryptionRequest decrypt = new DefaultSettingsDecryptionRequest();
152         decrypt.setProxies( request.getProxies() );
153         decrypt.setServers( request.getServers() );
154         SettingsDecryptionResult decrypted = settingsDecrypter.decrypt( decrypt );
155 
156         if ( logger.isDebugEnabled() )
157         {
158             for ( SettingsProblem problem : decrypted.getProblems() )
159             {
160                 logger.debug( problem.getMessage(), problem.getException() );
161             }
162         }
163 
164         DefaultMirrorSelector mirrorSelector = new DefaultMirrorSelector();
165         for ( Mirror mirror : request.getMirrors() )
166         {
167             mirrorSelector.add( mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, mirror.isBlocked(),
168                                 mirror.getMirrorOf(), mirror.getMirrorOfLayouts() );
169         }
170         session.setMirrorSelector( mirrorSelector );
171 
172         DefaultProxySelector proxySelector = new DefaultProxySelector();
173         for ( Proxy proxy : decrypted.getProxies() )
174         {
175             AuthenticationBuilder authBuilder = new AuthenticationBuilder();
176             authBuilder.addUsername( proxy.getUsername() ).addPassword( proxy.getPassword() );
177             proxySelector.add(
178                 new org.eclipse.aether.repository.Proxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(),
179                                                          authBuilder.build() ), proxy.getNonProxyHosts() );
180         }
181         session.setProxySelector( proxySelector );
182 
183         DefaultAuthenticationSelector authSelector = new DefaultAuthenticationSelector();
184         for ( Server server : decrypted.getServers() )
185         {
186             AuthenticationBuilder authBuilder = new AuthenticationBuilder();
187             authBuilder.addUsername( server.getUsername() ).addPassword( server.getPassword() );
188             authBuilder.addPrivateKey( server.getPrivateKey(), server.getPassphrase() );
189             authSelector.add( server.getId(), authBuilder.build() );
190 
191             if ( server.getConfiguration() != null )
192             {
193                 Xpp3Dom dom = (Xpp3Dom) server.getConfiguration();
194                 for ( int i = dom.getChildCount() - 1; i >= 0; i-- )
195                 {
196                     Xpp3Dom child = dom.getChild( i );
197                     if ( "wagonProvider".equals( child.getName() ) )
198                     {
199                         dom.removeChild( i );
200                     }
201                 }
202 
203                 XmlPlexusConfiguration config = new XmlPlexusConfiguration( dom );
204                 configProps.put( "aether.connector.wagon.config." + server.getId(), config );
205             }
206 
207             configProps.put( "aether.connector.perms.fileMode." + server.getId(), server.getFilePermissions() );
208             configProps.put( "aether.connector.perms.dirMode." + server.getId(), server.getDirectoryPermissions() );
209         }
210         session.setAuthenticationSelector( authSelector );
211 
212         session.setTransferListener( request.getTransferListener() );
213 
214         session.setRepositoryListener( eventSpyDispatcher.chainListener( new LoggingRepositoryListener( logger ) ) );
215 
216         session.setUserProperties( request.getUserProperties() );
217         session.setSystemProperties( request.getSystemProperties() );
218         session.setConfigProperties( configProps );
219 
220         mavenRepositorySystem.injectMirror( request.getRemoteRepositories(), request.getMirrors() );
221         mavenRepositorySystem.injectProxy( session, request.getRemoteRepositories() );
222         mavenRepositorySystem.injectAuthentication( session, request.getRemoteRepositories() );
223 
224         mavenRepositorySystem.injectMirror( request.getPluginArtifactRepositories(), request.getMirrors() );
225         mavenRepositorySystem.injectProxy( session, request.getPluginArtifactRepositories() );
226         mavenRepositorySystem.injectAuthentication( session, request.getPluginArtifactRepositories() );
227 
228         setUpLocalRepositoryManager( request, session );
229 
230         return session;
231     }
232 
233     private void setUpLocalRepositoryManager( MavenExecutionRequest request, DefaultRepositorySystemSession session )
234     {
235         LocalRepository localRepo = new LocalRepository( request.getLocalRepository().getBasedir() );
236 
237         if ( request.isUseLegacyLocalRepository() )
238         {
239             try
240             {
241                 session.setLocalRepositoryManager( simpleLocalRepoMgrFactory.newInstance( session, localRepo ) );
242                 logger.info( "Disabling enhanced local repository: using legacy is strongly discouraged to ensure"
243                                  + " build reproducibility." );
244             }
245             catch ( NoLocalRepositoryManagerException e )
246             {
247                 logger.error( "Failed to configure legacy local repository: falling back to default" );
248                 session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( session, localRepo ) );
249             }
250         }
251         else
252         {
253             session.setLocalRepositoryManager( repoSystem.newLocalRepositoryManager( session, localRepo ) );
254         }
255     }
256 
257     private Map<?, ?> getPropertiesFromRequestedProfiles( MavenExecutionRequest request )
258     {
259         List<String> activeProfileId =  request.getActiveProfiles();
260         Map<Object, Object> result = new HashMap<>();
261         for ( Profile profile: request.getProfiles() )
262         {
263             if ( activeProfileId.contains( profile.getId() ) )
264             {
265                 result.putAll( profile.getProperties() );
266             }
267         }
268         return result;
269     }
270 
271     private String getUserAgent()
272     {
273         String version = runtimeInformation.getMavenVersion();
274         version = version.isEmpty() ? version : "/" + version;
275         return "Apache-Maven" + version + " (Java " + System.getProperty( "java.version" ) + "; "
276             + System.getProperty( "os.name" ) + " " + System.getProperty( "os.version" ) + ")";
277     }
278 
279 }