/*
* Copyright (c) 2012, the Dart project authors.
*
* Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.dart.tools.debug.core.webkit;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* A WIP scope object.
*
* @see http://code.google.com/chrome/devtools/docs/protocol/tot/runtime.html#type-RemoteObject
*/
public class WebkitRemoteObject {
public static WebkitRemoteObject createFrom(JSONObject params) throws JSONException {
WebkitRemoteObject remoteObject = new WebkitRemoteObject();
remoteObject.className = JsonUtils.getString(params, "className");
remoteObject.description = JsonUtils.getString(params, "description");
remoteObject.objectId = JsonUtils.getString(params, "objectId");
remoteObject.subtype = JsonUtils.getString(params, "subtype");
remoteObject.type = JsonUtils.getString(params, "type");
if (params.has("value")) {
Object obj = params.get("value");
remoteObject.value = String.valueOf(obj);
}
return remoteObject;
}
public static WebkitRemoteObject createNull() {
WebkitRemoteObject obj = new WebkitRemoteObject();
obj.type = "object";
obj.subtype = "null";
obj.description = "null";
return obj;
}
String className;
private String description;
private String objectId;
private String subtype;
private String type;
private String value;
private int listLength = -1;
@Override
public boolean equals(Object obj) {
if (obj instanceof WebkitRemoteObject) {
return ((WebkitRemoteObject) obj).getObjectId().equals(getObjectId());
}
return false;
}
public String getClassName() {
if (className != null) {
return className;
}
if (isString()) {
return "String";
}
if (isBoolean()) {
return "bool";
}
if (isNumber()) {
return "num";
}
return null;
}
public String getDescription() {
return description;
}
/**
* Return the length of the list if this object is a list.
*
* @param webkitConnection
* @return
*/
public int getListLength(WebkitConnection connection) {
if (listLength == -1) {
final CountDownLatch latch = new CountDownLatch(1);
try {
connection.getRuntime().callListLength(objectId, new WebkitCallback<Integer>() {
@Override
public void handleResult(WebkitResult<Integer> result) {
if (result.isError()) {
listLength = 0;
} else if (result.getResult() == null) {
listLength = 0;
} else {
listLength = result.getResult().intValue();
}
latch.countDown();
}
});
} catch (IOException e) {
listLength = 0;
latch.countDown();
}
try {
latch.await(3, TimeUnit.SECONDS);
} catch (InterruptedException e) {
}
}
return listLength;
}
public String getObjectId() {
return objectId;
}
/**
* One of "array", "date", "node", "null", "regexp".
*/
public String getSubtype() {
return subtype;
}
/**
* One of "boolean", "function", "number", "object", "string", "undefined".
*/
public String getType() {
return type;
}
public String getValue() {
// Only numbers are returned with a description, and it's often more useful then the value
// field (for things like Infinity).
if (isNumber() && description != null) {
return description;
} else {
return value;
}
}
@Override
public int hashCode() {
return objectId.hashCode();
}
public boolean hasObjectId() {
return getObjectId() != null;
}
public boolean isBoolean() {
return "boolean".equals(type);
}
public boolean isDartFunction() {
return "<Dart Method>".equals(className);
}
public boolean isFunction() {
return "function".equals(type);
}
/**
* Returns true if this object is a Dart library reference.
*/
public boolean isLibraryRef() {
if (className == null) {
return false;
}
return className.startsWith("file:") || className.startsWith("http:");
}
public boolean isList() {
return "object".equals(type) && "List".equals(className);
}
public boolean isNode() {
return "node".equals(subtype);
}
public boolean isNull() {
if (isObject() && "null".equals(value)) {
return true;
} else {
return false;
}
}
public boolean isNumber() {
return "number".equals(type);
}
public boolean isObject() {
return "object".equals(type);
}
public boolean isPrimitive() {
return "number".equals(type) || "string".equals(type) || "boolean".equals(type);
}
public boolean isString() {
return "string".equals(type);
}
public boolean isSyntaxError() {
return isObject() && "SyntaxError".equals(className);
}
public boolean isUndefined() {
return "undefined".equals(type);
}
@Override
public String toString() {
if (value == null) {
return "[" + type + "," + description + "]";
} else {
return "[" + type + "," + value + "]";
}
}
void setDescription(String value) {
description = value;
}
}