package com.googlecode.gwt.test.internal.patchers;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsonUtils;
import com.googlecode.gwt.test.internal.utils.JsoUtils;
import com.googlecode.gwt.test.utils.JavaScriptObjects;
import java.util.ArrayList;
import java.util.List;
/**
* Helper class for JsArrayXXXPatcher
*
* @author Gael Lazzari
*/
class JsArrayHelper {
interface Converter<T> {
T convert(Object o);
String serialize(Object o);
}
private static Converter<Boolean> booleanConverter;
private static Converter<Integer> integerConverter;
private static final String JSARRAY_WRAPPED_LIST = "JSARRAY_WRAPPED_LIST";
private static Converter<Object> mixedConverter;
private static Converter<Double> numberConverter;
private static Converter<JavaScriptObject> objectConverter;
private static Converter<String> stringConverter;
public static <T> T get(JavaScriptObject jsArray, int index, Converter<T> converter) {
List<Object> wrapped = getWrappedList(jsArray);
Object o = (index < wrapped.size()) ? wrapped.get(index) : null;
return converter.convert(o);
}
public static Converter<Boolean> getBooleanConverter() {
if (booleanConverter == null) {
booleanConverter = new Converter<Boolean>() {
public Boolean convert(Object o) {
return (o != null) ? Boolean.valueOf(o.toString()) : false;
}
public String serialize(Object o) {
return (o != null) ? o.toString() : "";
}
};
}
return booleanConverter;
}
public static Converter<Integer> getIntegerConverter() {
if (integerConverter == null) {
integerConverter = new Converter<Integer>() {
public Integer convert(Object o) {
return (o != null) ? Integer.valueOf(o.toString()) : 0;
}
public String serialize(Object o) {
return (o != null) ? o.toString() : "";
}
};
}
return integerConverter;
}
public static Converter<Object> getMixedConverter() {
if (mixedConverter == null) {
mixedConverter = new Converter<Object>() {
public Object convert(Object o) {
return o;
}
public String serialize(Object o) {
if (o == null) {
return "";
} else if (o instanceof JavaScriptObject) {
return getObjectConverter().serialize(o);
} else {
return o.toString();
}
}
};
}
return mixedConverter;
}
public static Converter<Double> getNumberConverter() {
if (numberConverter == null) {
numberConverter = new Converter<Double>() {
public Double convert(Object o) {
return (o != null) ? Double.valueOf(o.toString()) : 0;
}
public String serialize(Object o) {
return (o != null) ? o.toString() : "";
}
};
}
return numberConverter;
}
public static Converter<JavaScriptObject> getObjectConverter() {
if (objectConverter == null) {
objectConverter = new Converter<JavaScriptObject>() {
public JavaScriptObject convert(Object o) {
if (o == null) {
return null;
} else if (o instanceof JavaScriptObject) {
return (JavaScriptObject) o;
} else {
return JsonUtils.safeEval(o.toString());
}
}
public String serialize(Object o) {
if (o == null) {
return "";
} else if (o instanceof JavaScriptObject) {
JavaScriptObject jso = (JavaScriptObject) o;
return JsoUtils.serialize(jso);
} else {
return o.toString();
}
}
};
}
return objectConverter;
}
public static Converter<String> getStringConverter() {
if (stringConverter == null) {
stringConverter = new Converter<String>() {
public String convert(Object o) {
if (o == null) {
return null;
} else if (o instanceof JavaScriptObject) {
return JsoUtils.serialize((JavaScriptObject) o);
} else {
return o.toString();
}
}
public String serialize(Object o) {
if (o == null) {
return "";
} else if (o instanceof JavaScriptObject) {
return JsoUtils.serialize((JavaScriptObject) o);
} else {
return o.toString();
}
}
};
}
return stringConverter;
}
@SuppressWarnings("unchecked")
public static List<Object> getWrappedList(JavaScriptObject jsArray) {
List<Object> wrappedList = (List<Object>) JavaScriptObjects.getObject(jsArray,
JSARRAY_WRAPPED_LIST);
if (wrappedList == null) {
wrappedList = new ArrayList<Object>();
JavaScriptObjects.setProperty(jsArray, JSARRAY_WRAPPED_LIST, wrappedList);
}
return wrappedList;
}
public static <T> String join(JavaScriptObject jsArray, String separator, Converter<T> converter) {
StringBuilder sb = new StringBuilder();
for (Object o : getWrappedList(jsArray)) {
sb.append(converter.serialize(o));
sb.append(separator);
}
return sb.substring(0, sb.length() - separator.length());
}
public static int length(JavaScriptObject jsArray) {
return getWrappedList(jsArray).size();
}
public static void push(JavaScriptObject jsArray, Object value) {
getWrappedList(jsArray).add(value);
}
public static void set(JavaScriptObject jsArray, int index, Object value) {
List<Object> wrapped = getWrappedList(jsArray);
int currentSize = wrapped.size();
if (index >= currentSize) {
for (int i = currentSize; i <= index; i++) {
wrapped.add(null);
}
}
wrapped.set(index, value);
}
public static void setLength(JavaScriptObject jsArray, int newLength) {
List<Object> list = getWrappedList(jsArray);
int currentSize = list.size();
if (currentSize > newLength) {
for (int i = newLength; i < currentSize; i++) {
list.remove(i - 1);
}
} else if (currentSize < newLength) {
for (int i = currentSize; i <= newLength; i++) {
list.add(null);
}
}
}
public static <T> T shift(JavaScriptObject jsArray, Converter<T> converter) {
List<Object> wrapped = getWrappedList(jsArray);
if (wrapped.size() == 0) {
return null;
}
Object o = wrapped.remove(0);
return converter.convert(o);
}
public static void unshift(JavaScriptObject jsArray, Object value) {
getWrappedList(jsArray).add(0, value);
}
}