org.chromium.sdk/src/org/chromium/sdk/internal/JsVariableImpl.java
changeset 2 e4420d2515f1
child 52 f577ea64429e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.chromium.sdk/src/org/chromium/sdk/internal/JsVariableImpl.java	Wed Dec 23 17:13:18 2009 -0800
@@ -0,0 +1,154 @@
+// 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.chromium.sdk.internal;
+
+
+import org.chromium.sdk.JsVariable;
+import org.chromium.sdk.JsValue.Type;
+
+/**
+ * A generic implementation of the JsVariable interface.
+ */
+public class JsVariableImpl implements JsVariable {
+
+  /**
+   * The variable value data as reported by the JavaScript VM (is used to
+   * construct the variable value.)
+   */
+  private final ValueMirror valueData;
+
+  /** The call frame this variable belongs in. */
+  private final CallFrameImpl callFrame;
+
+  /** The fully qualified name of this variable. */
+  private final String variableFqn;
+
+  private final NameDecorator nameDecorator;
+
+  /** The lazily constructed value of this variable. */
+  private final JsValueImpl value;
+
+  /** Variable name. */
+  private final String rawName;
+
+  /**
+   * Constructs a variable contained in the given call frame with the given
+   * value mirror.
+   *
+   * @param callFrame that owns this variable
+   * @param valueData value data for this variable
+   */
+  JsVariableImpl(CallFrameImpl callFrame, ValueMirror valueData, String name) {
+    this(callFrame, valueData, name, null, NameDecorator.NOOP);
+  }
+
+  /**
+   * Constructs a variable contained in the given call frame with the given
+   * value mirror.
+   *
+   * @param callFrame that owns this variable
+   * @param valueData for this variable
+   * @param variableFqn the fully qualified name of this variable
+   */
+  JsVariableImpl(CallFrameImpl callFrame, ValueMirror valueData, String name, String variableFqn,
+      NameDecorator nameDecorator) {
+    this.callFrame = callFrame;
+    this.valueData = valueData;
+    this.rawName = name;
+    this.variableFqn = variableFqn;
+    this.nameDecorator = nameDecorator;
+
+    Type type = this.valueData.getType();
+    switch (type) {
+      case TYPE_FUNCTION:
+        this.value = new JsFunctionImpl(callFrame, this.variableFqn, this.valueData);
+        break;
+      case TYPE_ERROR:
+      case TYPE_OBJECT:
+        this.value = new JsObjectImpl(callFrame, this.variableFqn, this.valueData);
+        break;
+      case TYPE_ARRAY:
+        this.value = new JsArrayImpl(callFrame, this.variableFqn, this.valueData);
+        break;
+      default:
+        this.value = new JsValueImpl(this.valueData);
+    }
+  }
+
+  /**
+   * @return a [probably compound] JsValue corresponding to this variable.
+   *         {@code null} if there was an error lazy-loading the value data.
+   */
+  public JsValueImpl getValue() {
+    return value;
+  }
+
+  public String getName() {
+    return nameDecorator.decorateVarName(rawName);
+  }
+
+  public String getRawName() {
+    return this.rawName;
+  }
+
+  public boolean isMutable() {
+    return false; // TODO(apavlov): fix once V8 supports it
+  }
+
+  public boolean isReadable() {
+    // TODO(apavlov): implement once the readability metadata are available
+    return true;
+  }
+
+  public synchronized void setValue(String newValue, SetValueCallback callback) {
+    // TODO(apavlov): currently V8 does not support it
+    if (!isMutable()) {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  @Override
+  public String toString() {
+    return new StringBuilder()
+        .append("[JsVariable: name=")
+        .append(getName())
+        .append(",value=")
+        .append(getValue())
+        .append(']')
+        .toString();
+  }
+
+  /**
+   * Returns the call frame owning this variable.
+   */
+  protected CallFrameImpl getCallFrame() {
+    return callFrame;
+  }
+
+  public ValueMirror getMirror() {
+    return valueData;
+  }
+
+  public String getFullyQualifiedName() {
+    return variableFqn != null
+        ? variableFqn
+        : getName();
+  }
+
+  static abstract class NameDecorator {
+    static final NameDecorator NOOP = new NameDecorator() {
+      @Override
+      String decorateVarName(String rawName) {
+        return rawName;
+      }
+      @Override
+      String buildAccessSuffix(String rawName) {
+        return "." + rawName;
+      }
+    };
+    abstract String decorateVarName(String rawName);
+    abstract String buildAccessSuffix(String rawName);
+  }
+}