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.execution;
20  
21  import java.io.File;
22  import java.util.Arrays;
23  import java.util.Date;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Properties;
27  import java.util.concurrent.ConcurrentHashMap;
28  
29  import org.apache.maven.artifact.repository.ArtifactRepository;
30  import org.apache.maven.artifact.repository.RepositoryCache;
31  import org.apache.maven.monitor.event.EventDispatcher;
32  import org.apache.maven.plugin.descriptor.PluginDescriptor;
33  import org.apache.maven.project.MavenProject;
34  import org.apache.maven.project.ProjectBuildingRequest;
35  import org.apache.maven.settings.Settings;
36  import org.codehaus.plexus.PlexusContainer;
37  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
38  import org.eclipse.aether.RepositorySystemSession;
39  
40  /**
41   * A Maven execution session.
42   *
43   * @author Jason van Zyl
44   */
45  public class MavenSession implements Cloneable {
46      private MavenExecutionRequest request;
47  
48      private MavenExecutionResult result;
49  
50      private RepositorySystemSession repositorySession;
51  
52      private Properties executionProperties;
53  
54      private ThreadLocal<MavenProject> currentProject = new ThreadLocal<>();
55  
56      /**
57       * These projects have already been topologically sorted in the {@link org.apache.maven.Maven} component before
58       * being passed into the session. This is also the potentially constrained set of projects by using --projects
59       * on the command line.
60       */
61      private List<MavenProject> projects;
62  
63      /**
64       * The full set of projects before any potential constraining by --projects. Useful in the case where you want to
65       * build a smaller set of projects but perform other operations in the context of your reactor.
66       */
67      private List<MavenProject> allProjects;
68  
69      private MavenProject topLevelProject;
70  
71      private ProjectDependencyGraph projectDependencyGraph;
72  
73      private boolean parallel;
74  
75      private final Map<String, Map<String, Map<String, Object>>> pluginContextsByProjectAndPluginKey =
76              new ConcurrentHashMap<>();
77  
78      public void setProjects(List<MavenProject> projects) {
79          if (!projects.isEmpty()) {
80              MavenProject first = projects.get(0);
81              this.currentProject = ThreadLocal.withInitial(() -> first);
82              this.topLevelProject = projects.stream()
83                      .filter(project -> project.isExecutionRoot())
84                      .findFirst()
85                      .orElse(first);
86          } else {
87              this.currentProject = new ThreadLocal<>();
88              this.topLevelProject = null;
89          }
90          this.projects = projects;
91      }
92  
93      public ArtifactRepository getLocalRepository() {
94          return request.getLocalRepository();
95      }
96  
97      public List<String> getGoals() {
98          return request.getGoals();
99      }
100 
101     /**
102      * Gets the user properties to use for interpolation and profile activation. The user properties have been
103      * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
104      * line.
105      *
106      * @return The user properties, never {@code null}.
107      */
108     public Properties getUserProperties() {
109         return request.getUserProperties();
110     }
111 
112     /**
113      * Gets the system properties to use for interpolation and profile activation. The system properties are collected
114      * from the runtime environment like {@link System#getProperties()} and environment variables.
115      *
116      * @return The system properties, never {@code null}.
117      */
118     public Properties getSystemProperties() {
119         return request.getSystemProperties();
120     }
121 
122     public Settings getSettings() {
123         return settings;
124     }
125 
126     public List<MavenProject> getProjects() {
127         return projects;
128     }
129 
130     public String getExecutionRootDirectory() {
131         return request.getBaseDirectory();
132     }
133 
134     public MavenExecutionRequest getRequest() {
135         return request;
136     }
137 
138     public void setCurrentProject(MavenProject currentProject) {
139         this.currentProject.set(currentProject);
140     }
141 
142     public MavenProject getCurrentProject() {
143         return currentProject.get();
144     }
145 
146     public ProjectBuildingRequest getProjectBuildingRequest() {
147         return request.getProjectBuildingRequest().setRepositorySession(getRepositorySession());
148     }
149 
150     public List<String> getPluginGroups() {
151         return request.getPluginGroups();
152     }
153 
154     public boolean isOffline() {
155         return request.isOffline();
156     }
157 
158     public MavenProject getTopLevelProject() {
159         return topLevelProject;
160     }
161 
162     public MavenExecutionResult getResult() {
163         return result;
164     }
165 
166     // Backward compat
167 
168     public Map<String, Object> getPluginContext(PluginDescriptor plugin, MavenProject project) {
169         String projectKey = project.getId();
170 
171         Map<String, Map<String, Object>> pluginContextsByKey = pluginContextsByProjectAndPluginKey.get(projectKey);
172 
173         if (pluginContextsByKey == null) {
174             pluginContextsByKey = new ConcurrentHashMap<>();
175 
176             pluginContextsByProjectAndPluginKey.put(projectKey, pluginContextsByKey);
177         }
178 
179         String pluginKey = plugin.getPluginLookupKey();
180 
181         Map<String, Object> pluginContext = pluginContextsByKey.get(pluginKey);
182 
183         if (pluginContext == null) {
184             pluginContext = new ConcurrentHashMap<>();
185 
186             pluginContextsByKey.put(pluginKey, pluginContext);
187         }
188 
189         return pluginContext;
190     }
191 
192     public ProjectDependencyGraph getProjectDependencyGraph() {
193         return projectDependencyGraph;
194     }
195 
196     public void setProjectDependencyGraph(ProjectDependencyGraph projectDependencyGraph) {
197         this.projectDependencyGraph = projectDependencyGraph;
198     }
199 
200     public String getReactorFailureBehavior() {
201         return request.getReactorFailureBehavior();
202     }
203 
204     @Override
205     public MavenSession clone() {
206         try {
207             MavenSession clone = (MavenSession) super.clone();
208             // the default must become the current project of the thread that clones this
209             MavenProject current = getCurrentProject();
210             // we replace the thread local of the clone to prevent write through and enforce the new default value
211             clone.currentProject = ThreadLocal.withInitial(() -> current);
212             return clone;
213         } catch (CloneNotSupportedException e) {
214             throw new RuntimeException("Bug", e);
215         }
216     }
217 
218     public Date getStartTime() {
219         return request.getStartTime();
220     }
221 
222     public boolean isParallel() {
223         return parallel;
224     }
225 
226     public void setParallel(boolean parallel) {
227         this.parallel = parallel;
228     }
229 
230     public RepositorySystemSession getRepositorySession() {
231         return repositorySession;
232     }
233 
234     private Map<String, MavenProject> projectMap;
235 
236     public void setProjectMap(Map<String, MavenProject> projectMap) {
237         this.projectMap = projectMap;
238     }
239 
240     /** This is a provisional method and may be removed */
241     public List<MavenProject> getAllProjects() {
242         return allProjects;
243     }
244 
245     /** This is a provisional method and may be removed */
246     public void setAllProjects(List<MavenProject> allProjects) {
247         this.allProjects = allProjects;
248     }
249 
250     /*if_not[MAVEN4]*/
251 
252     //
253     // Deprecated
254     //
255 
256     private PlexusContainer container;
257 
258     private final Settings settings;
259 
260     @Deprecated
261     /** @deprecated This appears to only be used in the ReactorReader and we can do any processing required there */
262     public Map<String, MavenProject> getProjectMap() {
263         return projectMap;
264     }
265 
266     @Deprecated
267     public MavenSession(
268             PlexusContainer container,
269             RepositorySystemSession repositorySession,
270             MavenExecutionRequest request,
271             MavenExecutionResult result) {
272         this.container = container;
273         this.request = request;
274         this.result = result;
275         this.settings = new SettingsAdapter(request);
276         this.repositorySession = repositorySession;
277     }
278 
279     @Deprecated
280     public MavenSession(
281             PlexusContainer container,
282             MavenExecutionRequest request,
283             MavenExecutionResult result,
284             MavenProject project) {
285         this(container, request, result, Arrays.asList(new MavenProject[] {project}));
286     }
287 
288     @Deprecated
289     @SuppressWarnings("checkstyle:parameternumber")
290     public MavenSession(
291             PlexusContainer container,
292             Settings settings,
293             ArtifactRepository localRepository,
294             EventDispatcher eventDispatcher,
295             ReactorManager unused,
296             List<String> goals,
297             String executionRootDir,
298             Properties executionProperties,
299             Date startTime) {
300         this(
301                 container,
302                 settings,
303                 localRepository,
304                 eventDispatcher,
305                 unused,
306                 goals,
307                 executionRootDir,
308                 executionProperties,
309                 null,
310                 startTime);
311     }
312 
313     @Deprecated
314     @SuppressWarnings("checkstyle:parameternumber")
315     public MavenSession(
316             PlexusContainer container,
317             Settings settings,
318             ArtifactRepository localRepository,
319             EventDispatcher eventDispatcher,
320             ReactorManager unused,
321             List<String> goals,
322             String executionRootDir,
323             Properties executionProperties,
324             Properties userProperties,
325             Date startTime) {
326         this.container = container;
327         this.settings = settings;
328         this.executionProperties = executionProperties;
329         this.request = new DefaultMavenExecutionRequest();
330         this.request.setUserProperties(userProperties);
331         this.request.setLocalRepository(localRepository);
332         this.request.setGoals(goals);
333         this.request.setBaseDirectory((executionRootDir != null) ? new File(executionRootDir) : null);
334         this.request.setStartTime(startTime);
335     }
336 
337     @Deprecated
338     public MavenSession(
339             PlexusContainer container,
340             MavenExecutionRequest request,
341             MavenExecutionResult result,
342             List<MavenProject> projects) {
343         this.container = container;
344         this.request = request;
345         this.result = result;
346         this.settings = new SettingsAdapter(request);
347         setProjects(projects);
348     }
349 
350     @Deprecated
351     public List<MavenProject> getSortedProjects() {
352         return getProjects();
353     }
354 
355     @Deprecated
356     //
357     // Used by Tycho and will break users and force them to upgrade to Maven 3.1 so we should really leave
358     // this here, possibly indefinitely.
359     //
360     public RepositoryCache getRepositoryCache() {
361         return null;
362     }
363 
364     @Deprecated
365     public EventDispatcher getEventDispatcher() {
366         return null;
367     }
368 
369     @Deprecated
370     public boolean isUsingPOMsFromFilesystem() {
371         return request.isProjectPresent();
372     }
373 
374     /**
375      * @deprecated Use either {@link #getUserProperties()} or {@link #getSystemProperties()}.
376      */
377     @Deprecated
378     public Properties getExecutionProperties() {
379         if (executionProperties == null) {
380             executionProperties = new Properties();
381             executionProperties.putAll(request.getSystemProperties());
382             executionProperties.putAll(request.getUserProperties());
383         }
384 
385         return executionProperties;
386     }
387 
388     @Deprecated
389     public PlexusContainer getContainer() {
390         return container;
391     }
392 
393     @Deprecated
394     public Object lookup(String role) throws ComponentLookupException {
395         return container.lookup(role);
396     }
397 
398     @Deprecated
399     public Object lookup(String role, String roleHint) throws ComponentLookupException {
400         return container.lookup(role, roleHint);
401     }
402 
403     @Deprecated
404     public List<Object> lookupList(String role) throws ComponentLookupException {
405         return container.lookupList(role);
406     }
407 
408     @Deprecated
409     public Map<String, Object> lookupMap(String role) throws ComponentLookupException {
410         return container.lookupMap(role);
411     }
412 
413     /*end[MAVEN4]*/
414 }