plugins/org.symbian.tools.tmw.debug/src/org/symbian/tools/tmw/debug/internal/model/JsWatchExpressionDelegate.java
changeset 471 06589bf52fa7
child 484 f5df819c1852
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugins/org.symbian.tools.tmw.debug/src/org/symbian/tools/tmw/debug/internal/model/JsWatchExpressionDelegate.java	Mon Aug 23 09:55:57 2010 -0700
@@ -0,0 +1,170 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.symbian.tools.tmw.debug.internal.model;
+
+import org.chromium.debug.core.model.DebugElementImpl;
+import org.chromium.debug.core.model.EvaluateContext;
+import org.chromium.debug.core.model.Variable;
+import org.chromium.sdk.JsEvaluateContext;
+import org.chromium.sdk.JsVariable;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugException;
+import org.eclipse.debug.core.model.IDebugElement;
+import org.eclipse.debug.core.model.IValue;
+import org.eclipse.debug.core.model.IWatchExpressionDelegate;
+import org.eclipse.debug.core.model.IWatchExpressionListener;
+import org.eclipse.debug.core.model.IWatchExpressionResult;
+import org.symbian.tools.tmw.debug.internal.Activator;
+
+/**
+ * Performs the Watch expression evaluation while debugging Chromium JavaScript.
+ */
+public class JsWatchExpressionDelegate implements IWatchExpressionDelegate {
+
+  private static final String[] EMPTY_STRINGS = new String[0];
+
+  private static final class GoodWatchExpressionResult implements IWatchExpressionResult {
+
+    private final Variable variable;
+
+    private final String expression;
+
+    private IValue value;
+
+    private DebugException exception;
+
+    private GoodWatchExpressionResult(Variable variable, String expression) {
+      this.variable = variable;
+      this.expression = expression;
+    }
+
+    public String[] getErrorMessages() {
+      return exception == null
+          ? EMPTY_STRINGS
+          : new String[] { exception.getStatus().getMessage() };
+    }
+
+    public DebugException getException() {
+      getValue();
+      return exception;
+    }
+
+    public String getExpressionText() {
+      return expression;
+    }
+
+    public synchronized IValue getValue() {
+      if (value == null && exception == null) {
+        try {
+          value = variable.getValue();
+        } catch (DebugException e) {
+          this.exception = e;
+        }
+      }
+      return value;
+    }
+
+    public boolean hasErrors() {
+      getValue();
+      return exception != null;
+    }
+  }
+
+  private static final class BadWatchExpressionResult implements IWatchExpressionResult {
+
+    private final DebugException exception;
+
+    private final String expressionText;
+
+    private BadWatchExpressionResult(DebugException exception, String expressionText) {
+      this.exception = exception;
+      this.expressionText = expressionText;
+    }
+
+    public String[] getErrorMessages() {
+      return new String[] { exception.getStatus().getMessage() };
+    }
+
+    public DebugException getException() {
+      return exception;
+    }
+
+    public String getExpressionText() {
+      return expressionText;
+    }
+
+    public IValue getValue() {
+      return null;
+    }
+
+    public boolean hasErrors() {
+      return true;
+    }
+  }
+
+  public void evaluateExpression(final String expression, final IDebugElement context,
+      final IWatchExpressionListener listener) {
+    final DebugElementImpl contextImpl = (DebugElementImpl) context;
+    if (!contextImpl.getDebugTarget().isSuspended()) {
+      // can only evaluate while suspended. Notify empty result.
+      listener.watchEvaluationFinished(new IWatchExpressionResult() {
+
+        public String[] getErrorMessages() {
+          return EMPTY_STRINGS;
+        }
+
+        public DebugException getException() {
+          return null;
+        }
+
+        public String getExpressionText() {
+          return expression;
+        }
+
+        public IValue getValue() {
+          return null;
+        }
+
+        public boolean hasErrors() {
+          return false;
+        }
+      });
+      return;
+    }
+
+    final EvaluateContext evaluateContext =
+        (EvaluateContext) contextImpl.getAdapter(EvaluateContext.class);
+    if (evaluateContext == null) {
+      listener.watchEvaluationFinished(new BadWatchExpressionResult(
+          new DebugException(
+              new Status(Status.ERROR, Activator.PLUGIN_ID, "Bad debug context")), //$NON-NLS-1$
+          expression));
+      return;
+    }
+
+    evaluateContext.getJsEvaluateContext().evaluateAsync(
+        expression,
+        new JsEvaluateContext.EvaluateCallback() {
+          public void success(JsVariable variable) {
+            final Variable var = new Variable(contextImpl.getDebugTarget(), variable, false);
+            listener.watchEvaluationFinished(new GoodWatchExpressionResult(var, expression));
+          }
+
+          public void failure(String message) {
+            listener.watchEvaluationFinished(new BadWatchExpressionResult(new DebugException(
+                createErrorStatus(message == null
+                    ? "Error evaluating expression"
+                    : message, null)), expression));
+            return;
+          }
+        },
+        null);
+  }
+
+  private static Status createErrorStatus(String message, Exception e) {
+    return new Status(Status.ERROR, Activator.PLUGIN_ID, message, e);
+  }
+
+}