001package org.apache.maven.execution;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *  http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.File;
023import java.util.Arrays;
024import java.util.Date;
025import java.util.List;
026import java.util.Map;
027import java.util.Properties;
028import java.util.concurrent.ConcurrentHashMap;
029
030import org.apache.maven.artifact.repository.ArtifactRepository;
031import org.apache.maven.artifact.repository.RepositoryCache;
032import org.apache.maven.monitor.event.EventDispatcher;
033import org.apache.maven.plugin.descriptor.PluginDescriptor;
034import org.apache.maven.project.MavenProject;
035import org.apache.maven.project.ProjectBuildingRequest;
036import org.apache.maven.settings.Settings;
037import org.codehaus.plexus.PlexusContainer;
038import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
039import org.eclipse.aether.RepositorySystemSession;
040
041/**
042 * @author Jason van Zyl
043 */
044public class MavenSession
045    implements Cloneable
046{
047    private MavenExecutionRequest request;
048
049    private MavenExecutionResult result;
050
051    private RepositorySystemSession repositorySession;
052
053    private Properties executionProperties;
054
055    private MavenProject currentProject;
056
057    /**
058     * These projects have already been topologically sorted in the {@link org.apache.maven.Maven} component before
059     * being passed into the session. This is also the potentially constrained set of projects by using --projects
060     * on the command line.
061     */
062    private List<MavenProject> projects;
063
064    /**
065     * The full set of projects before any potential constraining by --projects. Useful in the case where you want to
066     * build a smaller set of projects but perform other operations in the context of your reactor.
067     */
068    private List<MavenProject> allProjects;
069
070    private MavenProject topLevelProject;
071
072    private ProjectDependencyGraph projectDependencyGraph;
073
074    private boolean parallel;
075
076    private final Map<String, Map<String, Map<String, Object>>> pluginContextsByProjectAndPluginKey =
077        new ConcurrentHashMap<String, Map<String, Map<String, Object>>>();
078
079
080    public void setProjects( List<MavenProject> projects )
081    {
082        if ( !projects.isEmpty() )
083        {
084            this.currentProject = projects.get( 0 );
085            this.topLevelProject = currentProject;
086            for ( MavenProject project : projects )
087            {
088                if ( project.isExecutionRoot() )
089                {
090                    topLevelProject = project;
091                    break;
092                }
093            }
094        }
095        else
096        {
097            this.currentProject = null;
098            this.topLevelProject = null;
099        }
100        this.projects = projects;
101    }
102
103    public ArtifactRepository getLocalRepository()
104    {
105        return request.getLocalRepository();
106    }
107
108    public List<String> getGoals()
109    {
110        return request.getGoals();
111    }
112
113    /**
114     * Gets the user properties to use for interpolation and profile activation. The user properties have been
115     * configured directly by the user on his discretion, e.g. via the {@code -Dkey=value} parameter on the command
116     * line.
117     *
118     * @return The user properties, never {@code null}.
119     */
120    public Properties getUserProperties()
121    {
122        return request.getUserProperties();
123    }
124
125    /**
126     * Gets the system properties to use for interpolation and profile activation. The system properties are collected
127     * from the runtime environment like {@link System#getProperties()} and environment variables.
128     *
129     * @return The system properties, never {@code null}.
130     */
131    public Properties getSystemProperties()
132    {
133        return request.getSystemProperties();
134    }
135
136    public Settings getSettings()
137    {
138        return settings;
139    }
140
141    public List<MavenProject> getProjects()
142    {
143        return projects;
144    }
145
146    public String getExecutionRootDirectory()
147    {
148        return request.getBaseDirectory();
149    }
150
151    public MavenExecutionRequest getRequest()
152    {
153        return request;
154    }
155
156    public void setCurrentProject( MavenProject currentProject )
157    {
158        this.currentProject = currentProject;
159    }
160
161    public MavenProject getCurrentProject()
162    {
163        return currentProject;
164    }
165
166    public ProjectBuildingRequest getProjectBuildingRequest()
167    {
168        return request.getProjectBuildingRequest().setRepositorySession( getRepositorySession() );
169    }
170
171    public List<String> getPluginGroups()
172    {
173        return request.getPluginGroups();
174    }
175
176    public boolean isOffline()
177    {
178        return request.isOffline();
179    }
180
181    public MavenProject getTopLevelProject()
182    {
183        return topLevelProject;
184    }
185
186    public MavenExecutionResult getResult()
187    {
188        return result;
189    }
190
191    // Backward compat
192
193    public Map<String, Object> getPluginContext( PluginDescriptor plugin, MavenProject project )
194    {
195        String projectKey = project.getId();
196
197        Map<String, Map<String, Object>> pluginContextsByKey = pluginContextsByProjectAndPluginKey.get( projectKey );
198
199        if ( pluginContextsByKey == null )
200        {
201            pluginContextsByKey = new ConcurrentHashMap<String, Map<String, Object>>();
202
203            pluginContextsByProjectAndPluginKey.put( projectKey, pluginContextsByKey );
204        }
205
206        String pluginKey = plugin.getPluginLookupKey();
207
208        Map<String, Object> pluginContext = pluginContextsByKey.get( pluginKey );
209
210        if ( pluginContext == null )
211        {
212            pluginContext = new ConcurrentHashMap<String, Object>();
213
214            pluginContextsByKey.put( pluginKey, pluginContext );
215        }
216
217        return pluginContext;
218    }
219
220    public ProjectDependencyGraph getProjectDependencyGraph()
221    {
222        return projectDependencyGraph;
223    }
224
225    public void setProjectDependencyGraph( ProjectDependencyGraph projectDependencyGraph )
226    {
227        this.projectDependencyGraph = projectDependencyGraph;
228    }
229
230    public String getReactorFailureBehavior()
231    {
232        return request.getReactorFailureBehavior();
233    }
234
235    @Override
236    public MavenSession clone()
237    {
238        try
239        {
240            return (MavenSession) super.clone();
241        }
242        catch ( CloneNotSupportedException e )
243        {
244            throw new RuntimeException( "Bug", e );
245        }
246    }
247
248    public Date getStartTime()
249    {
250        return request.getStartTime();
251    }
252
253    public boolean isParallel()
254    {
255        return parallel;
256    }
257
258    public void setParallel( boolean parallel )
259    {
260        this.parallel = parallel;
261    }
262
263    public RepositorySystemSession getRepositorySession()
264    {
265        return repositorySession;
266    }
267
268    private Map<String, MavenProject> projectMap;
269
270    public void setProjectMap( Map<String, MavenProject> projectMap )
271    {
272        this.projectMap = projectMap;
273    }
274    
275    /** This is a provisional method and may be removed */
276    public List<MavenProject> getAllProjects()
277    {
278        return allProjects;
279    }
280
281    /** This is a provisional method and may be removed */
282    public void setAllProjects( List<MavenProject> allProjects )
283    {
284        this.allProjects = allProjects;
285    }
286    
287    /*if_not[MAVEN4]*/
288
289    //
290    // Deprecated 
291    //
292        
293    private PlexusContainer container;    
294    
295    private final Settings settings;
296    
297    @Deprecated
298    /** @deprecated This appears to only be used in the ReactorReader and we can do any processing required there */
299    public Map<String, MavenProject> getProjectMap() 
300    {
301        return projectMap;
302    }
303    
304    @Deprecated
305    public MavenSession( PlexusContainer container, RepositorySystemSession repositorySession,
306                         MavenExecutionRequest request, MavenExecutionResult result )
307    {
308        this.container = container;
309        this.request = request;
310        this.result = result;
311        this.settings = new SettingsAdapter( request );
312        this.repositorySession = repositorySession;
313    }
314    
315    @Deprecated
316    public MavenSession( PlexusContainer container, MavenExecutionRequest request, MavenExecutionResult result,
317                         MavenProject project )
318    {
319        this( container, request, result, Arrays.asList( new MavenProject[]{project} ) );
320    }
321
322    @Deprecated
323    public MavenSession( PlexusContainer container, Settings settings, ArtifactRepository localRepository,
324                         EventDispatcher eventDispatcher, ReactorManager unused, List<String> goals,
325                         String executionRootDir, Properties executionProperties, Date startTime )
326    {
327        this( container, settings, localRepository, eventDispatcher, unused, goals, executionRootDir,
328              executionProperties, null, startTime );
329    }
330
331    @Deprecated
332    public MavenSession( PlexusContainer container, Settings settings, ArtifactRepository localRepository,
333                         EventDispatcher eventDispatcher, ReactorManager unused, List<String> goals,
334                         String executionRootDir, Properties executionProperties, Properties userProperties,
335                         Date startTime )
336    {
337        this.container = container;
338        this.settings = settings;
339        this.executionProperties = executionProperties;
340        this.request = new DefaultMavenExecutionRequest();
341        this.request.setUserProperties( userProperties );
342        this.request.setLocalRepository( localRepository );
343        this.request.setGoals( goals );
344        this.request.setBaseDirectory( ( executionRootDir != null ) ? new File( executionRootDir ) : null );
345        this.request.setStartTime( startTime );
346    }
347
348    @Deprecated
349    public MavenSession( PlexusContainer container, MavenExecutionRequest request, MavenExecutionResult result,
350                         List<MavenProject> projects )
351    {
352        this.container = container;
353        this.request = request;
354        this.result = result;
355        this.settings = new SettingsAdapter( request );
356        setProjects( projects );
357    }
358
359    @Deprecated
360    public List<MavenProject> getSortedProjects()
361    {
362        return getProjects();
363    }
364    
365    @Deprecated
366    //
367    // Used by Tycho and will break users and force them to upgrade to Maven 3.1 so we should really leave
368    // this here, possibly indefinitely.
369    //
370    public RepositoryCache getRepositoryCache()
371    {
372        return null;
373    }
374
375    @Deprecated
376    public EventDispatcher getEventDispatcher()
377    {
378        return null;
379    }
380
381    @Deprecated
382    public boolean isUsingPOMsFromFilesystem()
383    {
384        return request.isProjectPresent();
385    }
386
387    /**
388     * @deprecated Use either {@link #getUserProperties()} or {@link #getSystemProperties()}.
389     */
390    @Deprecated
391    public Properties getExecutionProperties()
392    {
393        if ( executionProperties == null )
394        {
395            executionProperties = new Properties();
396            executionProperties.putAll( request.getSystemProperties() );
397            executionProperties.putAll( request.getUserProperties() );
398        }
399
400        return executionProperties;
401    }
402    
403    @Deprecated
404    public PlexusContainer getContainer()
405    {
406        return container;
407    }
408
409    @Deprecated
410    public Object lookup( String role )
411        throws ComponentLookupException
412    {
413        return container.lookup( role );
414    }
415
416    @Deprecated
417    public Object lookup( String role, String roleHint )
418        throws ComponentLookupException
419    {
420        return container.lookup( role, roleHint );
421    }
422
423    @Deprecated
424    public List<Object> lookupList( String role )
425        throws ComponentLookupException
426    {
427        return container.lookupList( role );
428    }
429
430    @Deprecated
431    public Map<String, Object> lookupMap( String role )
432        throws ComponentLookupException
433    {
434        return container.lookupMap( role );
435    }   
436    
437    /*end[MAVEN4]*/
438}