Package org.chromium.sdk.internal.v8native.value

Source Code of org.chromium.sdk.internal.v8native.value.JsVariableBase$Declarative

// 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.v8native.value;


import org.chromium.sdk.JsEvaluateContext.EvaluateCallback;
import org.chromium.sdk.JsDeclarativeVariable;
import org.chromium.sdk.JsFunction;
import org.chromium.sdk.JsObjectProperty;
import org.chromium.sdk.JsValue;
import org.chromium.sdk.JsValue.Type;
import org.chromium.sdk.JsVariable;
import org.chromium.sdk.RelayOk;
import org.chromium.sdk.SyncCallback;
import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException;
import org.chromium.sdk.internal.v8native.InternalContext;
import org.chromium.sdk.internal.v8native.V8CommandCallbackBase;
import org.chromium.sdk.internal.v8native.InternalContext.ContextDismissedCheckedException;
import org.chromium.sdk.internal.v8native.protocol.input.FailedCommandResponse;
import org.chromium.sdk.internal.v8native.protocol.input.SetVariableValueBody;
import org.chromium.sdk.internal.v8native.protocol.input.SuccessCommandResponse;
import org.chromium.sdk.internal.v8native.protocol.input.data.ValueHandle;
import org.chromium.sdk.internal.v8native.protocol.output.ScopeMessage;
import org.chromium.sdk.internal.v8native.protocol.output.SetVariableValueMessage;
import org.chromium.sdk.util.GenericCallback;

/**
* A generic implementation of the JsVariable interface.
*/
public abstract class JsVariableBase implements JsVariable {
  /** The value of this variable. */
  private volatile JsValueBase value;

  /** Variable name. */
  private final Object rawName;

  /**
   * Constructs a variable contained in the given context with the given value mirror.
   * @param valueLoader that owns this variable
   * @param valueData for this variable
   */
  public JsVariableBase(ValueLoader valueLoader, ValueMirror valueData, Object rawName) {
    this.rawName = rawName;
    this.value = createValue(valueLoader, valueData);
  }

  public static JsValueBase createValue(ValueLoader valueLoader, ValueMirror valueData) {
    Type type = valueData.getType();
    switch (type) {
      case TYPE_FUNCTION:
        return new JsFunctionImpl(valueLoader, valueData);
      case TYPE_ERROR:
      case TYPE_OBJECT:
      case TYPE_DATE:
      case TYPE_REGEXP:
        return new JsObjectBase.Impl(valueLoader, valueData);
      case TYPE_ARRAY:
        return new JsArrayImpl(valueLoader, valueData);
      default:
        return new JsValueBase.Impl(valueData);
    }
  }


  /**
   * @return a [probably compound] JsValue corresponding to this variable.
   *         {@code null} if there was an error lazy-loading the value data.
   */
  @Override
  public JsValueBase getValue() {
    return value;
  }

  @Override
  public String getName() {
    return rawName.toString();
  }

  Object getRawNameAsObject() {
    return this.rawName;
  }

  private static JsValueBase castValueArgument(JsValue value) {
    try {
      return (JsValueBase) value;
    } catch (ClassCastException e) {
      throw new IllegalArgumentException("Incorrect value argument", e);
    }
  }

  @Override
  public String toString() {
    return new StringBuilder()
        .append("[JsVariable: name=")
        .append(getName())
        .append(",value=")
        .append(getValue())
        .append(']')
        .toString();
  }

  /**
   * A non-abstract class that implements JsVariable.
   */
  public static class Impl extends JsVariableBase {
    public Impl(ValueLoader valueLoader, ValueMirror valueData, Object rawName) {
      super(valueLoader, valueData, rawName);
    }
    @Override public JsObjectProperty asObjectProperty() {
      return null;
    }
    @Override public JsDeclarativeVariable asDeclarativeVariable() {
      return null;
    }
  }

  public static class Declarative extends JsVariableBase implements JsDeclarativeVariable {
    private final VariableChanger changer;

    public Declarative(ValueLoader valueLoader, ValueMirror valueData, Object rawName,
        VariableChanger changer) {
      super(valueLoader, valueData, rawName);
      this.changer = changer;
    }

