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 static org.apache.maven.internal.impl.Utils.nonNull;
22  
23  import java.nio.file.Path;
24  import java.nio.file.Paths;
25  import java.time.Instant;
26  import java.util.Collections;
27  import java.util.HashMap;
28  import java.util.List;
29  import java.util.Map;
30  import java.util.NoSuchElementException;
31  import java.util.Objects;
32  import java.util.function.Supplier;
33  import java.util.stream.Collectors;
34  import org.apache.maven.RepositoryUtils;
35  import org.apache.maven.api.DependencyCoordinate;
36  import org.apache.maven.api.LocalRepository;
37  import org.apache.maven.api.Project;
38  import org.apache.maven.api.RemoteRepository;
39  import org.apache.maven.api.Service;
40  import org.apache.maven.api.Session;
41  import org.apache.maven.api.SessionData;
42  import org.apache.maven.api.annotations.Nonnull;
43  import org.apache.maven.api.annotations.Nullable;
44  import org.apache.maven.api.services.MavenException;
45  import org.apache.maven.api.settings.Settings;
46  import org.apache.maven.artifact.repository.ArtifactRepository;
47  import org.apache.maven.bridge.MavenRepositorySystem;
48  import org.apache.maven.execution.MavenSession;
49  import org.apache.maven.plugin.MojoExecution;
50  import org.apache.maven.plugin.descriptor.MojoDescriptor;
51  import org.apache.maven.plugin.descriptor.PluginDescriptor;
52  import org.apache.maven.rtinfo.RuntimeInformation;
53  import org.codehaus.plexus.PlexusContainer;
54  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
55  import org.eclipse.aether.DefaultRepositorySystemSession;
56  import org.eclipse.aether.RepositorySystem;
57  import org.eclipse.aether.RepositorySystemSession;
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 Paths.get(mavenSession.getRequest().getBaseDirectory());
153     }
154 
155     @Nonnull
156     @Override
157     public List<Project> getProjects() {
158         return getProjects(mavenSession.getProjects());
159     }
160 
161     @Nonnull
162     @Override
163     public Map<String, Object> getPluginContext(Project project) {
164         nonNull(project, "project");
165         try {
166             MojoExecution mojoExecution = container.lookup(MojoExecution.class);
167             MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
168             PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();
169             return mavenSession.getPluginContext(pluginDescriptor, ((DefaultProject) project).getProject());
170         } catch (ComponentLookupException e) {
171             throw new MavenException("The PluginContext is only available during a mojo execution", e);
172         }
173     }
174 
175     @Nonnull
176     @Override
177     public SessionData getData() {
178         org.eclipse.aether.SessionData data = session.getData();
179         return new SessionData() {
180             @Override
181             public void set(@Nonnull Object key, @Nullable Object value) {
182                 data.set(key, value);
183             }
184 
185             @Override
186             public boolean set(@Nonnull Object key, @Nullable Object oldValue, @Nullable Object newValue) {
187                 return data.set(key, oldValue, newValue);
188             }
189 
190             @Nullable
191             @Override
192             public Object get(@Nonnull Object key) {
193                 return data.get(key);
194             }
195 
196             @Nullable
197             @Override
198             public Object computeIfAbsent(@Nonnull Object key, @Nonnull Supplier<Object> supplier) {
199                 return data.computeIfAbsent(key, supplier);
200             }
201         };
202     }
203 
204     @Nonnull
205     @Override
206     public Session withLocalRepository(@Nonnull LocalRepository localRepository) {
207         nonNull(localRepository, "localRepository");
208         if (session.getLocalRepository() != null
209                 && Objects.equals(session.getLocalRepository().getBasedir().toPath(), localRepository.getPath())) {
210             return this;
211         }
212         org.eclipse.aether.repository.LocalRepository repository = toRepository(localRepository);
213         org.eclipse.aether.repository.LocalRepositoryManager localRepositoryManager =
214                 repositorySystem.newLocalRepositoryManager(session, repository);
215 
216         RepositorySystemSession repoSession =
217                 new DefaultRepositorySystemSession(session).setLocalRepositoryManager(localRepositoryManager);
218         MavenSession newSession = new MavenSession(
219                 mavenSession.getContainer(), repoSession, mavenSession.getRequest(), mavenSession.getResult());
220         return new DefaultSession(
221                 newSession, repositorySystem, repositories, mavenRepositorySystem, container, runtimeInformation);
222     }
223 
224     @Nonnull
225     @Override
226     public Session withRemoteRepositories(@Nonnull List<RemoteRepository> repositories) {
227         return new DefaultSession(
228                 mavenSession, repositorySystem, repositories, mavenRepositorySystem, container, 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 container.lookup(c);
245         } catch (ComponentLookupException 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) {
286         if (dependency instanceof DefaultDependencyCoordinate) {
287             return ((DefaultDependencyCoordinate) dependency).getDependency();
288         } else {
289             return new org.eclipse.aether.graph.Dependency(
290                     new org.eclipse.aether.artifact.DefaultArtifact(
291                             dependency.getGroupId(),
292                             dependency.getArtifactId(),
293                             dependency.getClassifier(),
294                             dependency.getType().getExtension(),
295                             dependency.getVersion().toString(),
296                             null),
297                     dependency.getScope().id());
298         }
299     }
300 }