1 package org.apache.maven.execution;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
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;
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 }