package com.eas.bound; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.ListIterator; import com.eas.core.Utils.JsObject; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArrayMixed; public class JsArrayList implements List<JavaScriptObject> { protected class WrapperIterator implements ListIterator<JavaScriptObject> { protected Object[] snapshot = toArray(); protected int cursor = -1; public WrapperIterator(int aCursor) { super(); cursor = aCursor; } public WrapperIterator() { super(); } @Override public boolean hasNext() { return !JsArrayList.this.isEmpty() && cursor < snapshot.length - 1; } @Override public JavaScriptObject next() { return (JavaScriptObject) snapshot[++cursor]; } @Override public void remove() { JsArrayList.this.remove(cursor); } @Override public void set(JavaScriptObject e) { JsArrayList.this.set(cursor, e); } @Override public void add(JavaScriptObject e) { JsArrayList.this.add(cursor, e); } @Override public boolean hasPrevious() { return !JsArrayList.this.isEmpty() && cursor > 0; } @Override public JavaScriptObject previous() { return (JavaScriptObject) snapshot[--cursor]; } @Override public int nextIndex() { return cursor + 1; } @Override public int previousIndex() { return cursor - 1; } }; protected final JsObject data; protected final JsObject splice; public JsArrayList(JavaScriptObject aData) { super(); data = aData.cast(); JavaScriptObject oSplice = data.getJs("splice"); splice = oSplice != null ? oSplice.<JsObject>cast() : null; } @Override public int size() { return data != null ? data.getInteger("length") : 0; } @Override public boolean isEmpty() { return data == null || size() == 0; } @Override public boolean contains(Object o) { return indexOf(o) != -1; } @Override public Iterator<JavaScriptObject> iterator() { return new WrapperIterator(); } @Override public Object[] toArray() { Object[] snapshot = new Object[size()]; for (int i = 0; i < size(); i++) snapshot[i] = get(i); return snapshot; } @Override public <T> T[] toArray(T[] a) { return (T[]) toArray(); } @Override public boolean add(JavaScriptObject e) { data.<JsArrayMixed> cast().push(e); return true; } @Override public boolean remove(Object o) { int index = indexOf(o); if (index > -1) { remove(index); return true; } else return false; } @Override public boolean containsAll(Collection<?> c) { for (Object o : c) { if (!contains(o)) return false; } return true; } @Override public boolean addAll(Collection<? extends JavaScriptObject> c) { if (c != null) { for (JavaScriptObject jso : c) { add(jso); } return true; } else return false; } @Override public boolean addAll(int index, Collection<? extends JavaScriptObject> c) { if (c != null && index >= 0 && index <= size()) { int added = 0; for (JavaScriptObject jso : c) { add(index + added, jso); added++; } return true; } else return false; } @Override public boolean removeAll(Collection<?> c) { boolean modified = false; if (c != null) { for (Object o : c) { boolean removed = remove(o); if (removed) modified = true; } } return modified; } @Override public boolean retainAll(Collection<?> c) { boolean modified = false; for (int i = size() - 1; i >= 0; i--) { JavaScriptObject item = get(i); if (!c.contains(item)) { remove(i); modified = true; } } return modified; } @Override public void clear() { data.<JsArrayMixed> cast().setLength(0); } @Override public JavaScriptObject get(int index) { return data.getSlot(index); } @Override public JavaScriptObject set(int index, JavaScriptObject element) { if (index >= 0 && index < size()) { JavaScriptObject was = get(index); data.setSlot(index, element); return was; } else return null; } @Override public void add(int index, JavaScriptObject element) { JsArrayMixed args = JavaScriptObject.createArray().cast(); args.push(index); args.push(0); args.push(element); splice.apply(data, args); } @Override public JavaScriptObject remove(int index) { JavaScriptObject res = data.<JsArrayMixed> cast().getObject(index); if(res != null){ JsArrayMixed args = JavaScriptObject.createArray().cast(); args.push(index); args.push(1); splice.apply(data, args); } return res; } @Override public int indexOf(Object o) { for (int i = 0; i < size(); i++) { JavaScriptObject item = get(i); if (item == o) return i; } return -1; } @Override public int lastIndexOf(Object o) { for (int i = size() - 1; i >= 0; i--) { JavaScriptObject item = get(i); if (item == o) return i; } return -1; } @Override public ListIterator<JavaScriptObject> listIterator() { return new WrapperIterator(); } @Override public ListIterator<JavaScriptObject> listIterator(int index) { return new WrapperIterator(index); } @Override public List<JavaScriptObject> subList(int fromIndex, int toIndex) { List<JavaScriptObject> res = new ArrayList<>(); for (int i = fromIndex; i <= toIndex; i++) { if (i >= 0 && i < size()) res.add(get(i)); } return res; } }