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