001 package railo.runtime.type.util; 002 003 import java.util.AbstractList; 004 import java.util.Iterator; 005 import java.util.List; 006 007 import railo.commons.lang.CFTypes; 008 import railo.runtime.PageContext; 009 import railo.runtime.converter.LazyConverter; 010 import railo.runtime.exp.ExpressionException; 011 import railo.runtime.exp.PageException; 012 import railo.runtime.exp.PageRuntimeException; 013 import railo.runtime.op.Caster; 014 import railo.runtime.type.Array; 015 import railo.runtime.type.Collection; 016 import railo.runtime.type.KeyImpl; 017 import railo.runtime.type.Objects; 018 import railo.runtime.type.Sizeable; 019 import railo.runtime.type.Struct; 020 import railo.runtime.type.dt.DateTime; 021 022 public abstract class ArraySupport extends AbstractList implements Array,List,Sizeable,Objects { 023 024 025 public static final short TYPE_OBJECT = 0; 026 public static final short TYPE_BOOLEAN = 1; 027 public static final short TYPE_BYTE = 2; 028 public static final short TYPE_SHORT = 3; 029 public static final short TYPE_INT = 4; 030 public static final short TYPE_LONG = 5; 031 public static final short TYPE_FLOAT = 6; 032 public static final short TYPE_DOUBLE = 7; 033 public static final short TYPE_CHARACTER = 8; 034 public static final short TYPE_STRING = 9; 035 036 @Override 037 public final void add(int index, Object element) { 038 try { 039 insert(index+1, element); 040 } catch (PageException e) { 041 throw new IndexOutOfBoundsException("can't insert value to List at position "+index+", " + 042 "valid values are from 0 to "+(size()-1)+", size is "+size()); 043 } 044 } 045 046 @Override 047 public final boolean addAll(java.util.Collection c) { 048 Iterator it = c.iterator(); 049 while(it.hasNext()) { 050 add(it.next()); 051 } 052 return true; 053 } 054 055 @Override 056 public final boolean remove(Object o) { 057 int index = indexOf(o); 058 if(index==-1) return false; 059 060 try { 061 removeE(index+1); 062 } catch (PageException e) { 063 return false; 064 } 065 return true; 066 } 067 068 @Override 069 public final boolean removeAll(java.util.Collection c) { 070 Iterator it = c.iterator(); 071 boolean rtn=false; 072 while(it.hasNext()) { 073 if(remove(it.next()))rtn=true; 074 } 075 return rtn; 076 } 077 078 @Override 079 public final boolean retainAll(java.util.Collection c) { 080 boolean modified = false; 081 Key[] keys = CollectionUtil.keys(this); 082 Key k; 083 for(int i=keys.length-1;i>=0;i--) { 084 k = keys[i]; 085 if(!c.contains(get(k,null))) { 086 removeEL(k); 087 modified = true; 088 } 089 } 090 return modified; 091 } 092 093 @Override 094 public final Object[] toArray(Object[] a) { 095 if(a==null) return toArray(); 096 097 098 Class trgClass=a.getClass().getComponentType(); 099 short type=TYPE_OBJECT; 100 if(trgClass==Boolean.class) type=TYPE_BOOLEAN; 101 else if(trgClass==Byte.class) type=TYPE_BYTE; 102 else if(trgClass==Short.class) type=TYPE_SHORT; 103 else if(trgClass==Integer.class) type=TYPE_INT; 104 else if(trgClass==Long.class) type=TYPE_LONG; 105 else if(trgClass==Float.class) type=TYPE_FLOAT; 106 else if(trgClass==Double.class) type=TYPE_DOUBLE; 107 else if(trgClass==Character.class) type=TYPE_CHARACTER; 108 else if(trgClass==String.class) type=TYPE_STRING; 109 110 111 Iterator it = iterator(); 112 int i=0; 113 Object o; 114 try { 115 while(it.hasNext()) { 116 o=it.next(); 117 switch(type){ 118 case TYPE_BOOLEAN: 119 o=Caster.toBoolean(o); 120 break; 121 case TYPE_BYTE: 122 o=Caster.toByte(o); 123 break; 124 case TYPE_CHARACTER: 125 o=Caster.toCharacter(o); 126 break; 127 case TYPE_DOUBLE: 128 o=Caster.toDouble(o); 129 break; 130 case TYPE_FLOAT: 131 o=Caster.toFloat(o); 132 break; 133 case TYPE_INT: 134 o=Caster.toInteger(o); 135 break; 136 case TYPE_LONG: 137 o=Caster.toLong(o); 138 break; 139 case TYPE_SHORT: 140 o=Caster.toShort(o); 141 break; 142 case TYPE_STRING: 143 o=Caster.toString(o); 144 break; 145 } 146 a[i++]=o; 147 } 148 } 149 catch(PageException pe){ 150 throw new PageRuntimeException(pe); 151 } 152 return a; 153 } 154 155 @Override 156 public final Object get(int index) { 157 if(index<0) 158 throw new IndexOutOfBoundsException("invalid index defintion ["+index+"], " + 159 "index should be a number between [0 - "+(size()-1)+"], size is "+size()); 160 if(index>=size()) 161 throw new IndexOutOfBoundsException("invalid index ["+index+"] defintion, " + 162 "index should be a number between [0 - "+(size()-1)+"], size is "+size()); 163 164 return get(index+1, null); 165 } 166 167 @Override 168 public final Object remove(int index) { 169 if(index<0) 170 throw new IndexOutOfBoundsException("invalid index defintion ["+index+"], " + 171 "index should be a number between [0 - "+(size()-1)+"], size is "+size()); 172 if(index>=size()) 173 throw new IndexOutOfBoundsException("invalid index ["+index+"] defintion, " + 174 "index should be a number between [0 - "+(size()-1)+"], size is "+size()); 175 176 return removeEL(index+1); 177 } 178 179 @Override 180 public final Object set(int index, Object element) { 181 Object o=get(index); 182 setEL(index+1, element); 183 return o; 184 } 185 186 187 @Override 188 public boolean containsKey(String key) { 189 return get(KeyImpl.init(key),null)!=null; 190 } 191 192 @Override 193 public boolean containsKey(Collection.Key key) { 194 return get(key,null)!=null; 195 } 196 197 @Override 198 public boolean containsKey(int key) { 199 return get(key,null)!=null; 200 } 201 202 203 @Override 204 public String toString() { 205 return LazyConverter.serialize(this); 206 } 207 208 @Override 209 public synchronized Object clone() { 210 return duplicate(true); 211 } 212 213 @Override 214 public String castToString() throws PageException { 215 throw new ExpressionException("Can't cast Complex Object Type Array to String", 216 "Use Built-In-Function \"serialize(Array):String\" to create a String from Array"); 217 } 218 219 @Override 220 public String castToString(String defaultValue) { 221 return defaultValue; 222 } 223 224 225 @Override 226 public boolean castToBooleanValue() throws PageException { 227 throw new ExpressionException("Can't cast Complex Object Type Array to a boolean value"); 228 } 229 230 @Override 231 public Boolean castToBoolean(Boolean defaultValue) { 232 return defaultValue; 233 } 234 235 236 237 @Override 238 public double castToDoubleValue() throws PageException { 239 throw new ExpressionException("Can't cast Complex Object Type Array to a number value"); 240 } 241 242 @Override 243 public double castToDoubleValue(double defaultValue) { 244 return defaultValue; 245 } 246 247 248 249 @Override 250 public DateTime castToDateTime() throws PageException { 251 throw new ExpressionException("Can't cast Complex Object Type Array to a Date"); 252 } 253 254 @Override 255 public DateTime castToDateTime(DateTime defaultValue) { 256 return defaultValue; 257 } 258 259 @Override 260 public int compareTo(boolean b) throws PageException { 261 throw new ExpressionException("can't compare Complex Object Type Array with a boolean value"); 262 } 263 264 @Override 265 public int compareTo(DateTime dt) throws PageException { 266 throw new ExpressionException("can't compare Complex Object Type Array with a DateTime Object"); 267 } 268 269 @Override 270 public int compareTo(double d) throws PageException { 271 throw new ExpressionException("can't compare Complex Object Type Array with a numeric value"); 272 } 273 274 @Override 275 public int compareTo(String str) throws PageException { 276 throw new ExpressionException("can't compare Complex Object Type Array with a String"); 277 } 278 279 @Override 280 public List toList() { 281 return this; 282 } 283 284 @Override 285 public Iterator<Object> valueIterator() { 286 return iterator(); 287 } 288 289 @Override 290 public Object get(PageContext pc, Key key, Object defaultValue) { 291 return get(key, defaultValue); 292 } 293 294 @Override 295 public Object get(PageContext pc, Key key) throws PageException { 296 return get(key); 297 } 298 299 @Override 300 public Object set(PageContext pc, Key propertyName, Object value) throws PageException { 301 return set(propertyName, value); 302 } 303 304 @Override 305 public Object setEL(PageContext pc, Key propertyName, Object value) { 306 return setEL(propertyName, value); 307 } 308 309 @Override 310 public Object call(PageContext pc, Key methodName, Object[] args) throws PageException { 311 return MemberUtil.call(pc, this, methodName, args, CFTypes.TYPE_ARRAY, "array"); 312 } 313 314 @Override 315 public Object callWithNamedValues(PageContext pc, Key methodName, Struct args) throws PageException { 316 return MemberUtil.callWithNamedValues(pc,this,methodName,args, CFTypes.TYPE_ARRAY, "array"); 317 } 318 319 @Override 320 public java.util.Iterator<Object> getIterator() { 321 return valueIterator(); 322 } 323 324 @Override 325 public synchronized void sort(String sortType, String sortOrder) throws PageException { 326 if(getDimension()>1) 327 throw new ExpressionException("only 1 dimensional arrays can be sorted"); 328 sort(ArrayUtil.toComparator(null, sortType, sortOrder,false)); 329 } 330 331 @Override 332 public boolean equals(Object obj){ 333 if(!(obj instanceof Collection)) return false; 334 return CollectionUtil.equals(this,(Collection)obj); 335 } 336 337 @Override 338 public int hashCode() { 339 return CollectionUtil.hashCode(this); 340 } 341 }