package railo.runtime.type.util;
import java.util.AbstractList;
import java.util.Iterator;
import java.util.List;
import railo.commons.lang.CFTypes;
import railo.runtime.PageContext;
import railo.runtime.converter.LazyConverter;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.exp.PageRuntimeException;
import railo.runtime.op.Caster;
import railo.runtime.type.Array;
import railo.runtime.type.Collection;
import railo.runtime.type.KeyImpl;
import railo.runtime.type.Objects;
import railo.runtime.type.Sizeable;
import railo.runtime.type.Struct;
import railo.runtime.type.dt.DateTime;
public abstract class ArraySupport extends AbstractList implements Array,List,Sizeable,Objects {
public static final short TYPE_OBJECT = 0;
public static final short TYPE_BOOLEAN = 1;
public static final short TYPE_BYTE = 2;
public static final short TYPE_SHORT = 3;
public static final short TYPE_INT = 4;
public static final short TYPE_LONG = 5;
public static final short TYPE_FLOAT = 6;
public static final short TYPE_DOUBLE = 7;
public static final short TYPE_CHARACTER = 8;
public static final short TYPE_STRING = 9;
@Override
public final void add(int index, Object element) {
try {
insert(index+1, element);
} catch (PageException e) {
throw new IndexOutOfBoundsException("can't insert value to List at position "+index+", " +
"valid values are from 0 to "+(size()-1)+", size is "+size());
}
}
@Override
public final boolean addAll(java.util.Collection c) {
Iterator it = c.iterator();
while(it.hasNext()) {
add(it.next());
}
return true;
}
@Override
public final boolean remove(Object o) {
int index = indexOf(o);
if(index==-1) return false;
try {
removeE(index+1);
} catch (PageException e) {
return false;
}
return true;
}
@Override
public final boolean removeAll(java.util.Collection c) {
Iterator it = c.iterator();
boolean rtn=false;
while(it.hasNext()) {
if(remove(it.next()))rtn=true;
}
return rtn;
}
@Override
public final boolean retainAll(java.util.Collection c) {
boolean modified = false;
Key[] keys = CollectionUtil.keys(this);
Key k;
for(int i=keys.length-1;i>=0;i--) {
k = keys[i];
if(!c.contains(get(k,null))) {
removeEL(k);
modified = true;
}
}
return modified;
}
@Override
public final Object[] toArray(Object[] a) {
if(a==null) return toArray();
Class trgClass=a.getClass().getComponentType();
short type=TYPE_OBJECT;
if(trgClass==Boolean.class) type=TYPE_BOOLEAN;
else if(trgClass==Byte.class) type=TYPE_BYTE;
else if(trgClass==Short.class) type=TYPE_SHORT;
else if(trgClass==Integer.class) type=TYPE_INT;
else if(trgClass==Long.class) type=TYPE_LONG;
else if(trgClass==Float.class) type=TYPE_FLOAT;
else if(trgClass==Double.class) type=TYPE_DOUBLE;
else if(trgClass==Character.class) type=TYPE_CHARACTER;
else if(trgClass==String.class) type=TYPE_STRING;
Iterator it = iterator();
int i=0;
Object o;
try {
while(it.hasNext()) {
o=it.next();
switch(type){
case TYPE_BOOLEAN:
o=Caster.toBoolean(o);
break;
case TYPE_BYTE:
o=Caster.toByte(o);
break;
case TYPE_CHARACTER:
o=Caster.toCharacter(o);
break;
case TYPE_DOUBLE:
o=Caster.toDouble(o);
break;
case TYPE_FLOAT:
o=Caster.toFloat(o);
break;
case TYPE_INT:
o=Caster.toInteger(o);
break;
case TYPE_LONG:
o=Caster.toLong(o);
break;
case TYPE_SHORT:
o=Caster.toShort(o);
break;
case TYPE_STRING:
o=Caster.toString(o);
break;
}
a[i++]=o;
}
}
catch(PageException pe){
throw new PageRuntimeException(pe);
}
return a;
}
@Override
public final Object get(int index) {
if(index<0)
throw new IndexOutOfBoundsException("invalid index defintion ["+index+"], " +
"index should be a number between [0 - "+(size()-1)+"], size is "+size());
if(index>=size())
throw new IndexOutOfBoundsException("invalid index ["+index+"] defintion, " +
"index should be a number between [0 - "+(size()-1)+"], size is "+size());
return get(index+1, null);
}
@Override
public final Object remove(int index) {
if(index<0)
throw new IndexOutOfBoundsException("invalid index defintion ["+index+"], " +
"index should be a number between [0 - "+(size()-1)+"], size is "+size());
if(index>=size())
throw new IndexOutOfBoundsException("invalid index ["+index+"] defintion, " +
"index should be a number between [0 - "+(size()-1)+"], size is "+size());
return removeEL(index+1);
}
@Override
public final Object set(int index, Object element) {
Object o=get(index);
setEL(index+1, element);
return o;
}
@Override
public boolean containsKey(String key) {
return get(KeyImpl.init(key),null)!=null;
}
@Override
public boolean containsKey(Collection.Key key) {
return get(key,null)!=null;
}
@Override
public boolean containsKey(int key) {
return get(key,null)!=null;
}
@Override
public String toString() {
return LazyConverter.serialize(this);
}
@Override
public synchronized Object clone() {
return duplicate(true);
}
@Override
public String castToString() throws PageException {
throw new ExpressionException("Can't cast Complex Object Type Array to String",
"Use Built-In-Function \"serialize(Array):String\" to create a String from Array");
}
@Override
public String castToString(String defaultValue) {
return defaultValue;
}
@Override
public boolean castToBooleanValue() throws PageException {
throw new ExpressionException("Can't cast Complex Object Type Array to a boolean value");
}
@Override
public Boolean castToBoolean(Boolean defaultValue) {
return defaultValue;
}
@Override
public double castToDoubleValue() throws PageException {
throw new ExpressionException("Can't cast Complex Object Type Array to a number value");
}
@Override
public double castToDoubleValue(double defaultValue) {
return defaultValue;
}
@Override
public DateTime castToDateTime() throws PageException {
throw new ExpressionException("Can't cast Complex Object Type Array to a Date");
}
@Override
public DateTime castToDateTime(DateTime defaultValue) {
return defaultValue;
}
@Override
public int compareTo(boolean b) throws PageException {
throw new ExpressionException("can't compare Complex Object Type Array with a boolean value");
}
@Override
public int compareTo(DateTime dt) throws PageException {
throw new ExpressionException("can't compare Complex Object Type Array with a DateTime Object");
}
@Override
public int compareTo(double d) throws PageException {
throw new ExpressionException("can't compare Complex Object Type Array with a numeric value");
}
@Override
public int compareTo(String str) throws PageException {
throw new ExpressionException("can't compare Complex Object Type Array with a String");
}
@Override
public List toList() {
return this;
}
@Override
public Iterator<Object> valueIterator() {
return iterator();
}
@Override
public Object get(PageContext pc, Key key, Object defaultValue) {
return get(key, defaultValue);
}
@Override
public Object get(PageContext pc, Key key) throws PageException {
return get(key);
}
@Override
public Object set(PageContext pc, Key propertyName, Object value) throws PageException {
return set(propertyName, value);
}
@Override
public Object setEL(PageContext pc, Key propertyName, Object value) {
return setEL(propertyName, value);
}
@Override
public Object call(PageContext pc, Key methodName, Object[] args) throws PageException {
return MemberUtil.call(pc, this, methodName, args, CFTypes.TYPE_ARRAY, "array");
}
@Override
public Object callWithNamedValues(PageContext pc, Key methodName, Struct args) throws PageException {
return MemberUtil.callWithNamedValues(pc,this,methodName,args, CFTypes.TYPE_ARRAY, "array");
}
@Override
public java.util.Iterator<Object> getIterator() {
return valueIterator();
}
@Override
public synchronized void sort(String sortType, String sortOrder) throws PageException {
if(getDimension()>1)
throw new ExpressionException("only 1 dimensional arrays can be sorted");
sort(ArrayUtil.toComparator(null, sortType, sortOrder,false));
}
@Override
public boolean equals(Object obj){
if(!(obj instanceof Collection)) return false;
return CollectionUtil.equals(this,(Collection)obj);
}
/*@Override
public int hashCode() {
return CollectionUtil.hashCode(this);
}*/
}