KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > debug > core > breakpoints > JavaLineBreakpoint


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.debug.core.breakpoints;
12
13  
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19 import java.util.Set JavaDoc;
20
21 import org.eclipse.core.resources.IMarker;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.resources.IWorkspaceRunnable;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IAdaptable;
26 import org.eclipse.core.runtime.IProgressMonitor;
27 import org.eclipse.core.runtime.IStatus;
28 import org.eclipse.core.runtime.Status;
29 import org.eclipse.debug.core.DebugEvent;
30 import org.eclipse.debug.core.DebugException;
31 import org.eclipse.debug.core.DebugPlugin;
32 import org.eclipse.debug.core.ILaunch;
33 import org.eclipse.debug.core.IStatusHandler;
34 import org.eclipse.debug.core.model.IBreakpoint;
35 import org.eclipse.debug.core.model.IDebugTarget;
36 import org.eclipse.debug.core.model.ISourceLocator;
37 import org.eclipse.debug.core.model.IValue;
38 import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
39 import org.eclipse.jdt.core.IJavaElement;
40 import org.eclipse.jdt.core.IJavaProject;
41 import org.eclipse.jdt.core.JavaCore;
42 import org.eclipse.jdt.core.dom.Message;
43 import org.eclipse.jdt.debug.core.IJavaDebugTarget;
44 import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
45 import org.eclipse.jdt.debug.core.IJavaPrimitiveValue;
46 import org.eclipse.jdt.debug.core.IJavaReferenceType;
47 import org.eclipse.jdt.debug.core.IJavaType;
48 import org.eclipse.jdt.debug.core.JDIDebugModel;
49 import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
50 import org.eclipse.jdt.debug.eval.ICompiledExpression;
51 import org.eclipse.jdt.debug.eval.IEvaluationListener;
52 import org.eclipse.jdt.debug.eval.IEvaluationResult;
53 import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
54 import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;
55 import org.eclipse.jdt.internal.debug.core.model.JDIStackFrame;
56 import org.eclipse.jdt.internal.debug.core.model.JDIThread;
57
58 import com.ibm.icu.text.MessageFormat;
59 import com.sun.jdi.AbsentInformationException;
60 import com.sun.jdi.ClassNotPreparedException;
61 import com.sun.jdi.Location;
62 import com.sun.jdi.NativeMethodException;
63 import com.sun.jdi.ObjectReference;
64 import com.sun.jdi.ReferenceType;
65 import com.sun.jdi.ThreadReference;
66 import com.sun.jdi.VMDisconnectedException;
67 import com.sun.jdi.event.Event;
68 import com.sun.jdi.request.BreakpointRequest;
69 import com.sun.jdi.request.EventRequest;
70 import com.sun.jdi.request.EventRequestManager;
71
72 public class JavaLineBreakpoint extends JavaBreakpoint implements IJavaLineBreakpoint {
73
74     /**
75      * Breakpoint attribute storing a breakpoint's conditional expression
76      * (value <code>"org.eclipse.jdt.debug.core.condition"</code>). This attribute is stored as a
77      * <code>String</code>.
78      */

79     protected static final String JavaDoc CONDITION= "org.eclipse.jdt.debug.core.condition"; //$NON-NLS-1$
80
/**
81      * Breakpoint attribute storing a breakpoint's condition enablement
82      * (value <code>"org.eclipse.jdt.debug.core.conditionEnabled"</code>). This attribute is stored as an
83      * <code>boolean</code>.
84      */

85     protected static final String JavaDoc CONDITION_ENABLED= "org.eclipse.jdt.debug.core.conditionEnabled"; //$NON-NLS-1$
86

87     /**
88      * Breakpoint attribute storing a breakpoint's condition suspend policy
89      * (value <code>" org.eclipse.jdt.debug.core.conditionSuspendOnTrue"
90      * </code>). This attribute is stored as an <code>boolean</code>.
91      */

92     protected static final String JavaDoc CONDITION_SUSPEND_ON_TRUE= "org.eclipse.jdt.debug.core.conditionSuspendOnTrue"; //$NON-NLS-1$
93

94     /**
95      * Breakpoint attribute storing a breakpoint's source file name (debug attribute)
96      * (value <code>"org.eclipse.jdt.debug.core.sourceName"</code>). This attribute is stored as
97      * a <code>String</code>.
98      */

99     protected static final String JavaDoc SOURCE_NAME= "org.eclipse.jdt.debug.core.sourceName"; //$NON-NLS-1$
100

101     private static final String JavaDoc JAVA_LINE_BREAKPOINT = "org.eclipse.jdt.debug.javaLineBreakpointMarker"; //$NON-NLS-1$
102

103     /**
104      * Maps suspended threads to the suspend event that suspended them
105      */

106     private Map JavaDoc fSuspendEvents= new HashMap JavaDoc();
107     /**
108      * The map of cached compiled expressions (ICompiledExpression) for this breakpoint, keyed by thread.
109      * This value must be cleared every time the breakpoint is added to a target.
110      */

111     private Map JavaDoc fCompiledExpressions= new HashMap JavaDoc();
112     
113     /**
114      * Cache of projects for stack frames to avoid repetitive project resolution on conditional
115      * breakpoints.
116      */

117     private Map JavaDoc fProjectsByFrame= new HashMap JavaDoc();
118     
119     /**
120      * The map of the result value of the condition (IValue) for this
121      * breakpoint, keyed by debug target.
122      */

123     private Map JavaDoc fConditionValues= new HashMap JavaDoc();
124     
125     /**
126      * Status code indicating that a request to create a breakpoint in a type
127      * with no line number attributes has occurred.
128      */

129     public static final int NO_LINE_NUMBERS= 162;
130         
131     public JavaLineBreakpoint() {
132     }
133
134     /**
135      * @see JDIDebugModel#createLineBreakpoint(IResource, String, int, int, int, int, boolean, Map)
136      */

137     public JavaLineBreakpoint(IResource resource, String JavaDoc typeName, int lineNumber, int charStart, int charEnd, int hitCount, boolean add, Map JavaDoc attributes) throws DebugException {
138         this(resource, typeName, lineNumber, charStart, charEnd, hitCount, add, attributes, JAVA_LINE_BREAKPOINT);
139     }
140     
141     protected JavaLineBreakpoint(final IResource resource, final String JavaDoc typeName, final int lineNumber, final int charStart, final int charEnd, final int hitCount, final boolean add, final Map JavaDoc attributes, final String JavaDoc markerType) throws DebugException {
142         IWorkspaceRunnable wr= new IWorkspaceRunnable() {
143             public void run(IProgressMonitor monitor) throws CoreException {
144     
145                 // create the marker
146
setMarker(resource.createMarker(markerType));
147                 
148                 // add attributes
149
addLineBreakpointAttributes(attributes, getModelIdentifier(), true, lineNumber, charStart, charEnd);
150                 addTypeNameAndHitCount(attributes, typeName, hitCount);
151                 // set attributes
152
attributes.put(SUSPEND_POLICY, new Integer JavaDoc(getDefaultSuspendPolicy()));
153                 ensureMarker().setAttributes(attributes);
154                 
155                 // add to breakpoint manager if requested
156
register(add);
157             }
158         };
159         run(getMarkerRule(resource), wr);
160     }
161     
162     /* (non-Javadoc)
163      * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#addToTarget(org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
164      */

165     public void addToTarget(JDIDebugTarget target) throws CoreException {
166         clearCachedExpressionFor(target);
167         super.addToTarget(target);
168     }
169
170     /* (non-Javadoc)
171      * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#removeFromTarget(org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget)
172      */

173     public void removeFromTarget(JDIDebugTarget target) throws CoreException {
174         clearCachedExpressionFor(target);
175         clearCachedSuspendEvents(target);
176         fConditionValues.remove(target);
177         super.removeFromTarget(target);
178     }
179     
180     /**
181      * Removes all suspend events which are currently
182      * being cached for threads in the given target.
183      */

184     protected void clearCachedSuspendEvents(JDIDebugTarget target) {
185         removeCachedThreads(fSuspendEvents, target);
186     }
187     
188     private void removeCachedThreads(Map JavaDoc map, JDIDebugTarget target) {
189         Set JavaDoc threads= map.keySet();
190         List JavaDoc threadsToRemove= new ArrayList JavaDoc();
191         Iterator JavaDoc iter= threads.iterator();
192         JDIThread thread;
193         while (iter.hasNext()) {
194             thread= (JDIThread)iter.next();
195             if (thread.getDebugTarget() == target) {
196                 threadsToRemove.add(thread);
197             }
198         }
199         iter= threadsToRemove.iterator();
200         while (iter.hasNext()) {
201             map.remove(iter.next());
202         }
203     }
204     
205     /**
206      * Removes all compiled expressions which are currently
207      * being cached for threads in the given target.
208      */

209     protected void clearCachedExpressionFor(JDIDebugTarget target) {
210         removeCachedThreads(fCompiledExpressions, target);
211
212         // clean up cached projects for stack frames
213
Set JavaDoc frames= fProjectsByFrame.keySet();
214         List JavaDoc framesToRemove= new ArrayList JavaDoc();
215         Iterator JavaDoc iter= frames.iterator();
216         JDIStackFrame frame;
217         while (iter.hasNext()) {
218             frame= (JDIStackFrame)iter.next();
219             if (frame.getDebugTarget() == target) {
220                 framesToRemove.add(frame);
221             }
222         }
223         iter= framesToRemove.iterator();
224         while (iter.hasNext()) {
225             fProjectsByFrame.remove(iter.next());
226         }
227         
228     }
229     
230     /* (non-Javadoc)
231      * @see org.eclipse.debug.core.model.ILineBreakpoint#getLineNumber()
232      */

233     public int getLineNumber() throws CoreException {
234         return ensureMarker().getAttribute(IMarker.LINE_NUMBER, -1);
235     }
236
237     /* (non-Javadoc)
238      * @see org.eclipse.debug.core.model.ILineBreakpoint#getCharStart()
239      */

240     public int getCharStart() throws CoreException {
241         return ensureMarker().getAttribute(IMarker.CHAR_START, -1);
242     }
243
244     /* (non-Javadoc)
245      * @see org.eclipse.debug.core.model.ILineBreakpoint#getCharEnd()
246      */

247     public int getCharEnd() throws CoreException {
248         return ensureMarker().getAttribute(IMarker.CHAR_END, -1);
249     }
250     /**
251      * Returns the type of marker associated with Java line breakpoints
252      */

253     public static String JavaDoc getMarkerType() {
254         return JAVA_LINE_BREAKPOINT;
255     }
256         
257     /* (non-Javadoc)
258      * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#newRequest(org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget, com.sun.jdi.ReferenceType)
259      */

260     protected EventRequest[] newRequests(JDIDebugTarget target, ReferenceType type) throws CoreException {
261         int lineNumber = getLineNumber();
262         List JavaDoc locations = determineLocations(lineNumber, type, target);
263         if (locations == null || locations.isEmpty()) {
264             // could be an inner type not yet loaded, or line information not available
265
return null;
266         }
267         EventRequest[] requests = new EventRequest[locations.size()];
268         int i = 0;
269         Iterator JavaDoc iterator = locations.iterator();
270         while (iterator.hasNext()) {
271             Location location = (Location) iterator.next();
272             requests[i] = createLineBreakpointRequest(location, target);
273             i++;
274         }
275         return requests;
276     }
277
278     /**
279      * Creates, installs, and returns a line breakpoint request at
280      * the given location for this breakpoint.
281      */

282     protected BreakpointRequest createLineBreakpointRequest(Location location, JDIDebugTarget target) throws CoreException {
283         BreakpointRequest request = null;
284         EventRequestManager manager = target.getEventRequestManager();
285         if (manager == null) {
286             target.requestFailed(JDIDebugBreakpointMessages.JavaLineBreakpoint_Unable_to_create_breakpoint_request___VM_disconnected__1, null);
287         }
288         try {
289             request= manager.createBreakpointRequest(location);
290             configureRequest(request, target);
291         } catch (VMDisconnectedException e) {
292             if (!target.isAvailable()) {
293                 return null;
294             }
295             JDIDebugPlugin.log(e);
296         } catch (RuntimeException JavaDoc e) {
297             target.internalError(e);
298             return null;
299         }
300         return request;
301     }
302     
303     /**
304      * @see JavaBreakpoint#setRequestThreadFilter(EventRequest)
305      */

306     protected void setRequestThreadFilter(EventRequest request, ThreadReference thread) {
307         ((BreakpointRequest)request).addThreadFilter(thread);
308     }
309         
310     /**
311      * Returns a list of locations of the given line number in the given type.
312      * Returns <code>null</code> if locations cannot be determined.
313      */

314     protected List JavaDoc determineLocations(int lineNumber, ReferenceType type, JDIDebugTarget target) {
315         List JavaDoc locations= null;
316         try {
317             locations= type.locationsOfLine(lineNumber);
318         } catch (AbsentInformationException aie) {
319             IStatus status= new Status(IStatus.ERROR, JDIDebugPlugin.getUniqueIdentifier(), NO_LINE_NUMBERS, JDIDebugBreakpointMessages.JavaLineBreakpoint_Absent_Line_Number_Information_1, null);
320             IStatusHandler handler= DebugPlugin.getDefault().getStatusHandler(status);
321             if (handler != null) {
322                 try {
323                     handler.handleStatus(status, type);
324                 } catch (CoreException e) {
325                 }
326             }
327             return null;
328         } catch (NativeMethodException e) {
329             return null;
330         } catch (VMDisconnectedException e) {
331             return null;
332         } catch (ClassNotPreparedException e) {
333             // could be a nested type that is not yet loaded
334
return null;
335         } catch (RuntimeException JavaDoc e) {
336             // not able to retrieve line information
337
target.internalError(e);
338             return null;
339         }
340         return locations;
341     }
342     
343     /**
344      * Adds the standard attributes of a line breakpoint to
345      * the given attribute map.
346      * The standard attributes are:
347      * <ol>
348      * <li>IBreakpoint.ID</li>
349      * <li>IBreakpoint.ENABLED</li>
350      * <li>IMarker.LINE_NUMBER</li>
351      * <li>IMarker.CHAR_START</li>
352      * <li>IMarker.CHAR_END</li>
353      * </ol>
354      *
355      */

356     public void addLineBreakpointAttributes(Map JavaDoc attributes, String JavaDoc modelIdentifier, boolean enabled, int lineNumber, int charStart, int charEnd) {
357         attributes.put(IBreakpoint.ID, modelIdentifier);
358         attributes.put(IBreakpoint.ENABLED, Boolean.valueOf(enabled));
359         attributes.put(IMarker.LINE_NUMBER, new Integer JavaDoc(lineNumber));
360         attributes.put(IMarker.CHAR_START, new Integer JavaDoc(charStart));
361         attributes.put(IMarker.CHAR_END, new Integer JavaDoc(charEnd));
362     }
363     
364     /**
365      * Adds type name and hit count attributes to the given
366      * map.
367      *
368      * If <code>hitCount > 0</code>, adds the <code>HIT_COUNT</code> attribute
369      * to the given breakpoint, and resets the <code>EXPIRED</code> attribute
370      * to false (since, if the hit count is changed, the breakpoint should no
371      * longer be expired).
372      */

373     public void addTypeNameAndHitCount(Map JavaDoc attributes, String JavaDoc typeName, int hitCount) {
374         attributes.put(TYPE_NAME, typeName);
375         if (hitCount > 0) {
376             attributes.put(HIT_COUNT, new Integer JavaDoc(hitCount));
377             attributes.put(EXPIRED, Boolean.FALSE);
378         }
379     }
380     
381     /**
382      * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#handleBreakpointEvent(com.sun.jdi.event.Event, org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget, org.eclipse.jdt.internal.debug.core.model.JDIThread)
383      *
384      * (From referenced JavaDoc:
385      * Returns whether the thread should be resumed
386      */

387     public boolean handleBreakpointEvent(Event event, JDIDebugTarget target, JDIThread thread) {
388         if (hasCondition()) {
389             try {
390                 return handleConditionalBreakpointEvent(event, thread, target);
391             } catch (CoreException exception) {
392                 JDIDebugPlugin.log(exception);
393                 return !suspendForEvent(event, thread);
394             }
395         }
396         return !suspendForEvent(event, thread); // Resume if suspend fails
397
}
398     
399     /**
400      * Returns whether this breakpoint has an enabled condition
401      */

402     protected boolean hasCondition() {
403         try {
404             String JavaDoc condition = getCondition();
405             return isConditionEnabled() && condition != null && (condition.length() > 0);
406         } catch (CoreException exception) {
407             JDIDebugPlugin.log(exception);
408             return false;
409         }
410     }
411     
412     /**
413      * Suspends the given thread for the given breakpoint event. Returns
414      * whether the thread suspends.
415      */

416     protected boolean suspendForEvent(Event event, JDIThread thread) {
417         expireHitCount(event);
418         return suspend(thread);
419     }
420     
421     /**
422      * Suspends the given thread for the given breakpoint event after
423      * a conditional expression evaluation. This method tells the thread
424      * to fire a suspend event immediately instead of queue'ing the event.
425      * This is required because of the asynchronous nature of expression
426      * evaluation. The EventDispatcher has already fired queued events
427      * by the time the evaluation completes.
428      */

429     protected boolean suspendForCondition(Event event, JDIThread thread) {
430         expireHitCount(event);
431         return thread.handleSuspendForBreakpoint(this, false);
432     }
433     
434     /**
435      * Returns whether this breakpoint should resume based on the
436      * value of its condition.
437      *
438      * If there is not an enabled condition which evaluates to <code>true</code>,
439      * the thread should resume.
440      */

441     protected boolean handleConditionalBreakpointEvent(Event event, JDIThread thread, JDIDebugTarget target) throws CoreException {
442         synchronized (thread) {
443             if (thread.isPerformingEvaluation()) {
444                 // If an evaluation is already being computed for this thread,
445
// we can't perform another
446
return !suspendForEvent(event, thread);
447             }
448             final String JavaDoc condition= getCondition();
449             if (!hasCondition()) {
450                 return !suspendForEvent(event, thread);
451             }
452             EvaluationListener listener= new EvaluationListener();
453     
454             int suspendPolicy= SUSPEND_THREAD;
455             try {
456                 suspendPolicy= getSuspendPolicy();
457             } catch (CoreException e) {
458             }
459             if (suspendPolicy == SUSPEND_VM) {
460                 ((JDIDebugTarget)thread.getDebugTarget()).prepareToSuspendByBreakpoint(this);
461             } else {
462                 thread.handleSuspendForBreakpointQuiet(this);
463             }
464             List JavaDoc frames = thread.computeNewStackFrames();
465             if (frames.size() == 0) {
466                 return !suspendForEvent(event, thread);
467             }
468             JDIStackFrame frame= (JDIStackFrame)frames.get(0);
469             IJavaProject project= getJavaProject(frame);
470             if (project == null) {
471                 throw new CoreException(new Status(IStatus.ERROR, JDIDebugModel.getPluginIdentifier(), DebugException.REQUEST_FAILED,
472                     JDIDebugBreakpointMessages.JavaLineBreakpoint_Unable_to_compile_conditional_breakpoint___missing_Java_project_context__1, null));
473             }
474             IAstEvaluationEngine engine = getEvaluationEngine(target, project);
475             if (engine == null) {
476                 // If no engine is available, suspend
477
return !suspendForEvent(event, thread);
478             }
479             ICompiledExpression expression= (ICompiledExpression)fCompiledExpressions.get(thread);
480             if (expression == null) {
481                 expression= engine.getCompiledExpression(condition, frame);
482                 fCompiledExpressions.put(thread, expression);
483             }
484             if (conditionHasErrors(expression)) {
485                 fireConditionHasErrors(expression);
486                 return !suspendForEvent(event, thread);
487             }
488             fSuspendEvents.put(thread, event);
489             thread.setEvaluatingConditionalBreakpoint(true);
490             engine.evaluateExpression(expression, frame, listener, DebugEvent.EVALUATION_IMPLICIT, false);
491     
492             // Do not resume. When the evaluation returns, the evaluation listener
493
// will resume the thread if necessary or update for suspension.
494
return false;
495         }
496     }
497     
498     private IJavaProject getJavaProject(JDIStackFrame stackFrame) {
499         IJavaProject project= (IJavaProject) fProjectsByFrame.get(stackFrame);
500         if (project == null) {
501             project = computeJavaProject(stackFrame);
502             if (project != null) {
503                 fProjectsByFrame.put(stackFrame, project);
504             }
505         }
506         return project;
507     }
508     
509     private IJavaProject computeJavaProject(JDIStackFrame stackFrame) {
510         ILaunch launch = stackFrame.getLaunch();
511         if (launch == null) {
512             return null;
513         }
514         ISourceLocator locator= launch.getSourceLocator();
515         if (locator == null)
516             return null;
517         
518         Object JavaDoc sourceElement= null;
519         try {
520             if (locator instanceof ISourceLookupDirector && !stackFrame.isStatic()) {
521                 IJavaType thisType = stackFrame.getThis().getJavaType();
522                 if (thisType instanceof IJavaReferenceType) {
523                     String JavaDoc[] sourcePaths= ((IJavaReferenceType) thisType).getSourcePaths(null);
524                     if (sourcePaths != null && sourcePaths.length > 0) {
525                         sourceElement= ((ISourceLookupDirector) locator).getSourceElement(sourcePaths[0]);
526                     }
527                 }
528             }
529         } catch (DebugException e) {
530             DebugPlugin.log(e);
531         }
532         if (sourceElement == null) {
533             sourceElement = locator.getSourceElement(stackFrame);
534         }
535         if (!(sourceElement instanceof IJavaElement) && sourceElement instanceof IAdaptable) {
536             Object JavaDoc element= ((IAdaptable)sourceElement).getAdapter(IJavaElement.class);
537             if (element != null) {
538                 sourceElement= element;
539             }
540         }
541         if (sourceElement instanceof IJavaElement) {
542             return ((IJavaElement) sourceElement).getJavaProject();
543         } else if (sourceElement instanceof IResource) {
544             IJavaProject project = JavaCore.create(((IResource)sourceElement).getProject());
545             if (project.exists()) {
546                 return project;
547             }
548         }
549         return null;
550     }
551     
552     /**
553      * Listens for evaluation completion for condition evaluation.
554      * If an evaluation evaluates <code>true</code> or has an error, this breakpoint
555      * will suspend the thread in which the breakpoint was hit.
556      * If the evaluation returns <code>false</code>, the thread is resumed.
557      */

558     class EvaluationListener implements IEvaluationListener {
559         public void evaluationComplete(IEvaluationResult result) {
560             JDIThread thread= (JDIThread)result.getThread();
561             thread.setEvaluatingConditionalBreakpoint(false);
562             Event event= (Event)fSuspendEvents.get(thread);
563             if (result.hasErrors()) {
564                 DebugException exception= result.getException();
565                 Throwable JavaDoc wrappedException= exception.getStatus().getException();
566                 if (wrappedException instanceof VMDisconnectedException) {
567                     JDIDebugPlugin.log(wrappedException);
568                     try {
569                         thread.resumeQuiet();
570                     } catch(DebugException e) {
571                         JDIDebugPlugin.log(e);
572                     }
573                 } else {
574                     fireConditionHasRuntimeErrors(exception);
575                     suspendForCondition(event, thread);
576                     return;
577                 }
578             }
579             try {
580                 IValue value= result.getValue();
581                 if (isConditionSuspendOnTrue()) {
582                     if (value instanceof IJavaPrimitiveValue) {
583                         // Suspend when the condition evaluates true
584
IJavaPrimitiveValue javaValue= (IJavaPrimitiveValue)value;
585                         if (isConditionSuspendOnTrue()) {
586                             if (javaValue.getJavaType().getName().equals("boolean") && javaValue.getBooleanValue()) { //$NON-NLS-1$
587
suspendForCondition(event, thread);
588                                 return;
589                             }
590                         }
591                     }
592                 } else {
593                     IDebugTarget debugTarget= thread.getDebugTarget();
594                     IValue lastValue= (IValue)fConditionValues.get(debugTarget);
595                     fConditionValues.put(debugTarget, value);
596                     if (!value.equals(lastValue)) {
597                         suspendForCondition(event, thread);
598                         return;
599                     }
600                 }
601                 int suspendPolicy= SUSPEND_THREAD;
602                 try {
603                     suspendPolicy= getSuspendPolicy();
604                 } catch (CoreException e) {
605                 }
606                 if (suspendPolicy == SUSPEND_VM) {
607                     ((JDIDebugTarget)thread.getDebugTarget()).resumeQuiet();
608                 } else {
609                     thread.resumeQuiet();
610                 }
611                 return;
612             } catch (DebugException e) {
613                 JDIDebugPlugin.log(e);
614             }
615             // Suspend when an error occurs
616
suspendForEvent(event, thread);
617         }
618     }
619     
620     private void fireConditionHasRuntimeErrors(DebugException exception) {
621         JDIDebugPlugin.getDefault().fireBreakpointHasRuntimeException(this, exception);
622     }
623     
624     /**
625      * Notifies listeners that a conditional breakpoint expression has been
626      * compiled that contains errors
627      */

628     private void fireConditionHasErrors(ICompiledExpression expression) {
629         JDIDebugPlugin.getDefault().fireBreakpointHasCompilationErrors(this, getMessages(expression));
630     }
631     
632     /**
633      * Convert an array of <code>String</code> to an array of
634      * <code>Message</code>.
635      */

636     private Message[] getMessages(ICompiledExpression expression) {
637         String JavaDoc[] errorMessages= expression.getErrorMessages();
638         Message[] messages= new Message[errorMessages.length];
639         for (int i= 0; i < messages.length; i++) {
640             messages[i]= new Message(errorMessages[i], -1);
641         }
642         return messages;
643     }
644
645     /**
646      * Returns whether the cached conditional expression has errors or
647      * <code>false</code> if there is no cached expression
648      */

649     public boolean conditionHasErrors(ICompiledExpression expression) {
650         return expression.hasErrors();
651     }
652     
653     /**
654      * Returns an evaluation engine for evaluating this breakpoint's condition
655      * in the given target and project context.
656      */

657     public IAstEvaluationEngine getEvaluationEngine(IJavaDebugTarget vm, IJavaProject project) {
658         return ((JDIDebugTarget)vm).getEvaluationEngine(project);
659     }
660     
661     /* (non-Javadoc)
662      * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#supportsCondition()
663      */

664     public boolean supportsCondition() {
665         return true;
666     }
667     
668     /* (non-Javadoc)
669      * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#getCondition()
670      */

671     public String JavaDoc getCondition() throws CoreException {
672         return ensureMarker().getAttribute(CONDITION, null);
673     }
674     
675     /* (non-Javadoc)
676      * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#setCondition(java.lang.String)
677      */

678     public void setCondition(String JavaDoc condition) throws CoreException {
679         // Clear the cached compiled expressions
680
fCompiledExpressions.clear();
681         fConditionValues.clear();
682         fSuspendEvents.clear();
683         if (condition != null && condition.trim().length() == 0) {
684             condition = null;
685         }
686         setAttributes(new String JavaDoc []{CONDITION}, new Object JavaDoc[]{condition});
687         recreate();
688     }
689
690     protected String JavaDoc getMarkerMessage(boolean conditionEnabled, String JavaDoc condition, int hitCount, int suspendPolicy, int lineNumber) {
691         StringBuffer JavaDoc message= new StringBuffer JavaDoc(super.getMarkerMessage(hitCount, suspendPolicy));
692         if (lineNumber != -1) {
693             message.append(MessageFormat.format(JDIDebugBreakpointMessages.JavaLineBreakpoint___line___0___1, new Object JavaDoc[]{Integer.toString(lineNumber)}));
694         }
695         if (conditionEnabled && condition != null) {
696             message.append(MessageFormat.format(JDIDebugBreakpointMessages.JavaLineBreakpoint___Condition___0___2, new Object JavaDoc[]{condition}));
697         }
698             
699         return message.toString();
700     }
701
702     /* (non-Javadoc)
703      * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#isConditionEnabled()
704      */

705     public boolean isConditionEnabled() throws CoreException {
706         return ensureMarker().getAttribute(CONDITION_ENABLED, false);
707     }
708     
709     /* (non-Javadoc)
710      * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#setConditionEnabled(boolean)
711      */

712     public void setConditionEnabled(boolean conditionEnabled) throws CoreException {
713         setAttributes(new String JavaDoc[]{CONDITION_ENABLED}, new Object JavaDoc[]{Boolean.valueOf(conditionEnabled)});
714         recreate();
715     }
716     
717     /* (non-Javadoc)
718      * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#cleanupForThreadTermination(org.eclipse.jdt.internal.debug.core.model.JDIThread)
719      */

720     protected void cleanupForThreadTermination(JDIThread thread) {
721         fSuspendEvents.remove(thread);
722         fCompiledExpressions.remove(thread);
723         super.cleanupForThreadTermination(thread);
724     }
725     
726     /* (non-Javadoc)
727      * @see org.eclipse.jdt.internal.debug.core.breakpoints.JavaBreakpoint#addInstanceFilter(com.sun.jdi.request.EventRequest, com.sun.jdi.ObjectReference)
728      */

729     protected void addInstanceFilter(EventRequest request,ObjectReference object) {
730         if (request instanceof BreakpointRequest) {
731             ((BreakpointRequest)request).addInstanceFilter(object);
732         }
733     }
734
735     /* (non-Javadoc)
736      * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#isConditionSuspendOnTrue()
737      */

738     public boolean isConditionSuspendOnTrue() throws DebugException {
739         return ensureMarker().getAttribute(CONDITION_SUSPEND_ON_TRUE, true);
740     }
741
742     /* (non-Javadoc)
743      * @see org.eclipse.jdt.debug.core.IJavaLineBreakpoint#setConditionSuspendOnTrue(boolean)
744      */

745     public void setConditionSuspendOnTrue(boolean suspendOnTrue) throws CoreException {
746         if (isConditionSuspendOnTrue() != suspendOnTrue) {
747             setAttributes(new String JavaDoc[]{CONDITION_SUSPEND_ON_TRUE}, new Object JavaDoc[]{Boolean.valueOf(suspendOnTrue)});
748             fConditionValues.clear();
749             recreate();
750         }
751     }
752
753 }
754
Popular Tags