org.chromium.sdk/src/org/chromium/sdk/internal/SubpropertiesMirror.java
changeset 2 e4420d2515f1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org.chromium.sdk/src/org/chromium/sdk/internal/SubpropertiesMirror.java	Wed Dec 23 17:13:18 2009 -0800
@@ -0,0 +1,155 @@
+// 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 java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.chromium.sdk.internal.protocol.data.FunctionValueHandle;
+import org.chromium.sdk.internal.protocol.data.ObjectValueHandle;
+import org.chromium.sdk.internal.tools.v8.V8ProtocolUtil;
+
+/**
+ * This class is intended to hold properties either already parsed or to be parsed on demand.
+ */
+public abstract class SubpropertiesMirror {
+  public abstract List<? extends PropertyReference> getProperties();
+
+  public abstract List<? extends PropertyReference> getInternalProperties();
+
+  public abstract Object getAdditionalProperties();
+
+  public static class ObjectValueBased extends JsonBased<ObjectValueHandle> {
+    private final ObjectValueHandle objectValueHandle;
+    public ObjectValueBased(ObjectValueHandle valueHandle,
+        AdditionalPropertyFactory<ObjectValueHandle> additionalPropertyFactory) {
+      super(additionalPropertyFactory);
+      this.objectValueHandle = valueHandle;
+    }
+    @Override
+    protected ObjectValueHandle getObjectForFactory() {
+      return objectValueHandle;
+    }
+    @Override
+    protected ObjectValueHandle getObjectValue() {
+      return objectValueHandle;
+    }
+  }
+  public static class FunctionValueBased extends JsonBased<FunctionValueHandle> {
+    private final FunctionValueHandle functionValueHandle;
+    public FunctionValueBased(FunctionValueHandle functionValueHandle,
+        AdditionalPropertyFactory<FunctionValueHandle> additionalPropertyFactory) {
+      super(additionalPropertyFactory);
+      this.functionValueHandle = functionValueHandle;
+    }
+    @Override
+    protected FunctionValueHandle getObjectForFactory() {
+      return functionValueHandle;
+    }
+    @Override
+    protected ObjectValueHandle getObjectValue() {
+      return functionValueHandle.getSuper();
+    }
+  }
+
+  /**
+   * Keeps properties in for of JSON and parses JSON on demand.
+   */
+  public static abstract class JsonBased<T> extends SubpropertiesMirror {
+    private final AdditionalPropertyFactory<T> additionalPropertyFactory;
+
+    private List<? extends PropertyReference> properties = null;
+    private List<? extends PropertyReference> internalProperties = null;
+    private Object additionalProperties = null;
+
+    public JsonBased(AdditionalPropertyFactory<T> additionalPropertyFactory) {
+      if (additionalPropertyFactory == null) {
+        additionalPropertyFactory = NO_OP_FACTORY;
+      }
+      this.additionalPropertyFactory = additionalPropertyFactory;
+    }
+
+    @Override
+    public synchronized List<? extends PropertyReference> getProperties() {
+      if (properties == null) {
+        properties = V8ProtocolUtil.extractObjectProperties(getObjectValue());
+      }
+      return properties;
+    }
+
+    @Override
+    public synchronized List<? extends PropertyReference> getInternalProperties() {
+      if (internalProperties == null) {
+        internalProperties = V8ProtocolUtil.extractObjectInternalProperties(getObjectValue());
+      }
+      return internalProperties;
+    }
+
+    protected abstract ObjectValueHandle getObjectValue();
+
+    @Override
+    public Object getAdditionalProperties() {
+      if (additionalProperties == null) {
+        additionalProperties =
+            additionalPropertyFactory.createAdditionalProperties(getObjectForFactory());
+      }
+      return additionalProperties;
+    }
+    protected abstract T getObjectForFactory();
+
+    public interface AdditionalPropertyFactory<T> {
+      Object createAdditionalProperties(T jsonWithProperties);
+    }
+
+    private static AdditionalPropertyFactory NO_OP_FACTORY = new AdditionalPropertyFactory<Void>() {
+      public Object createAdditionalProperties(Void jsonWithProperties) {
+        return EMPTY_OBJECT;
+      }
+    };
+  }
+
+  static class ListBased extends SubpropertiesMirror {
+    private final List<PropertyReference> list;
+
+    ListBased(PropertyReference ... refs) {
+      this.list = Collections.unmodifiableList(Arrays.asList(refs));
+    }
+
+    @Override
+    public List<? extends PropertyReference> getProperties() {
+      return list;
+    }
+
+    @Override
+    public List<? extends PropertyReference> getInternalProperties() {
+      return Collections.emptyList();
+    }
+
+    @Override
+    public Object getAdditionalProperties() {
+      return EMPTY_OBJECT;
+    }
+  }
+
+  static final SubpropertiesMirror EMPTY = new SubpropertiesMirror() {
+    @Override
+    public List<? extends PropertyReference> getProperties() {
+      return Collections.emptyList();
+    }
+
+    @Override
+    public List<? extends PropertyReference> getInternalProperties() {
+      return Collections.emptyList();
+    }
+
+    @Override
+    public Object getAdditionalProperties() {
+      return EMPTY_OBJECT;
+    }
+  };
+
+  private static final Object EMPTY_OBJECT = new Object();
+}