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