001 package railo.runtime.type.wrap; 002 003 import java.util.ArrayList; 004 import java.util.Collections; 005 import java.util.Comparator; 006 import java.util.Iterator; 007 import java.util.List; 008 import java.util.ListIterator; 009 import java.util.Map.Entry; 010 011 import railo.commons.lang.CFTypes; 012 import railo.runtime.PageContext; 013 import railo.runtime.converter.LazyConverter; 014 import railo.runtime.dump.DumpData; 015 import railo.runtime.dump.DumpProperties; 016 import railo.runtime.dump.DumpUtil; 017 import railo.runtime.exp.ExpressionException; 018 import railo.runtime.exp.PageException; 019 import railo.runtime.op.Caster; 020 import railo.runtime.op.Duplicator; 021 import railo.runtime.type.Array; 022 import railo.runtime.type.ArrayImpl; 023 import railo.runtime.type.Collection; 024 import railo.runtime.type.KeyImpl; 025 import railo.runtime.type.Sizeable; 026 import railo.runtime.type.Struct; 027 import railo.runtime.type.dt.DateTime; 028 import railo.runtime.type.it.EntryIterator; 029 import railo.runtime.type.it.KeyIterator; 030 import railo.runtime.type.it.StringIterator; 031 import railo.runtime.type.util.ArrayUtil; 032 import railo.runtime.type.util.MemberUtil; 033 034 /** 035 * 036 */ 037 public class ListAsArray implements Array,List,Sizeable { 038 039 protected List list; 040 041 private ListAsArray(List list) { 042 this.list=list; 043 } 044 045 public static Array toArray(List list) { 046 if(list instanceof ArrayAsList) return ((ArrayAsList)list).array; 047 if(list instanceof Array) return (Array) list; 048 return new ListAsArray(list); 049 } 050 051 052 @Override 053 public Object append(Object o) throws PageException { 054 list.add(o); 055 return o; 056 } 057 058 059 @Override 060 public Object appendEL(Object o) { 061 list.add(o); 062 return o; 063 } 064 065 @Override 066 public boolean containsKey(int index) { 067 return get(index-1,null)!=null; 068 } 069 070 @Override 071 public Object get(int key, Object defaultValue) { 072 try { 073 Object rtn = list.get(key-1); 074 if(rtn==null) return defaultValue; 075 return rtn; 076 } 077 catch(Throwable t) { 078 return defaultValue; 079 } 080 } 081 082 @Override 083 public Object getE(int key) throws PageException { 084 try { 085 Object rtn = list.get(key-1); 086 if(rtn==null) throw new ExpressionException("Element at position ["+key+"] does not exist in list"); 087 return rtn; 088 } 089 catch(Throwable t) { 090 throw new ExpressionException("Element at position ["+key+"] does not exist in list",t.getMessage()); 091 } 092 } 093 094 @Override 095 public int getDimension() { 096 return 1; 097 } 098 099 public boolean insert(int key, Object value) throws PageException { 100 try { 101 list.add(key-1, value); 102 } 103 catch(Throwable t) { 104 throw new ExpressionException("can't insert value to array at position "+key+", array goes from 1 to "+size()); 105 } 106 return true; 107 } 108 109 public int[] intKeys() { 110 ListIterator lit = list.listIterator(); 111 ArrayList keys = new ArrayList(); 112 int index=0; 113 Object v; 114 while(lit.hasNext()) { 115 index=lit.nextIndex()+1; 116 v=lit.next(); 117 if(v!=null)keys.add(Integer.valueOf(index)); 118 } 119 int[] intKeys = new int[keys.size()]; 120 Iterator it = keys.iterator(); 121 index=0; 122 while(it.hasNext()) { 123 intKeys[index++]=((Integer)it.next()).intValue(); 124 } 125 126 return intKeys; 127 } 128 129 @Override 130 public Object prepend(Object o) throws PageException { 131 list.add(0,o); 132 return o; 133 } 134 135 public Object removeE(int key) throws PageException { 136 try { 137 return list.remove(key-1); 138 } 139 catch(Throwable t) { 140 throw new ExpressionException("can not remove Element at position ["+key+"]",t.getMessage()); 141 } 142 } 143 144 @Override 145 public Object removeEL(int key) { 146 try { 147 return removeE(key); 148 } catch (PageException e) { 149 return null; 150 } 151 } 152 153 public void resize(int to) throws PageException { 154 while(size()<to)list.add(null); 155 } 156 157 @Override 158 public Object setE(int key, Object value) throws PageException { 159 if(key<=size()) { 160 try { 161 list.set(key-1, value); 162 } 163 catch(Throwable t) { 164 throw new ExpressionException("can not set Element at position ["+key+"]",t.getMessage()); 165 } 166 167 } 168 else { 169 while(size()<key-1)list.add(null); 170 list.add(value); 171 } 172 return value; 173 } 174 175 @Override 176 public Object setEL(int key, Object value) { 177 try { 178 return setE(key, value); 179 } catch (Throwable t) {} 180 return value; 181 } 182 183 @Override 184 public void sort(String sortType, String sortOrder) throws PageException { 185 sort(ArrayUtil.toComparator(null, sortType, sortOrder, false)); 186 } 187 188 @Override 189 public synchronized void sort(Comparator comp) throws PageException { 190 if(getDimension()>1) 191 throw new ExpressionException("only 1 dimensional arrays can be sorted"); 192 Collections.sort(list,comp); 193 } 194 195 @Override 196 public Object[] toArray() { 197 return list.toArray(); 198 } 199 200 public ArrayList toArrayList() { 201 return new ArrayList(list); 202 } 203 204 @Override 205 public void clear() { 206 list.clear(); 207 } 208 209 @Override 210 public boolean containsKey(String key) { 211 return get(key,null)!=null; 212 } 213 214 @Override 215 public boolean containsKey(Key key) { 216 return get(key,null)!=null; 217 } 218 219 @Override 220 public Collection duplicate(boolean deepCopy) {new ArrayImpl().duplicate(deepCopy); 221 return new ListAsArray((List)Duplicator.duplicate(list,deepCopy)); 222 } 223 224 225 226 @Override 227 public Object get(String key) throws PageException { 228 return getE(Caster.toIntValue(key)); 229 } 230 231 @Override 232 public Object get(Key key) throws PageException { 233 return get(key.getString()); 234 } 235 236 @Override 237 public Object get(String key, Object defaultValue) { 238 double index=Caster.toIntValue(key,Integer.MIN_VALUE); 239 if(index==Integer.MIN_VALUE) return defaultValue; 240 return get((int)index,defaultValue); 241 } 242 243 @Override 244 public Object get(Key key, Object defaultValue) { 245 return get(key.getString(),defaultValue); 246 } 247 248 @Override 249 public Key[] keys() { 250 int[] intKeys = intKeys(); 251 Collection.Key[] keys = new Collection.Key[intKeys.length]; 252 for(int i=0;i<intKeys.length;i++) { 253 keys[i]=KeyImpl.init(Caster.toString(intKeys[i])); 254 } 255 return keys; 256 } 257 258 @Override 259 public Object remove(Key key) throws PageException { 260 return removeE(Caster.toIntValue(key.getString())); 261 } 262 263 @Override 264 public Object removeEL(Key key) { 265 double index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 266 if(index==Integer.MIN_VALUE) return null; 267 return removeEL((int)index); 268 } 269 270 @Override 271 public Object set(String key, Object value) throws PageException { 272 return setE(Caster.toIntValue(key),value); 273 } 274 275 @Override 276 public Object set(Key key, Object value) throws PageException { 277 return set(key.getString(),value); 278 } 279 280 @Override 281 public Object setEL(String key, Object value) { 282 double index=Caster.toIntValue(key,Integer.MIN_VALUE); 283 if(index==Integer.MIN_VALUE) return value; 284 return setEL((int)index,value); 285 } 286 287 @Override 288 public Object setEL(Key key, Object value) { 289 return setEL(key.getString(), value); 290 } 291 292 @Override 293 public int size() { 294 return list.size(); 295 } 296 297 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) { 298 return DumpUtil.toDumpData(list, pageContext,maxlevel,dp); 299 } 300 301 @Override 302 public Iterator iterator() { 303 return list.iterator(); 304 } 305 306 @Override 307 public Iterator<Collection.Key> keyIterator() { 308 return new KeyIterator(keys()); 309 } 310 311 @Override 312 public Iterator<String> keysAsStringIterator() { 313 return new StringIterator(keys()); 314 } 315 316 @Override 317 public Iterator<Entry<Key, Object>> entryIterator() { 318 return new EntryIterator(this,keys()); 319 } 320 321 @Override 322 public String castToString() throws PageException { 323 throw new ExpressionException("Can't cast Complex Object Type "+Caster.toClassName(list)+" to String", 324 "Use Built-In-Function \"serialize(Array):String\" to create a String from Array"); 325 } 326 327 @Override 328 public String castToString(String defaultValue) { 329 return defaultValue; 330 } 331 332 333 @Override 334 public boolean castToBooleanValue() throws PageException { 335 throw new ExpressionException("Can't cast Complex Object Type "+Caster.toClassName(list)+" to a boolean value"); 336 } 337 338 @Override 339 public Boolean castToBoolean(Boolean defaultValue) { 340 return defaultValue; 341 } 342 343 344 @Override 345 public double castToDoubleValue() throws PageException { 346 throw new ExpressionException("Can't cast Complex Object Type "+Caster.toClassName(list)+" to a number value"); 347 } 348 349 @Override 350 public double castToDoubleValue(double defaultValue) { 351 return defaultValue; 352 } 353 354 355 @Override 356 public DateTime castToDateTime() throws PageException { 357 throw new ExpressionException("Can't cast Complex Object Type "+Caster.toClassName(list)+" to a Date"); 358 } 359 360 @Override 361 public DateTime castToDateTime(DateTime defaultValue) { 362 return defaultValue; 363 } 364 365 @Override 366 public int compareTo(boolean b) throws PageException { 367 throw new ExpressionException("can't compare Complex Object Type "+Caster.toClassName(list)+" with a boolean value"); 368 } 369 370 @Override 371 public int compareTo(DateTime dt) throws PageException { 372 throw new ExpressionException("can't compare Complex Object Type "+Caster.toClassName(list)+" with a DateTime Object"); 373 } 374 375 @Override 376 public int compareTo(double d) throws PageException { 377 throw new ExpressionException("can't compare Complex Object Type "+Caster.toClassName(list)+" with a numeric value"); 378 } 379 380 @Override 381 public int compareTo(String str) throws PageException { 382 throw new ExpressionException("can't compare Complex Object Type "+Caster.toClassName(list)+" with a String"); 383 } 384 385 @Override 386 public String toString() { 387 return LazyConverter.serialize(this); 388 } 389 390 @Override 391 public Object clone() { 392 return duplicate(true); 393 } 394 395 @Override 396 public boolean add(Object o) { 397 return list.add(o); 398 } 399 400 @Override 401 public void add(int index, Object element) { 402 list.add(index, element); 403 } 404 405 @Override 406 public boolean addAll(java.util.Collection c) { 407 return list.addAll(c); 408 } 409 410 @Override 411 public boolean addAll(int index, java.util.Collection c) { 412 return list.addAll(index, c); 413 } 414 415 @Override 416 public boolean contains(Object o) { 417 return list.contains(o); 418 } 419 420 @Override 421 public boolean containsAll(java.util.Collection c) { 422 return list.contains(c); 423 } 424 425 @Override 426 public Object get(int index) { 427 return list.get(index); 428 } 429 430 @Override 431 public int indexOf(Object o) { 432 return list.indexOf(o); 433 } 434 435 @Override 436 public boolean isEmpty() { 437 return list.isEmpty(); 438 } 439 440 @Override 441 public int lastIndexOf(Object o) { 442 return list.lastIndexOf(o); 443 } 444 445 @Override 446 public ListIterator listIterator() { 447 return list.listIterator(); 448 } 449 450 @Override 451 public ListIterator listIterator(int index) { 452 return list.listIterator(index); 453 } 454 455 @Override 456 public boolean remove(Object o) { 457 return list.remove(o); 458 } 459 460 @Override 461 public Object remove(int index) { 462 return list.remove(index); 463 } 464 465 @Override 466 public boolean removeAll(java.util.Collection c) { 467 return list.removeAll(c); 468 } 469 470 @Override 471 public boolean retainAll(java.util.Collection c) { 472 return list.retainAll(c); 473 } 474 475 @Override 476 public Object set(int index, Object element) { 477 return list.set(index, element); 478 } 479 480 @Override 481 public List subList(int fromIndex, int toIndex) { 482 return list.subList(fromIndex, toIndex); 483 } 484 485 @Override 486 public Object[] toArray(Object[] a) { 487 return list.toArray(a); 488 } 489 490 491 @Override 492 public List toList() { 493 return this; 494 } 495 496 public Iterator valueIterator() { 497 return list.iterator(); 498 } 499 500 @Override 501 public long sizeOf() { 502 return ArrayUtil.sizeOf(list); 503 } 504 505 @Override 506 public Object get(PageContext pc, Key key, Object defaultValue) { 507 return get(key, defaultValue); 508 } 509 510 @Override 511 public Object get(PageContext pc, Key key) throws PageException { 512 return get(key); 513 } 514 515 @Override 516 public Object set(PageContext pc, Key propertyName, Object value) throws PageException { 517 return set(propertyName, value); 518 } 519 520 @Override 521 public Object setEL(PageContext pc, Key propertyName, Object value) { 522 return setEL(propertyName, value); 523 } 524 525 @Override 526 public Object call(PageContext pc, Key methodName, Object[] args) throws PageException { 527 return MemberUtil.call(pc, this, methodName, args, CFTypes.TYPE_ARRAY, "array"); 528 } 529 530 @Override 531 public Object callWithNamedValues(PageContext pc, Key methodName, Struct args) throws PageException { 532 return MemberUtil.callWithNamedValues(pc,this,methodName,args, CFTypes.TYPE_ARRAY, "array"); 533 } 534 535 @Override 536 public java.util.Iterator<Object> getIterator() { 537 return valueIterator(); 538 } 539 }