001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019package lucee.runtime.type; 020 021import java.util.ArrayList; 022import java.util.Comparator; 023import java.util.Date; 024import java.util.Iterator; 025import java.util.List; 026import java.util.Map.Entry; 027 028import lucee.commons.lang.ExceptionUtil; 029import lucee.commons.lang.SizeOf; 030import lucee.runtime.PageContext; 031import lucee.runtime.config.NullSupportHelper; 032import lucee.runtime.dump.DumpData; 033import lucee.runtime.dump.DumpProperties; 034import lucee.runtime.dump.DumpUtil; 035import lucee.runtime.engine.ThreadLocalPageContext; 036import lucee.runtime.exp.DatabaseException; 037import lucee.runtime.exp.DeprecatedException; 038import lucee.runtime.exp.ExpressionException; 039import lucee.runtime.exp.PageException; 040import lucee.runtime.exp.PageRuntimeException; 041import lucee.runtime.op.Caster; 042import lucee.runtime.op.Duplicator; 043import lucee.runtime.op.Operator; 044import lucee.runtime.op.ThreadLocalDuplication; 045import lucee.runtime.op.date.DateCaster; 046import lucee.runtime.reflection.Reflector; 047import lucee.runtime.reflection.pairs.MethodInstance; 048import lucee.runtime.type.dt.DateTime; 049import lucee.runtime.type.it.EntryIterator; 050import lucee.runtime.type.it.KeyIterator; 051import lucee.runtime.type.it.StringIterator; 052import lucee.runtime.type.scope.Undefined; 053import lucee.runtime.type.util.CollectionUtil; 054import lucee.runtime.type.util.QueryUtil; 055import lucee.runtime.util.ArrayIterator; 056 057/** 058 * implementation of the query column 059 */ 060public class QueryColumnImpl implements QueryColumnPro,Sizeable,Objects { 061 062 private static final long serialVersionUID = -5544446523204021493L; 063 private static final int CAPACITY=32; 064 065 protected int type; 066 protected int size; 067 protected Object[] data; 068 069 protected boolean typeChecked=false; 070 protected QueryImpl query; 071 protected Collection.Key key; 072 073 /** 074 * constructor with type 075 * @param query 076 * @param key 077 * @param type 078 */ 079 public QueryColumnImpl(QueryImpl query, Collection.Key key, int type) { 080 this.data=new Object[CAPACITY]; 081 this.type=type; 082 this.key=key; 083 this.query=query; 084 } 085 086 /** 087 * constructor with array 088 * @param query 089 * @param array 090 * @param type 091 */ 092 public QueryColumnImpl(QueryImpl query, Collection.Key key, Array array,int type) { 093 data=array.toArray(); 094 size=array.size(); 095 this.type=type; 096 this.query=query; 097 this.key=key; 098 } 099 100 /** 101 * @param query 102 * @param type type as (java.sql.Types.XYZ) int 103 * @param size 104 */ 105 public QueryColumnImpl(QueryImpl query, Collection.Key key, int type, int size) { 106 this.data=new Object[size]; 107 this.type=type; 108 this.size=size; 109 this.query=query; 110 this.key=key; 111 } 112 113 114 /** 115 * Constructor of the class 116 * for internal usage only 117 */ 118 public QueryColumnImpl() { 119 } 120 121 @Override 122 public int size() { 123 return size; 124 } 125 126 @Override 127 public Collection.Key[] keys() { 128 Collection.Key[] k=new Collection.Key[size()]; 129 int len=k.length; 130 for(int i=1;i<=len;i++) { 131 k[i-1]=KeyImpl.init(Caster.toString(i)); 132 } 133 return k; 134 } 135 136 @Override 137 public Object remove(Collection.Key key) throws PageException { 138 resetType(); 139 return set(Caster.toIntValue(key.getString()),""); 140 } 141 142 @Override 143 public Object remove(int row) throws DatabaseException { 144 // query.disconnectCache(); 145 resetType(); 146 return set(row,""); 147 } 148 149 150 @Override 151 public Object removeEL(Collection.Key key) { 152 // query.disconnectCache(); 153 resetType(); 154 return setEL(Caster.toIntValue(key.getString(),-1),""); 155 } 156 157 @Override 158 public Object removeEL(int row) { 159 // query.disconnectCache(); 160 resetType(); 161 return setEL(row,""); 162 } 163 164 @Override 165 public synchronized void clear() { 166 // query.disconnectCache(); 167 resetType(); 168 data=new Object[CAPACITY]; 169 size=0; 170 } 171 172 @Override 173 public Object remove(PageContext pc) throws PageException { 174 return remove(query.getCurrentrow(pc.getId())); 175 } 176 177 public Object removeEL(PageContext pc) { 178 return removeEL(query.getCurrentrow(pc.getId())); 179 } 180 181 @Override 182 public Object get(String key) throws PageException { 183 return get(KeyImpl.init(key)); 184 } 185 186 @Override 187 public Object get(Key key) throws PageException { 188 return get((PageContext)null,key); 189 } 190 191 @Override 192 public Object get(PageContext pc, Collection.Key key) throws PageException { 193 int row=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 194 if(row==Integer.MIN_VALUE) { 195 Object child=getChildElement(pc,key,NullSupportHelper.NULL()); 196 if(child!=NullSupportHelper.NULL()) return child; 197 throw new DatabaseException("key ["+key+"] not found",null,null,null); 198 } 199 return QueryUtil.getValue(this,row); 200 } 201 202 private Object getChildElement(PageContext pc,Key key, Object defaultValue) {// pc maybe null 203 // column and query has same name 204 if(key.equals(this.key)) { 205 return query.get(key,defaultValue); 206 } 207 // get it from undefined scope 208 pc = ThreadLocalPageContext.get(pc); 209 if(pc!=null){ 210 Undefined undefined = pc.undefinedScope(); 211 boolean old = undefined.setAllowImplicidQueryCall(false); 212 Object sister = undefined.get(this.key,NullSupportHelper.NULL()); 213 undefined.setAllowImplicidQueryCall(old); 214 if(sister!=NullSupportHelper.NULL()){ 215 try { 216 return pc.get(sister, key); 217 } catch (PageException e) { 218 return defaultValue; 219 } 220 } 221 } 222 return defaultValue; 223 } 224 225 /** 226 * touch the given line on the column at given row 227 * @param row 228 * @return new row or existing 229 * @throws DatabaseException 230 */ 231 public Object touch(int row) { 232 if(row<1 || row>size) return NullSupportHelper.full()?null:""; 233 Object o=data[row-1]; 234 if(o!=null) return o; 235 return setEL(row,new StructImpl()); 236 } 237 238 /** 239 * touch the given line on the column at given row 240 * @param row 241 * @return new row or existing 242 * @throws DatabaseException 243 */ 244 public Object touchEL(int row) { 245 return touch(row); 246 } 247 248 @Override 249 public Object get(Key key, Object defaultValue) { 250 return get(null,key,defaultValue); 251 } 252 253 @Override 254 public Object get(PageContext pc, Collection.Key key, Object defaultValue) {// pc maybe null 255 int row=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 256 if(row==Integer.MIN_VALUE) { 257 return getChildElement(pc,key, defaultValue); 258 } 259 return get(row,defaultValue); 260 } 261 262 @Override 263 public Object get(String key, Object defaultValue) { 264 return get(KeyImpl.init(key),defaultValue); 265 } 266 267 @Override 268 public Object get(int row) throws DeprecatedException { 269 throw new DeprecatedException("this method is no longer supported, use instead get(int,Object)"); 270 //return QueryUtil.getValue(this,row); 271 } 272 273 @Override 274 public Object get(int row, Object emptyValue) { 275 if(row<1 || row>size) return emptyValue; 276 return data[row-1]==null?emptyValue:data[row-1]; 277 } 278 279 @Override 280 public Object set(String key, Object value) throws PageException { 281 int row=Caster.toIntValue(key,Integer.MIN_VALUE); 282 if(row==Integer.MIN_VALUE)return query.set(key,value); 283 return set(row,value); 284 } 285 286 public Object set(Collection.Key key, Object value) throws PageException { 287 int row=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 288 if(row==Integer.MIN_VALUE)return query.set(key,value); 289 return set(row,value); 290 } 291 292 @Override 293 public synchronized Object set(int row, Object value) throws DatabaseException { 294 // query.disconnectCache(); 295 if(row<1) throw new DatabaseException("invalid row number ["+row+"]","valid row numbers a greater or equal to one",null,null); 296 if(row>size) { 297 if(size==0)throw new DatabaseException("cannot set a value to a empty query, you first have to add a row",null,null,null); 298 throw new DatabaseException("invalid row number ["+row+"]","valid row numbers goes from 1 to "+size,null,null); 299 } 300 301 value=reDefineType(value); 302 data[row-1]=value; 303 return value; 304 } 305 @Override 306 public synchronized Object setEL(String key, Object value) { 307 int index=Caster.toIntValue(key,Integer.MIN_VALUE); 308 if(index==Integer.MIN_VALUE) query.setEL(key,value); 309 return setEL(index, value); 310 311 } 312 313 public Object setEL(Collection.Key key, Object value) { 314 int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE); 315 if(index==Integer.MIN_VALUE) query.setEL(key,value); 316 return setEL(index, value); 317 } 318 319 @Override 320 public synchronized Object setEL(int row, Object value) { 321 // query.disconnectCache(); 322 if(row<1 || row>size) return value; 323 324 value=reDefineType(value); 325 data[row-1]=value; 326 return value; 327 } 328 329 @Override 330 public synchronized void add(Object value) { 331 // query.disconnectCache(); 332 if(data.length<=size) growTo(size); 333 data[size++]=value; 334 } 335 336 @Override 337 public synchronized void cutRowsTo(int maxrows) { 338 // query.disconnectCache(); 339 if(maxrows>-1 && maxrows<size)size=maxrows; 340 } 341 342 @Override 343 public synchronized void addRow(int count) { 344 // query.disconnectCache(); 345 if(data.length<(size+count)) growTo(size+count); 346 for(int i=0;i<count;i++)size++; 347 } 348 349 public synchronized Object removeRow(int row) throws DatabaseException { 350 // query.disconnectCache(); 351 if(row<1 || row>size) 352 throw new DatabaseException("invalid row number ["+row+"]","valid rows goes from 1 to "+size,null,null); 353 Object o=data[row-1]; 354 for(int i=row;i<size;i++) { 355 data[i-1]=data[i]; 356 } 357 size--; 358 if(NullSupportHelper.full()) return o; 359 return o==null?"":o; 360 } 361 362 @Override 363 public int getType() { 364 reOrganizeType(); 365 return type; 366 } 367 368 369 @Override 370 public String getTypeAsString() { 371 return QueryImpl.getColumTypeName(getType()); 372 } 373 374 375 @Override 376 public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) { 377 return DumpUtil.toDumpData(QueryUtil.getValue(this,query.getCurrentrow(pageContext.getId())), pageContext,maxlevel,dp); 378 } 379 380 private synchronized void growTo(int row) { 381 382 int newSize=(data.length+1)*2; 383 while(newSize<=row) { 384 //print.ln(newSize+"<="+row); 385 newSize*=2; 386 } 387 388 Object[] newData=new Object[newSize]; 389 for(int i=0;i<data.length;i++) { 390 newData[i]=data[i]; 391 } 392 data=newData; 393 } 394 395 private Object reDefineType(Object value) { 396 return QueryColumnUtil.reDefineType(this,value); 397 } 398 399 private synchronized void resetType() { 400 QueryColumnUtil.resetType(this); 401 } 402 403 private synchronized void reOrganizeType() { 404 QueryColumnUtil.reOrganizeType(this); 405 } 406 407 public Collection.Key getKey() { 408 return key; 409 } 410 public void setKey(Collection.Key key) { 411 this.key = key; 412 } 413 414 @Override 415 public String getKeyAsString() throws PageException { 416 return key.getLowerString();// TODO ist das OK? 417 } 418 419 @Override 420 public Object get(PageContext pc) { 421 return QueryUtil.getValue(this,query.getCurrentrow(pc.getId())); 422 } 423 424 @Override 425 public Object get(PageContext pc, Object defaultValue) { 426 return get(query.getCurrentrow(pc.getId()),defaultValue); 427 } 428 429 @Override 430 public Object touch(PageContext pc) throws PageException { 431 return touch(query.getCurrentrow(pc.getId())); 432 } 433 434 public Object touchEL(PageContext pc) { 435 return touchEL(query.getCurrentrow(pc.getId())); 436 } 437 438 @Override 439 public Object set(PageContext pc, Object value) throws PageException { 440 return set(query.getCurrentrow(pc.getId()),value); 441 } 442 443 @Override 444 public Object setEL(PageContext pc, Object value) { 445 return setEL(query.getCurrentrow(pc.getId()),value); 446 } 447 448 @Override 449 public Object getParent() { 450 return query; 451 } 452 453 @Override 454 public String castToString() throws PageException { 455 return Caster.toString(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null)); 456 } 457 458 @Override 459 public String castToString(String defaultValue) { 460 Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL()); 461 if(value==NullSupportHelper.NULL()) return defaultValue; 462 return Caster.toString(value,defaultValue); 463 } 464 465 @Override 466 public boolean castToBooleanValue() throws PageException { 467 return Caster.toBooleanValue(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null)); 468 } 469 470 @Override 471 public Boolean castToBoolean(Boolean defaultValue) { 472 Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL()); 473 if(value==NullSupportHelper.NULL()) return defaultValue; 474 return Caster.toBoolean(value,defaultValue); 475 } 476 477 @Override 478 public double castToDoubleValue() throws PageException { 479 return Caster.toDoubleValue(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null)); 480 } 481 482 @Override 483 public double castToDoubleValue(double defaultValue) { 484 Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL()); 485 if(value==NullSupportHelper.NULL()) return defaultValue; 486 return Caster.toDoubleValue(value,true,defaultValue); 487 } 488 489 @Override 490 public DateTime castToDateTime() throws PageException { 491 return DateCaster.toDateAdvanced(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null),null); 492 } 493 494 @Override 495 public DateTime castToDateTime(DateTime defaultValue) { 496 Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL()); 497 if(value==NullSupportHelper.NULL()) return defaultValue; 498 return DateCaster.toDateAdvanced(value,DateCaster.CONVERTING_TYPE_OFFSET,null,defaultValue); 499 } 500 501 502 @Override 503 public int compareTo(boolean b) throws PageException { 504 return Operator.compare(castToBooleanValue(), b); 505 } 506 507 @Override 508 public int compareTo(DateTime dt) throws PageException { 509 return Operator.compare((Date)castToDateTime(), (Date)dt); 510 } 511 512 @Override 513 public int compareTo(double d) throws PageException { 514 return Operator.compare(castToDoubleValue(), d); 515 } 516 517 @Override 518 public int compareTo(String str) throws PageException { 519 return Operator.compare(castToString(), str); 520 } 521 522 @Override 523 public synchronized Object clone() { 524 return duplicate(true); 525 } 526 527 public synchronized Collection duplicate(boolean deepCopy) { 528 return cloneColumn(query,deepCopy); 529 } 530 531 public synchronized QueryColumnPro cloneColumn(Query query, boolean deepCopy) { 532 return cloneColumnImpl(deepCopy); 533 } 534 535 public synchronized QueryColumnImpl cloneColumnImpl(boolean deepCopy) { 536 QueryColumnImpl clone=new QueryColumnImpl(); 537 populate(this, clone, deepCopy); 538 return clone; 539 } 540 541 protected static void populate(QueryColumnImpl src,QueryColumnImpl trg, boolean deepCopy) { 542 543 boolean inside=ThreadLocalDuplication.set(src, trg); 544 try{ 545 trg.key=src.key; 546 trg.query=src.query; 547 trg.size=src.size; 548 trg.type=src.type; 549 trg.key=src.key; 550 551 trg.data=new Object[src.data.length]; 552 for(int i=0;i<src.data.length;i++) { 553 trg.data[i]=deepCopy?Duplicator.duplicate(src.data[i],true):src.data[i]; 554 } 555 } 556 finally { 557 if(!inside)ThreadLocalDuplication.reset(); 558 } 559 } 560 561 562 @Override 563 public String toString() { 564 try { 565 return Caster.toString(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null)); 566 } catch (PageException e) { 567 return super.toString(); 568 } 569 } 570 571 @Override 572 public boolean containsKey(String key) { 573 return containsKey(KeyImpl.init(key)); 574 } 575 576 @Override 577 public boolean containsKey(Collection.Key key) { 578 return get(key,NullSupportHelper.NULL())!=NullSupportHelper.NULL(); 579 } 580 581 @Override 582 public long sizeOf() { 583 return SizeOf.size(key)+SizeOf.size(data); 584 } 585 586 public Iterator iterator() { 587 return keyIterator(); 588 } 589 590 @Override 591 public Iterator<Collection.Key> keyIterator() { 592 return new KeyIterator(keys()); 593 } 594 595 @Override 596 public Iterator<String> keysAsStringIterator() { 597 return new StringIterator(keys()); 598 } 599 600 @Override 601 public Iterator<Entry<Key, Object>> entryIterator() { 602 return new EntryIterator(this, keys()); 603 } 604 605 @Override 606 public Iterator<Object> valueIterator() { 607 return new ArrayIterator(data,0,size); 608 } 609 610 @Override 611 public Object callWithNamedValues(PageContext pc, Key methodName,Struct args) throws PageException { 612 613 throw new ExpressionException("No matching Method/Function ["+methodName+"] for call with named arguments found"); 614 //return pc.getFunctionWithNamedValues(get(query.getCurrentrow()), methodName, Caster.toFunctionValues(args)); 615 } 616 617 @Override 618 public Object call(PageContext pc, Key methodName, Object[] arguments) throws PageException { 619 MethodInstance mi = Reflector.getMethodInstanceEL(this,this.getClass(), methodName, arguments); 620 if(mi!=null) { 621 try { 622 return mi.invoke(this); 623 } catch (Throwable t) { 624 ExceptionUtil.rethrowIfNecessary(t); 625 try { 626 return pc.getFunction(QueryUtil.getValue(this,query.getCurrentrow(pc.getId())), methodName, arguments); 627 } catch (PageException pe) { 628 throw Caster.toPageException(t); 629 } 630 } 631 } 632 return pc.getFunction(QueryUtil.getValue(this,query.getCurrentrow(pc.getId())), methodName, arguments); 633 } 634 635 @Override 636 public Object set(PageContext pc, Key propertyName, Object value) throws PageException { 637 return set(propertyName, value); 638 } 639 640 @Override 641 public Object setEL(PageContext pc, Key propertyName, Object value) { 642 return setEL(propertyName, value); 643 } 644 645 public void add(int index, Object element) { 646 throwNotAllowedToAlter(); 647 //setEL(index+1, element); 648 } 649 650 private void throwNotAllowedToAlter() { 651 throw new PageRuntimeException(new DatabaseException( 652 "Query columns do not support methods that would alter the structure of a query column" 653 ,"you must use an analogous method on the query" 654 ,null 655 ,null)); 656 657 } 658 659 public boolean addAll(java.util.Collection<? extends Object> c) { 660 throwNotAllowedToAlter(); 661 return false; 662 /*Iterator<? extends Object> it = c.iterator(); 663 while(it.hasNext()){ 664 add(it.next()); 665 } 666 return true;*/ 667 } 668 669 public boolean addAll(int index, java.util.Collection<? extends Object> c) { 670 throwNotAllowedToAlter(); 671 return false; 672 /*Iterator<? extends Object> it = c.iterator(); 673 while(it.hasNext()){ 674 setEL(++index,it.next()); 675 } 676 return true;*/ 677 } 678 679 public boolean contains(Object o) { 680 return indexOf(o)!=-1; 681 } 682 683 public boolean containsAll(java.util.Collection<?> c) { 684 Iterator<? extends Object> it = c.iterator(); 685 while(it.hasNext()){ 686 if(indexOf(it.next())==-1) return false; 687 } 688 return true; 689 } 690 691 public int indexOf(Object o) { 692 for(int i=0;i<size;i++){ 693 try { 694 if(Operator.compare(o, data[i])==0) return i; 695 } 696 catch (PageException e) {} 697 } 698 return -1; 699 } 700 701 public int lastIndexOf(Object o) { 702 for(int i=size-1;i>=0;i--){ 703 try { 704 if(Operator.compare(o, data[i])==0) return i; 705 } 706 catch (PageException e) {} 707 } 708 return -1; 709 } 710 711 public boolean isEmpty() { 712 return size()==0; 713 } 714 715 public boolean removeAll(java.util.Collection<?> c) { 716 throwNotAllowedToAlter(); 717 return false; 718 /*boolean hasChanged=false; 719 Iterator<? extends Object> it = c.iterator(); 720 while(it.hasNext()){ 721 if(remove(it.next())) { 722 hasChanged=true; 723 } 724 } 725 return hasChanged;*/ 726 } 727 728 public boolean retainAll(java.util.Collection<?> c) { 729 throwNotAllowedToAlter(); 730 return false; 731 /*boolean hasChanged=false; 732 Iterator it = valueIterator(); 733 while(it.hasNext()){ 734 if(!c.contains(it.next())){ 735 hasChanged=true; 736 it.remove(); 737 } 738 } 739 return hasChanged;*/ 740 } 741 742 public List<Object> subList(int fromIndex, int toIndex) { 743 ArrayList<Object> list=new ArrayList<Object>(); 744 for(int i=fromIndex;i<toIndex;i++){ 745 list.add(data[i]); 746 } 747 return list; 748 } 749 750 public Object[] toArray() { 751 return toArray(new Object[size()]); 752 } 753 754 public Object[] toArray(Object[] trg) { 755 System.arraycopy(data, 0, trg, 0, data.length>trg.length?trg.length:data.length); 756 return trg; 757 } 758 759 @Override 760 public QueryColumnPro toDebugColumn() { 761 return _toDebugColumn(); 762 } 763 764 public DebugQueryColumn _toDebugColumn() { 765 return new DebugQueryColumn(data,key,query,size,type,typeChecked); 766 } 767 768 @Override 769 public java.util.Iterator<String> getIterator() { 770 return keysAsStringIterator(); 771 } 772 773 @Override 774 public boolean equals(Object obj){ 775 if(!(obj instanceof Collection)) return false; 776 return CollectionUtil.equals(this,(Collection)obj); 777 } 778 779 @Override 780 public int getDimension() { 781 return 1; 782 } 783 784 @Override 785 public Object getE(int row) throws PageException { 786 return get(row); 787 } 788 789 @Override 790 public Object setE(int key, Object value) throws PageException { 791 return set(key, value); 792 } 793 794 @Override 795 public int[] intKeys() { 796 int[] keys=new int[size()]; 797 int len=keys.length; 798 for(int i=1;i<=len;i++) { 799 keys[i-1]=i; 800 } 801 return keys; 802 } 803 804 @Override 805 public boolean insert(int key, Object value) throws PageException { 806 throwNotAllowedToAlter(); 807 return false; 808 } 809 810 @Override 811 public Object append(Object o) throws PageException { 812 throwNotAllowedToAlter(); 813 return o; 814 } 815 816 @Override 817 public Object appendEL(Object o) { 818 throwNotAllowedToAlter(); 819 return o; 820 } 821 822 @Override 823 public Object prepend(Object o) throws PageException { 824 throwNotAllowedToAlter(); 825 return o; 826 } 827 828 @Override 829 public void resize(int to) throws PageException { 830 throwNotAllowedToAlter(); 831 } 832 833 @Override 834 public void sort(String sortType, String sortOrder) throws PageException { 835 throwNotAllowedToAlter(); 836 } 837 838 @Override 839 public void sort(Comparator comp) { 840 throwNotAllowedToAlter(); 841 } 842 843 @Override 844 public List toList() { 845 Iterator<Object> it = valueIterator(); 846 ArrayList list=new ArrayList(); 847 while(it.hasNext()){ 848 list.add(it.next()); 849 } 850 return list; 851 } 852 853 @Override 854 public Object removeE(int key) throws PageException { 855 throwNotAllowedToAlter(); 856 return null; 857 } 858 859 @Override 860 public boolean containsKey(int key) { 861 return get(key,NullSupportHelper.NULL())!=NullSupportHelper.NULL(); 862 } 863 864 /*@Override 865 public int hashCode() { 866 return CollectionUtil.hashCode(this); 867 }*/ 868}