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     @Override
144     public Path getRootDirectory() {
145         return mavenSession.getRequest().getRootDirectory();
146     }
147 
148     @Override
149     public Path getTopDirectory() {
150         return mavenSession.getRequest().getTopDirectory();
151     }
152 
153     @Nonnull
154     @Override
155     public List<Project> getProjects() {
156         return getProjects(mavenSession.getProjects());
157     }
158 
159     @Nonnull
160     @Override
161     public Map<String, Object> getPluginContext(Project project) {
162         nonNull(project, "project");
163         try {
164             MojoExecution mojoExecution = container.lookup(MojoExecution.class);
165             MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
166             PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
167             return mavenSession.getPluginContext(pluginDescriptor, ((DefaultProject) project).getProject());
168         } catch (ComponentLookupException e) {
169             throw new MavenException("The PluginContext is only available during a mojo execution", e);
170         }
171     }
172 
173     @Nonnull
174     @Override
175     public SessionData getData() {
176         org.eclipse.aether.SessionData data = session.getData();
177         return new SessionData() {
178             @Override
179             public void set(@Nonnull Object key, @Nullable Object value) {
180                 data.set(key, value);
181             }
182 
183             @Override
184             public boolean set(@Nonnull Object key, @Nullable Object oldValue, @Nullable Object newValue) {
185                 return data.set(key, oldValue, newValue);
186             }
187 
188             @Nullable
189             @Override
190             public Object get(@Nonnull Object key) {
191                 return data.get(key);
192             }
193 
194             @Nullable
195             @Override
196             public Object computeIfAbsent(@Nonnull Object key, @Nonnull Supplier<Object> supplier) {
197                 return data.computeIfAbsent(key, supplier);
198             }
199         };
200     }
201 
202     @Nonnull
203     @Override
204     public Session withLocalRepository(@Nonnull LocalRepository localRepository) {
205         nonNull(localRepository, "localRepository");
206         if (session.getLocalRepository() != null
207                 && Objects.equals(session.getLocalRepository().getBasedir().toPath(), localRepository.getPath())) {
208             return this;
209         }
210         org.eclipse.aether.repository.LocalRepository repository = toRepository(localRepository);
211         org.eclipse.aether.repository.LocalRepositoryManager localRepositoryManager =
212                 repositorySystem.newLocalRepositoryManager(session, repository);
213 
214         RepositorySystemSession repoSession =
215                 new DefaultRepositorySystemSession(session).setLocalRepositoryManager(localRepositoryManager);
216         MavenSession newSession = new MavenSession(
217                 mavenSession.getContainer(), repoSession, mavenSession.getRequest(), mavenSession.getResult());
218         return new DefaultSession(
219                 newSession, repositorySystem, repositories, mavenRepositorySystem, container, runtimeInformation);
220     }
221 
222     @Nonnull
223     @Override
224     public Session withRemoteRepositories(@Nonnull List<RemoteRepository> repositories) {
225         return new DefaultSession(
226                 mavenSession, repositorySystem, repositories, mavenRepositorySystem, container, runtimeInformation);
227     }
228 
229     @Nonnull
230     @Override
231     @SuppressWarnings("unchecked")
232     public <T extends Service> T getService(Class<T> clazz) throws NoSuchElementException {
233         T t = (T) services.computeIfAbsent(clazz, this::lookup);
234         if (t == null) {
235             throw new NoSuchElementException(clazz.getName());
236         }
237         return t;
238     }
239 
240     private Service lookup(Class<? extends Service> c) {
241         try {
242             return container.lookup(c);
243         } catch (ComponentLookupException e) {
244             NoSuchElementException nsee = new NoSuchElementException(c.getName());
245             e.initCause(e);
246             throw nsee;
247         }
248     }
249 
250     @Nonnull
251     public RepositorySystemSession getSession() {
252         return session;
253     }
254 
255     @Nonnull
256     public RepositorySystem getRepositorySystem() {
257         return repositorySystem;
258     }
259 
260     public ArtifactRepository toArtifactRepository(RemoteRepository repository) {
261         if (repository instanceof DefaultRemoteRepository) {
262             org.eclipse.aether.repository.RemoteRepository rr = ((DefaultRemoteRepository) repository).getRepository();
263 
264             try {
265                 return mavenRepositorySystem.createRepository(
266                         rr.getUrl(),
267                         rr.getId(),
268                         rr.getPolicy(false).isEnabled(),
269                         rr.getPolicy(false).getUpdatePolicy(),
270                         rr.getPolicy(true).isEnabled(),
271                         rr.getPolicy(true).getUpdatePolicy(),
272                         rr.getPolicy(false).getChecksumPolicy());
273 
274             } catch (Exception e) {
275                 throw new RuntimeException("Unable to create repository", e);
276             }
277         } else {
278             // TODO
279             throw new UnsupportedOperationException("Not yet implemented");
280         }
281     }
282 
283     public org.eclipse.aether.graph.Dependency toDependency(DependencyCoordinate dependency) {
284         if (dependency instanceof DefaultDependencyCoordinate) {
285             return ((DefaultDependencyCoordinate) dependency).getDependency();
286         } else {
287             return new org.eclipse.aether.graph.Dependency(
288                     new org.eclipse.aether.artifact.DefaultArtifact(
289                             dependency.getGroupId(),
290                             dependency.getArtifactId(),
291                             dependency.getClassifier(),
292                             dependency.getType().getExtension(),
293                             dependency.getVersion().toString(),
294                             null),
295                     dependency.getScope().id());
296         }
297     }
298 }