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