View Javadoc

1   package org.apache.maven.execution;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  
23  import org.apache.maven.artifact.ArtifactUtils;
24  import org.apache.maven.plugin.descriptor.PluginDescriptor;
25  import org.apache.maven.project.DuplicateProjectException;
26  import org.apache.maven.project.MavenProject;
27  import org.apache.maven.project.MissingProjectException;
28  import org.apache.maven.project.ProjectSorter;
29  import org.codehaus.plexus.util.dag.CycleDetectedException;
30  
31  import java.util.ArrayList;
32  import java.util.HashMap;
33  import java.util.Iterator;
34  import java.util.List;
35  import java.util.Map;
36  
37  public class ReactorManager
38  {
39      public static final String FAIL_FAST = "fail-fast";
40  
41      public static final String FAIL_AT_END = "fail-at-end";
42  
43      public static final String FAIL_NEVER = "fail-never";
44  
45      public static final String MAKE_MODE = "make";
46  
47      public static final String MAKE_DEPENDENTS_MODE = "make-dependents";
48  
49      // make projects that depend on me, and projects that I depend on
50      public static final String MAKE_BOTH_MODE = "make-both";
51      
52      private List blackList = new ArrayList();
53  
54      private Map buildFailuresByProject = new HashMap();
55  
56      private Map pluginContextsByProjectAndPluginKey = new HashMap();
57  
58      private String failureBehavior = FAIL_FAST;
59  
60      private final ProjectSorter sorter;
61  
62      private Map buildSuccessesByProject = new HashMap();
63  
64      public ReactorManager( List projects )
65          throws CycleDetectedException, DuplicateProjectException, MissingProjectException
66      {
67          this.sorter = new ProjectSorter( projects );
68      }
69      
70      public ReactorManager( List projects, List selectedProjects, String resumeFrom, String makeBehavior )
71          throws CycleDetectedException, DuplicateProjectException, MissingProjectException
72      {
73          boolean make, makeDependents;
74          if ( makeBehavior == null )
75          {
76              make = false;
77              makeDependents = false;
78          }
79          else if ( MAKE_MODE.equals( makeBehavior ) )
80          {
81              make = true;
82              makeDependents = false;
83          }
84          else if ( MAKE_DEPENDENTS_MODE.equals( makeBehavior ) )
85          {
86              make = false;
87              makeDependents = true;
88          }
89          else if ( MAKE_BOTH_MODE.equals( makeBehavior ) )
90          {
91              make = true;
92              makeDependents = true;
93          }
94          else
95          {
96              throw new IllegalArgumentException( "Invalid make behavior (must be one of: \'" + MAKE_MODE + "\', \'"
97                  + MAKE_DEPENDENTS_MODE + "\', \'" + MAKE_BOTH_MODE + "\')." );
98          }
99          this.sorter = new ProjectSorter( projects, selectedProjects, resumeFrom, make, makeDependents );
100     }
101 
102     public Map getPluginContext( PluginDescriptor plugin, MavenProject project )
103     {
104         Map pluginContextsByKey = (Map) pluginContextsByProjectAndPluginKey.get( project.getId() );
105 
106         if ( pluginContextsByKey == null )
107         {
108             pluginContextsByKey = new HashMap();
109             pluginContextsByProjectAndPluginKey.put( project.getId(), pluginContextsByKey );
110         }
111 
112         Map pluginContext = (Map) pluginContextsByKey.get( plugin.getPluginLookupKey() );
113 
114         if ( pluginContext == null )
115         {
116             pluginContext = new HashMap();
117             pluginContextsByKey.put( plugin.getPluginLookupKey(), pluginContext );
118         }
119 
120         return pluginContext;
121     }
122 
123     public void setFailureBehavior( String failureBehavior )
124     {
125         if ( failureBehavior == null )
126         {
127             this.failureBehavior = FAIL_FAST; // default
128             return;
129         }
130         if ( FAIL_FAST.equals( failureBehavior ) || FAIL_AT_END.equals( failureBehavior ) ||
131             FAIL_NEVER.equals( failureBehavior ) )
132         {
133             this.failureBehavior = failureBehavior;
134         }
135         else
136         {
137             throw new IllegalArgumentException( "Invalid failure behavior (must be one of: \'" + FAIL_FAST + "\', \'" +
138                 FAIL_AT_END + "\', \'" + FAIL_NEVER + "\')." );
139         }
140     }
141 
142     public String getFailureBehavior()
143     {
144         return failureBehavior;
145     }
146 
147     public void blackList( MavenProject project )
148     {
149         blackList( getProjectKey( project ) );
150     }
151 
152     private void blackList( String id )
153     {
154         if ( !blackList.contains( id ) )
155         {
156             blackList.add( id );
157 
158             List dependents = sorter.getDependents( id );
159 
160             if ( dependents != null && !dependents.isEmpty() )
161             {
162                 for ( Iterator it = dependents.iterator(); it.hasNext(); )
163                 {
164                     String dependentId = (String) it.next();
165 
166                     if ( !buildSuccessesByProject.containsKey( dependentId ) &&
167                         !buildFailuresByProject.containsKey( dependentId ) )
168                     {
169                         blackList( dependentId );
170                     }
171                 }
172             }
173         }
174     }
175 
176     public boolean isBlackListed( MavenProject project )
177     {
178         return blackList.contains( getProjectKey( project ) );
179     }
180 
181     private static String getProjectKey( MavenProject project )
182     {
183         return ArtifactUtils.versionlessKey( project.getGroupId(), project.getArtifactId() );
184     }
185 
186     public void registerBuildFailure( MavenProject project, Exception error, String task, long time )
187     {
188         buildFailuresByProject.put( getProjectKey( project ), new BuildFailure( error, task, time ) );
189     }
190 
191     public boolean hasBuildFailures()
192     {
193         return !buildFailuresByProject.isEmpty();
194     }
195 
196     public boolean hasBuildFailure( MavenProject project )
197     {
198         return buildFailuresByProject.containsKey( getProjectKey( project ) );
199     }
200 
201     public boolean hasMultipleProjects()
202     {
203         return sorter.hasMultipleProjects();
204     }
205 
206     public List<MavenProject> getSortedProjects()
207     {
208         return sorter.getSortedProjects();
209     }
210 
211     public MavenProject getTopLevelProject()
212     {
213         return sorter.getTopLevelProject();
214     }
215 
216     public boolean hasBuildSuccess( MavenProject project )
217     {
218         return buildSuccessesByProject.containsKey( getProjectKey( project ) );
219     }
220 
221     public void registerBuildSuccess( MavenProject project, long time )
222     {
223         buildSuccessesByProject.put( getProjectKey( project ), new BuildSuccess( project, time ) );
224     }
225 
226     public BuildFailure getBuildFailure( MavenProject project )
227     {
228         return (BuildFailure) buildFailuresByProject.get( getProjectKey( project ) );
229     }
230 
231     public BuildSuccess getBuildSuccess( MavenProject project )
232     {
233         return (BuildSuccess) buildSuccessesByProject.get( getProjectKey( project ) );
234     }
235 
236     public boolean executedMultipleProjects()
237     {
238         return buildFailuresByProject.size() + buildSuccessesByProject.size() > 1;
239     }
240 }