/******************************************************************************* * Copyright (c) 2006, 2007 Intel Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Intel Corporation - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.managedbuilder.internal.buildmodel; import java.io.OutputStream; import org.eclipse.cdt.managedbuilder.buildmodel.BuildDescriptionManager; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildCommand; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildDescription; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildResource; import org.eclipse.cdt.managedbuilder.buildmodel.IBuildStep; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; /** * * This class implements the IBuildStep building * To build the step, create an instance of this class * and invoke the build method * * NOTE: This class is subject to change and discuss, * and is currently available in experimental mode only * */ public class StepBuilder implements IBuildModelBuilder { private IBuildStep fStep; private IPath fCWD; private GenDirInfo fDirs; private boolean fResumeOnErrs; private int fNumCommands = -1; private CommandBuilder fCommandBuilders[]; private IResourceRebuildStateContainer fRebuildStateContainer; public StepBuilder(IBuildStep step, IResourceRebuildStateContainer rs){ this(step, null, rs); } public StepBuilder(IBuildStep step, IPath cwd, IResourceRebuildStateContainer rs){ this(step, cwd, true, null, rs); } public StepBuilder(IBuildStep step, IPath cwd, boolean resumeOnErrs, GenDirInfo dirs, IResourceRebuildStateContainer rs){ fStep = step; fCWD = cwd; fDirs = dirs; fResumeOnErrs = resumeOnErrs; if(fDirs == null) fDirs = new GenDirInfo(fStep.getBuildDescription().getConfiguration()); if(fCWD == null) fCWD = fStep.getBuildDescription().getDefaultBuildDirLocation(); fRebuildStateContainer = rs; } /* (non-Javadoc) * @see org.eclipse.cdt.managedbuilder.internal.builddescription.IBuildDescriptionBuilder#build(java.io.OutputStream, java.io.OutputStream, org.eclipse.core.runtime.IProgressMonitor) */ public int build(OutputStream out, OutputStream err, IProgressMonitor monitor){ monitor.beginTask("", getNumCommands()); //$NON-NLS-1$ monitor.subTask(""); //$NON-NLS-1$ int status = STATUS_OK; CommandBuilder bs[] = getCommandBuilders(); if(bs.length > 0){ //TODO: monitor createOutDirs(new NullProgressMonitor()); for(int i = 0; i < bs.length && status != STATUS_CANCELLED && (fResumeOnErrs || status == STATUS_OK); i++){ CommandBuilder builder = bs[i]; switch(builder.build(out, err, new SubProgressMonitor(monitor, builder.getNumCommands()))){ case STATUS_OK: break; case STATUS_CANCELLED: status = STATUS_CANCELLED; case STATUS_ERROR_BUILD: if(status != STATUS_ERROR_LAUNCH) status = STATUS_ERROR_BUILD; break; case STATUS_ERROR_LAUNCH: default: status = STATUS_ERROR_LAUNCH; break; } } //TODO: monitor status = postProcess(status, new NullProgressMonitor()); } monitor.done(); return status; } protected int postProcess(int status, IProgressMonitor monitor){ if(status != STATUS_ERROR_LAUNCH){ refreshOutputs(monitor); } switch(status){ case STATUS_OK: clearRebuildState(); break; case STATUS_CANCELLED: case STATUS_ERROR_BUILD: case STATUS_ERROR_LAUNCH: default: cleanOutputs(monitor); break; } return status; } private void clearRebuildState(){ if(fRebuildStateContainer == null) return; IBuildResource[] rcs = fStep.getOutputResources(); DescriptionBuilder.putAll(fRebuildStateContainer, rcs, 0, false); rcs = fStep.getInputResources(); DescriptionBuilder.putAll(fRebuildStateContainer, rcs, 0, false); } protected void refreshOutputs(IProgressMonitor monitor){ if(fStep == fStep.getBuildDescription().getInputStep()) return; IBuildResource rcs[] = fStep.getOutputResources(); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); for(int i = 0; i < rcs.length; i++){ IPath path = rcs[i].getFullPath(); if(path != null){ IFile file = root.getFile(path); try { file.refreshLocal(IResource.DEPTH_ZERO, monitor); } catch (CoreException e) { if(DbgUtil.DEBUG){ DbgUtil.trace("failed to refresh resource " //$NON-NLS-1$ + file.getFullPath() + ", error: " + e.getLocalizedMessage()); //$NON-NLS-1$ } } } } } protected void cleanOutputs(IProgressMonitor monitor){ if(fStep == fStep.getBuildDescription().getInputStep()) return; IBuildResource bRcs[] = fStep.getOutputResources(); for(int i = 0; i < bRcs.length; i++){ if(!bRcs[i].isProjectResource()) continue; IResource rc = BuildDescriptionManager.findResourceForBuildResource(bRcs[i]); if(rc != null){ try { rc.delete(true, monitor); } catch (CoreException e) { if(DbgUtil.DEBUG){ DbgUtil.trace("failed to delete resource " //$NON-NLS-1$ + rc.getFullPath() + ", error: " + e.getLocalizedMessage()); //$NON-NLS-1$ } } } } } protected void createOutDirs(IProgressMonitor monitor){ IBuildDescription des = fStep.getBuildDescription(); if(des != null && des.getInputStep() == fStep){ IPath path = des.getDefaultBuildDirFullPath(); if(path != null){ fDirs.createIfProjectDir(path, monitor); } } IBuildResource rcs[] = fStep.getOutputResources(); for(int i = 0; i < rcs.length; i++){ fDirs.createDir(rcs[i], monitor); } } public int getNumCommands() { if(fNumCommands == -1){ CommandBuilder bs[] = getCommandBuilders(); fNumCommands = 0; for(int i = 0; i < bs.length; i++){ fNumCommands += bs[i].getNumCommands(); } } return fNumCommands; } protected CommandBuilder[] getCommandBuilders(){ if(fCommandBuilders == null){ IBuildCommand cmds[] = fStep.getCommands(fCWD, null, null, true); if(cmds == null) fCommandBuilders = new CommandBuilder[0]; else { fCommandBuilders = new CommandBuilder[cmds.length]; for(int i = 0; i < cmds.length; i++){ fCommandBuilders[i] = new CommandBuilder(cmds[i], fRebuildStateContainer); } } } return fCommandBuilders; } }