1 19 20 package org.netbeans.modules.debugger.jpda.breakpoints; 21 22 import com.sun.jdi.IncompatibleThreadStateException; 23 import com.sun.jdi.ReferenceType; 24 import com.sun.jdi.StackFrame; 25 import com.sun.jdi.ThreadReference; 26 import com.sun.jdi.VMDisconnectedException; 27 import com.sun.jdi.Value; 28 import com.sun.jdi.VirtualMachine; 29 import com.sun.jdi.request.EventRequest; 30 import com.sun.jdi.request.EventRequestManager; 31 import java.util.ArrayList ; 32 import java.util.LinkedList ; 33 import java.util.List ; 34 import java.beans.PropertyChangeListener ; 35 import java.beans.PropertyChangeEvent ; 36 import java.util.logging.Logger ; 37 import javax.swing.event.ChangeEvent ; 38 import javax.swing.event.ChangeListener ; 39 import org.netbeans.api.debugger.Breakpoint; 40 41 import org.netbeans.api.debugger.jpda.InvalidExpressionException; 42 import org.netbeans.api.debugger.jpda.JPDABreakpoint; 43 import org.netbeans.api.debugger.jpda.MethodBreakpoint; 44 import org.netbeans.api.debugger.jpda.Variable; 45 import org.netbeans.api.debugger.jpda.event.JPDABreakpointEvent; 46 import org.netbeans.api.debugger.jpda.JPDADebugger; 47 import org.netbeans.api.debugger.Session; 48 import org.netbeans.api.debugger.DebuggerManager; 49 50 import org.netbeans.modules.debugger.jpda.JPDADebuggerImpl; 51 import org.netbeans.modules.debugger.jpda.expr.Expression; 52 import org.netbeans.modules.debugger.jpda.expr.ParseException; 53 import org.netbeans.modules.debugger.jpda.models.JPDAThreadImpl; 54 import org.netbeans.modules.debugger.jpda.models.ReturnVariableImpl; 55 import org.netbeans.modules.debugger.jpda.util.Executor; 56 import org.openide.ErrorManager; 57 58 59 63 public abstract class BreakpointImpl implements Executor, PropertyChangeListener { 64 65 private static Logger logger = Logger.getLogger("org.netbeans.modules.debugger.jpda.breakpoints"); 67 private JPDADebuggerImpl debugger; 68 private JPDABreakpoint breakpoint; 69 private BreakpointsReader reader; 70 private final Session session; 71 private Expression compiledCondition; 72 private List <EventRequest> requests = new ArrayList <EventRequest>(); 73 74 75 protected BreakpointImpl (JPDABreakpoint p, BreakpointsReader reader, JPDADebuggerImpl debugger, Session session) { 76 this.debugger = debugger; 77 this.reader = reader; 78 breakpoint = p; 79 this.session = session; 80 } 81 82 85 final void set () { 86 breakpoint.addPropertyChangeListener (this); 87 update (); 88 } 89 90 93 void fixed () { 94 if (reader != null) { 95 reader.storeCachedClassName(breakpoint, null); 96 } 97 update (); 98 } 99 100 103 final void update () { 104 if ( (getVirtualMachine () == null) || 105 (getDebugger ().getState () == JPDADebugger.STATE_DISCONNECTED) 106 ) return; 107 removeAllEventRequests (); 108 if (breakpoint.isEnabled () && isEnabled()) { 109 setRequests (); 110 } 111 } 112 113 protected boolean isEnabled() { 114 return true; 115 } 116 117 protected final void setValidity(Breakpoint.VALIDITY validity, String reason) { 118 if (breakpoint instanceof ChangeListener ) { 119 ((ChangeListener ) breakpoint).stateChanged(new ValidityChangeEvent(validity, reason)); 120 } 121 } 122 123 public void propertyChange (PropertyChangeEvent evt) { 124 String propertyName = evt.getPropertyName(); 125 if (Breakpoint.PROP_DISPOSED.equals(propertyName)) { 126 remove(); 127 } else if (!Breakpoint.PROP_VALIDITY.equals(propertyName)) { 128 if (reader != null) { 129 reader.storeCachedClassName(breakpoint, null); 130 } 131 if (Breakpoint.PROP_ENABLED.equals(propertyName)) { 132 update (); 133 } 134 } 135 } 136 137 protected abstract void setRequests (); 138 139 protected final void remove () { 140 removeAllEventRequests (); 141 breakpoint.removePropertyChangeListener(this); 142 setValidity(Breakpoint.VALIDITY.UNKNOWN, null); 143 } 144 145 protected JPDABreakpoint getBreakpoint () { 146 return breakpoint; 147 } 148 149 protected JPDADebuggerImpl getDebugger () { 150 return debugger; 151 } 152 153 protected VirtualMachine getVirtualMachine () { 154 return getDebugger ().getVirtualMachine (); 155 } 156 157 protected EventRequestManager getEventRequestManager () { 158 VirtualMachine vm = getVirtualMachine(); 159 if (vm == null) { 160 throw new VMDisconnectedException(); 162 } 163 return vm.eventRequestManager (); 164 } 165 166 synchronized protected void addEventRequest (EventRequest r) { 167 logger.fine("BreakpointImpl addEventRequest: " + r); 168 requests.add (r); 169 getDebugger ().getOperator ().register (r, this); 170 171 if (getBreakpoint().getSuspend() == JPDABreakpoint.SUSPEND_ALL) 174 r.setSuspendPolicy (JPDABreakpoint.SUSPEND_ALL); 175 else 176 r.setSuspendPolicy (JPDABreakpoint.SUSPEND_EVENT_THREAD); 177 r.enable (); 178 } 179 180 synchronized private void removeAllEventRequests () { 181 if (requests.size () == 0) return; 182 VirtualMachine vm = getDebugger().getVirtualMachine(); 183 if (vm == null) return; 184 int i, k = requests.size (); 185 try { 186 for (i = 0; i < k; i++) { 187 EventRequest r = requests.get (i); 188 logger.fine("BreakpointImpl removeEventRequest: " + r); 189 vm.eventRequestManager().deleteEventRequest(r); 190 getDebugger ().getOperator ().unregister (r); 191 } 192 193 } catch (VMDisconnectedException e) { 194 } catch (com.sun.jdi.InternalException e) { 195 } 196 requests = new LinkedList <EventRequest>(); 197 } 198 199 public boolean perform ( 200 String condition, 201 ThreadReference thread, 202 ReferenceType referenceType, 203 Value value 204 ) { 205 boolean resume; 207 208 try { 210 getDebugger().setAltCSF(thread.frame(0)); 211 } catch (com.sun.jdi.IncompatibleThreadStateException e) { 212 ErrorManager.getDefault().notify(e); 213 } catch (java.lang.IndexOutOfBoundsException e) { 214 } 216 Variable variable = null; 217 if (getBreakpoint() instanceof MethodBreakpoint && 218 (((MethodBreakpoint) getBreakpoint()).getBreakpointType() 219 & MethodBreakpoint.TYPE_METHOD_EXIT) != 0) { 220 JPDAThreadImpl jt = (JPDAThreadImpl) getDebugger().getThread(thread); 221 if (value != null) { 222 ReturnVariableImpl retVariable = new ReturnVariableImpl(getDebugger(), value, "", jt.getMethodName()); 223 jt.setReturnVariable(retVariable); 224 variable = retVariable; 225 } 226 } 227 if (variable == null) { 228 variable = debugger.getVariable(value); 229 } 230 231 232 if ((condition == null) || condition.equals ("")) { 233 JPDABreakpointEvent e = new JPDABreakpointEvent ( 234 getBreakpoint (), 235 debugger, 236 JPDABreakpointEvent.CONDITION_NONE, 237 debugger.getThread (thread), 238 referenceType, 239 variable 240 ); 241 getDebugger ().fireBreakpointEvent ( 242 getBreakpoint (), 243 e 244 ); 245 resume = getBreakpoint().getSuspend() == JPDABreakpoint.SUSPEND_NONE || e.getResume (); 246 logger.fine("BreakpointImpl: perform breakpoint (no condition): " + this + " resume: " + resume); 247 } else { 248 resume = evaluateCondition ( 249 condition, 250 thread, 251 referenceType, 252 variable 253 ); 254 resume = getBreakpoint().getSuspend() == JPDABreakpoint.SUSPEND_NONE || resume; 256 } 257 getDebugger().setAltCSF(null); 258 if (!resume) { 259 DebuggerManager.getDebuggerManager().setCurrentSession(session); 260 getDebugger ().setStoppedState (thread); 261 } 262 return resume; 264 } 265 266 private boolean evaluateCondition ( 267 String condition, 268 ThreadReference thread, 269 ReferenceType referenceType, 270 Variable variable 271 ) { 272 try { 273 try { 274 boolean result; 275 JPDABreakpointEvent ev; 276 synchronized (debugger.LOCK) { 277 StackFrame sf = thread.frame (0); 278 result = evaluateConditionIn (condition, sf); 279 ev = new JPDABreakpointEvent ( 280 getBreakpoint (), 281 debugger, 282 result ? 283 JPDABreakpointEvent.CONDITION_TRUE : 284 JPDABreakpointEvent.CONDITION_FALSE, 285 debugger.getThread (thread), 286 referenceType, 287 variable 288 ); 289 } 290 getDebugger ().fireBreakpointEvent ( 291 getBreakpoint (), 292 ev 293 ); 294 295 logger.fine("BreakpointImpl: perform breakpoint (condition = " + result + "): " + this + " resume: " + (!result || ev.getResume ())); 298 return !result || ev.getResume (); 299 } catch (ParseException ex) { 300 JPDABreakpointEvent ev = new JPDABreakpointEvent ( 301 getBreakpoint (), 302 debugger, 303 ex, 304 debugger.getThread (thread), 305 referenceType, 306 variable 307 ); 308 getDebugger ().fireBreakpointEvent ( 309 getBreakpoint (), 310 ev 311 ); 312 logger.fine("BreakpointImpl: perform breakpoint (bad condition): " + this + " resume: " + ev.getResume ()); 313 return ev.getResume (); 314 } catch (InvalidExpressionException ex) { 315 JPDABreakpointEvent ev = new JPDABreakpointEvent ( 316 getBreakpoint (), 317 debugger, 318 ex, 319 debugger.getThread (thread), 320 referenceType, 321 variable 322 ); 323 getDebugger ().fireBreakpointEvent ( 324 getBreakpoint (), 325 ev 326 ); 327 logger.fine("BreakpointImpl: perform breakpoint (invalid condition): " + this + " resume: " + ev.getResume ()); 328 return ev.getResume (); 329 } 330 } catch (IncompatibleThreadStateException ex) { 331 ex.printStackTrace (); 333 } 334 return false; } 337 338 342 private boolean evaluateConditionIn ( 343 String condExpr, 344 StackFrame frame 345 ) throws ParseException, InvalidExpressionException { 346 if ( compiledCondition == null || 348 !compiledCondition.getExpression ().equals (condExpr) 349 ) 350 compiledCondition = Expression.parse ( 351 condExpr, 352 Expression.LANGUAGE_JAVA_1_5 353 ); 354 355 com.sun.jdi.Value value = getDebugger ().evaluateIn ( 358 compiledCondition, 359 frame 360 ); 361 try { 362 return ((com.sun.jdi.BooleanValue) value).booleanValue (); 363 } catch (ClassCastException e) { 364 throw new InvalidExpressionException (e); 365 } 366 } 367 368 371 static boolean match (String name, String pattern) { 372 if (pattern.startsWith ("*")) 373 return name.endsWith (pattern.substring (1)); 374 else 375 if (pattern.endsWith ("*")) 376 return name.startsWith ( 377 pattern.substring (0, pattern.length () - 1) 378 ); 379 return name.equals (pattern); 380 } 381 382 private static final class ValidityChangeEvent extends ChangeEvent { 383 384 private String reason; 385 386 public ValidityChangeEvent(Breakpoint.VALIDITY validity, String reason) { 387 super(validity); 388 this.reason = reason; 389 } 390 391 public String toString() { 392 return reason; 393 } 394 } 395 } 396 | Popular Tags |