| /******************************************************************************* |
| * Copyright (c) 2004, 2005 IBM 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ant.internal.ui.antsupport.logger; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Stack; |
| import java.util.Vector; |
| |
| import org.apache.tools.ant.BuildEvent; |
| import org.apache.tools.ant.Location; |
| import org.apache.tools.ant.Target; |
| import org.apache.tools.ant.Task; |
| import org.eclipse.ant.internal.ui.antsupport.logger.util.AntDebugUtil; |
| import org.eclipse.ant.internal.ui.debug.IAntDebugController; |
| import org.eclipse.ant.internal.ui.debug.model.AntDebugTarget; |
| import org.eclipse.ant.internal.ui.debug.model.AntThread; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.debug.core.DebugEvent; |
| import org.eclipse.debug.core.ILaunch; |
| import org.eclipse.debug.core.model.IBreakpoint; |
| import org.eclipse.debug.core.model.ILineBreakpoint; |
| import org.eclipse.debug.core.model.IProcess; |
| |
| public class AntProcessDebugBuildLogger extends AntProcessBuildLogger implements IAntDebugController { |
| |
| private boolean fStepOverSuspend= false; |
| private boolean fStepIntoSuspend= false; |
| private boolean fClientSuspend= false; |
| private boolean fShouldSuspend= false; |
| |
| private Stack fTasks= new Stack(); |
| private Task fCurrentTask; |
| private Task fStepOverTask; |
| private Task fLastTaskFinished; |
| |
| private List fBreakpoints= null; |
| |
| //properties set before execution |
| private Map fInitialProperties= null; |
| private Map fProperties= null; |
| |
| private Map fTargetToBuildSequence= null; |
| private Target fTargetToExecute= null; |
| private Target fTargetExecuting= null; |
| |
| private AntDebugTarget fAntDebugTarget; |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.BuildListener#buildStarted(org.apache.tools.ant.BuildEvent) |
| */ |
| public void buildStarted(BuildEvent event) { |
| super.buildStarted(event); |
| IProcess process= getAntProcess(fProcessId); |
| ILaunch launch= process.getLaunch(); |
| fAntDebugTarget= new AntDebugTarget(launch, process, this); |
| launch.addDebugTarget(fAntDebugTarget); |
| |
| fAntDebugTarget.buildStarted(); |
| } |
| |
| private void initializeBuildSequenceInformation(BuildEvent event) { |
| fTargetToBuildSequence= new HashMap(); |
| fTargetToExecute= AntDebugUtil.initializeBuildSequenceInformation(event, fTargetToBuildSequence); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.BuildListener#taskFinished(org.apache.tools.ant.BuildEvent) |
| */ |
| public void taskFinished(BuildEvent event) { |
| super.taskFinished(event); |
| fLastTaskFinished= (Task)fTasks.pop(); |
| fCurrentTask= null; |
| waitIfSuspended(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.BuildListener#taskStarted(org.apache.tools.ant.BuildEvent) |
| */ |
| public void taskStarted(BuildEvent event) { |
| if (fInitialProperties == null) {//implicit or top level target does not fire targetStarted() |
| fInitialProperties= event.getProject().getProperties(); |
| } |
| super.taskStarted(event); |
| fCurrentTask= event.getTask(); |
| fTasks.push(fCurrentTask); |
| waitIfSuspended(); |
| } |
| |
| private synchronized void waitIfSuspended() { |
| if (fCurrentTask != null) { |
| int detail= -1; |
| boolean shouldSuspend= true; |
| IBreakpoint breakpoint= breakpointAtLineNumber(fCurrentTask.getLocation()); |
| if (breakpoint != null) { |
| detail= -2; |
| fAntDebugTarget.breakpointHit(breakpoint); |
| } else if (fStepIntoSuspend) { |
| detail= DebugEvent.STEP_END; |
| fStepIntoSuspend= false; |
| } else if (fStepOverSuspend) { |
| if (fLastTaskFinished == fStepOverTask) { |
| detail= DebugEvent.STEP_END; |
| fStepOverSuspend= false; |
| fStepOverTask= null; |
| } else { |
| shouldSuspend= false; |
| } |
| } else if (fClientSuspend) { |
| detail= DebugEvent.CLIENT_REQUEST; |
| fClientSuspend= false; |
| } else { |
| shouldSuspend= false; |
| } |
| if (shouldSuspend) { |
| if (detail != -2) { //not already notified of hitting breakpoint |
| fAntDebugTarget.suspended(detail); |
| } |
| try { |
| wait(); |
| } catch (InterruptedException e) { |
| } |
| } |
| } else if (fShouldSuspend) { |
| try { |
| fShouldSuspend= false; |
| wait(); |
| } catch (InterruptedException e) { |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#resume() |
| */ |
| public synchronized void resume() { |
| notifyAll(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#suspend() |
| */ |
| public synchronized void suspend() { |
| fClientSuspend= true; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#stepInto() |
| */ |
| public synchronized void stepInto() { |
| fStepIntoSuspend= true; |
| notifyAll(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#stepOver() |
| */ |
| public synchronized void stepOver() { |
| fStepOverSuspend= true; |
| fStepOverTask= fCurrentTask; |
| notifyAll(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#handleBreakpoint(org.eclipse.debug.core.model.IBreakpoint, boolean) |
| */ |
| public void handleBreakpoint(IBreakpoint breakpoint, boolean added) { |
| if (added) { |
| if (fBreakpoints == null) { |
| fBreakpoints= new ArrayList(); |
| } |
| if (!fBreakpoints.contains(breakpoint)) { |
| fBreakpoints.add(breakpoint); |
| } |
| } else { |
| fBreakpoints.remove(breakpoint); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#getProperties() |
| */ |
| public void getProperties() { |
| if (!fAntDebugTarget.isSuspended()) { |
| return; |
| } |
| StringBuffer propertiesRepresentation= new StringBuffer(); |
| if (!fTasks.isEmpty()) { |
| AntDebugUtil.marshallProperties(propertiesRepresentation, ((Task)fTasks.peek()).getProject(), fInitialProperties, fProperties, true); |
| fProperties= ((Task)fTasks.peek()).getProject().getProperties(); |
| } |
| if (fAntDebugTarget.getThreads().length > 0) { |
| ((AntThread) fAntDebugTarget.getThreads()[0]).newProperties(propertiesRepresentation.toString()); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.ant.internal.ui.debug.IAntDebugController#getStackFrames() |
| */ |
| public void getStackFrames() { |
| StringBuffer stackRepresentation= new StringBuffer(); |
| AntDebugUtil.marshalStack(stackRepresentation, fTasks, fTargetToExecute, fTargetExecuting, fTargetToBuildSequence); |
| ((AntThread) fAntDebugTarget.getThreads()[0]).buildStack(stackRepresentation.toString()); |
| } |
| |
| private IBreakpoint breakpointAtLineNumber(Location location) { |
| if (fBreakpoints == null) { |
| return null; |
| } |
| int lineNumber= AntDebugUtil.getLineNumber(location); |
| File locationFile= new File(AntDebugUtil.getFileName(location)); |
| for (int i = 0; i < fBreakpoints.size(); i++) { |
| ILineBreakpoint breakpoint = (ILineBreakpoint) fBreakpoints.get(i); |
| int breakpointLineNumber; |
| try { |
| if (!breakpoint.isEnabled()) { |
| continue; |
| } |
| breakpointLineNumber = breakpoint.getLineNumber(); |
| } catch (CoreException e) { |
| return null; |
| } |
| IFile resource= (IFile) breakpoint.getMarker().getResource(); |
| if (breakpointLineNumber == lineNumber && resource.getLocation().toFile().equals(locationFile)) { |
| return breakpoint; |
| } |
| } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.apache.tools.ant.BuildListener#targetStarted(org.apache.tools.ant.BuildEvent) |
| */ |
| public void targetStarted(BuildEvent event) { |
| if (fInitialProperties == null) { |
| fInitialProperties= event.getProject().getProperties(); |
| } |
| if (fTargetToBuildSequence == null) { |
| initializeBuildSequenceInformation(event); |
| } |
| super.targetStarted(event); |
| fTargetExecuting= event.getTarget(); |
| if (event.getTarget().equals(fTargetToExecute)) { |
| //the dependancies of the target to execute have been met |
| //prepare for the next target |
| Vector targets= (Vector) event.getProject().getReference("eclipse.ant.targetVector"); //$NON-NLS-1$ |
| if (!targets.isEmpty()) { |
| fTargetToExecute= (Target) event.getProject().getTargets().get(targets.remove(0)); |
| } else { |
| fTargetToExecute= null; |
| } |
| } |
| } |
| } |