Lines 14-19
Link Here
|
14 |
*******************************************************************************/ |
14 |
*******************************************************************************/ |
15 |
package org.eclipse.core.internal.events; |
15 |
package org.eclipse.core.internal.events; |
16 |
|
16 |
|
|
|
17 |
import org.eclipse.core.runtime.Status; |
18 |
|
19 |
import org.eclipse.core.resources.IncrementalProjectBuilder; |
20 |
|
17 |
import java.util.*; |
21 |
import java.util.*; |
18 |
import org.eclipse.core.internal.dtree.DeltaDataTree; |
22 |
import org.eclipse.core.internal.dtree.DeltaDataTree; |
19 |
import org.eclipse.core.internal.resources.*; |
23 |
import org.eclipse.core.internal.resources.*; |
Lines 134-145
Link Here
|
134 |
|
138 |
|
135 |
private void basicBuild(int trigger, IncrementalProjectBuilder builder, Map<String,String> args, MultiStatus status, IProgressMonitor monitor) { |
139 |
private void basicBuild(int trigger, IncrementalProjectBuilder builder, Map<String,String> args, MultiStatus status, IProgressMonitor monitor) { |
136 |
try { |
140 |
try { |
137 |
currentBuilder = builder; |
141 |
// currentBuilder = builder; |
|
|
142 |
InternalBuilder currentBuilder2 = builder; |
138 |
//clear any old requests to forget built state |
143 |
//clear any old requests to forget built state |
139 |
currentBuilder.clearLastBuiltStateRequests(); |
144 |
// currentBuilder.clearLastBuiltStateRequests(); |
|
|
145 |
currentBuilder2.clearLastBuiltStateRequests(); |
140 |
// Figure out want kind of build is needed |
146 |
// Figure out want kind of build is needed |
141 |
boolean clean = trigger == IncrementalProjectBuilder.CLEAN_BUILD; |
147 |
boolean clean = trigger == IncrementalProjectBuilder.CLEAN_BUILD; |
142 |
currentLastBuiltTree = currentBuilder.getLastBuiltTree(); |
148 |
currentLastBuiltTree = currentBuilder2.getLastBuiltTree(); |
143 |
|
149 |
|
144 |
// Does the build command respond to this trigger? |
150 |
// Does the build command respond to this trigger? |
145 |
boolean isBuilding = builder.getCommand().isBuilding(trigger); |
151 |
boolean isBuilding = builder.getCommand().isBuilding(trigger); |
Lines 167-180
Link Here
|
167 |
ISchedulingRule rule = null; |
173 |
ISchedulingRule rule = null; |
168 |
try { |
174 |
try { |
169 |
//short-circuit if none of the projects this builder cares about have changed. |
175 |
//short-circuit if none of the projects this builder cares about have changed. |
170 |
if (!needsBuild(currentBuilder, trigger)) { |
176 |
if (!needsBuild(currentBuilder2, trigger)) { |
171 |
//use up the progress allocated for this builder |
177 |
//use up the progress allocated for this builder |
172 |
monitor.beginTask("", 1); //$NON-NLS-1$ |
178 |
monitor.beginTask("", 1); //$NON-NLS-1$ |
173 |
monitor.done(); |
179 |
monitor.done(); |
174 |
return; |
180 |
return; |
175 |
} |
181 |
} |
176 |
rule = builder.getRule(trigger, args); |
182 |
rule = builder.getRule(trigger, args); |
177 |
String name = currentBuilder.getLabel(); |
183 |
String name = currentBuilder2.getLabel(); |
178 |
String message; |
184 |
String message; |
179 |
if (name != null) |
185 |
if (name != null) |
180 |
message = NLS.bind(Messages.events_invoking_2, name, builder.getProject().getFullPath()); |
186 |
message = NLS.bind(Messages.events_invoking_2, name, builder.getProject().getFullPath()); |
Lines 189-194
Link Here
|
189 |
depth = getWorkManager().beginUnprotected(); |
195 |
depth = getWorkManager().beginUnprotected(); |
190 |
// Acquire the rule required for running this builder |
196 |
// Acquire the rule required for running this builder |
191 |
if (rule != null) { |
197 |
if (rule != null) { |
|
|
198 |
// System.out.println("starting rule " + rule.toString()); //$NON-NLS-1$ |
192 |
Job.getJobManager().beginRule(rule, monitor); |
199 |
Job.getJobManager().beginRule(rule, monitor); |
193 |
// Now that we've acquired the rule, changes may have been made concurrently, ensure we're pointing at the |
200 |
// Now that we've acquired the rule, changes may have been made concurrently, ensure we're pointing at the |
194 |
// correct currentTree so delta contains concurrent changes made in areas guarded by the scheduling rule |
201 |
// correct currentTree so delta contains concurrent changes made in areas guarded by the scheduling rule |
Lines 196-222
Link Here
|
196 |
currentTree = workspace.getElementTree(); |
203 |
currentTree = workspace.getElementTree(); |
197 |
} |
204 |
} |
198 |
//do the build |
205 |
//do the build |
199 |
SafeRunner.run(getSafeRunnable(trigger, args, status, monitor)); |
206 |
SafeRunner.run(getSafeRunnable(trigger, args, status, monitor, currentBuilder2)); |
200 |
} finally { |
207 |
} finally { |
201 |
// Re-acquire the WS lock, then release the scheduling rule |
208 |
// Re-acquire the WS lock, then release the scheduling rule |
202 |
if (depth >= 0) |
209 |
if (depth >= 0) |
203 |
getWorkManager().endUnprotected(depth); |
210 |
getWorkManager().endUnprotected(depth); |
204 |
if (rule != null) |
211 |
if (rule != null) |
205 |
Job.getJobManager().endRule(rule); |
212 |
Job.getJobManager().endRule(rule); |
|
|
213 |
// System.out.println("end rule " + rule.toString()); //$NON-NLS-1$ |
206 |
// Be sure to clean up after ourselves. |
214 |
// Be sure to clean up after ourselves. |
207 |
if (clean || currentBuilder.wasForgetStateRequested()) { |
215 |
if (clean || currentBuilder2.wasForgetStateRequested()) { |
208 |
currentBuilder.setLastBuiltTree(null); |
216 |
currentBuilder2.setLastBuiltTree(null); |
209 |
} else if (currentBuilder.wasRememberStateRequested()) { |
217 |
} else if (currentBuilder2.wasRememberStateRequested()) { |
210 |
// If remember last build state, and FULL_BUILD |
218 |
// If remember last build state, and FULL_BUILD |
211 |
// last tree must be set to => null for next build |
219 |
// last tree must be set to => null for next build |
212 |
if (trigger == IncrementalProjectBuilder.FULL_BUILD) |
220 |
if (trigger == IncrementalProjectBuilder.FULL_BUILD) |
213 |
currentBuilder.setLastBuiltTree(null); |
221 |
currentBuilder2.setLastBuiltTree(null); |
214 |
// else don't modify the last built tree |
222 |
// else don't modify the last built tree |
215 |
} else { |
223 |
} else { |
216 |
// remember the current state as the last built state. |
224 |
// remember the current state as the last built state. |
217 |
ElementTree lastTree = workspace.getElementTree(); |
225 |
ElementTree lastTree = workspace.getElementTree(); |
218 |
lastTree.immutable(); |
226 |
// lastTree.immutable(); |
219 |
currentBuilder.setLastBuiltTree(lastTree); |
227 |
currentBuilder2.setLastBuiltTree(lastTree); |
220 |
} |
228 |
} |
221 |
hookEndBuild(builder); |
229 |
hookEndBuild(builder); |
222 |
} |
230 |
} |
Lines 234-240
Link Here
|
234 |
checkCanceled(trigger, monitor); |
242 |
checkCanceled(trigger, monitor); |
235 |
BuildCommand command = (BuildCommand) commands[i]; |
243 |
BuildCommand command = (BuildCommand) commands[i]; |
236 |
IProgressMonitor sub = Policy.subMonitorFor(monitor, 1); |
244 |
IProgressMonitor sub = Policy.subMonitorFor(monitor, 1); |
237 |
IncrementalProjectBuilder builder = getBuilder(buildConfiguration, command, i, status, context); |
245 |
// IncrementalProjectBuilder builder = getBuilder(buildConfiguration, command, i, status, context); |
|
|
246 |
IncrementalProjectBuilder builder; |
247 |
if(IncrementalProjectBuilder.PARALLEL_FULL_BUILD == trigger) { |
248 |
builder = getParallelBuilder(buildConfiguration, command, i, status, context); |
249 |
} else { |
250 |
builder = getBuilder(buildConfiguration, command, i, status, context); |
251 |
} |
238 |
if (builder != null) |
252 |
if (builder != null) |
239 |
basicBuild(trigger, builder, command.getArguments(false), status, sub); |
253 |
basicBuild(trigger, builder, command.getArguments(false), status, sub); |
240 |
} |
254 |
} |
Lines 511-517
Link Here
|
511 |
* The outermost workspace operation has finished. Do an autobuild if necessary. |
525 |
* The outermost workspace operation has finished. Do an autobuild if necessary. |
512 |
*/ |
526 |
*/ |
513 |
public void endTopLevel(boolean needsBuild) { |
527 |
public void endTopLevel(boolean needsBuild) { |
514 |
autoBuildJob.build(needsBuild); |
528 |
// autoBuildJob.build(needsBuild); |
515 |
} |
529 |
} |
516 |
|
530 |
|
517 |
/** |
531 |
/** |
Lines 694-700
Link Here
|
694 |
/** |
708 |
/** |
695 |
* Returns the safe runnable instance for invoking a builder |
709 |
* Returns the safe runnable instance for invoking a builder |
696 |
*/ |
710 |
*/ |
697 |
private ISafeRunnable getSafeRunnable(final int trigger, final Map<String, String> args, final MultiStatus status, final IProgressMonitor monitor) { |
711 |
private ISafeRunnable getSafeRunnable(final int trigger, final Map<String, String> args, final MultiStatus status, final IProgressMonitor monitor, final InternalBuilder currentBuilder2) { |
698 |
return new ISafeRunnable() { |
712 |
return new ISafeRunnable() { |
699 |
public void handleException(Throwable e) { |
713 |
public void handleException(Throwable e) { |
700 |
if (e instanceof OperationCanceledException) { |
714 |
if (e instanceof OperationCanceledException) { |
Lines 702-719
Link Here
|
702 |
Policy.debug("Build canceled"); //$NON-NLS-1$ |
716 |
Policy.debug("Build canceled"); //$NON-NLS-1$ |
703 |
//just discard built state when a builder cancels, to ensure |
717 |
//just discard built state when a builder cancels, to ensure |
704 |
//that it is called again on the very next build. |
718 |
//that it is called again on the very next build. |
705 |
currentBuilder.forgetLastBuiltState(); |
719 |
currentBuilder2.forgetLastBuiltState(); |
706 |
throw (OperationCanceledException) e; |
720 |
throw (OperationCanceledException) e; |
707 |
} |
721 |
} |
708 |
//ResourceStats.buildException(e); |
722 |
//ResourceStats.buildException(e); |
709 |
// don't log the exception....it is already being logged in SafeRunner#run |
723 |
// don't log the exception....it is already being logged in SafeRunner#run |
710 |
|
724 |
|
711 |
//add a generic message to the MultiStatus |
725 |
//add a generic message to the MultiStatus |
712 |
String builderName = currentBuilder.getLabel(); |
726 |
String builderName = currentBuilder2.getLabel(); |
713 |
if (builderName == null || builderName.length() == 0) |
727 |
if (builderName == null || builderName.length() == 0) |
714 |
builderName = currentBuilder.getClass().getName(); |
728 |
builderName = currentBuilder2.getClass().getName(); |
715 |
String pluginId = currentBuilder.getPluginId(); |
729 |
String pluginId = currentBuilder2.getPluginId(); |
716 |
String message = NLS.bind(Messages.events_builderError, builderName, currentBuilder.getProject().getName()); |
730 |
String message = NLS.bind(Messages.events_builderError, builderName, currentBuilder2.getProject().getName()); |
717 |
status.add(new Status(IStatus.ERROR, pluginId, IResourceStatus.BUILD_FAILED, message, e)); |
731 |
status.add(new Status(IStatus.ERROR, pluginId, IResourceStatus.BUILD_FAILED, message, e)); |
718 |
|
732 |
|
719 |
//add the exception status to the MultiStatus |
733 |
//add the exception status to the MultiStatus |
Lines 725-736
Link Here
|
725 |
IProject[] prereqs = null; |
739 |
IProject[] prereqs = null; |
726 |
//invoke the appropriate build method depending on the trigger |
740 |
//invoke the appropriate build method depending on the trigger |
727 |
if (trigger != IncrementalProjectBuilder.CLEAN_BUILD) |
741 |
if (trigger != IncrementalProjectBuilder.CLEAN_BUILD) |
728 |
prereqs = currentBuilder.build(trigger, args, monitor); |
742 |
prereqs = currentBuilder2.build(trigger, args, monitor); |
729 |
else |
743 |
else |
730 |
currentBuilder.clean(monitor); |
744 |
currentBuilder2.clean(monitor); |
731 |
if (prereqs == null) |
745 |
if (prereqs == null) |
732 |
prereqs = new IProject[0]; |
746 |
prereqs = new IProject[0]; |
733 |
currentBuilder.setInterestingProjects(prereqs.clone()); |
747 |
currentBuilder2.setInterestingProjects(prereqs.clone()); |
734 |
} |
748 |
} |
735 |
}; |
749 |
}; |
736 |
} |
750 |
} |
Lines 1145-1148
Link Here
|
1145 |
Policy.log(status); |
1159 |
Policy.log(status); |
1146 |
return workspace.getRoot(); |
1160 |
return workspace.getRoot(); |
1147 |
} |
1161 |
} |
|
|
1162 |
|
1163 |
public void buildParallel(IProgressMonitor subMonitorFor) { |
1164 |
final MultiStatus status = new MultiStatus(ResourcesPlugin.PI_RESOURCES, IResourceStatus.INTERNAL_ERROR, Messages.events_errors, null); |
1165 |
|
1166 |
IProject[] projects = workspace.getRoot().getProjects(IContainer.INCLUDE_HIDDEN); |
1167 |
DirectedGraphs<IProject> directedGraphs = new DirectedGraphs<IProject>(); |
1168 |
for (IProject project : projects) { |
1169 |
directedGraphs.addNode(new Node<IProject>(project)); |
1170 |
} |
1171 |
for (IProject project : projects) { |
1172 |
if (!project.isAccessible()) |
1173 |
continue; |
1174 |
ProjectDescription desc = ((Project)project).internalGetDescription(); |
1175 |
if (desc == null) |
1176 |
continue; |
1177 |
IProject[] refs = desc.getAllReferences(false); |
1178 |
Node<IProject> node = directedGraphs.getNodeWithContent(project); |
1179 |
for (IProject referencedProject : refs) { |
1180 |
Node<IProject> node2 = directedGraphs.getNodeWithContent(referencedProject); |
1181 |
if(node2 != null) { |
1182 |
node2.addOutgoingEdge(node); |
1183 |
} |
1184 |
} |
1185 |
} |
1186 |
ThreadPoolBuilder threadPoolBuilder = new ThreadPoolBuilder(); |
1187 |
try { |
1188 |
IBuildExecutor buildExecutor = new IBuildExecutor() { |
1189 |
public void executeBuild(IBuildDescription buildDescription) { |
1190 |
NullProgressMonitor progressMonitor = new NullProgressMonitor(); |
1191 |
basicBuild(buildDescription.getBuildConfiguration(), IncrementalProjectBuilder.PARALLEL_FULL_BUILD, buildDescription.getBuildContext(), status, progressMonitor); |
1192 |
}}; |
1193 |
threadPoolBuilder.run(directedGraphs, buildExecutor); |
1194 |
} catch (InterruptedException e) { |
1195 |
status.add(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, Messages.events_errors, e)); |
1196 |
} |
1197 |
} |
1198 |
|
1199 |
private IncrementalProjectBuilder getParallelBuilder(IBuildConfiguration buildConfiguration, BuildCommand command, int buildSpecIndex, MultiStatus status, IBuildContext buildContext) throws CoreException { |
1200 |
// always construct a new builder for parallel builds (think about pooling here) |
1201 |
InternalBuilder result = initializeBuilder(command.getBuilderName(), buildConfiguration, buildSpecIndex, status); |
1202 |
command.setBuilders(result); |
1203 |
result.setCommand(command); |
1204 |
result.setBuildConfig(buildConfiguration); |
1205 |
result.startupOnInitialize(); |
1206 |
// } |
1207 |
|
1208 |
if (!validateNature(result, command.getBuilderName())) { |
1209 |
//skip this builder and null its last built tree because it is invalid |
1210 |
//if the nature gets added or re-enabled a full build will be triggered |
1211 |
result.setLastBuiltTree(null); |
1212 |
return null; |
1213 |
} |
1214 |
return (IncrementalProjectBuilder) result; |
1215 |
} |
1216 |
|
1148 |
} |
1217 |
} |