001: package org.drools.base.mvel;
002:
003: import org.mvel.MVELRuntime;
004: import org.mvel.debug.Debugger;
005: import org.mvel.debug.Frame;
006:
007: /**
008: * Debug Handler for MVEL dialect.
009: *
010: * Takes care of registering breakpoints and calling required methods
011: * to trigger eclipse debugger to keep breakpoints in sync etc.
012: *
013: * @author Ahti Kitsik
014: *
015: */
016: public final class MVELDebugHandler {
017:
018: private static int onBreakReturn = Debugger.CONTINUE;
019:
020: public final static String DEBUG_LAUNCH_KEY = "mvel.debugger";
021:
022: private static Boolean debugMode = null;
023:
024: static {
025: MVELRuntime.setThreadDebugger(new MVELDebugger());
026: }
027:
028: /**
029: * Notify remote debugger that runtime is ready to get latest breakpoint
030: * information
031: *
032: */
033: public static void receiveBreakpoints() {
034: }
035:
036: /**
037: * This is catched by the remote debugger
038: *
039: * @param frame
040: */
041: private final static int onBreak(Frame frame) {
042: // We always fall back to Debugger.CONTINUE after each onBreak to avoid eternal step-over flag
043: //int oldReturn = onBreakReturn;
044: //onBreakReturn = Debugger.CONTINUE;
045: //return oldReturn;
046: return onBreakReturn;
047: }
048:
049: protected final static void registerBreakpoint(String sourceName,
050: int lineNumber) {
051: //System.out.println("Registering breakpoint for "+sourceName+":"+lineNumber);
052: MVELRuntime.registerBreakpoint(sourceName, lineNumber);
053: }
054:
055: protected final static void clearAllBreakpoints() {
056: //System.out.println("Clearing all breakpoints");
057: MVELRuntime.clearAllBreakpoints();
058: }
059:
060: protected final static void removeBreakpoint(String sourceName,
061: int lineNumber) {
062: //System.out.println("Removing breakpoint from "+sourceName+":"+lineNumber);
063: MVELRuntime.removeBreakpoint(sourceName, lineNumber);
064: }
065:
066: private static class MVELDebugger implements Debugger {
067:
068: public MVELDebugger() {
069: }
070:
071: public int onBreak(Frame frame) {
072: return MVELDebugHandler.onBreak(frame);
073: // This call is supposed to be catched by the remote debugger
074: }
075:
076: }
077:
078: protected final static void setOnBreakReturn(int value) {
079: onBreakReturn = value;
080: }
081:
082: /**
083: * Do nothing for now. ensures that class is loaded prior debug handler
084: */
085: public static void prepare() {
086: //do nothing
087: }
088:
089: /**
090: * Returns current debug mode.<br/>
091: * Holds lazy initialized internal reference to improve performance.<br/>
092: * Therefore you can't change System property "mvel.debugger" after isDebugMode is called at least once.<br/>
093: * <br/>
094: * To update debug mode at runtime use {@link MVELDebugHandler#setDebugMode(boolean)}<br/>
095: * @return <code>true</code> if debug mode is enabled.
096: */
097: public static boolean isDebugMode() {
098: if (debugMode == null) {
099: debugMode = Boolean.valueOf(System
100: .getProperty(DEBUG_LAUNCH_KEY));
101: }
102: return debugMode.booleanValue();
103: }
104:
105: /**
106: * Sets debug mode on/off.<br/>
107: * Updates local MVELDebugHandler property and System property "mvel.debugger"<br/>
108: * <br/>
109: * There's no need to ever call this method unless you write junit tests!<br/>
110: *
111: * @param b is Debug enabled?
112: */
113: public static void setDebugMode(boolean b) {
114: debugMode = Boolean.valueOf(b);
115: System.setProperty(DEBUG_LAUNCH_KEY, debugMode.toString());
116: }
117:
118: }
|