1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.apache.myfaces.shared_orchestra.util; 20 21 import java.beans.PropertyEditor; 22 import java.beans.PropertyEditorManager; 23 import java.math.BigDecimal; 24 import java.math.BigInteger; 25 26 import javax.servlet.jsp.el.ELException; 27 28 import org.apache.commons.logging.Log; 29 import org.apache.commons.logging.LogFactory; 30 31 /** 32 * 33 * <p>This class contains the logic for coercing data types before 34 * operators are applied to them. 35 * 36 * <p>The following is the list of rules applied for various type 37 * conversions. 38 * 39 * <ul><pre> 40 * Applying arithmetic operator 41 * Binary operator - A {+,-,*} B 42 * if A and B are null 43 * return 0 44 * if A or B is BigDecimal, coerce both to BigDecimal and then: 45 * if operator is +, return <code>A.add(B)</code> 46 * if operator is -, return <code>A.subtract(B)</code> 47 * if operator is *, return <code>A.multiply(B)</code> 48 * if A or B is Float, Double, or String containing ".", "e", or "E" 49 * if A or B is BigInteger, coerce both A and B to BigDecimal and apply operator 50 * coerce both A and B to Double and apply operator 51 * if A or B is BigInteger, coerce both to BigInteger and then: 52 * if operator is +, return <code>A.add(B)</code> 53 * if operator is -, return <code>A.subtract(B)</code> 54 * if operator is *, return <code>A.multiply(B)</code> 55 * otherwise 56 * coerce both A and B to Long 57 * apply operator 58 * if operator results in exception (such as divide by 0), error 59 * 60 * Binary operator - A {/,div} B 61 * if A and B are null 62 * return 0 63 * if A or B is a BigDecimal or BigInteger, coerce both to BigDecimal and 64 * return <code>A.divide(B, BigDecimal.ROUND_HALF_UP)</code> 65 * otherwise 66 * coerce both A and B to Double 67 * apply operator 68 * if operator results in exception (such as divide by 0), error 69 * 70 * Binary operator - A {%,mod} B 71 * if A and B are null 72 * return 0 73 * if A or B is BigDecimal, Float, Double, or String containing ".", "e" or "E" 74 * coerce both to Double 75 * apply operator 76 * if A or B is BigInteger, coerce both to BigInteger and return 77 * <code>A.remainder(B)</code> 78 * otherwise 79 * coerce both A and B to Long 80 * apply operator 81 * if operator results in exception (such as divide by 0), error 82 * 83 * Unary minus operator - -A 84 * if A is null 85 * return 0 86 * if A is BigInteger or BigDecimal, return <code>A.negate()</code> 87 * if A is String 88 * if A contains ".", "e", or "E" 89 * coerce to Double, apply operator 90 * otherwise 91 * coerce to a Long and apply operator 92 * if A is Byte,Short,Integer,Long,Float,Double 93 * retain type, apply operator 94 * if operator results in exception, error 95 * otherwise 96 * error 97 * 98 * Applying "empty" operator - empty A 99 * if A is null 100 * return true 101 * if A is zero-length String 102 * return true 103 * if A is zero-length array 104 * return true 105 * if A is List and ((List) A).isEmpty() 106 * return true 107 * if A is Map and ((Map) A).isEmpty() 108 * return true 109 * if A is Collection an ((Collection) A).isEmpty() 110 * return true 111 * otherwise 112 * return false 113 * 114 * Applying logical operators 115 * Binary operator - A {and,or} B 116 * coerce both A and B to Boolean, apply operator 117 * NOTE - operator stops as soon as expression can be determined, i.e., 118 * A and B and C and D - if B is false, then only A and B is evaluated 119 * Unary not operator - not A 120 * coerce A to Boolean, apply operator 121 * 122 * Applying relational operator 123 * A {<,>,<=,>=,lt,gt,lte,gte} B 124 * if A==B 125 * if operator is >= or <= 126 * return true 127 * otherwise 128 * return false 129 * if A or B is null 130 * return false 131 * if A or B is BigDecimal, coerce both A and B to BigDecimal and use the 132 * return value of <code>A.compareTo(B)</code> 133 * if A or B is Float or Double 134 * coerce both A and B to Double 135 * apply operator 136 * if A or B is BigInteger, coerce both A and B to BigInteger and use the 137 * return value of <code>A.compareTo(B)</code> 138 * if A or B is Byte,Short,Character,Integer,Long 139 * coerce both A and B to Long 140 * apply operator 141 * if A or B is String 142 * coerce both A and B to String, compare lexically 143 * if A is Comparable 144 * if A.compareTo (B) throws exception 145 * error 146 * otherwise 147 * use result of A.compareTo(B) 148 * if B is Comparable 149 * if B.compareTo (A) throws exception 150 * error 151 * otherwise 152 * use result of B.compareTo(A) 153 * otherwise 154 * error 155 * 156 * Applying equality operator 157 * A {==,!=} B 158 * if A==B 159 * apply operator 160 * if A or B is null 161 * return false for ==, true for != 162 * if A or B is BigDecimal, coerce both A and B to BigDecimal and then: 163 * if operator is == or eq, return <code>A.equals(B)</code> 164 * if operator is != or ne, return <code>!A.equals(B)</code> 165 * if A or B is Float or Double 166 * coerce both A and B to Double 167 * apply operator 168 * if A or B is BigInteger, coerce both A and B to BigInteger and then: 169 * if operator is == or eq, return <code>A.equals(B)</code> 170 * if operator is != or ne, return <code>!A.equals(B)</code> 171 * if A or B is Byte,Short,Character,Integer,Long 172 * coerce both A and B to Long 173 * apply operator 174 * if A or B is Boolean 175 * coerce both A and B to Boolean 176 * apply operator 177 * if A or B is String 178 * coerce both A and B to String, compare lexically 179 * otherwise 180 * if an error occurs while calling A.equals(B) 181 * error 182 * apply operator to result of A.equals(B) 183 * 184 * coercions 185 * 186 * coerce A to String 187 * A is String 188 * return A 189 * A is null 190 * return "" 191 * A.toString throws exception 192 * error 193 * otherwise 194 * return A.toString 195 * 196 * coerce A to Number type N 197 * A is null or "" 198 * return 0 199 * A is Character 200 * convert to short, apply following rules 201 * A is Boolean 202 * error 203 * A is Number type N 204 * return A 205 * A is Number, coerce quietly to type N using the following algorithm 206 * If N is BigInteger 207 * If A is BigDecimal, return <code>A.toBigInteger()</code> 208 * Otherwise, return <code>BigInteger.valueOf(A.longValue())</code> 209 * if N is BigDecimal 210 * If A is a BigInteger, return <code>new BigDecimal(A)</code> 211 * Otherwise, return <code>new BigDecimal(A.doubleValue())</code> 212 * If N is Byte, return <code>new Byte(A.byteValue())</code> 213 * If N is Short, return <code>new Short(A.shortValue())</code> 214 * If N is Integer, return <code>new Integer(A.integerValue())</code> 215 * If N is Long, return <code>new Long(A.longValue())</code> 216 * If N is Float, return <code>new Float(A.floatValue())</code> 217 * If N is Double, return <code>new Double(A.doubleValue())</code> 218 * otherwise ERROR 219 * A is String 220 * If N is BigDecimal then: 221 * If <code>new BigDecimal(A)</code> throws an exception then ERROR 222 * Otherwise, return <code>new BigDecimal(A)</code> 223 * If N is BigInteger then: 224 * If <code>new BigInteger(A)</code> throws an exception, then ERROR 225 * Otherwise, return <code>new BigInteger(A)</code> 226 * new <code>N.valueOf(A)</code> throws exception 227 * error 228 * return <code>N.valueOf(A)</code> 229 * otherwise 230 * error 231 * 232 * coerce A to Character should be 233 * A is null or "" 234 * return (char) 0 235 * A is Character 236 * return A 237 * A is Boolean 238 * error 239 * A is Number with less precision than short 240 * coerce quietly - return (char) A 241 * A is Number with greater precision than short 242 * coerce quietly - return (char) A 243 * A is String 244 * return A.charAt (0) 245 * otherwise 246 * error 247 * 248 * coerce A to Boolean 249 * A is null or "" 250 * return false 251 * A is Boolean 252 * return A 253 * A is String 254 * Boolean.valueOf(A) throws exception 255 * error 256 * return Boolean.valueOf(A) 257 * otherwise 258 * error 259 * 260 * coerce A to any other type T 261 * A is null 262 * return null 263 * A is assignable to T 264 * coerce quietly 265 * A is String 266 * T has no PropertyEditor 267 * if A is "", return null 268 * otherwise error 269 * T's PropertyEditor throws exception 270 * if A is "", return null 271 * otherwise error 272 * otherwise 273 * apply T's PropertyEditor 274 * otherwise 275 * error 276 * </pre></ul> 277 * 278 * This is a copy from commons-el Coercions class. 279 * 280 * @author Nathan Abramson - Art Technology Group 281 * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author$ 282 **/ 283 284 class _Coercions 285 { 286 //------------------------------------- 287 // Constants 288 //------------------------------------- 289 private static final Number ZERO = new Integer(0); 290 private static Log log = LogFactory.getLog(_Coercions.class); 291 292 //------------------------------------- 293 /** 294 * 295 * Coerces the given value to the specified class. 296 **/ 297 public static Object coerce (Object pValue, 298 Class pClass) 299 throws ELException 300 { 301 if (pClass == String.class) { 302 return coerceToString (pValue); 303 } 304 else if (isNumberClass (pClass)) { 305 return coerceToPrimitiveNumber (pValue, pClass); 306 } 307 else if (pClass == Character.class || 308 pClass == Character.TYPE) { 309 return coerceToCharacter (pValue); 310 } 311 else if (pClass == Boolean.class || 312 pClass == Boolean.TYPE) { 313 return coerceToBoolean (pValue); 314 } 315 else { 316 return coerceToObject (pValue, pClass); 317 } 318 } 319 320 //------------------------------------- 321 /** 322 * 323 * Returns true if the given class is Byte, Short, Integer, Long, 324 * Float, Double, BigInteger, or BigDecimal 325 **/ 326 static boolean isNumberClass (Class pClass) 327 { 328 return 329 pClass == Byte.class || 330 pClass == Byte.TYPE || 331 pClass == Short.class || 332 pClass == Short.TYPE || 333 pClass == Integer.class || 334 pClass == Integer.TYPE || 335 pClass == Long.class || 336 pClass == Long.TYPE || 337 pClass == Float.class || 338 pClass == Float.TYPE || 339 pClass == Double.class || 340 pClass == Double.TYPE || 341 pClass == BigInteger.class || 342 pClass == BigDecimal.class; 343 } 344 345 //------------------------------------- 346 /** 347 * 348 * Coerces the specified value to a String 349 **/ 350 public static String coerceToString (Object pValue) 351 throws ELException 352 { 353 if (pValue == null) { 354 return ""; 355 } 356 else if (pValue instanceof String) { 357 return (String) pValue; 358 } 359 else { 360 try { 361 return pValue.toString (); 362 } 363 catch (Exception exc) { 364 if (log.isErrorEnabled()) { 365 String message = _MessageUtil.getMessageWithArgs( 366 _Constants.TOSTRING_EXCEPTION, 367 pValue.getClass().getName()); 368 log.error(message, exc); 369 throw new ELException(exc); 370 } 371 return ""; 372 } 373 } 374 } 375 376 //------------------------------------- 377 /** 378 * 379 * Coerces a value to the given primitive number class 380 **/ 381 public static Number coerceToPrimitiveNumber (Object pValue, 382 Class pClass) 383 throws ELException 384 { 385 if (pValue == null || 386 "".equals (pValue)) { 387 return coerceToPrimitiveNumber (ZERO, pClass); 388 } 389 else if (pValue instanceof Character) { 390 char val = ((Character) pValue).charValue (); 391 return coerceToPrimitiveNumber (new Short((short) val), pClass); 392 } 393 else if (pValue instanceof Boolean) { 394 if (log.isErrorEnabled()) { 395 String message = _MessageUtil.getMessageWithArgs( 396 _Constants.BOOLEAN_TO_NUMBER, pValue, pClass.getName()); 397 log.error(message); 398 throw new ELException(message); 399 } 400 return coerceToPrimitiveNumber(ZERO, pClass); 401 } 402 else if (pValue.getClass () == pClass) { 403 return (Number) pValue; 404 } 405 else if (pValue instanceof Number) { 406 return coerceToPrimitiveNumber ((Number) pValue, pClass); 407 } 408 else if (pValue instanceof String) { 409 try { 410 return coerceToPrimitiveNumber ((String) pValue, pClass); 411 } 412 catch (Exception exc) { 413 if (log.isErrorEnabled()) { 414 String message = _MessageUtil.getMessageWithArgs( 415 _Constants.STRING_TO_NUMBER_EXCEPTION, 416 (String) pValue, pClass.getName()); 417 log.error(message); 418 throw new ELException(message); 419 } 420 return coerceToPrimitiveNumber (ZERO, pClass); 421 } 422 } 423 else { 424 if (log.isErrorEnabled()) { 425 String message = _MessageUtil.getMessageWithArgs( 426 _Constants.COERCE_TO_NUMBER, 427 pValue.getClass().getName(), 428 pClass.getName()); 429 log.error(message); 430 throw new ELException(message); 431 } 432 return coerceToPrimitiveNumber (0, pClass); 433 } 434 } 435 436 //------------------------------------- 437 /** 438 * 439 * Coerces a value to an Integer, returning null if the coercion 440 * isn't possible. 441 **/ 442 public static Integer coerceToInteger (Object pValue) 443 throws ELException 444 { 445 if (pValue == null) { 446 return null; 447 } 448 else if (pValue instanceof Character) { 449 return _PrimitiveObjects.getInteger 450 ((int) (((Character) pValue).charValue ())); 451 } 452 else if (pValue instanceof Boolean) { 453 if (log.isWarnEnabled()) { 454 log.warn( 455 _MessageUtil.getMessageWithArgs( 456 _Constants.BOOLEAN_TO_NUMBER, pValue, Integer.class.getName())); 457 } 458 return _PrimitiveObjects.getInteger 459 (((Boolean) pValue).booleanValue () ? 1 : 0); 460 } 461 else if (pValue instanceof Integer) { 462 return (Integer) pValue; 463 } 464 else if (pValue instanceof Number) { 465 return _PrimitiveObjects.getInteger (((Number) pValue).intValue ()); 466 } 467 else if (pValue instanceof String) { 468 try { 469 return Integer.valueOf ((String) pValue); 470 } 471 catch (Exception exc) { 472 if (log.isWarnEnabled()) { 473 log.warn( 474 _MessageUtil.getMessageWithArgs( 475 _Constants.STRING_TO_NUMBER_EXCEPTION, 476 (String) pValue, 477 Integer.class.getName())); 478 } 479 return null; 480 } 481 } 482 else { 483 if (log.isWarnEnabled()) { 484 log.warn( 485 _MessageUtil.getMessageWithArgs( 486 _Constants.COERCE_TO_NUMBER, 487 pValue.getClass().getName(), 488 Integer.class.getName())); 489 } 490 return null; 491 } 492 } 493 494 //------------------------------------- 495 /** 496 * 497 * Coerces a long to the given primitive number class 498 **/ 499 static Number coerceToPrimitiveNumber (long pValue, 500 Class pClass) 501 throws ELException 502 { 503 if (pClass == Byte.class || pClass == Byte.TYPE) { 504 return _PrimitiveObjects.getByte ((byte) pValue); 505 } 506 else if (pClass == Short.class || pClass == Short.TYPE) { 507 return _PrimitiveObjects.getShort ((short) pValue); 508 } 509 else if (pClass == Integer.class || pClass == Integer.TYPE) { 510 return _PrimitiveObjects.getInteger ((int) pValue); 511 } 512 else if (pClass == Long.class || pClass == Long.TYPE) { 513 return _PrimitiveObjects.getLong (pValue); 514 } 515 else if (pClass == Float.class || pClass == Float.TYPE) { 516 return _PrimitiveObjects.getFloat ((float) pValue); 517 } 518 else if (pClass == Double.class || pClass == Double.TYPE) { 519 return _PrimitiveObjects.getDouble ((double) pValue); 520 } 521 else { 522 return _PrimitiveObjects.getInteger (0); 523 } 524 } 525 526 //------------------------------------- 527 /** 528 * 529 * Coerces a double to the given primitive number class 530 **/ 531 static Number coerceToPrimitiveNumber (double pValue, 532 Class pClass) 533 throws ELException 534 { 535 if (pClass == Byte.class || pClass == Byte.TYPE) { 536 return _PrimitiveObjects.getByte ((byte) pValue); 537 } 538 else if (pClass == Short.class || pClass == Short.TYPE) { 539 return _PrimitiveObjects.getShort ((short) pValue); 540 } 541 else if (pClass == Integer.class || pClass == Integer.TYPE) { 542 return _PrimitiveObjects.getInteger ((int) pValue); 543 } 544 else if (pClass == Long.class || pClass == Long.TYPE) { 545 return _PrimitiveObjects.getLong ((long) pValue); 546 } 547 else if (pClass == Float.class || pClass == Float.TYPE) { 548 return _PrimitiveObjects.getFloat ((float) pValue); 549 } 550 else if (pClass == Double.class || pClass == Double.TYPE) { 551 return _PrimitiveObjects.getDouble (pValue); 552 } 553 else { 554 return _PrimitiveObjects.getInteger (0); 555 } 556 } 557 558 //------------------------------------- 559 /** 560 * 561 * Coerces a Number to the given primitive number class 562 **/ 563 static Number coerceToPrimitiveNumber (Number pValue, Class pClass) 564 throws ELException 565 { 566 if (pClass == Byte.class || pClass == Byte.TYPE) { 567 return _PrimitiveObjects.getByte (pValue.byteValue ()); 568 } 569 else if (pClass == Short.class || pClass == Short.TYPE) { 570 return _PrimitiveObjects.getShort (pValue.shortValue ()); 571 } 572 else if (pClass == Integer.class || pClass == Integer.TYPE) { 573 return _PrimitiveObjects.getInteger (pValue.intValue ()); 574 } 575 else if (pClass == Long.class || pClass == Long.TYPE) { 576 return _PrimitiveObjects.getLong (pValue.longValue ()); 577 } 578 else if (pClass == Float.class || pClass == Float.TYPE) { 579 return _PrimitiveObjects.getFloat (pValue.floatValue ()); 580 } 581 else if (pClass == Double.class || pClass == Double.TYPE) { 582 return _PrimitiveObjects.getDouble (pValue.doubleValue ()); 583 } 584 else if (pClass == BigInteger.class) { 585 if (pValue instanceof BigDecimal) 586 return ((BigDecimal) pValue).toBigInteger(); 587 else 588 return BigInteger.valueOf(pValue.longValue()); 589 } 590 else if (pClass == BigDecimal.class) { 591 if (pValue instanceof BigInteger) 592 return new BigDecimal((BigInteger) pValue); 593 else 594 return new BigDecimal(pValue.doubleValue()); 595 } 596 else { 597 return _PrimitiveObjects.getInteger (0); 598 } 599 } 600 601 //------------------------------------- 602 /** 603 * 604 * Coerces a String to the given primitive number class 605 **/ 606 static Number coerceToPrimitiveNumber (String pValue, Class pClass) 607 throws ELException 608 { 609 if (pClass == Byte.class || pClass == Byte.TYPE) { 610 return Byte.valueOf (pValue); 611 } 612 else if (pClass == Short.class || pClass == Short.TYPE) { 613 return Short.valueOf (pValue); 614 } 615 else if (pClass == Integer.class || pClass == Integer.TYPE) { 616 return Integer.valueOf (pValue); 617 } 618 else if (pClass == Long.class || pClass == Long.TYPE) { 619 return Long.valueOf (pValue); 620 } 621 else if (pClass == Float.class || pClass == Float.TYPE) { 622 return Float.valueOf (pValue); 623 } 624 else if (pClass == Double.class || pClass == Double.TYPE) { 625 return Double.valueOf (pValue); 626 } 627 else if (pClass == BigInteger.class) { 628 return new BigInteger(pValue); 629 } 630 else if (pClass == BigDecimal.class) { 631 return new BigDecimal(pValue); 632 } 633 else { 634 return _PrimitiveObjects.getInteger (0); 635 } 636 } 637 638 //------------------------------------- 639 /** 640 * 641 * Coerces a value to a Character 642 **/ 643 public static Character coerceToCharacter (Object pValue) 644 throws ELException 645 { 646 if (pValue == null || 647 "".equals (pValue)) { 648 return _PrimitiveObjects.getCharacter ((char) 0); 649 } 650 else if (pValue instanceof Character) { 651 return (Character) pValue; 652 } 653 else if (pValue instanceof Boolean) { 654 if (log.isErrorEnabled()) { 655 String message = _MessageUtil.getMessageWithArgs( 656 _Constants.BOOLEAN_TO_CHARACTER, pValue); 657 log.error(message); 658 throw new ELException(message); 659 } 660 return _PrimitiveObjects.getCharacter ((char) 0); 661 } 662 else if (pValue instanceof Number) { 663 return _PrimitiveObjects.getCharacter 664 ((char) ((Number) pValue).shortValue ()); 665 } 666 else if (pValue instanceof String) { 667 String str = (String) pValue; 668 return _PrimitiveObjects.getCharacter (str.charAt (0)); 669 } 670 else { 671 if (log.isErrorEnabled()) { 672 String message = _MessageUtil.getMessageWithArgs( 673 _Constants.COERCE_TO_CHARACTER, 674 pValue.getClass().getName()); 675 log.error(message); 676 throw new ELException(message); 677 } 678 return _PrimitiveObjects.getCharacter ((char) 0); 679 } 680 } 681 682 //------------------------------------- 683 /** 684 * 685 * Coerces a value to a Boolean 686 **/ 687 public static Boolean coerceToBoolean (Object pValue) 688 throws ELException 689 { 690 if (pValue == null || 691 "".equals (pValue)) { 692 return Boolean.FALSE; 693 } 694 else if (pValue instanceof Boolean) { 695 return (Boolean) pValue; 696 } 697 else if (pValue instanceof String) { 698 String str = (String) pValue; 699 try { 700 return Boolean.valueOf (str); 701 } 702 catch (Exception exc) { 703 if (log.isErrorEnabled()) { 704 String message = _MessageUtil.getMessageWithArgs( 705 _Constants.STRING_TO_BOOLEAN, (String) pValue); 706 log.error(message, exc); 707 throw new ELException(message, exc); 708 } 709 return Boolean.FALSE; 710 } 711 } 712 else { 713 if (log.isErrorEnabled()) { 714 String message = _MessageUtil.getMessageWithArgs( 715 _Constants.COERCE_TO_BOOLEAN, 716 pValue.getClass().getName()); 717 log.error(message); 718 throw new ELException(message); 719 } 720 return Boolean.TRUE; 721 } 722 } 723 724 //------------------------------------- 725 /** 726 * 727 * Coerces a value to the specified Class that is not covered by any 728 * of the above cases 729 **/ 730 public static Object coerceToObject (Object pValue, Class pClass) 731 throws ELException 732 { 733 if (pValue == null) { 734 return null; 735 } 736 else if (pClass.isAssignableFrom (pValue.getClass ())) { 737 return pValue; 738 } 739 else if (pValue instanceof String) { 740 String str = (String) pValue; 741 PropertyEditor pe = PropertyEditorManager.findEditor (pClass); 742 if (pe == null) { 743 if ("".equals (str)) { 744 return null; 745 } 746 else { 747 if (log.isErrorEnabled()) { 748 String message = _MessageUtil.getMessageWithArgs( 749 _Constants.NO_PROPERTY_EDITOR, 750 str, pClass.getName()); 751 log.error(message); 752 throw new ELException(message); 753 } 754 return null; 755 } 756 } 757 try { 758 pe.setAsText (str); 759 return pe.getValue (); 760 } 761 catch (IllegalArgumentException exc) { 762 if ("".equals (str)) { 763 return null; 764 } 765 else { 766 if (log.isErrorEnabled()) { 767 String message = _MessageUtil.getMessageWithArgs( 768 _Constants.PROPERTY_EDITOR_ERROR, 769 pValue, 770 pClass.getName()); 771 log.error(message, exc); 772 throw new ELException(message, exc); 773 } 774 return null; 775 } 776 } 777 } 778 else { 779 if (log.isErrorEnabled()) { 780 String message = _MessageUtil.getMessageWithArgs( 781 _Constants.COERCE_TO_OBJECT, 782 pValue.getClass().getName(), 783 pClass.getName()); 784 log.error(message); 785 throw new ELException(message); 786 } 787 return null; 788 } 789 } 790 791 //------------------------------------- 792 // Applying operators 793 //------------------------------------- 794 /** 795 * 796 * Performs all of the necessary type conversions, then calls on the 797 * appropriate operator. 798 **/ 799 /* 800 public static Object applyArithmeticOperator 801 (Object pLeft, 802 Object pRight, 803 ArithmeticOperator pOperator) 804 throws ELException 805 { 806 if (pLeft == null && 807 pRight == null) { 808 if (log.isWarnEnabled()) { 809 log.warn( 810 MessageUtil.getMessageWithArgs( 811 Constants.ARITH_OP_NULL, 812 pOperator.getOperatorSymbol())); 813 } 814 return PrimitiveObjects.getInteger (0); 815 } 816 817 else if (isBigDecimal(pLeft) || isBigDecimal(pRight)) { 818 BigDecimal left = (BigDecimal) 819 coerceToPrimitiveNumber(pLeft, BigDecimal.class); 820 BigDecimal right = (BigDecimal) 821 coerceToPrimitiveNumber(pRight, BigDecimal.class); 822 return pOperator.apply(left, right); 823 } 824 825 else if (isFloatingPointType(pLeft) || 826 isFloatingPointType(pRight) || 827 isFloatingPointString(pLeft) || 828 isFloatingPointString(pRight)) { 829 if (isBigInteger(pLeft) || isBigInteger(pRight)) { 830 BigDecimal left = (BigDecimal) 831 coerceToPrimitiveNumber(pLeft, BigDecimal.class); 832 BigDecimal right = (BigDecimal) 833 coerceToPrimitiveNumber(pRight, BigDecimal.class); 834 return pOperator.apply(left, right); 835 } else { 836 double left = 837 coerceToPrimitiveNumber(pLeft, Double.class). 838 doubleValue(); 839 double right = 840 coerceToPrimitiveNumber(pRight, Double.class). 841 doubleValue(); 842 return 843 PrimitiveObjects.getDouble(pOperator.apply(left, right)); 844 } 845 } 846 847 else if (isBigInteger(pLeft) || isBigInteger(pRight)) { 848 BigInteger left = (BigInteger) 849 coerceToPrimitiveNumber(pLeft, BigInteger.class); 850 BigInteger right = (BigInteger) 851 coerceToPrimitiveNumber(pRight, BigInteger.class); 852 return pOperator.apply(left, right); 853 } 854 855 else { 856 long left = 857 coerceToPrimitiveNumber (pLeft, Long.class). 858 longValue (); 859 long right = 860 coerceToPrimitiveNumber (pRight, Long.class). 861 longValue (); 862 return 863 PrimitiveObjects.getLong (pOperator.apply (left, right)); 864 } 865 }*/ 866 867 //------------------------------------- 868 /** 869 * 870 * Performs all of the necessary type conversions, then calls on the 871 * appropriate operator. 872 **/ 873 /* 874 public static Object applyRelationalOperator 875 (Object pLeft, 876 Object pRight, 877 RelationalOperator pOperator) 878 throws ELException 879 { 880 if (isBigDecimal(pLeft) || isBigDecimal(pRight)) { 881 BigDecimal left = (BigDecimal) 882 coerceToPrimitiveNumber(pLeft, BigDecimal.class); 883 BigDecimal right = (BigDecimal) 884 coerceToPrimitiveNumber(pRight, BigDecimal.class); 885 return PrimitiveObjects.getBoolean(pOperator.apply(left, right)); 886 } 887 888 else if (isFloatingPointType (pLeft) || 889 isFloatingPointType (pRight)) { 890 double left = 891 coerceToPrimitiveNumber (pLeft, Double.class). 892 doubleValue (); 893 double right = 894 coerceToPrimitiveNumber (pRight, Double.class). 895 doubleValue (); 896 return 897 PrimitiveObjects.getBoolean (pOperator.apply (left, right)); 898 } 899 900 else if (isBigInteger(pLeft) || isBigInteger(pRight)) { 901 BigInteger left = (BigInteger) 902 coerceToPrimitiveNumber(pLeft, BigInteger.class); 903 BigInteger right = (BigInteger) 904 coerceToPrimitiveNumber(pRight, BigInteger.class); 905 return PrimitiveObjects.getBoolean(pOperator.apply(left, right)); 906 } 907 908 else if (isIntegerType (pLeft) || 909 isIntegerType (pRight)) { 910 long left = 911 coerceToPrimitiveNumber (pLeft, Long.class). 912 longValue (); 913 long right = 914 coerceToPrimitiveNumber (pRight, Long.class). 915 longValue (); 916 return 917 PrimitiveObjects.getBoolean (pOperator.apply (left, right)); 918 } 919 920 else if (pLeft instanceof String || 921 pRight instanceof String) { 922 String left = coerceToString (pLeft); 923 String right = coerceToString (pRight); 924 return 925 PrimitiveObjects.getBoolean (pOperator.apply (left, right)); 926 } 927 928 else if (pLeft instanceof Comparable) { 929 try { 930 int result = ((Comparable) pLeft).compareTo (pRight); 931 return 932 PrimitiveObjects.getBoolean 933 (pOperator.apply (result, -result)); 934 } 935 catch (Exception exc) { 936 if (log.isErrorEnabled()) { 937 String message = MessageUtil.getMessageWithArgs( 938 Constants.COMPARABLE_ERROR, 939 pLeft.getClass().getName(), 940 (pRight == null) ? "null" : pRight.getClass().getName(), 941 pOperator.getOperatorSymbol()); 942 log.error(message, exc); 943 throw new ELException(message, exc); 944 } 945 return Boolean.FALSE; 946 } 947 } 948 949 else if (pRight instanceof Comparable) { 950 try { 951 int result = ((Comparable) pRight).compareTo (pLeft); 952 return 953 PrimitiveObjects.getBoolean 954 (pOperator.apply (-result, result)); 955 } 956 catch (Exception exc) { 957 if (log.isErrorEnabled()) { 958 String message = MessageUtil.getMessageWithArgs( 959 Constants.COMPARABLE_ERROR, 960 pRight.getClass().getName(), 961 (pLeft == null) ? "null" : pLeft.getClass().getName(), 962 pOperator.getOperatorSymbol()); 963 log.error(message, exc); 964 throw new ELException(message, exc); 965 } 966 return Boolean.FALSE; 967 } 968 } 969 970 else { 971 if (log.isErrorEnabled()) { 972 String message = MessageUtil.getMessageWithArgs( 973 Constants.ARITH_OP_BAD_TYPE, 974 pOperator.getOperatorSymbol(), 975 pLeft.getClass().getName(), 976 pRight.getClass().getName()); 977 log.error(message); 978 throw new ELException(message); 979 } 980 return Boolean.FALSE; 981 } 982 }*/ 983 984 //------------------------------------- 985 /** 986 * 987 * Performs all of the necessary type conversions, then calls on the 988 * appropriate operator. 989 **/ 990 /* 991 public static Object applyEqualityOperator 992 (Object pLeft, 993 Object pRight, 994 EqualityOperator pOperator) 995 throws ELException 996 { 997 if (pLeft == pRight) { 998 return PrimitiveObjects.getBoolean (pOperator.apply (true)); 999 } 1000 1001 else if (pLeft == null || 1002 pRight == null) { 1003 return PrimitiveObjects.getBoolean (pOperator.apply (false)); 1004 } 1005 1006 else if (isBigDecimal(pLeft) || isBigDecimal(pRight)) { 1007 BigDecimal left = (BigDecimal) 1008 coerceToPrimitiveNumber(pLeft, BigDecimal.class); 1009 BigDecimal right = (BigDecimal) 1010 coerceToPrimitiveNumber(pRight, BigDecimal.class); 1011 return PrimitiveObjects.getBoolean(pOperator.apply(left.equals(right))); 1012 } 1013 1014 else if (isFloatingPointType (pLeft) || 1015 isFloatingPointType (pRight)) { 1016 double left = 1017 coerceToPrimitiveNumber (pLeft, Double.class). 1018 doubleValue (); 1019 double right = 1020 coerceToPrimitiveNumber (pRight, Double.class). 1021 doubleValue (); 1022 return 1023 PrimitiveObjects.getBoolean 1024 (pOperator.apply (left == right)); 1025 } 1026 1027 else if (isBigInteger(pLeft) || isBigInteger(pRight)) { 1028 BigInteger left = (BigInteger) 1029 coerceToPrimitiveNumber(pLeft, BigInteger.class); 1030 BigInteger right = (BigInteger) 1031 coerceToPrimitiveNumber(pRight, BigInteger.class); 1032 return PrimitiveObjects.getBoolean(pOperator.apply(left.equals(right))); 1033 } 1034 1035 else if (isIntegerType (pLeft) || 1036 isIntegerType (pRight)) { 1037 long left = 1038 coerceToPrimitiveNumber (pLeft, Long.class). 1039 longValue (); 1040 long right = 1041 coerceToPrimitiveNumber (pRight, Long.class). 1042 longValue (); 1043 return 1044 PrimitiveObjects.getBoolean 1045 (pOperator.apply (left == right)); 1046 } 1047 1048 else if (pLeft instanceof Boolean || 1049 pRight instanceof Boolean) { 1050 boolean left = coerceToBoolean (pLeft).booleanValue (); 1051 boolean right = coerceToBoolean (pRight).booleanValue (); 1052 return 1053 PrimitiveObjects.getBoolean 1054 (pOperator.apply (left == right)); 1055 } 1056 1057 else if (pLeft instanceof String || 1058 pRight instanceof String) { 1059 String left = coerceToString (pLeft); 1060 String right = coerceToString (pRight); 1061 return 1062 PrimitiveObjects.getBoolean 1063 (pOperator.apply (left.equals (right))); 1064 } 1065 1066 else { 1067 try { 1068 return 1069 PrimitiveObjects.getBoolean 1070 (pOperator.apply (pLeft.equals (pRight))); 1071 } 1072 catch (Exception exc) { 1073 if (log.isErrorEnabled()) { 1074 String message = MessageUtil.getMessageWithArgs( 1075 Constants.ERROR_IN_EQUALS, 1076 pLeft.getClass().getName(), 1077 pRight.getClass().getName(), 1078 pOperator.getOperatorSymbol()); 1079 log.error(message, exc); 1080 throw new ELException(message, exc); 1081 } 1082 return Boolean.FALSE; 1083 } 1084 } 1085 }*/ 1086 1087 //------------------------------------- 1088 /** 1089 * 1090 * Returns true if the given Object is of a floating point type 1091 **/ 1092 public static boolean isFloatingPointType (Object pObject) 1093 { 1094 return 1095 pObject != null && 1096 isFloatingPointType (pObject.getClass ()); 1097 } 1098 1099 //------------------------------------- 1100 /** 1101 * 1102 * Returns true if the given class is of a floating point type 1103 **/ 1104 public static boolean isFloatingPointType (Class pClass) 1105 { 1106 return 1107 pClass == Float.class || 1108 pClass == Float.TYPE || 1109 pClass == Double.class || 1110 pClass == Double.TYPE; 1111 } 1112 1113 //------------------------------------- 1114 /** 1115 * 1116 * Returns true if the given string might contain a floating point 1117 * number - i.e., it contains ".", "e", or "E" 1118 **/ 1119 public static boolean isFloatingPointString (Object pObject) 1120 { 1121 if (pObject instanceof String) { 1122 String str = (String) pObject; 1123 int len = str.length (); 1124 for (int i = 0; i < len; i++) { 1125 char ch = str.charAt (i); 1126 if (ch == '.' || 1127 ch == 'e' || 1128 ch == 'E') { 1129 return true; 1130 } 1131 } 1132 return false; 1133 } 1134 else { 1135 return false; 1136 } 1137 } 1138 1139 //------------------------------------- 1140 /** 1141 * 1142 * Returns true if the given Object is of an integer type 1143 **/ 1144 public static boolean isIntegerType (Object pObject) 1145 { 1146 return 1147 pObject != null && 1148 isIntegerType (pObject.getClass ()); 1149 } 1150 1151 //------------------------------------- 1152 /** 1153 * 1154 * Returns true if the given class is of an integer type 1155 **/ 1156 public static boolean isIntegerType (Class pClass) 1157 { 1158 return 1159 pClass == Byte.class || 1160 pClass == Byte.TYPE || 1161 pClass == Short.class || 1162 pClass == Short.TYPE || 1163 pClass == Character.class || 1164 pClass == Character.TYPE || 1165 pClass == Integer.class || 1166 pClass == Integer.TYPE || 1167 pClass == Long.class || 1168 pClass == Long.TYPE; 1169 } 1170 1171 //------------------------------------- 1172 1173 /** 1174 * Returns true if the given object is BigInteger. 1175 * @param pObject - Object to evaluate 1176 * @return - true if the given object is BigInteger 1177 */ 1178 public static boolean isBigInteger(Object pObject) { 1179 return 1180 pObject != null && pObject instanceof BigInteger; 1181 } 1182 1183 /** 1184 * Returns true if the given object is BigDecimal. 1185 * @param pObject - Object to evaluate 1186 * @return - true if the given object is BigDecimal 1187 */ 1188 public static boolean isBigDecimal(Object pObject) { 1189 return 1190 pObject != null && pObject instanceof BigDecimal; 1191 } 1192 }