001 package railo.runtime.type.util; 002 003 import java.sql.Types; 004 import java.text.Collator; 005 import java.util.ArrayList; 006 import java.util.Comparator; 007 import java.util.Iterator; 008 import java.util.List; 009 import java.util.ListIterator; 010 import java.util.Map; 011 import java.util.Set; 012 013 import railo.commons.lang.ArrayUtilException; 014 import railo.commons.lang.SizeOf; 015 import railo.commons.lang.StringUtil; 016 import railo.runtime.PageContext; 017 import railo.runtime.engine.ThreadLocalPageContext; 018 import railo.runtime.exp.CasterException; 019 import railo.runtime.exp.ExpressionException; 020 import railo.runtime.exp.PageException; 021 import railo.runtime.op.Caster; 022 import railo.runtime.op.Decision; 023 import railo.runtime.op.Operator; 024 import railo.runtime.type.Array; 025 import railo.runtime.type.QueryColumn; 026 import railo.runtime.type.comparator.NumberComparator; 027 import railo.runtime.type.comparator.SortRegister; 028 import railo.runtime.type.comparator.TextComparator; 029 030 /** 031 * Util for diffrent methods to manipulate arrays 032 */ 033 public final class ArrayUtil { 034 035 public static final Object[] OBJECT_EMPTY = new Object[]{}; 036 037 /** 038 * trims all value of a String Array 039 * @param arr 040 * @return trimmed array 041 */ 042 public static String[] trim(String[] arr) { 043 for(int i=0;i<arr.length;i++) { 044 arr[i]=arr[i].trim(); 045 } 046 return arr; 047 } 048 049 050 /** 051 * @param list 052 * @return array 053 */ 054 public static SortRegister[] toSortRegisterArray(ArrayList list) { 055 SortRegister[] arr=new SortRegister[list.size()]; 056 for(int i=0;i<arr.length;i++) { 057 arr[i]=new SortRegister(i,list.get(i)); 058 } 059 return arr; 060 } 061 062 /** 063 * @param column 064 * @return array 065 */ 066 public static SortRegister[] toSortRegisterArray(QueryColumn column) { 067 SortRegister[] arr=new SortRegister[column.size()]; 068 int type = column.getType(); 069 for(int i=0;i<arr.length;i++) { 070 arr[i]=new SortRegister(i,toSortRegisterArray(column.get(i+1,null),type)); 071 } 072 return arr; 073 } 074 075 private static Object toSortRegisterArray(Object value, int type) { 076 077 Object mod=null; 078 // Date 079 if(Types.TIMESTAMP==type) { 080 mod= Caster.toDate(value, true, null,null); 081 } 082 // Double 083 else if(Types.DOUBLE==type) { 084 mod= Caster.toDouble(value,null); 085 } 086 // Boolean 087 else if(Types.BOOLEAN==type) { 088 mod= Caster.toBoolean(value,null); 089 } 090 // Varchar 091 else if(Types.VARCHAR==type) { 092 mod= Caster.toString(value,null); 093 } 094 else return value; 095 096 if(mod!=null) return mod; 097 return value; 098 } 099 100 /** 101 * swap to values of the array 102 * @param array 103 * @param left left value to swap 104 * @param right right value to swap 105 * @throws ExpressionException 106 */ 107 public static void swap(Array array, int left, int right) throws ExpressionException { 108 int len=array.size(); 109 if(len==0) 110 throw new ExpressionException("array is empty"); 111 if(left<1 || left>len) 112 throw new ExpressionException("invalid index ["+left+"]","valid indexes are from 1 to "+len); 113 if(right<1 || right>len) 114 throw new ExpressionException("invalid index ["+right+"]","valid indexes are from 1 to "+len); 115 116 try { 117 Object leftValue=array.get(left,null); 118 Object rightValue=array.get(right,null); 119 array.setE(left,rightValue); 120 array.setE(right,leftValue); 121 } catch (PageException e) { 122 throw new ExpressionException("can't swap values of array",e.getMessage()); 123 } 124 125 } 126 127 /** 128 * find a object in array 129 * @param array 130 * @param object object to find 131 * @return position in array or 0 132 */ 133 public static int find(Array array, Object object) { 134 int len=array.size(); 135 for(int i=1;i<=len;i++) { 136 Object tmp=array.get(i,null); 137 try { 138 if(tmp !=null && Operator.compare(object,tmp)==0) 139 return i; 140 } catch (PageException e) {} 141 } 142 return 0; 143 } 144 145 /** 146 * average of all values of the array, only work when all values are numeric 147 * @param array 148 * @return average of all values 149 * @throws ExpressionException 150 */ 151 public static double avg(Array array) throws ExpressionException { 152 if(array.size()==0)return 0; 153 return sum(array)/array.size(); 154 } 155 156 /** 157 * sum of all values of a array, only work when all values are numeric 158 * @param array Array 159 * @return sum of all values 160 * @throws ExpressionException 161 */ 162 public static double sum(Array array) throws ExpressionException { 163 if(array.getDimension()>1) 164 throw new ExpressionException("can only get sum/avg from 1 dimensional arrays"); 165 166 double rtn=0; 167 int len=array.size(); 168 //try { 169 for(int i=1;i<=len;i++) { 170 rtn+=_toDoubleValue(array,i); 171 } 172 /*} 173 catch (PageException e) { 174 throw new ExpressionException("exception while execute array operation: "+e.getMessage()); 175 }*/ 176 return rtn; 177 } 178 179 private static double _toDoubleValue(Array array, int i) throws ExpressionException { 180 Object obj = array.get(i,null); 181 if(obj==null)throw new ExpressionException("there is no element at position ["+i+"] or the element is null"); 182 double tmp = Caster.toDoubleValue(obj,Double.NaN); 183 if(Double.isNaN(tmp)) 184 throw new CasterException(obj,Double.class); 185 return tmp; 186 } 187 188 189 /** 190 * the smallest value, of all values inside the array, only work when all values are numeric 191 * @param array 192 * @return the smallest value 193 * @throws PageException 194 */ 195 public static double min(Array array) throws PageException { 196 if(array.getDimension()>1) 197 throw new ExpressionException("can only get max value from 1 dimensional arrays"); 198 if(array.size()==0) return 0; 199 200 double rtn=_toDoubleValue(array,1); 201 int len=array.size(); 202 try { 203 for(int i=2;i<=len;i++) { 204 double v=_toDoubleValue(array,i); 205 if(rtn>v)rtn=v; 206 207 } 208 } catch (PageException e) { 209 throw new ExpressionException("exception while execute array operation: "+e.getMessage()); 210 } 211 return rtn; 212 } 213 214 /** 215 * the greatest value, of all values inside the array, only work when all values are numeric 216 * @param array 217 * @return the greatest value 218 * @throws PageException 219 */ 220 public static double max(Array array) throws PageException { 221 if(array.getDimension()>1) 222 throw new ExpressionException("can only get max value from 1 dimensional arrays"); 223 if(array.size()==0) return 0; 224 225 double rtn=_toDoubleValue(array,1); 226 int len=array.size(); 227 try { 228 for(int i=2;i<=len;i++) { 229 double v=_toDoubleValue(array,i); 230 if(rtn<v)rtn=v; 231 232 } 233 } catch (PageException e) { 234 throw new ExpressionException("exception while execute array operation: "+e.getMessage()); 235 } 236 return rtn; 237 } 238 239 /** 240 * return index of given value in Array or -1 241 * @param arr 242 * @param value 243 * @return index of position in array 244 */ 245 public static int indexOf(String[] arr, String value) { 246 for(int i=0;i<arr.length;i++) { 247 if(arr[i].equals(value)) return i; 248 } 249 return -1; 250 } 251 252 /** 253 * return index of given value in Array or -1 254 * @param arr 255 * @param value 256 * @return index of position in array 257 */ 258 public static int indexOfIgnoreCase(String[] arr, String value) { 259 for(int i=0;i<arr.length;i++) { 260 if(arr[i].equalsIgnoreCase(value)) return i; 261 } 262 return -1; 263 } 264 265 266 267 /** 268 * convert a primitive array (value type) to Object Array (reference type). 269 * @param primArr value type Array 270 * @return reference type Array 271 */ 272 public static Boolean[] toReferenceType(boolean[] primArr) { 273 Boolean[] refArr=new Boolean[primArr.length]; 274 for(int i=0;i<primArr.length;i++)refArr[i]=Caster.toBoolean(primArr[i]); 275 return refArr; 276 } 277 278 /** 279 * convert a primitive array (value type) to Object Array (reference type). 280 * @param primArr value type Array 281 * @return reference type Array 282 */ 283 public static Byte[] toReferenceType(byte[] primArr) { 284 Byte[] refArr=new Byte[primArr.length]; 285 for(int i=0;i<primArr.length;i++)refArr[i]=new Byte(primArr[i]); 286 return refArr; 287 } 288 289 /** 290 * convert a primitive array (value type) to Object Array (reference type). 291 * @param primArr value type Array 292 * @return reference type Array 293 */ 294 public static Character[] toReferenceType(char[] primArr) { 295 Character[] refArr=new Character[primArr.length]; 296 for(int i=0;i<primArr.length;i++)refArr[i]=new Character(primArr[i]); 297 return refArr; 298 } 299 300 /** 301 * convert a primitive array (value type) to Object Array (reference type). 302 * @param primArr value type Array 303 * @return reference type Array 304 */ 305 public static Short[] toReferenceType(short[] primArr) { 306 Short[] refArr=new Short[primArr.length]; 307 for(int i=0;i<primArr.length;i++)refArr[i]=Short.valueOf(primArr[i]); 308 return refArr; 309 } 310 311 /** 312 * convert a primitive array (value type) to Object Array (reference type). 313 * @param primArr value type Array 314 * @return reference type Array 315 */ 316 public static Integer[] toReferenceType(int[] primArr) { 317 Integer[] refArr=new Integer[primArr.length]; 318 for(int i=0;i<primArr.length;i++)refArr[i]=Integer.valueOf(primArr[i]); 319 return refArr; 320 } 321 322 /** 323 * convert a primitive array (value type) to Object Array (reference type). 324 * @param primArr value type Array 325 * @return reference type Array 326 */ 327 public static Long[] toReferenceType(long[] primArr) { 328 Long[] refArr=new Long[primArr.length]; 329 for(int i=0;i<primArr.length;i++)refArr[i]=Long.valueOf(primArr[i]); 330 return refArr; 331 } 332 333 /** 334 * convert a primitive array (value type) to Object Array (reference type). 335 * @param primArr value type Array 336 * @return reference type Array 337 */ 338 public static Float[] toReferenceType(float[] primArr) { 339 Float[] refArr=new Float[primArr.length]; 340 for(int i=0;i<primArr.length;i++)refArr[i]=new Float(primArr[i]); 341 return refArr; 342 } 343 344 /** 345 * convert a primitive array (value type) to Object Array (reference type). 346 * @param primArr value type Array 347 * @return reference type Array 348 */ 349 public static Double[] toReferenceType(double[] primArr) { 350 Double[] refArr=new Double[primArr.length]; 351 for(int i=0;i<primArr.length;i++)refArr[i]=new Double(primArr[i]); 352 return refArr; 353 } 354 355 /** 356 * gets a value of a array at defined index 357 * @param o 358 * @param index 359 * @return value at index position 360 * @throws ArrayUtilException 361 */ 362 public static Object get(Object o,int index) throws ArrayUtilException { 363 o=get(o,index,null); 364 if(o!=null) return o; 365 throw new ArrayUtilException("Object is not a array, or index is invalid"); 366 } 367 368 /** 369 * gets a value of a array at defined index 370 * @param o 371 * @param index 372 * @return value of the variable 373 */ 374 public static Object get(Object o,int index, Object defaultValue) { 375 if(index<0) return null; 376 if(o instanceof Object[]) { 377 Object[] arr=((Object[])o); 378 if(arr.length>index)return arr[index]; 379 } 380 else if(o instanceof boolean[]) { 381 boolean[] arr=((boolean[])o); 382 if(arr.length>index)return arr[index]?Boolean.TRUE:Boolean.FALSE; 383 } 384 else if(o instanceof byte[]) { 385 byte[] arr=((byte[])o); 386 if(arr.length>index)return new Byte(arr[index]); 387 } 388 else if(o instanceof char[]) { 389 char[] arr=((char[])o); 390 if(arr.length>index)return ""+(arr[index]); 391 } 392 else if(o instanceof short[]) { 393 short[] arr=((short[])o); 394 if(arr.length>index)return Short.valueOf(arr[index]); 395 } 396 else if(o instanceof int[]) { 397 int[] arr=((int[])o); 398 if(arr.length>index)return Integer.valueOf(arr[index]); 399 } 400 else if(o instanceof long[]) { 401 long[] arr=((long[])o); 402 if(arr.length>index)return Long.valueOf(arr[index]); 403 } 404 else if(o instanceof float[]) { 405 float[] arr=((float[])o); 406 if(arr.length>index)return new Float(arr[index]); 407 } 408 else if(o instanceof double[]) { 409 double[] arr=((double[])o); 410 if(arr.length>index)return new Double(arr[index]); 411 } 412 return defaultValue; 413 } 414 415 /** 416 * sets a value to a array at defined index 417 * @param o 418 * @param index 419 * @param value 420 * @return value setted 421 * @throws ArrayUtilException 422 */ 423 public static Object set(Object o,int index, Object value) throws ArrayUtilException { 424 if(index<0) 425 throw invalidIndex(index,0); 426 if(o instanceof Object[]) { 427 Object[] arr=((Object[])o); 428 if(arr.length>index)return arr[index]=value; 429 throw invalidIndex(index,arr.length); 430 } 431 else if(o instanceof boolean[]) { 432 boolean[] arr=((boolean[])o); 433 if(arr.length>index) { 434 arr[index]=Caster.toBooleanValue(value,false); 435 return arr[index]?Boolean.TRUE:Boolean.FALSE; 436 } 437 throw invalidIndex(index,arr.length); 438 } 439 else if(o instanceof byte[]) { 440 byte[] arr=((byte[])o); 441 if(arr.length>index) { 442 double v=Caster.toDoubleValue(value,Double.NaN); 443 if(Decision.isValid(v)) { 444 return new Byte(arr[index]=(byte)v); 445 } 446 } 447 throw invalidIndex(index,arr.length); 448 } 449 else if(o instanceof short[]) { 450 short[] arr=((short[])o); 451 if(arr.length>index) { 452 double v=Caster.toDoubleValue(value,Double.NaN); 453 if(Decision.isValid(v)) { 454 return Short.valueOf(arr[index]=(short)v); 455 } 456 } 457 throw invalidIndex(index,arr.length); 458 } 459 else if(o instanceof int[]) { 460 int[] arr=((int[])o); 461 if(arr.length>index) { 462 double v=Caster.toDoubleValue(value,Double.NaN); 463 if(Decision.isValid(v)) { 464 return Integer.valueOf(arr[index]=(int)v); 465 } 466 } 467 throw invalidIndex(index,arr.length); 468 } 469 else if(o instanceof long[]) { 470 long[] arr=((long[])o); 471 if(arr.length>index) { 472 double v=Caster.toDoubleValue(value,Double.NaN); 473 if(Decision.isValid(v)) { 474 return Long.valueOf(arr[index]=(long)v); 475 } 476 } 477 throw invalidIndex(index,arr.length); 478 } 479 else if(o instanceof float[]) { 480 float[] arr=((float[])o); 481 if(arr.length>index) { 482 double v=Caster.toDoubleValue(value,Double.NaN); 483 if(Decision.isValid(v)) { 484 return new Float(arr[index]=(float)v); 485 } 486 } 487 throw invalidIndex(index,arr.length); 488 } 489 else if(o instanceof double[]) { 490 double[] arr=((double[])o); 491 if(arr.length>index) { 492 double v=Caster.toDoubleValue(value,Double.NaN); 493 if(Decision.isValid(v)) { 494 return new Double(arr[index]=v); 495 } 496 } 497 throw invalidIndex(index,arr.length); 498 } 499 else if(o instanceof char[]) { 500 char[] arr=((char[])o); 501 if(arr.length>index) { 502 String str=Caster.toString(value,null); 503 if(str!=null && str.length()>0) { 504 char c=str.charAt(0); 505 arr[index]=c; 506 return str; 507 } 508 } 509 throw invalidIndex(index,arr.length); 510 } 511 throw new ArrayUtilException("Object ["+Caster.toClassName(o)+"] is not a Array"); 512 } 513 514 515 private static ArrayUtilException invalidIndex(int index, int length) { 516 return new ArrayUtilException("Invalid index ["+index+"] for native Array call, Array has a Size of "+length); 517 } 518 519 /** 520 * sets a value to a array at defined index 521 * @param o 522 * @param index 523 * @param value 524 * @return value setted 525 */ 526 public static Object setEL(Object o,int index, Object value) { 527 try { 528 return set(o,index,value); 529 } catch (ArrayUtilException e) { 530 return null; 531 } 532 } 533 534 public static boolean isEmpty(List list) { 535 return list==null || list.isEmpty(); 536 } 537 538 public static boolean isEmpty(Object[] array) { 539 return array==null || array.length==0; 540 } 541 public static boolean isEmpty(boolean[] array) { 542 return array==null || array.length==0; 543 } 544 public static boolean isEmpty(char[] array) { 545 return array==null || array.length==0; 546 } 547 public static boolean isEmpty(double[] array) { 548 return array==null || array.length==0; 549 } 550 public static boolean isEmpty(long[] array) { 551 return array==null || array.length==0; 552 } 553 public static boolean isEmpty(int[] array) { 554 return array==null || array.length==0; 555 } 556 public static boolean isEmpty(float[] array) { 557 return array==null || array.length==0; 558 } 559 public static boolean isEmpty(byte[] array) { 560 return array==null || array.length==0; 561 } 562 563 564 565 566 567 568 569 570 571 572 public static int size(Object[] array) { 573 if(array==null) return 0; 574 return array.length; 575 } 576 public static int size(boolean[] array) { 577 if(array==null) return 0; 578 return array.length; 579 } 580 public static int size(char[] array) { 581 if(array==null) return 0; 582 return array.length; 583 } 584 public static int size(double[] array) { 585 if(array==null) return 0; 586 return array.length; 587 } 588 public static int size(long[] array) { 589 if(array==null) return 0; 590 return array.length; 591 } 592 public static int size(int[] array) { 593 if(array==null) return 0; 594 return array.length; 595 } 596 public static int size(float[] array) { 597 if(array==null) return 0; 598 return array.length; 599 } 600 public static int size(byte[] array) { 601 if(array==null) return 0; 602 return array.length; 603 } 604 605 606 public static boolean[] toBooleanArray(Object obj) throws PageException { 607 if(obj instanceof boolean[]) return (boolean[]) obj; 608 609 Array arr = Caster.toArray(obj); 610 boolean[] tarr=new boolean[arr.size()]; 611 for(int i=0;i<tarr.length;i++) { 612 tarr[i]=Caster.toBooleanValue(arr.getE(i+1)); 613 } 614 return tarr; 615 } 616 617 public static byte[] toByteArray(Object obj) throws PageException { 618 if(obj instanceof byte[]) return (byte[]) obj; 619 620 Array arr = Caster.toArray(obj); 621 byte[] tarr=new byte[arr.size()]; 622 for(int i=0;i<tarr.length;i++) { 623 tarr[i]=Caster.toByteValue(arr.getE(i+1)); 624 } 625 return tarr; 626 } 627 628 public static short[] toShortArray(Object obj) throws PageException { 629 if(obj instanceof short[]) return (short[]) obj; 630 631 Array arr = Caster.toArray(obj); 632 short[] tarr=new short[arr.size()]; 633 for(int i=0;i<tarr.length;i++) { 634 tarr[i]=Caster.toShortValue(arr.getE(i+1)); 635 } 636 return tarr; 637 } 638 639 public static int[] toIntArray(Object obj) throws PageException { 640 if(obj instanceof int[]) return (int[]) obj; 641 642 Array arr = Caster.toArray(obj); 643 int[] tarr=new int[arr.size()]; 644 for(int i=0;i<tarr.length;i++) { 645 tarr[i]=Caster.toIntValue(arr.getE(i+1)); 646 } 647 return tarr; 648 } 649 650 public static Object[] toNullArray(Object obj) throws PageException { 651 Array arr = Caster.toArray(obj); 652 Object[] tarr=new Object[arr.size()]; 653 for(int i=0;i<tarr.length;i++) { 654 tarr[i]=Caster.toNull(arr.getE(i+1)); 655 } 656 return tarr; 657 } 658 659 public static long[] toLongArray(Object obj) throws PageException { 660 if(obj instanceof long[]) return (long[]) obj; 661 662 Array arr = Caster.toArray(obj); 663 long[] tarr=new long[arr.size()]; 664 for(int i=0;i<tarr.length;i++) { 665 tarr[i]=Caster.toLongValue(arr.getE(i+1)); 666 } 667 return tarr; 668 } 669 670 public static float[] toFloatArray(Object obj) throws PageException { 671 if(obj instanceof float[]) return (float[]) obj; 672 673 Array arr = Caster.toArray(obj); 674 float[] tarr=new float[arr.size()]; 675 for(int i=0;i<tarr.length;i++) { 676 tarr[i]=Caster.toFloatValue(arr.getE(i+1)); 677 } 678 return tarr; 679 } 680 681 public static double[] toDoubleArray(Object obj) throws PageException { 682 if(obj instanceof double[]) return (double[]) obj; 683 684 Array arr = Caster.toArray(obj); 685 double[] tarr=new double[arr.size()]; 686 for(int i=0;i<tarr.length;i++) { 687 tarr[i]=Caster.toDoubleValue(arr.getE(i+1)); 688 } 689 return tarr; 690 } 691 692 public static char[] toCharArray(Object obj) throws PageException { 693 if(obj instanceof char[]) return (char[]) obj; 694 695 Array arr = Caster.toArray(obj); 696 char[] tarr=new char[arr.size()]; 697 for(int i=0;i<tarr.length;i++) { 698 tarr[i]=Caster.toCharValue(arr.getE(i+1)); 699 } 700 return tarr; 701 } 702 703 704 public static int arrayContainsIgnoreEmpty(Array arr, String value, boolean ignoreCase) { 705 int count=0; 706 int len=arr.size(); 707 708 for(int i=1;i<=len;i++) { 709 String item=arr.get(i,"").toString(); 710 if(ignoreCase) { 711 if(StringUtil.indexOfIgnoreCase(item,value)!=-1) return count; 712 } 713 else { 714 if(item.indexOf(value)!=-1) return count; 715 } 716 count++; 717 } 718 return -1; 719 } 720 721 722 public static Object[] toReferenceType(Object obj) throws CasterException { 723 Object[] ref = toReferenceType(obj,null); 724 if(ref!=null) return ref; 725 throw new CasterException(obj,Object[].class); 726 727 } 728 public static Object[] toReferenceType(Object obj,Object[] defaultValue) { 729 if(obj instanceof Object[]) return (Object[])obj; 730 else if(obj instanceof boolean[]) return toReferenceType((boolean[])obj); 731 else if(obj instanceof byte[]) return toReferenceType((byte[])obj); 732 else if(obj instanceof char[]) return toReferenceType((char[])obj); 733 else if(obj instanceof short[]) return toReferenceType((short[])obj); 734 else if(obj instanceof int[]) return toReferenceType((int[])obj); 735 else if(obj instanceof long[]) return toReferenceType((long[])obj); 736 else if(obj instanceof float[]) return toReferenceType((float[])obj); 737 else if(obj instanceof double[]) return toReferenceType((double[])obj); 738 return defaultValue; 739 } 740 741 742 public static Object[] clone(Object[] src, Object[] trg) { 743 for(int i=0;i<src.length;i++){ 744 trg[i]=src[i]; 745 } 746 return trg; 747 } 748 749 750 public static Object[] keys(Map map) { 751 if(map==null) return new Object[0]; 752 Set set = map.keySet(); 753 if(set==null) return new Object[0]; 754 Object[] arr = set.toArray(); 755 if(arr==null) return new Object[0]; 756 return arr; 757 } 758 759 public static Object[] values(Map map) { 760 if(map==null) return new Object[0]; 761 return map.values().toArray(); 762 } 763 764 765 public static long sizeOf(List list) { 766 ListIterator it = list.listIterator(); 767 long size=0; 768 while(it.hasNext()){ 769 size+=SizeOf.size(it.next()); 770 } 771 return size; 772 } 773 774 public static long sizeOf(Array array) { 775 Iterator it = array.valueIterator(); 776 long size=0; 777 while(it.hasNext()){ 778 size+=SizeOf.size(it.next()); 779 } 780 return size; 781 } 782 783 784 /** 785 * creates a native array out of the input list, if all values are from the same type, this type is used for the array, otherwise object 786 * @param list 787 */ 788 public static Object[] toArray(List<?> list) { 789 Iterator<?> it = list.iterator(); 790 Class clazz=null; 791 while(it.hasNext()){ 792 Object v = it.next(); 793 if(v==null) continue; 794 if(clazz==null) clazz=v.getClass(); 795 else if(clazz!=v.getClass()) return list.toArray(); 796 } 797 if(clazz==Object.class || clazz==null) 798 return list.toArray(); 799 800 Object arr = java.lang.reflect.Array.newInstance(clazz, list.size()); 801 return list.toArray((Object[]) arr); 802 } 803 804 805 public static Comparator toComparator(PageContext pc,String sortType, String sortOrder, boolean localeSensitive) throws PageException { 806 // check sortorder 807 boolean isAsc=true; 808 if(sortOrder.equalsIgnoreCase("asc"))isAsc=true; 809 else if(sortOrder.equalsIgnoreCase("desc"))isAsc=false; 810 else throw new ExpressionException("invalid sort order type ["+sortOrder+"], sort order types are [asc and desc]"); 811 812 // text 813 if(sortType.equalsIgnoreCase("text")) { 814 if(localeSensitive)return toCollator(pc,Collator.IDENTICAL); 815 return new TextComparator(isAsc,false); 816 } 817 // text no case 818 else if(sortType.equalsIgnoreCase("textnocase")) { 819 if(localeSensitive)return toCollator(pc,Collator.TERTIARY); 820 return new TextComparator(isAsc,true); 821 } 822 // numeric 823 else if(sortType.equalsIgnoreCase("numeric")) { 824 return new NumberComparator(isAsc); 825 } 826 else { 827 throw new ExpressionException("invalid sort type ["+sortType+"], sort types are [text, textNoCase, numeric]"); 828 } 829 } 830 private static Comparator toCollator(PageContext pc, int strength) { 831 Collator c=Collator.getInstance(ThreadLocalPageContext.getLocale(pc)); 832 c.setStrength(strength); 833 c.setDecomposition(Collator.CANONICAL_DECOMPOSITION); 834 return c; 835 } 836 }