View Javadoc
1   package org.apache.maven.internal.impl;
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.nio.file.Path;
23  import java.nio.file.Paths;
24  import java.time.Instant;
25  import java.util.Collections;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.NoSuchElementException;
30  import java.util.Objects;
31  import java.util.function.Supplier;
32  import java.util.stream.Collectors;
33  
34  import org.apache.maven.RepositoryUtils;
35  import org.apache.maven.api.DependencyCoordinate;
36  import org.apache.maven.api.LocalRepository;
37  import org.apache.maven.api.Project;
38  import org.apache.maven.api.RemoteRepository;
39  import org.apache.maven.api.Service;
40  import org.apache.maven.api.Session;
41  import org.apache.maven.api.SessionData;
42  import org.apache.maven.api.annotations.Nonnull;
43  import org.apache.maven.api.annotations.Nullable;
44  import org.apache.maven.api.services.MavenException;
45  import org.apache.maven.api.settings.Settings;
46  import org.apache.maven.artifact.repository.ArtifactRepository;
47  import org.apache.maven.bridge.MavenRepositorySystem;
48  import org.apache.maven.execution.MavenSession;
49  import org.apache.maven.plugin.MojoExecution;
50  import org.apache.maven.plugin.descriptor.MojoDescriptor;
51  import org.apache.maven.plugin.descriptor.PluginDescriptor;
52  import org.apache.maven.rtinfo.RuntimeInformation;
53  import org.codehaus.plexus.PlexusContainer;
54  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
55  import org.eclipse.aether.DefaultRepositorySystemSession;
56  import org.eclipse.aether.RepositorySystem;
57  import org.eclipse.aether.RepositorySystemSession;
58  
59  import static org.apache.maven.internal.impl.Utils.nonNull;
60  
61  public class DefaultSession extends AbstractSession
62  {
63  
64      private final MavenSession mavenSession;
65      private final RepositorySystemSession session;
66      private final RepositorySystem repositorySystem;
67      private final List<RemoteRepository> repositories;
68      private final MavenRepositorySystem mavenRepositorySystem;
69      private final PlexusContainer container;
70      private final RuntimeInformation runtimeInformation;
71      private final Map<Class<? extends Service>, Service> services = new HashMap<>();
72  
73      @SuppressWarnings( "checkstyle:ParameterNumber" )
74      public DefaultSession( @Nonnull MavenSession session,
75                             @Nonnull RepositorySystem repositorySystem,
76                             @Nullable List<RemoteRepository> repositories,
77                             @Nonnull MavenRepositorySystem mavenRepositorySystem,
78                             @Nonnull PlexusContainer container,
79                             @Nonnull RuntimeInformation runtimeInformation )
80      {
81          this.mavenSession = nonNull( session );
82          this.session = mavenSession.getRepositorySession();
83          this.repositorySystem = nonNull( repositorySystem );
84          this.repositories = repositories != null
85                  ? repositories
86                  : mavenSession.getRequest().getRemoteRepositories().stream()
87                  .map( RepositoryUtils::toRepo ).map( this::getRemoteRepository ).collect( Collectors.toList() );
88          this.mavenRepositorySystem = mavenRepositorySystem;
89          this.container = container;
90          this.runtimeInformation = runtimeInformation;
91      }
92  
93      public MavenSession getMavenSession()
94      {
95          return mavenSession;
96      }
97  
98      @Nonnull
99      @Override
100     public LocalRepository getLocalRepository()
101     {
102         return new DefaultLocalRepository( session.getLocalRepository() );
103     }
104 
105     @Nonnull
106     @Override
107     public List<RemoteRepository> getRemoteRepositories()
108     {
109         return Collections.unmodifiableList( repositories );
110     }
111 
112     @Nonnull
113     @Override
114     public Settings getSettings()
115     {
116         return mavenSession.getSettings().getDelegate();
117     }
118 
119     @Nonnull
120     @Override
121     public Map<String, String> getUserProperties()
122     {
123         return new PropertiesAsMap( mavenSession.getUserProperties() );
124     }
125 
126     @Nonnull
127     @Override
128     public Map<String, String> getSystemProperties()
129     {
130         return new PropertiesAsMap( mavenSession.getSystemProperties() );
131     }
132 
133     @Nonnull
134     @Override
135     public String getMavenVersion()
136     {
137         return runtimeInformation.getMavenVersion();
138     }
139 
140     @Override
141     public int getDegreeOfConcurrency()
142     {
143         return mavenSession.getRequest().getDegreeOfConcurrency();
144     }
145 
146     @Nonnull
147     @Override
148     public Instant getStartTime()
149     {
150         return mavenSession.getStartTime().toInstant();
151     }
152 
153     @Nonnull
154     @Override
155     public Path getMultiModuleProjectDirectory()
156     {
157         return mavenSession.getRequest().getMultiModuleProjectDirectory().toPath();
158     }
159 
160     @Nonnull
161     @Override
162     public Path getExecutionRootDirectory()
163     {
164         return Paths.get( mavenSession.getRequest().getBaseDirectory() );
165     }
166 
167     @Nonnull
168     @Override
169     public List<Project> getProjects()
170     {
171         return getProjects( mavenSession.getProjects() );
172     }
173 
174     @Nonnull
175     @Override
176     public Map<String, Object> getPluginContext( Project project )
177     {
178         nonNull( project, "project" );
179         try
180         {
181             MojoExecution mojoExecution = container.lookup( MojoExecution.class );
182             MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
183             PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
184             return mavenSession.getPluginContext( pluginDescriptor, ( ( DefaultProject ) project ).getProject() );
185         }
186         catch ( ComponentLookupException e )
187         {
188             throw new MavenException( "The PluginContext is only available during a mojo execution", e );
189         }
190     }
191 
192     @Nonnull
193     @Override
194     public SessionData getData()
195     {
196         org.eclipse.aether.SessionData data = session.getData();
197         return new SessionData()
198         {
199             @Override
200             public void set( @Nonnull Object key, @Nullable Object value )
201             {
202                 data.set( key, value );
203             }
204 
205             @Override
206             public boolean set( @Nonnull Object key, @Nullable Object oldValue, @Nullable Object newValue )
207             {
208                 return data.set( key, oldValue, newValue );
209             }
210 
211             @Nullable
212             @Override
213             public Object get( @Nonnull Object key )
214             {
215                 return data.get( key );
216             }
217 
218             @Nullable
219             @Override
220             public Object computeIfAbsent( @Nonnull Object key, @Nonnull Supplier<Object> supplier )
221             {
222                  return data.computeIfAbsent( key, supplier );
223             }
224         };
225     }
226 
227     @Nonnull
228     @Override
229     public Session withLocalRepository( @Nonnull LocalRepository localRepository )
230     {
231         nonNull( localRepository, "localRepository" );
232         if ( session.getLocalRepository() != null
233                 && Objects.equals( session.getLocalRepository().getBasedir().toPath(),
234                 localRepository.getPath() ) )
235         {
236             return this;
237         }
238         org.eclipse.aether.repository.LocalRepository repository = toRepository( localRepository );
239         org.eclipse.aether.repository.LocalRepositoryManager localRepositoryManager
240                 = repositorySystem.newLocalRepositoryManager( session, repository );
241 
242         RepositorySystemSession repoSession = new DefaultRepositorySystemSession( session )
243                 .setLocalRepositoryManager( localRepositoryManager );
244         MavenSession newSession = new MavenSession( mavenSession.getContainer(), repoSession,
245                 mavenSession.getRequest(), mavenSession.getResult() );
246         return new DefaultSession( newSession, repositorySystem, repositories,
247                 mavenRepositorySystem, container, runtimeInformation );
248     }
249 
250     @Nonnull
251     @Override
252     public Session withRemoteRepositories( @Nonnull List<RemoteRepository> repositories )
253     {
254         return new DefaultSession( mavenSession, repositorySystem, repositories,
255                 mavenRepositorySystem, container, runtimeInformation );
256     }
257 
258     @Nonnull
259     @Override
260     @SuppressWarnings( "unchecked" )
261     public <T extends Service> T getService( Class<T> clazz ) throws NoSuchElementException
262     {
263         T t = (T) services.computeIfAbsent( clazz, this::lookup );
264         if ( t == null )
265         {
266             throw new NoSuchElementException( clazz.getName() );
267         }
268         return t;
269     }
270 
271     private Service lookup( Class<? extends Service> c )
272     {
273         try
274         {
275             return container.lookup( c );
276         }
277         catch ( ComponentLookupException e )
278         {
279             NoSuchElementException nsee = new NoSuchElementException( c.getName() );
280             e.initCause( e );
281             throw nsee;
282         }
283     }
284 
285     @Nonnull
286     public RepositorySystemSession getSession()
287     {
288         return session;
289     }
290 
291     @Nonnull
292     public RepositorySystem getRepositorySystem()
293     {
294         return repositorySystem;
295     }
296 
297     public ArtifactRepository toArtifactRepository( RemoteRepository repository )
298     {
299         if ( repository instanceof DefaultRemoteRepository )
300         {
301             org.eclipse.aether.repository.RemoteRepository rr
302                     = ( (DefaultRemoteRepository) repository ).getRepository();
303 
304             try
305             {
306                 return mavenRepositorySystem.createRepository(
307                         rr.getUrl(),
308                         rr.getId(),
309                         rr.getPolicy( false ).isEnabled(),
310                         rr.getPolicy( false ).getUpdatePolicy(),
311                         rr.getPolicy( true ).isEnabled(),
312                         rr.getPolicy( true ).getUpdatePolicy(),
313                         rr.getPolicy( false ).getChecksumPolicy()
314 
315                 );
316             }
317             catch ( Exception e )
318             {
319                 throw new RuntimeException( "Unable to create repository", e );
320             }
321         }
322         else
323         {
324             // TODO
325             throw new UnsupportedOperationException( "Not yet implemented" );
326         }
327     }
328 
329     public org.eclipse.aether.graph.Dependency toDependency( DependencyCoordinate dependency )
330     {
331         if ( dependency instanceof DefaultDependencyCoordinate )
332         {
333             return ( (DefaultDependencyCoordinate) dependency ).getDependency();
334         }
335         else
336         {
337             return new org.eclipse.aether.graph.Dependency(
338                     new org.eclipse.aether.artifact.DefaultArtifact(
339                             dependency.getGroupId(),
340                             dependency.getArtifactId(),
341                             dependency.getClassifier(),
342                             dependency.getType().getExtension(),
343                             dependency.getVersion().toString(),
344                             null ),
345                     dependency.getScope().id() );
346         }
347     }
348 
349 }