    @Override public JsObjectProperty asObjectProperty() {
      return null;
    }
    @Override public JsDeclarativeVariable asDeclarativeVariable() {
      return this;
    }

    @Override public boolean isMutable() {
      return changer != null;
    }

    @Override
    public RelayOk setValue(JsValue newValue, final SetValueCallback userCallback,
        SyncCallback syncCallback) throws UnsupportedOperationException {
      JsValueBase jsValueBase = castValueArgument(newValue);
      String variableName = getName();
      GenericCallback<JsValueBase> hostCallback =
          new GenericCallback<JsValueBase>() {
        @Override
        public void success(JsValueBase newValue) {
          JsVariableBase baseThis = Declarative.this;
          // Access to private field of base class.
          baseThis.value = newValue;
          if (userCallback != null) {
            userCallback.success();
          }
        }

        @Override
        public void failure(Exception cause) {
          if (userCallback != null) {
            userCallback.failure(cause);
          }
        }
      };
      return changer.setValue(variableName, jsValueBase, hostCallback, syncCallback);
    }
  }

  /**
   * Responsible for changing declarative variable value. Contains all necessary data.
   */
  public static class VariableChanger {
    private final InternalContext internalContext;
    private final ScopeMessage.Ref scopeRef;

    VariableChanger(InternalContext internalContext, ScopeMessage.Ref scopeRef) {
      this.internalContext = internalContext;
      this.scopeRef = scopeRef;
    }

    RelayOk setValue(String variableName, JsValueBase jsValueBase,
        final GenericCallback<JsValueBase> callback, SyncCallback syncCallback) {
      // TODO: check for host.
      SetVariableValueMessage message = new SetVariableValueMessage(scopeRef, variableName,
          jsValueBase.getJsonParam(internalContext));

      V8CommandCallbackBase innerCallback = new V8CommandCallbackBase() {
        @Override
        public void success(SuccessCommandResponse successResponse) {
          SetVariableValueBody body;
          try {
            body = successResponse.body().asSetVariableValueBody();
          } catch (JsonProtocolParseException e) {
            throw new RuntimeException(e);
          }
          ValueHandle newValueHandle = body.newValue();
          ValueLoaderImpl valueLoader = internalContext.getValueLoader();
          ValueMirror mirror = valueLoader.addDataToMap(newValueHandle);
          JsValueBase value = JsVariableBase.createValue(valueLoader, mirror);
          callback.success(value);
        }

        @Override
        public void failure(String message, FailedCommandResponse.ErrorDetails errorDetails) {
          callback.failure(new Exception(message));
        }
      };
      try {
        return internalContext.sendV8CommandAsync(message, true,
            innerCallback, syncCallback);
      } catch (ContextDismissedCheckedException e) {
        return internalContext.getDebugSession().maybeRethrowContextException(e,
            syncCallback);
      }
    }
  }

  /**
   * An extension to {@link JsVariableBase} that additional provides {@link JsObjectProperty}
   * interface.
   * TODO: properly support getters, setters etc. once supported by protocol.
   */
  static class Property extends JsVariableBase implements JsObjectProperty {
    public Property(ValueLoader valueLoader, ValueMirror valueData, Object rawName) {
      super(valueLoader, valueData, rawName);
    }
    @Override public JsObjectProperty asObjectProperty() {
      return this;
    }
    @Override public JsDeclarativeVariable asDeclarativeVariable() {
      return null;
    }
    @Override public boolean isWritable() {
      return true;
    }
    @Override public JsValue getGetter() {
      return null;
    }
    @Override public JsFunction getGetterAsFunction() {
      return null;
    }
    @Override public JsValue getSetter() {
      return null;
    }
    @Override public boolean isConfigurable() {
      return true;
    }
    @Override public boolean isEnumerable() {
      return true;
    }
    @Override public RelayOk evaluateGet(EvaluateCallback callback, SyncCallback syncCallback) {
      throw new RuntimeException();
    }
  }
}
TOP

Related Classes of org.chromium.sdk.internal.v8native.value.JsVariableBase$Declarative

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.