blob: aaa3878b8238ff22e82cedea93683893bca827f3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.ant.debugger;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.tools.ant.module.api.AntProjectCookie;
import org.apache.tools.ant.module.api.support.TargetLister;
import org.apache.tools.ant.module.spi.AntEvent;
import org.netbeans.api.debugger.ActionsManager;
import org.netbeans.api.debugger.Breakpoint;
import org.netbeans.api.debugger.DebuggerManager;
import org.netbeans.api.debugger.Watch;
import org.netbeans.modules.ant.debugger.breakpoints.AntBreakpoint;
import org.netbeans.modules.ant.debugger.breakpoints.BreakpointModel;
import org.netbeans.spi.debugger.ActionsProviderSupport;
import org.netbeans.spi.debugger.ContextProvider;
import org.netbeans.spi.debugger.DebuggerEngineProvider;
import org.netbeans.spi.viewmodel.NodeModel;
import org.netbeans.spi.viewmodel.TreeModel;
import org.openide.execution.ExecutorTask;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.text.Annotatable;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.util.TaskListener;
import org.w3c.dom.Element;
/**
* Ant debugger.
*
* @author Honza
*/
public class AntDebugger extends ActionsProviderSupport {
private static final Logger logger = Logger.getLogger(AntDebugger.class.getName());
/** The ReqeustProcessor used by action performers. */
private static RequestProcessor actionsRequestProcessor;
private static RequestProcessor killRequestProcessor;
private AntProjectCookie antCookie;
private AntDebuggerEngineProvider engineProvider;
private ContextProvider contextProvider;
private ExecutorTask execTask;
private final Object LOCK = new Object ();
private final Object LOCK_ACTIONS = new Object();
private boolean actionRunning = false;
private IOManager ioManager;
private Object currentLine;
private LinkedList callStackList = new LinkedList();
private File currentFile;
private String currentTargetName;
private String currentTaskName;
private int originatingIndex = -1; // Current index of the virtual originating target in the call stack
private volatile boolean suspended = false;
private final List<StateListener> stateListeners = new CopyOnWriteArrayList<StateListener>();
private VariablesModel variablesModel;
private WatchesModel watchesModel;
private BreakpointModel breakpointModel;
public AntDebugger (
ContextProvider contextProvider
) {
this.contextProvider = contextProvider;
// init antCookie
antCookie = contextProvider.lookupFirst(null, AntProjectCookie.class);
// init engineProvider
engineProvider = (AntDebuggerEngineProvider) contextProvider.lookupFirst
(null, DebuggerEngineProvider.class);
// init actions
for (Iterator it = actions.iterator(); it.hasNext(); ) {
setEnabled (it.next(), true);
}
ioManager = new IOManager (antCookie.getFile ().getName ());
}
void setExecutor(ExecutorTask execTask) {
this.execTask = execTask;
if (execTask != null) {
execTask.addTaskListener(new TaskListener() {
@Override
public void taskFinished(org.openide.util.Task task) {
// The ANT task was finished
finish();
}
});
}
}
// ActionsProvider .........................................................
private static final Set<Object> actions = new HashSet<>();
private static final Set<Object> actionsToDisable = new HashSet<>();
static {
actions.add (ActionsManager.ACTION_KILL);
actions.add (ActionsManager.ACTION_CONTINUE);
actions.add (ActionsManager.ACTION_START);
actions.add (ActionsManager.ACTION_STEP_INTO);
actions.add (ActionsManager.ACTION_STEP_OVER);
actions.add (ActionsManager.ACTION_STEP_OUT);
actionsToDisable.addAll(actions);
// Ignore the KILL action
actionsToDisable.remove(ActionsManager.ACTION_KILL);
}
@Override
public Set getActions () {
return actions;
}
@Override
public void doAction (Object action) {
synchronized (LOCK_ACTIONS) {
actionRunning = true;
}
logger.log(Level.FINE, "AntDebugger.doAction({0}), is kill = {1}", new Object[]{action, action == ActionsManager.ACTION_KILL});
if (action == ActionsManager.ACTION_KILL) {
finish ();
} else
if (action == ActionsManager.ACTION_CONTINUE) {
doContinue ();
} else
if (action == ActionsManager.ACTION_START) {
return ;
} else
if ( action == ActionsManager.ACTION_STEP_INTO ||
action == ActionsManager.ACTION_STEP_OUT ||
action == ActionsManager.ACTION_STEP_OVER
) {
doStep (action);
}
synchronized (LOCK_ACTIONS) {
if (actionRunning) {
try {
LOCK_ACTIONS.wait();
} catch (InterruptedException iex) {}
}
}
}
@Override
public void postAction(final Object action, final Runnable actionPerformedNotifier) {
if (action == ActionsManager.ACTION_KILL) {
synchronized (AntDebugger.class) {
if (killRequestProcessor == null) {
killRequestProcessor = new RequestProcessor("Ant debugger finish RP", 1);
}
}
killRequestProcessor.post(new Runnable() {
@Override
public void run() {
try {
doAction(action);
} finally {
actionPerformedNotifier.run();
}
}
});
return ;
}
setDebugActionsEnabled(false);
synchronized (AntDebugger.class) {
if (actionsRequestProcessor == null) {
actionsRequestProcessor = new RequestProcessor("Ant debugger actions RP", 1);
}
}
actionsRequestProcessor.post(new Runnable() {
@Override
public void run() {
try {
doAction(action);
} finally {
actionPerformedNotifier.run();
setDebugActionsEnabled(true);
}
}
});
}
private void setDebugActionsEnabled(boolean enabled) {
for (Object action : actionsToDisable) {
setEnabled(action, enabled);
}
}
// other methods ...........................................................
public boolean isSuspended() {
return suspended;
}
private void setSuspended(boolean suspended) {
this.suspended = suspended;
fireStateChanged(suspended);
}
private void fireStateChanged(boolean suspended) {
for (StateListener sl : stateListeners) {
sl.suspended(suspended);
}
}
private void fireFinished() {
for (StateListener sl : stateListeners) {
sl.finished();
}
}
void addStateListener(StateListener sl) {
stateListeners.add(sl);
}
void removeStateListener(StateListener sl) {
stateListeners.remove(sl);
}
private AntEvent lastEvent;
/**
* Called from DebuggerAntLogger.
*/
void taskStarted (AntEvent event) {
if (finished) {
return ;
}
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "AntDebugger.taskStarted({0})", event);
}
Object taskLine = Utils.getLine (event);
callStackList.addFirst(
new Task (event.getTaskStructure (),
taskLine,
event.getScriptLocation ()));
currentTaskName = event.getTaskStructure().getName();
originatingIndex = 0;
if (!ignoreFrame()) {
elementStarted(event);
}
}
private void elementStarted(AntEvent event) {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "AntDebugger.elementStarted({0}), doStop = {1}", new Object[]{event, doStop});
}
if (finished) {
return ;
}
if (!doStop) {
if (!onBreakpoint ()) {
logger.fine(" Not on breakpoint, continuing...");
return ; // continue
} else {
logger.fine(" Is on breakpoint.");
}
}
logger.fine("AntDebugger.elementStarted() stopping...");
stopHere(event);
logger.fine("AntDebugger.elementStarted() finished.");
}
private void stopHere(AntEvent event) {
synchronized (this) {
lastEvent = event;
}
updateUI();
currentFile = event.getScriptLocation();
// update variable values
Set properties = event.getPropertyNames ();
variables = (String[]) properties.toArray
(new String [properties.size ()]);
fireVariables ();
fireWatches ();
fireBreakpoints ();
// enable actions
synchronized (LOCK_ACTIONS) {
actionRunning = false;
LOCK_ACTIONS.notifyAll();
}
// wait for next stepping orders
setSuspended(true);
synchronized (LOCK) {
try {
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "stopHere(): waiting in thread ''{0}'' ...", Thread.currentThread());
}
LOCK.wait ();
if (logger.isLoggable(Level.FINE)) {
logger.log(Level.FINE, "stopHere(): wait in thread ''{0}'' notified.", Thread.currentThread());
}
} catch (InterruptedException ex) {
logger.fine("AntDebugger.stopHere() was interrupted.");
Thread.currentThread().interrupt();
}
}
if (!finished) {
setSuspended(false);
}
synchronized (this) {
lastEvent = null;
}
}
void taskFinished (AntEvent event) {
if (finished) {
return ;
}
if (callStackList.size() > 0) {
callStackList.remove(0);
} else {
logger.log(Level.CONFIG, "Empty call stack when task {0} finished.", event.getTaskStructure().getName());
}
if (taskEndToStopAt != null &&
taskEndToStopAt.equals(event.getTaskStructure().getName()) &&
event.getScriptLocation().equals(fileToStopAt)) {
if (targetEndToStopAt != null) {
if (targetEndToStopAt.equals(event.getTargetName())) {
targetEndToStopAt = null;
taskEndToStopAt = null;
fileToStopAt = null;
doStop = true;
}
} else {
taskEndToStopAt = null;
fileToStopAt = null;
doStop = true;
}
}
}
/**
* Called from DebuggerAntLogger.
*/
void buildFinished (AntEvent event) {
engineProvider.getDestructor ().killEngine ();
ioManager.closeStream ();
Utils.unmarkCurrent ();
fireFinished();
// finish actions
synchronized (LOCK_ACTIONS) {
actionRunning = false;
LOCK_ACTIONS.notifyAll();
}
}
@NbBundle.Messages({"# {0} - a target name",
"# {1} - script location",
"MSG_TargetNotFound=Unable to find the target \"{0}\" in script {1}"})
void targetStarted(AntEvent event) {
if (finished) {
return ;
}
String targetName = event.getTargetName();
//updateTargetsByName(event.getScriptLocation());
TargetLister.Target target = findTarget(targetName, event.getScriptLocation());
List<TargetOriginating> originatingTargets = null;
if (callStackList.size() > 0) {
Object topFrame = callStackList.get(0);
if (topFrame instanceof Task) {
Task t1 = (Task) topFrame;
String startingTargetName = t1.getTaskStructure().getAttribute("target");
if (startingTargetName != null && !targetName.equals(startingTargetName)) {
originatingTargets = findPath(event.getScriptLocation(), startingTargetName, targetName);
}
} else if (topFrame instanceof TargetLister.Target) {
String start = ((TargetLister.Target) topFrame).getName();
List path = findPath (event.getScriptLocation(), start, targetName);
if (path != null) {
callStackList.removeFirst();
originatingTargets = path;
}
} else if (topFrame instanceof TargetOriginating) {
String start = ((TargetOriginating) topFrame).getOriginatingTarget().getName();
if (start.equals(targetName)) {
callStackList.removeFirst();
originatingIndex--;
} else {
List<TargetOriginating> path = findPath (event.getScriptLocation(), start, targetName);
if (path != null) {
callStackList.removeFirst();
originatingTargets = path;
}
}
}
} else {
String[] sessionOriginatingTargets = event.getSession ().getOriginatingTargets();
int l = sessionOriginatingTargets.length;
for (int i = 0; i < l; i++) {
String start = sessionOriginatingTargets [i];
if (start.equals(targetName)) {
continue;
}
List<TargetOriginating> path = findPath (event.getScriptLocation(), start, targetName);
if (path != null) {
originatingTargets = path;
break;
}
//originatingTargets = getOriginatingTargets(null, target);
}
}
if (originatingTargets != null) {
originatingIndex = originatingTargets.size();
callStackList.addAll(0, originatingTargets);
} else {
originatingIndex = 0;
}
//callStackList.add(getOriginatingTargets(start, target));
Object topFrame = (callStackList.size()) > 0 ? callStackList.getFirst() : null;
if (topFrame instanceof TargetOriginating) {
if (((TargetOriginating) topFrame).getOriginatingTarget().getName().equals(targetName)) {
callStackList.removeFirst();
originatingIndex--;
}
}
if (target == null) {
ioManager.println(Bundle.MSG_TargetNotFound(targetName, event.getScriptLocation()), null, true);
}
callStackList.addFirst(target);
currentTargetName = targetName;
currentTaskName = null;
elementStarted(event);
}
void targetFinished(AntEvent event) {
if (finished) {
return ;
}
if (callStackList.size() > 0) {
callStackList.remove(0);
} else {
logger.log(Level.CONFIG, "Empty call stack when target {0} finished.", event.getTargetName());
}
if (targetEndToStopAt != null && targetEndToStopAt.equals(event.getTargetName()) &&
fileToStopAt.equals(event.getScriptLocation())) {
targetEndToStopAt = null;
taskEndToStopAt = null;
fileToStopAt = null;
doStop = true;
}
currentTargetName = null;
}
private Object getTopFrame() {
Object topFrame;
if (originatingIndex > 0) {
topFrame = callStackList.get(originatingIndex);
} else {
topFrame = callStackList.get(0);
}
if (topFrame instanceof TargetOriginating) {
topFrame = ((TargetOriginating) topFrame).getOriginatingTarget();
}
return topFrame;
}
private void updateUI () {
/*TargetLister.Target nextTarget = getNextTarget ();
String nextTargetName = nextTarget == null ?
null : nextTarget.getName ();*/
Object topFrame;
String nextTargetName = null;
if (originatingIndex > 0) {
topFrame = callStackList.get(originatingIndex);
} else {
topFrame = callStackList.get(0);
}
if (topFrame instanceof TargetOriginating) {
TargetLister.Target nextTarget = ((TargetOriginating) topFrame).getDependentTarget();
nextTargetName = nextTarget.getName();
topFrame = ((TargetOriginating) topFrame).getOriginatingTarget();
}
if (topFrame != null) {
currentLine = topFrame instanceof Task ?
((Task) topFrame).getLine () :
Utils.getLine (
(TargetLister.Target) topFrame,
nextTargetName
);
} else {
currentLine = null;
}
if (currentLine != null) {
updateOutputWindow (currentLine);
Utils.markCurrent (currentLine);
}
getCallStackModel ().fireChanges ();
}
private void updateOutputWindow (Object currentLine) {
Object topFrame = getTopFrame();
if (topFrame instanceof Task) {
Task task = (Task) topFrame;
ioManager.println (
task.getFile ().getName () + ":" +
(Utils.getLineNumber (currentLine) + 1) +
": Task " + getStackAsString (),
currentLine
);
} else {
TargetLister.Target target = (TargetLister.Target) topFrame;
ioManager.println (
target.getScript ().getFile ().getName () + ":" +
(Utils.getLineNumber (currentLine) + 1) +
": Target " + getStackAsString (),
currentLine
);
}
}
private String getStackAsString () {
StringBuffer sb = new StringBuffer ();
int i = callStackList.size() - 1;
sb.append (getFrameName (callStackList.get(i--)));
int end = Math.max(0, originatingIndex);
while (i >= end) {
sb.append ('.').append (getFrameName (callStackList.get(i--)));
}
return new String (sb);
}
private static String getFrameName (Object frame) {
if (frame instanceof TargetOriginating) {
frame = ((TargetOriginating) frame).getOriginatingTarget();
}
if (frame == null) {
return "?";
}
return frame instanceof Task ?
((Task) frame).getTaskStructure ().getName () :
((TargetLister.Target) frame).getName ();
}
private boolean ignoreFrame() {
if (callStackList.size() <= 1) {
return false;
}
//String frameName = getFrameName (callStackList.get(0));
if ("import".equals(currentTaskName)) {
String frameName = getFrameName (callStackList.get(1));
if ("antcall".equals(frameName)) {
return true; // Ignore import after antcall
}
}
return false;
}
private Map watches = new HashMap ();
private boolean onBreakpoint () {
// 1) stop on watch value change
Watch[] ws = DebuggerManager.getDebuggerManager ().
getWatches ();
int j, jj = ws.length;
for (j = 0; j < jj; j++) {
Object value = getVariableValue (ws [j].getExpression ());
if (value == null) {
value = new Integer (0);
}
if ( watches.containsKey (ws [j].getExpression ()) &&
!watches.get (ws [j].getExpression ()).equals (value)
) {
/* SOME NONSENSE ???
callStack = new Object [jj - j];
System.arraycopy
(callStackInternal, j, callStack, 0, jj - j);
*/
watches.put (
ws [j].getExpression (),
value
);
return true;
} else {
watches.put (
ws [j].getExpression (),
value
);
}
}
// 2) check line breakpoints
Breakpoint[] breakpoints = DebuggerManager.getDebuggerManager ().
getBreakpoints ();
jj = callStackList.size();
if (jj >= 1) {
Object frame = callStackList.getFirst();
if (frame instanceof TargetOriginating) {
frame = ((TargetOriginating) frame).getOriginatingTarget();
}
Object line;
if (frame == null) {
line = null;
} else {
line = frame instanceof Task ?
((Task) frame).getLine () :
Utils.getLine (
(TargetLister.Target) frame,
null
);
}
if (line != null) {
line = new Annotatable[] { ((Annotatable[]) line)[0] };
}
int i, k = breakpoints.length;
for (i = 0; i < k; i++) {
if ( breakpoints [i] instanceof AntBreakpoint &&
breakpoints [i].isEnabled() &&
Utils.contains (
line,
((AntBreakpoint) breakpoints [i]).getLine ()
)
) {
//callStack = new Object [jj - j];
//callStackList.subList(0, jj - j).toArray(callStack);
//System.arraycopy
// (callStackInternal, j, callStack, 0, jj - j);
return true;
}
}
}
return false;
}
public Object getCurrentLine () {
return currentLine;
}
// stepping hell ...........................................................
private Object lastAction;
private String targetEndToStopAt = null;
private String taskEndToStopAt = null;
private File fileToStopAt = null;
private volatile boolean doStop = true; // stop on the next task/target
private volatile boolean finished = false; // When the debugger has finished.
public boolean isFinished() {
return finished;
}
private void doContinue () {
Utils.unmarkCurrent ();
//lastAction = ActionsManager.ACTION_CONTINUE;
doStop = false;
targetEndToStopAt = null;
taskEndToStopAt = null;
fileToStopAt = null;
doEngineStep ();
}
/**
* should define callStack based on callStackInternal & action.
*/
private void doStep (Object action) {
if (action == ActionsManager.ACTION_STEP_INTO) {
if (originatingIndex > 0) {
originatingIndex--;
updateUI();
// enable actions
synchronized (LOCK_ACTIONS) {
actionRunning = false;
LOCK_ACTIONS.notifyAll();
}
return ;
}
doStop = true;
} else if (action == ActionsManager.ACTION_STEP_OVER) {
if (originatingIndex > 0) {
Object frame = callStackList.get(originatingIndex);
TargetLister.Target dep = ((TargetOriginating) frame).getDependentTarget();
targetEndToStopAt = dep.getName();
taskEndToStopAt = null;
fileToStopAt = currentFile;
doStop = false;
} else {
taskEndToStopAt = currentTaskName;
targetEndToStopAt = currentTargetName;
fileToStopAt = currentFile;
doStop = false;
}
} else if (action == ActionsManager.ACTION_STEP_OUT) {
if (originatingIndex > 1) {
Object frame = callStackList.get(originatingIndex - 1);
TargetLister.Target dep = ((TargetOriginating) frame).getDependentTarget();
targetEndToStopAt = dep.getName();
taskEndToStopAt = null;
fileToStopAt = currentFile;
doStop = false;
}
if (callStackList.size() > 1) {
Object frame = callStackList.get(1);
if (frame instanceof Task) {
taskEndToStopAt = ((Task) frame).getTaskStructure().getName();
for (int i = 2; i < callStackList.size(); i++) {
frame = callStackList.get(i);
if (frame instanceof String) {
targetEndToStopAt = ((TargetLister.Target) frame).getName();
break;
}
}
} else {
if (frame instanceof TargetOriginating) {
targetEndToStopAt = ((TargetOriginating) frame).getOriginatingTarget().getName();
} else {
targetEndToStopAt = ((TargetLister.Target) frame).getName();
}
}
fileToStopAt = currentFile;
doStop = false;
}
} else {
throw new IllegalArgumentException(action.toString());
}
doEngineStep();
//S ystem.out.println("doStep - end");
}
private void doEngineStep () {
//S ystem.out.println("doEngineStep " + doNotStopInTarget);
synchronized (LOCK) {
LOCK.notify ();
}
}
private void finish () {
logger.fine("AntDebugger.finish()");
if (finished) {
logger.fine("finish(): already finished.");
return ;
}
if (execTask != null) {
execTask.stop();
}
logger.fine("finish(): task stopped.");
Utils.unmarkCurrent ();
doStop = false;
finished = true;
taskEndToStopAt = null;
targetEndToStopAt = null;
fileToStopAt = null;
fireFinished();
synchronized (LOCK) {
LOCK.notify ();
}
logger.fine("finish(): notify called.");
buildFinished(null);
logger.fine("finish() done, build finished.");
}
// support for call stack ..................................................
private CallStackModel callStackModel;
private CallStackModel getCallStackModel () {
if (callStackModel == null) {
callStackModel = (CallStackModel) contextProvider.lookupFirst
("CallStackView", TreeModel.class);
}
return callStackModel;
}
Object[] getCallStack () {
//System.out.println("Orig call stack = "+java.util.Arrays.asList(callStack));
//System.out.println("NEW call stack = "+callStackList);
Object[] callStack;
if (originatingIndex > 0) {
callStack = callStackList.subList(originatingIndex, callStackList.size()).toArray();
} else {
callStack = callStackList.toArray();
}
for (int i = 0; i < callStack.length; i++) {
if (callStack[i] instanceof TargetOriginating) {
callStack[i] = ((TargetOriginating) callStack[i]).getOriginatingTarget();
}
}
return callStack;
}
private LinkedList<TargetOriginating> findPath (
File file,
String start,
String end
) {
TargetLister.Target t = findTarget(start, file);
if (t == null) {
return null; // A non-existing target referenced
}
if (start.equals (end)) {
LinkedList<TargetOriginating> ll = new LinkedList<>();
ll.addFirst (new TargetOriginating(null, t));
return ll;
}
String depends = t.getElement ().getAttribute ("depends");
StringTokenizer st = new StringTokenizer (depends, ",");
while (st.hasMoreTokens ()) {
String newStart = st.nextToken ().trim();
LinkedList<TargetOriginating> ll = findPath (
file,
newStart,
end
);
if (ll == null) {
continue;
}
TargetOriginating to = (TargetOriginating) ll.getLast();
if (to.getOriginatingTarget() == null) {
to.setOriginatingTarget(t);
} else {
ll.addLast(new TargetOriginating(t, to.getOriginatingTarget()));
}
return ll;
}
return null;
}
/**
* File as a script location is a key. Values are maps of name to Target.
*/
private Map<File, Map<String, TargetLister.Target>> nameToTargetByFiles = new HashMap<>();
/**
* File as a script location is a key, values are project names.
*/
private Map<File, String> projectNamesByFiles = new HashMap<>();
private synchronized TargetLister.Target findTarget(String name, File file) {
Map<String, TargetLister.Target> nameToTarget = nameToTargetByFiles.get(file);
if (nameToTarget == null) {
nameToTarget = new HashMap<>();
FileObject fo = FileUtil.toFileObject(file);
DataObject dob;
try {
dob = DataObject.find (fo);
} catch (DataObjectNotFoundException donfex) {
throw new IllegalStateException(donfex.getLocalizedMessage());
}
AntProjectCookie ant = dob.getLookup().lookup(AntProjectCookie.class);
if (ant != null) {
Element proj = ant.getProjectElement();
if (proj != null) {
String projName = proj.getAttribute("name");
projectNamesByFiles.put(file, projName);
}
try {
Set targets = TargetLister.getTargets (ant);
Iterator<TargetLister.Target> it = targets.iterator ();
while (it.hasNext ()) {
TargetLister.Target t = it.next();
nameToTarget.put (t.getName (), t);
}
} catch (IOException ioex) {
// Ignore - we'll have an empty map
}
} else {
logger.log(Level.WARNING, "No ant cookie from {0}, fo = {1}", new Object[]{dob, fo});
}
nameToTargetByFiles.put(file, nameToTarget);
}
TargetLister.Target target = (TargetLister.Target) nameToTarget.get(name);
if (target == null) {
String projName = (String) projectNamesByFiles.get(file);
if (name.startsWith(projName+".")) {
name = name.substring(projName.length() + 1);
target = (TargetLister.Target) nameToTarget.get(name);
}
}
return target;
}
// support for variables ...................................................
synchronized void setVariablesModel(VariablesModel variablesModel) {
this.variablesModel = variablesModel;
}
synchronized void setWatchesModel(WatchesModel watchesModel) {
this.watchesModel = watchesModel;
}
private void fireVariables () {
synchronized(this) {
if (variablesModel == null) {
return ;
}
}
variablesModel.fireChanges();
}
private void fireWatches () {
synchronized(this) {
if (watchesModel == null) {
return ;
}
}
watchesModel.fireChanges();
}
private void fireBreakpoints () {
synchronized(this) {
if (breakpointModel == null) {
List<? extends NodeModel> bpNodeModels = DebuggerManager.getDebuggerManager().lookup("BreakpointsView", NodeModel.class);
for (NodeModel model : bpNodeModels) {
if (model instanceof BreakpointModel) {
breakpointModel = (BreakpointModel) model;
break;
}
}
}
}
breakpointModel.fireChanges();
}
String evaluate (String expression) {
String value = getVariableValue (expression);
if (value != null) {
return value;
}
synchronized (this) {
if (lastEvent == null) {
return null;
}
return lastEvent.evaluate (expression);
}
}
private String[] variables = new String [0];
String[] getVariables () {
return variables;
}
String getVariableValue (String variableName) {
synchronized (this) {
if (lastEvent == null) {
return null;
}
return lastEvent.getProperty (variableName);
}
}
/**
* The originating target, that was not entered yet, but is causing another
* target to be entered.
*
* @author Martin Entlicher
*/
private static class TargetOriginating {
private TargetLister.Target target;
private TargetLister.Target dependent;
/**
* Creates a new TargetOriginating object.
* @param target the originating target
* @param dependent the target depending upon the originating one
*/
TargetOriginating (
TargetLister.Target target,
TargetLister.Target dependent
) {
this.target = target;
this.dependent = dependent;
}
TargetLister.Target getOriginatingTarget () {
return target;
}
void setOriginatingTarget (TargetLister.Target target) {
this.target = target;
}
TargetLister.Target getDependentTarget () {
return dependent;
}
}
interface StateListener {
void suspended(boolean suspended);
void finished();
}
}