View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.internal.impl;
20  
21  import java.nio.file.Path;
22  import java.time.Instant;
23  import java.util.Collections;
24  import java.util.HashMap;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.NoSuchElementException;
28  import java.util.Objects;
29  import java.util.function.Supplier;
30  import java.util.stream.Collectors;
31  
32  import org.apache.maven.RepositoryUtils;
33  import org.apache.maven.api.DependencyCoordinate;
34  import org.apache.maven.api.LocalRepository;
35  import org.apache.maven.api.Project;
36  import org.apache.maven.api.RemoteRepository;
37  import org.apache.maven.api.Service;
38  import org.apache.maven.api.Session;
39  import org.apache.maven.api.SessionData;
40  import org.apache.maven.api.annotations.Nonnull;
41  import org.apache.maven.api.annotations.Nullable;
42  import org.apache.maven.api.services.MavenException;
43  import org.apache.maven.api.settings.Settings;
44  import org.apache.maven.artifact.repository.ArtifactRepository;
45  import org.apache.maven.bridge.MavenRepositorySystem;
46  import org.apache.maven.execution.MavenSession;
47  import org.apache.maven.plugin.MojoExecution;
48  import org.apache.maven.plugin.descriptor.MojoDescriptor;
49  import org.apache.maven.plugin.descriptor.PluginDescriptor;
50  import org.apache.maven.rtinfo.RuntimeInformation;
51  import org.codehaus.plexus.PlexusContainer;
52  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
53  import org.eclipse.aether.DefaultRepositorySystemSession;
54  import org.eclipse.aether.RepositorySystem;
55  import org.eclipse.aether.RepositorySystemSession;
56  
57  import static org.apache.maven.internal.impl.Utils.nonNull;
58  
59  public class DefaultSession extends AbstractSession {
60  
61      private final MavenSession mavenSession;
62      private final RepositorySystemSession session;
63      private final RepositorySystem repositorySystem;
64      private final List<RemoteRepository> repositories;
65      private final MavenRepositorySystem mavenRepositorySystem;
66      private final PlexusContainer container;
67      private final RuntimeInformation runtimeInformation;
68      private final Map<Class<? extends Service>, Service> services = new HashMap<>();
69  
70      @SuppressWarnings("checkstyle:ParameterNumber")
71      public DefaultSession(
72              @Nonnull MavenSession session,
73              @Nonnull RepositorySystem repositorySystem,
74              @Nullable List<RemoteRepository> repositories,
75              @Nonnull MavenRepositorySystem mavenRepositorySystem,
76              @Nonnull PlexusContainer container,
77              @Nonnull RuntimeInformation runtimeInformation) {
78          this.mavenSession = nonNull(session);
79          this.session = mavenSession.getRepositorySession();
80          this.repositorySystem = nonNull(repositorySystem);
81          this.repositories = repositories != null
82                  ? repositories
83                  : mavenSession.getRequest().getRemoteRepositories().stream()
84                          .map(RepositoryUtils::toRepo)
85                          .map(this::getRemoteRepository)
86                          .collect(Collectors.toList());
87          this.mavenRepositorySystem = mavenRepositorySystem;
88          this.container = container;
89          this.runtimeInformation = runtimeInformation;
90      }
91  
92      public MavenSession getMavenSession() {
93          return mavenSession;
94      }
95  
96      @Nonnull
97      @Override
98      public LocalRepository getLocalRepository() {
99          return new DefaultLocalRepository(session.getLocalRepository());
100     }
101 
102     @Nonnull
103     @Override
104     public List<RemoteRepository> getRemoteRepositories() {
105         return Collections.unmodifiableList(repositories);
106     }
107 
108     @Nonnull
109     @Override
110     public Settings getSettings() {
111         return mavenSession.getSettings().getDelegate();
112     }
113 
114     @Nonnull
115     @Override
116     public Map<String, String> getUserProperties() {
117         return new PropertiesAsMap(mavenSession.getUserProperties());
118     }
119 
120     @Nonnull
121     @Override
122     public Map<String, String> getSystemProperties() {
123         return new PropertiesAsMap(mavenSession.getSystemProperties());
124     }
125 
126     @Nonnull
127     @Override
128     public String getMavenVersion() {
129         return runtimeInformation.getMavenVersion();
130     }
131 
132     @Override
133     public int getDegreeOfConcurrency() {
134         return mavenSession.getRequest().getDegreeOfConcurrency();
135     }
136 
137     @Nonnull
138     @Override
139     public Instant getStartTime() {
140         return mavenSession.getStartTime().toInstant();
141     }
142 
143     @Nonnull
144     @Override
145     public Path getMultiModuleProjectDirectory() {
146         return mavenSession.getRequest().getMultiModuleProjectDirectory().toPath();
147     }
148 
149     @Nonnull
150     @Override
151     public Path getExecutionRootDirectory() {
152         return getTopDirectory();
153     }
154 
155     @Override
156     public Path getRootDirectory() {
157         return mavenSession.getRequest().getRootDirectory();
158     }
159 
160     @Override
161     public Path getTopDirectory() {
162         return mavenSession.getRequest().getTopDirectory();
163     }
164 
165     @Nonnull
166     @Override
167     public List<Project> getProjects() {
168         return getProjects(mavenSession.getProjects());
169     }
170 
171     @Nonnull
172     @Override
173     public Map<String, Object> getPluginContext(Project project) {
174         nonNull(project, "project");
175         try {
176             MojoExecution mojoExecution = container.lookup(MojoExecution.class);
177             MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
178             PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
179             return mavenSession.getPluginContext(pluginDescriptor, ((DefaultProject) project).getProject());
180         } catch (ComponentLookupException e) {
181             throw new MavenException("The PluginContext is only available during a mojo execution", e);
182         }
183     }
184 
185     @Nonnull
186     @Override
187     public SessionData getData() {
188         org.eclipse.aether.SessionData data = session.getData();
189         return new SessionData() {
190             @Override
191             public void set(@Nonnull Object key, @Nullable Object value) {
192                 data.set(key, value);
193             }
194 
195             @Override
196             public boolean set(@Nonnull Object key, @Nullable Object oldValue, @Nullable Object newValue) {
197                 return data.set(key, oldValue, newValue);
198             }
199 
200             @Nullable
201             @Override
202             public Object get(@Nonnull Object key) {
203                 return data.get(key);
204             }
205 
206             @Nullable
207             @Override
208             public Object computeIfAbsent(@Nonnull Object key, @Nonnull Supplier<Object> supplier) {
209                 return data.computeIfAbsent(key, supplier);
210             }
211         };
212     }
213 
214     @Nonnull
215     @Override
216     public Session withLocalRepository(@Nonnull LocalRepository localRepository) {
217         nonNull(localRepository, "localRepository");
218         if (session.getLocalRepository() != null
219                 && Objects.equals(session.getLocalRepository().getBasedir().toPath(), localRepository.getPath())) {
220             return this;
221         }
222         org.eclipse.aether.repository.LocalRepository repository = toRepository(localRepository);
223         org.eclipse.aether.repository.LocalRepositoryManager localRepositoryManager =
224                 repositorySystem.newLocalRepositoryManager(session, repository);
225 
226         RepositorySystemSession repoSession =
227                 new DefaultRepositorySystemSession(session).setLocalRepositoryManager(localRepositoryManager);
228         MavenSession newSession = new MavenSession(
229                 mavenSession.getContainer(), repoSession, mavenSession.getRequest(), mavenSession.getResult());
230         return new DefaultSession(
231                 newSession, repositorySystem, repositories, mavenRepositorySystem, container, runtimeInformation);
232     }
233 
234     @Nonnull
235     @Override
236     public Session withRemoteRepositories(@Nonnull List<RemoteRepository> repositories) {
237         return new DefaultSession(
238                 mavenSession, repositorySystem, repositories, mavenRepositorySystem, container, runtimeInformation);
239     }
240 
241     @Nonnull
242     @Override
243     @SuppressWarnings("unchecked")
244     public <T extends Service> T getService(Class<T> clazz) throws NoSuchElementException {
245         T t = (T) services.computeIfAbsent(clazz, this::lookup);
246         if (t == null) {
247             throw new NoSuchElementException(clazz.getName());
248         }
249         return t;
250     }
251 
252     private Service lookup(Class<? extends Service> c) {
253         try {
254             return container.lookup(c);
255         } catch (ComponentLookupException e) {
256             NoSuchElementException nsee = new NoSuchElementException(c.getName());
257             e.initCause(e);
258             throw nsee;
259         }
260     }
261 
262     @Nonnull
263     public RepositorySystemSession getSession() {
264         return session;
265     }
266 
267     @Nonnull
268     public RepositorySystem getRepositorySystem() {
269         return repositorySystem;
270     }
271 
272     public ArtifactRepository toArtifactRepository(RemoteRepository repository) {
273         if (repository instanceof DefaultRemoteRepository) {
274             org.eclipse.aether.repository.RemoteRepository rr = ((DefaultRemoteRepository) repository).getRepository();
275 
276             try {
277                 return mavenRepositorySystem.createRepository(
278                         rr.getUrl(),
279                         rr.getId(),
280                         rr.getPolicy(false).isEnabled(),
281                         rr.getPolicy(false).getUpdatePolicy(),
282                         rr.getPolicy(true).isEnabled(),
283                         rr.getPolicy(true).getUpdatePolicy(),
284                         rr.getPolicy(false).getChecksumPolicy());
285 
286             } catch (Exception e) {
287                 throw new RuntimeException("Unable to create repository", e);
288             }
289         } else {
290             // TODO
291             throw new UnsupportedOperationException("Not yet implemented");
292         }
293     }
294 
295     public org.eclipse.aether.graph.Dependency toDependency(DependencyCoordinate dependency) {
296         if (dependency instanceof DefaultDependencyCoordinate) {
297             return ((DefaultDependencyCoordinate) dependency).getDependency();
298         } else {
299             return new org.eclipse.aether.graph.Dependency(
300                     new org.eclipse.aether.artifact.DefaultArtifact(
301                             dependency.getGroupId(),
302                             dependency.getArtifactId(),
303                             dependency.getClassifier(),
304                             dependency.getType().getExtension(),
305                             dependency.getVersion().toString(),
306                             null),
307                     dependency.getScope().id());
308         }
309     }
310 }