/*
* Copyright 2011 Chad Retz
*
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
*
* 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 org.gwtnode.core;
import org.gwtnode.core.node.util.Util;
import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayInteger;
import com.google.gwt.core.client.JsArrayMixed;
import com.google.gwt.core.client.JsArrayString;
/**
* JavaScript utility methods
*
* @author Chad Retz
*/
public class JavaScriptUtils {
public static native JavaScriptObject getProperty(JavaScriptObject parent, String propertyName) /*-{
return parent[propertyName];
}-*/;
public static native JavaScriptObject undefined() /*-{
return undefined;
}-*/;
public static native void throwJavaScriptObject(JavaScriptObject err) /*-{
throw err;
}-*/;
public static JsArrayInteger toIntegerArray(byte... bytes) {
JsArrayInteger ret = JavaScriptObject.createArray().cast();
for (byte byt : bytes) {
ret.push(byt);
}
return ret;
}
public static JsArrayString toStringArray(String... strings) {
JsArrayString ret = JavaScriptObject.createArray().cast();
for (String string : strings) {
ret.push(string);
}
return ret;
}
public static void addToArray(JsArrayMixed array, Object value) {
if (value == null) {
array.push((JavaScriptObject) null);
} else if (value instanceof Boolean) {
array.push((Boolean) value);
} else if (value instanceof Integer) {
array.push((Integer) value);
} else if (value instanceof Double) {
array.push((Double) value);
} else if (value instanceof Float) {
array.push((Float) value);
} else if (value instanceof Byte) {
array.push((Byte) value);
} else if (value instanceof Character) {
array.push((Character) value);
} else if (value instanceof Short) {
array.push((Short) value);
} else if (value instanceof String) {
array.push((String) value);
} else if (value instanceof JavaScriptObject) {
array.push((JavaScriptObject) value);
} else {
array.push("" + value);
}
}
public static JsArrayMixed toMixedArray(Object... values) {
JsArrayMixed ret = JavaScriptObject.createArray().cast();
for (Object value : values) {
addToArray(ret, value);
}
return ret;
}
public static StringBuilder appendException(Throwable throwable, StringBuilder builder) {
return appendException(throwable, true, builder);
}
private static StringBuilder appendException(Throwable throwable,
boolean topLevel, StringBuilder builder) {
if (topLevel) {
builder.append("Exception: ").append(throwable).append('\n');
} else {
builder.append("Caused by: ").append(throwable).append('\n');
}
if (throwable instanceof JavaScriptException) {
if (throwable.getStackTrace().length == 0) {
throwable.fillInStackTrace();
}
builder.append(" JS Error: ").append(Util.get().inspect(
((JavaScriptException) throwable).getException(), true)).append('\n');
}
StackTraceElement[] stackTraceElements = throwable.getStackTrace();
if (stackTraceElements != null && stackTraceElements.length > 0) {
for (StackTraceElement stackTraceElement : stackTraceElements) {
builder.append(" ").append(stackTraceElement).append('\n');
}
} else {
builder.append("[no stacktrace]\n");
}
if (throwable.getCause() != null && throwable.getCause() != throwable) {
return appendException(throwable.getCause(), false, builder);
} else {
return builder;
}
}
/**
* Unescape JS strings and return them, surrounded by single quotes.
* Specifically, this unescapes \b, \f, \n, \0, \r, \t, and single quotes.
*
* @param string The string to unescape
* @return The unescaped string
*/
public static String unescapeJavaScriptString(String string) {
StringBuilder ret = new StringBuilder(string.length()).append('\'');
for (int i = 0; i < string.length(); i++) {
char chr = string.charAt(i);
switch (chr) {
case '\b':
ret.append("\\b");
break;
case '\f':
ret.append("\\f");
break;
case '\n':
ret.append("\\n");
break;
case '\0':
//TODO: does this even work?
ret.append("\\0");
break;
case '\r':
ret.append("\\r");
break;
case '\t':
ret.append("\\t");
break;
case '\'':
ret.append("\\'");
break;
default:
ret.append(chr);
}
}
return ret.append('\'').toString();
}
private JavaScriptUtils() {
}
}