KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > el > Coercions


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  * Copyright (c) 1999 The Apache Software Foundation. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if
20  * any, must include the following acknowlegement:
21  * "This product includes software developed by the
22  * Apache Software Foundation (http://www.apache.org/)."
23  * Alternately, this acknowlegement may appear in the software itself,
24  * if and wherever such third-party acknowlegements normally appear.
25  *
26  * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
27  * Foundation" must not be used to endorse or promote products derived
28  * from this software without prior written permission. For written
29  * permission, please contact apache@apache.org.
30  *
31  * 5. Products derived from this software may not be called "Apache"
32  * nor may "Apache" appear in their names without prior written
33  * permission of the Apache Group.
34  *
35  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46  * SUCH DAMAGE.
47  * ====================================================================
48  *
49  * This software consists of voluntary contributions made by many
50  * individuals on behalf of the Apache Software Foundation. For more
51  * information on the Apache Software Foundation, please see
52  * <http://www.apache.org/>.
53  *
54  */

55
56 package org.apache.commons.el;
57
58 import java.beans.PropertyEditor JavaDoc;
59 import java.beans.PropertyEditorManager JavaDoc;
60 import java.math.BigInteger JavaDoc;
61 import java.math.BigDecimal JavaDoc;
62 import javax.servlet.jsp.el.ELException JavaDoc;
63
64 /**
65  *
66  * <p>This class contains the logic for coercing data types before
67  * operators are applied to them.
68  *
69  * <p>The following is the list of rules applied for various type
70  * conversions.
71  *
72  * <ul><pre>
73  * Applying arithmetic operator
74  * Binary operator - A {+,-,*} B
75  * if A and B are null
76  * return 0
77  * if A or B is BigDecimal, coerce both to BigDecimal and then:
78  * if operator is +, return <code>A.add(B)</code>
79  * if operator is -, return <code>A.subtract(B)</code>
80  * if operator is *, return <code>A.multiply(B)</code>
81  * if A or B is Float, Double, or String containing ".", "e", or "E"
82  * if A or B is BigInteger, coerce both A and B to BigDecimal and apply operator
83  * coerce both A and B to Double and apply operator
84  * if A or B is BigInteger, coerce both to BigInteger and then:
85  * if operator is +, return <code>A.add(B)</code>
86  * if operator is -, return <code>A.subtract(B)</code>
87  * if operator is *, return <code>A.multiply(B)</code>
88  * otherwise
89  * coerce both A and B to Long
90  * apply operator
91  * if operator results in exception (such as divide by 0), error
92  *
93  * Binary operator - A {/,div} B
94  * if A and B are null
95  * return 0
96  * if A or B is a BigDecimal or BigInteger, coerce both to BigDecimal and
97  * return <code>A.divide(B, BigDecimal.ROUND_HALF_UP)</code>
98  * otherwise
99  * coerce both A and B to Double
100  * apply operator
101  * if operator results in exception (such as divide by 0), error
102  *
103  * Binary operator - A {%,mod} B
104  * if A and B are null
105  * return 0
106  * if A or B is BigDecimal, Float, Double, or String containing ".", "e" or "E"
107  * coerce both to Double
108  * apply operator
109  * if A or B is BigInteger, coerce both to BigInteger and return
110  * <code>A.remainder(B)</code>
111  * otherwise
112  * coerce both A and B to Long
113  * apply operator
114  * if operator results in exception (such as divide by 0), error
115  *
116  * Unary minus operator - -A
117  * if A is null
118  * return 0
119  * if A is BigInteger or BigDecimal, return <code>A.negate()</code>
120  * if A is String
121  * if A contains ".", "e", or "E"
122  * coerce to Double, apply operator
123  * otherwise
124  * coerce to a Long and apply operator
125  * if A is Byte,Short,Integer,Long,Float,Double
126  * retain type, apply operator
127  * if operator results in exception, error
128  * otherwise
129  * error
130  *
131  * Applying "empty" operator - empty A
132  * if A is null
133  * return true
134  * if A is zero-length String
135  * return true
136  * if A is zero-length array
137  * return true
138  * if A is List and ((List) A).isEmpty()
139  * return true
140  * if A is Map and ((Map) A).isEmpty()
141  * return true
142  * if A is Collection an ((Collection) A).isEmpty()
143  * return true
144  * otherwise
145  * return false
146  *
147  * Applying logical operators
148  * Binary operator - A {and,or} B
149  * coerce both A and B to Boolean, apply operator
150  * NOTE - operator stops as soon as expression can be determined, i.e.,
151  * A and B and C and D - if B is false, then only A and B is evaluated
152  * Unary not operator - not A
153  * coerce A to Boolean, apply operator
154  *
155  * Applying relational operator
156  * A {<,>,<=,>=,lt,gt,lte,gte} B
157  * if A==B
158  * if operator is >= or <=
159  * return true
160  * otherwise
161  * return false
162  * if A or B is null
163  * return false
164  * if A or B is BigDecimal, coerce both A and B to BigDecimal and use the
165  * return value of <code>A.compareTo(B)</code>
166  * if A or B is Float or Double
167  * coerce both A and B to Double
168  * apply operator
169  * if A or B is BigInteger, coerce both A and B to BigInteger and use the
170  * return value of <code>A.compareTo(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 String
175  * coerce both A and B to String, compare lexically
176  * if A is Comparable
177  * if A.compareTo (B) throws exception
178  * error
179  * otherwise
180  * use result of A.compareTo(B)
181  * if B is Comparable
182  * if B.compareTo (A) throws exception
183  * error
184  * otherwise
185  * use result of B.compareTo(A)
186  * otherwise
187  * error
188  *
189  * Applying equality operator
190  * A {==,!=} B
191  * if A==B
192  * apply operator
193  * if A or B is null
194  * return false for ==, true for !=
195  * if A or B is BigDecimal, coerce both A and B to BigDecimal and then:
196  * if operator is == or eq, return <code>A.equals(B)</code>
197  * if operator is != or ne, return <code>!A.equals(B)</code>
198  * if A or B is Float or Double
199  * coerce both A and B to Double
200  * apply operator
201  * if A or B is BigInteger, coerce both A and B to BigInteger and then:
202  * if operator is == or eq, return <code>A.equals(B)</code>
203  * if operator is != or ne, return <code>!A.equals(B)</code>
204  * if A or B is Byte,Short,Character,Integer,Long
205  * coerce both A and B to Long
206  * apply operator
207  * if A or B is Boolean
208  * coerce both A and B to Boolean
209  * apply operator
210  * if A or B is String
211  * coerce both A and B to String, compare lexically
212  * otherwise
213  * if an error occurs while calling A.equals(B)
214  * error
215  * apply operator to result of A.equals(B)
216  *
217  * coercions
218  *
219  * coerce A to String
220  * A is String
221  * return A
222  * A is null
223  * return ""
224  * A.toString throws exception
225  * error
226  * otherwise
227  * return A.toString
228  *
229  * coerce A to Number type N
230  * A is null or ""
231  * return 0
232  * A is Character
233  * convert to short, apply following rules
234  * A is Boolean
235  * error
236  * A is Number type N
237  * return A
238  * A is Number, coerce quietly to type N using the following algorithm
239  * If N is BigInteger
240  * If A is BigDecimal, return <code>A.toBigInteger()</code>
241  * Otherwise, return <code>BigInteger.valueOf(A.longValue())</code>
242  * if N is BigDecimal
243  * If A is a BigInteger, return <code>new BigDecimal(A)</code>
244  * Otherwise, return <code>new BigDecimal(A.doubleValue())</code>
245  * If N is Byte, return <code>new Byte(A.byteValue())</code>
246  * If N is Short, return <code>new Short(A.shortValue())</code>
247  * If N is Integer, return <code>new Integer(A.integerValue())</code>
248  * If N is Long, return <code>new Long(A.longValue())</code>
249  * If N is Float, return <code>new Float(A.floatValue())</code>
250  * If N is Double, return <code>new Double(A.doubleValue())</code>
251  * otherwise ERROR
252  * A is String
253  * If N is BigDecimal then:
254  * If <code>new BigDecimal(A)</code> throws an exception then ERROR
255  * Otherwise, return <code>new BigDecimal(A)</code>
256  * If N is BigInteger then:
257  * If <code>new BigInteger(A)</code> throws an exception, then ERROR
258  * Otherwise, return <code>new BigInteger(A)</code>
259  * new <code>N.valueOf(A)</code> throws exception
260  * error
261  * return <code>N.valueOf(A)</code>
262  * otherwise
263  * error
264  *
265  * coerce A to Character should be
266  * A is null or ""
267  * return (char) 0
268  * A is Character
269  * return A
270  * A is Boolean
271  * error
272  * A is Number with less precision than short
273  * coerce quietly - return (char) A
274  * A is Number with greater precision than short
275  * coerce quietly - return (char) A
276  * A is String
277  * return A.charAt (0)
278  * otherwise
279  * error
280  *
281  * coerce A to Boolean
282  * A is null or ""
283  * return false
284  * A is Boolean
285  * return A
286  * A is String
287  * Boolean.valueOf(A) throws exception
288  * error
289  * return Boolean.valueOf(A)
290  * otherwise
291  * error
292  *
293  * coerce A to any other type T
294  * A is null
295  * return null
296  * A is assignable to T
297  * coerce quietly
298  * A is String
299  * T has no PropertyEditor
300  * if A is "", return null
301  * otherwise error
302  * T's PropertyEditor throws exception
303  * if A is "", return null
304  * otherwise error
305  * otherwise
306  * apply T's PropertyEditor
307  * otherwise
308  * error
309  * </pre></ul>
310  *
311  * @author Nathan Abramson - Art Technology Group
312  * @version $Change: 181177 $$DateTime: 2001/06/26 08:45:09 $$Author: luehe $
313  **/

314
315 public class Coercions
316 {
317    private static final Number JavaDoc ZERO = new Integer JavaDoc(0);
318   //-------------------------------------
319
/**
320    *
321    * Coerces the given value to the specified class.
322    **/

323   public static Object JavaDoc coerce (Object JavaDoc pValue,
324                    Class JavaDoc pClass,
325                    Logger pLogger)
326     throws ELException JavaDoc
327   {
328     if (pClass == String JavaDoc.class) {
329       return coerceToString (pValue, pLogger);
330     }
331     else if (isNumberClass (pClass)) {
332       return coerceToPrimitiveNumber (pValue, pClass, pLogger);
333     }
334     else if (pClass == Character JavaDoc.class ||
335          pClass == Character.TYPE) {
336       return coerceToCharacter (pValue, pLogger);
337     }
338     else if (pClass == Boolean JavaDoc.class ||
339          pClass == Boolean.TYPE) {
340       return coerceToBoolean (pValue, pLogger);
341     }
342     else {
343       return coerceToObject (pValue, pClass, pLogger);
344     }
345   }
346
347   //-------------------------------------
348
/**
349    *
350    * Returns true if the given class is Byte, Short, Integer, Long,
351    * Float, Double, BigInteger, or BigDecimal
352    **/

353   static boolean isNumberClass (Class JavaDoc pClass)
354   {
355     return
356       pClass == Byte JavaDoc.class ||
357       pClass == Byte.TYPE ||
358       pClass == Short JavaDoc.class ||
359       pClass == Short.TYPE ||
360       pClass == Integer JavaDoc.class ||
361       pClass == Integer.TYPE ||
362       pClass == Long JavaDoc.class ||
363       pClass == Long.TYPE ||
364       pClass == Float JavaDoc.class ||
365       pClass == Float.TYPE ||
366       pClass == Double JavaDoc.class ||
367       pClass == Double.TYPE ||
368       pClass == BigInteger JavaDoc.class ||
369       pClass == BigDecimal JavaDoc.class;
370   }
371
372   //-------------------------------------
373
/**
374    *
375    * Coerces the specified value to a String
376    **/

377   public static String JavaDoc coerceToString (Object JavaDoc pValue,
378                        Logger pLogger)
379     throws ELException JavaDoc
380   {
381     if (pValue == null) {
382       return "";
383     }
384     else if (pValue instanceof String JavaDoc) {
385       return (String JavaDoc) pValue;
386     }
387     else {
388       try {
389     return pValue.toString ();
390       }
391       catch (Exception JavaDoc exc) {
392     if (pLogger.isLoggingError ()) {
393       pLogger.logError (Constants.TOSTRING_EXCEPTION,
394                 exc,
395                 pValue.getClass ().getName ());
396     }
397     return "";
398       }
399     }
400   }
401
402   //-------------------------------------
403
/**
404    *
405    * Coerces a value to the given primitive number class
406    **/

407   public static Number JavaDoc coerceToPrimitiveNumber (Object JavaDoc pValue,
408                         Class JavaDoc pClass,
409                         Logger pLogger)
410     throws ELException JavaDoc
411   {
412     if (pValue == null ||
413     "".equals (pValue)) {
414       return coerceToPrimitiveNumber (ZERO, pClass);
415     }
416     else if (pValue instanceof Character JavaDoc) {
417       char val = ((Character JavaDoc) pValue).charValue ();
418       return coerceToPrimitiveNumber (new Short JavaDoc((short) val), pClass);
419     }
420     else if (pValue instanceof Boolean JavaDoc) {
421       if (pLogger.isLoggingError ()) {
422     pLogger.logError (Constants.BOOLEAN_TO_NUMBER,
423               pValue,
424               pClass.getName ());
425       }
426       return coerceToPrimitiveNumber (ZERO, pClass);
427     }
428     else if (pValue.getClass () == pClass) {
429       return (Number JavaDoc) pValue;
430     }
431     else if (pValue instanceof Number JavaDoc) {
432       return coerceToPrimitiveNumber ((Number JavaDoc) pValue, pClass);
433     }
434     else if (pValue instanceof String JavaDoc) {
435       try {
436     return coerceToPrimitiveNumber ((String JavaDoc) pValue, pClass);
437       }
438       catch (Exception JavaDoc exc) {
439     if (pLogger.isLoggingError ()) {
440       pLogger.logError
441         (Constants.STRING_TO_NUMBER_EXCEPTION,
442          (String JavaDoc) pValue,
443          pClass.getName ());
444     }
445     return coerceToPrimitiveNumber (ZERO, pClass);
446       }
447     }
448     else {
449       if (pLogger.isLoggingError ()) {
450     pLogger.logError
451       (Constants.COERCE_TO_NUMBER,
452        pValue.getClass ().getName (),
453        pClass.getName ());
454       }
455       return coerceToPrimitiveNumber (0, pClass);
456     }
457   }
458
459   //-------------------------------------
460
/**
461    *
462    * Coerces a value to an Integer, returning null if the coercion
463    * isn't possible.
464    **/

465   public static Integer JavaDoc coerceToInteger (Object JavaDoc pValue,
466                      Logger pLogger)
467     throws ELException JavaDoc
468   {
469     if (pValue == null) {
470       return null;
471     }
472     else if (pValue instanceof Character JavaDoc) {
473       return PrimitiveObjects.getInteger
474     ((int) (((Character JavaDoc) pValue).charValue ()));
475     }
476     else if (pValue instanceof Boolean JavaDoc) {
477       if (pLogger.isLoggingWarning ()) {
478     pLogger.logWarning (Constants.BOOLEAN_TO_NUMBER,
479                 pValue,
480                 Integer JavaDoc.class.getName ());
481       }
482       return PrimitiveObjects.getInteger
483     (((Boolean JavaDoc) pValue).booleanValue () ? 1 : 0);
484     }
485     else if (pValue instanceof Integer JavaDoc) {
486       return (Integer JavaDoc) pValue;
487     }
488     else if (pValue instanceof Number JavaDoc) {
489       return PrimitiveObjects.getInteger (((Number JavaDoc) pValue).intValue ());
490     }
491     else if (pValue instanceof String JavaDoc) {
492       try {
493     return Integer.valueOf ((String JavaDoc) pValue);
494       }
495       catch (Exception JavaDoc exc) {
496     if (pLogger.isLoggingWarning ()) {
497       pLogger.logWarning
498         (Constants.STRING_TO_NUMBER_EXCEPTION,
499          (String JavaDoc) pValue,
500          Integer JavaDoc.class.getName ());
501     }
502     return null;
503       }
504     }
505     else {
506       if (pLogger.isLoggingWarning ()) {
507     pLogger.logWarning
508       (Constants.COERCE_TO_NUMBER,
509        pValue.getClass ().getName (),
510        Integer JavaDoc.class.getName ());
511       }
512       return null;
513     }
514   }
515
516   //-------------------------------------
517
/**
518    *
519    * Coerces a long to the given primitive number class
520    **/

521   static Number JavaDoc coerceToPrimitiveNumber (long pValue,
522                      Class JavaDoc pClass)
523     throws ELException JavaDoc
524   {
525     if (pClass == Byte JavaDoc.class || pClass == Byte.TYPE) {
526       return PrimitiveObjects.getByte ((byte) pValue);
527     }
528     else if (pClass == Short JavaDoc.class || pClass == Short.TYPE) {
529       return PrimitiveObjects.getShort ((short) pValue);
530     }
531     else if (pClass == Integer JavaDoc.class || pClass == Integer.TYPE) {
532       return PrimitiveObjects.getInteger ((int) pValue);
533     }
534     else if (pClass == Long JavaDoc.class || pClass == Long.TYPE) {
535       return PrimitiveObjects.getLong (pValue);
536     }
537     else if (pClass == Float JavaDoc.class || pClass == Float.TYPE) {
538       return PrimitiveObjects.getFloat ((float) pValue);
539     }
540     else if (pClass == Double JavaDoc.class || pClass == Double.TYPE) {
541       return PrimitiveObjects.getDouble ((double) pValue);
542     }
543     else {
544       return PrimitiveObjects.getInteger (0);
545     }
546   }
547
548   //-------------------------------------
549
/**
550    *
551    * Coerces a double to the given primitive number class
552    **/

553   static Number JavaDoc coerceToPrimitiveNumber (double pValue,
554                      Class JavaDoc pClass)
555     throws ELException JavaDoc
556   {
557     if (pClass == Byte JavaDoc.class || pClass == Byte.TYPE) {
558       return PrimitiveObjects.getByte ((byte) pValue);
559     }
560     else if (pClass == Short JavaDoc.class || pClass == Short.TYPE) {
561       return PrimitiveObjects.getShort ((short) pValue);
562     }
563     else if (pClass == Integer JavaDoc.class || pClass == Integer.TYPE) {
564       return PrimitiveObjects.getInteger ((int) pValue);
565     }
566     else if (pClass == Long JavaDoc.class || pClass == Long.TYPE) {
567       return PrimitiveObjects.getLong ((long) pValue);
568     }
569     else if (pClass == Float JavaDoc.class || pClass == Float.TYPE) {
570       return PrimitiveObjects.getFloat ((float) pValue);
571     }
572     else if (pClass == Double JavaDoc.class || pClass == Double.TYPE) {
573       return PrimitiveObjects.getDouble (pValue);
574     }
575     else {
576       return PrimitiveObjects.getInteger (0);
577     }
578   }
579
580   //-------------------------------------
581
/**
582    *
583    * Coerces a Number to the given primitive number class
584    **/

585   static Number JavaDoc coerceToPrimitiveNumber (Number JavaDoc pValue,
586                      Class JavaDoc pClass)
587     throws ELException JavaDoc
588   {
589     if (pClass == Byte JavaDoc.class || pClass == Byte.TYPE) {
590       return PrimitiveObjects.getByte (pValue.byteValue ());
591     }
592     else if (pClass == Short JavaDoc.class || pClass == Short.TYPE) {
593       return PrimitiveObjects.getShort (pValue.shortValue ());
594     }
595     else if (pClass == Integer JavaDoc.class || pClass == Integer.TYPE) {
596       return PrimitiveObjects.getInteger (pValue.intValue ());
597     }
598     else if (pClass == Long JavaDoc.class || pClass == Long.TYPE) {
599       return PrimitiveObjects.getLong (pValue.longValue ());
600     }
601     else if (pClass == Float JavaDoc.class || pClass == Float.TYPE) {
602       return PrimitiveObjects.getFloat (pValue.floatValue ());
603     }
604     else if (pClass == Double JavaDoc.class || pClass == Double.TYPE) {
605       return PrimitiveObjects.getDouble (pValue.doubleValue ());
606     }
607     else if (pClass == BigInteger JavaDoc.class) {
608         if (pValue instanceof BigDecimal JavaDoc)
609             return ((BigDecimal JavaDoc) pValue).toBigInteger();
610         else
611             return BigInteger.valueOf(pValue.longValue());
612     }
613     else if (pClass == BigDecimal JavaDoc.class) {
614         if (pValue instanceof BigInteger JavaDoc)
615             return new BigDecimal JavaDoc((BigInteger JavaDoc) pValue);
616         else
617             return new BigDecimal JavaDoc(pValue.doubleValue());
618     }
619     else {
620       return PrimitiveObjects.getInteger (0);
621     }
622   }
623
624   //-------------------------------------
625
/**
626    *
627    * Coerces a String to the given primitive number class
628    **/

629   static Number JavaDoc coerceToPrimitiveNumber (String JavaDoc pValue,
630                      Class JavaDoc pClass)
631     throws ELException JavaDoc
632   {
633     if (pClass == Byte JavaDoc.class || pClass == Byte.TYPE) {
634       return Byte.valueOf (pValue);
635     }
636     else if (pClass == Short JavaDoc.class || pClass == Short.TYPE) {
637       return Short.valueOf (pValue);
638     }
639     else if (pClass == Integer JavaDoc.class || pClass == Integer.TYPE) {
640       return Integer.valueOf (pValue);
641     }
642     else if (pClass == Long JavaDoc.class || pClass == Long.TYPE) {
643       return Long.valueOf (pValue);
644     }
645     else if (pClass == Float JavaDoc.class || pClass == Float.TYPE) {
646       return Float.valueOf (pValue);
647     }
648     else if (pClass == Double JavaDoc.class || pClass == Double.TYPE) {
649       return Double.valueOf (pValue);
650     }
651     else if (pClass == BigInteger JavaDoc.class) {
652         return new BigInteger JavaDoc(pValue);
653     }
654     else if (pClass == BigDecimal JavaDoc.class) {
655         return new BigDecimal JavaDoc(pValue);
656     }
657     else {
658       return PrimitiveObjects.getInteger (0);
659     }
660   }
661
662   //-------------------------------------
663
/**
664    *
665    * Coerces a value to a Character
666    **/

667   public static Character JavaDoc coerceToCharacter (Object JavaDoc pValue,
668                          Logger pLogger)
669     throws ELException JavaDoc
670   {
671     if (pValue == null ||
672     "".equals (pValue)) {
673       return PrimitiveObjects.getCharacter ((char) 0);
674     }
675     else if (pValue instanceof Character JavaDoc) {
676       return (Character JavaDoc) pValue;
677     }
678     else if (pValue instanceof Boolean JavaDoc) {
679       if (pLogger.isLoggingError ()) {
680     pLogger.logError (Constants.BOOLEAN_TO_CHARACTER, pValue);
681       }
682       return PrimitiveObjects.getCharacter ((char) 0);
683     }
684     else if (pValue instanceof Number JavaDoc) {
685       return PrimitiveObjects.getCharacter
686     ((char) ((Number JavaDoc) pValue).shortValue ());
687     }
688     else if (pValue instanceof String JavaDoc) {
689       String JavaDoc str = (String JavaDoc) pValue;
690       return PrimitiveObjects.getCharacter (str.charAt (0));
691     }
692     else {
693       if (pLogger.isLoggingError ()) {
694     pLogger.logError
695       (Constants.COERCE_TO_CHARACTER,
696        pValue.getClass ().getName ());
697       }
698       return PrimitiveObjects.getCharacter ((char) 0);
699     }
700   }
701
702   //-------------------------------------
703
/**
704    *
705    * Coerces a value to a Boolean
706    **/

707   public static Boolean JavaDoc coerceToBoolean (Object JavaDoc pValue,
708                      Logger pLogger)
709     throws ELException JavaDoc
710   {
711     if (pValue == null ||
712     "".equals (pValue)) {
713       return Boolean.FALSE;
714     }
715     else if (pValue instanceof Boolean JavaDoc) {
716       return (Boolean JavaDoc) pValue;
717     }
718     else if (pValue instanceof String JavaDoc) {
719       String JavaDoc str = (String JavaDoc) pValue;
720       try {
721     return Boolean.valueOf (str);
722       }
723       catch (Exception JavaDoc exc) {
724     if (pLogger.isLoggingError ()) {
725       pLogger.logError
726         (Constants.STRING_TO_BOOLEAN,
727          exc,
728          (String JavaDoc) pValue);
729     }
730     return Boolean.FALSE;
731       }
732     }
733     else {
734       if (pLogger.isLoggingError ()) {
735     pLogger.logError
736       (Constants.COERCE_TO_BOOLEAN,
737        pValue.getClass ().getName ());
738       }
739       return Boolean.TRUE;
740     }
741   }
742
743   //-------------------------------------
744
/**
745    *
746    * Coerces a value to the specified Class that is not covered by any
747    * of the above cases
748    **/

749   public static Object JavaDoc coerceToObject (Object JavaDoc pValue,
750                        Class JavaDoc pClass,
751                        Logger pLogger)
752     throws ELException JavaDoc
753   {
754     if (pValue == null) {
755       return null;
756     }
757     else if (pClass.isAssignableFrom (pValue.getClass ())) {
758       return pValue;
759     }
760     else if (pValue instanceof String JavaDoc) {
761       String JavaDoc str = (String JavaDoc) pValue;
762       PropertyEditor JavaDoc pe = PropertyEditorManager.findEditor (pClass);
763       if (pe == null) {
764     if ("".equals (str)) {
765       return null;
766     }
767     else {
768       if (pLogger.isLoggingError ()) {
769         pLogger.logError
770           (Constants.NO_PROPERTY_EDITOR,
771            str,
772            pClass.getName ());
773       }
774       return null;
775     }
776       }
777       try {
778     pe.setAsText (str);
779     return pe.getValue ();
780       }
781       catch (IllegalArgumentException JavaDoc exc) {
782     if ("".equals (str)) {
783       return null;
784     }
785     else {
786       if (pLogger.isLoggingError ()) {
787         pLogger.logError
788           (Constants.PROPERTY_EDITOR_ERROR,
789            exc,
790            pValue,
791            pClass.getName ());
792       }
793       return null;
794     }
795       }
796     }
797     else {
798       if (pLogger.isLoggingError ()) {
799     pLogger.logError
800       (Constants.COERCE_TO_OBJECT,
801        pValue.getClass ().getName (),
802        pClass.getName ());
803       }
804       return null;
805     }
806   }
807
808   //-------------------------------------
809
// Applying operators
810
//-------------------------------------
811
/**
812    *
813    * Performs all of the necessary type conversions, then calls on the
814    * appropriate operator.
815    **/

816   public static Object JavaDoc applyArithmeticOperator
817     (Object JavaDoc pLeft,
818      Object JavaDoc pRight,
819      ArithmeticOperator pOperator,
820      Logger pLogger)
821     throws ELException JavaDoc
822   {
823     if (pLeft == null &&
824     pRight == null) {
825       if (pLogger.isLoggingWarning ()) {
826     pLogger.logWarning
827       (Constants.ARITH_OP_NULL,
828        pOperator.getOperatorSymbol ());
829       }
830       return PrimitiveObjects.getInteger (0);
831     }
832
833     else if (isBigDecimal(pLeft) || isBigDecimal(pRight)) {
834         BigDecimal JavaDoc left = (BigDecimal JavaDoc)
835             coerceToPrimitiveNumber(pLeft, BigDecimal JavaDoc.class, pLogger);
836         BigDecimal JavaDoc right = (BigDecimal JavaDoc)
837             coerceToPrimitiveNumber(pRight, BigDecimal JavaDoc.class, pLogger);
838         return pOperator.apply(left, right);
839     }
840
841     else if (isFloatingPointType(pLeft) ||
842         isFloatingPointType(pRight) ||
843         isFloatingPointString(pLeft) ||
844         isFloatingPointString(pRight)) {
845         if (isBigInteger(pLeft) || isBigInteger(pRight)) {
846             BigDecimal JavaDoc left = (BigDecimal JavaDoc)
847                 coerceToPrimitiveNumber(pLeft, BigDecimal JavaDoc.class, pLogger);
848             BigDecimal JavaDoc right = (BigDecimal JavaDoc)
849                 coerceToPrimitiveNumber(pRight, BigDecimal JavaDoc.class, pLogger);
850             return pOperator.apply(left, right);
851         } else {
852             double left =
853                 coerceToPrimitiveNumber(pLeft, Double JavaDoc.class, pLogger).
854                 doubleValue();
855             double right =
856                 coerceToPrimitiveNumber(pRight, Double JavaDoc.class, pLogger).
857                 doubleValue();
858             return
859                 PrimitiveObjects.getDouble(pOperator.apply(left, right));
860         }
861     }
862
863     else if (isBigInteger(pLeft) || isBigInteger(pRight)) {
864         BigInteger JavaDoc left = (BigInteger JavaDoc)
865             coerceToPrimitiveNumber(pLeft, BigInteger JavaDoc.class, pLogger);
866         BigInteger JavaDoc right = (BigInteger JavaDoc)
867             coerceToPrimitiveNumber(pRight, BigInteger JavaDoc.class, pLogger);
868         return pOperator.apply(left, right);
869     }
870
871     else {
872       long left =
873     coerceToPrimitiveNumber (pLeft, Long JavaDoc.class, pLogger).
874     longValue ();
875       long right =
876     coerceToPrimitiveNumber (pRight, Long JavaDoc.class, pLogger).
877     longValue ();
878       return
879     PrimitiveObjects.getLong (pOperator.apply (left, right));
880     }
881   }
882
883   //-------------------------------------
884
/**
885    *
886    * Performs all of the necessary type conversions, then calls on the
887    * appropriate operator.
888    **/

889   public static Object JavaDoc applyRelationalOperator
890     (Object JavaDoc pLeft,
891      Object JavaDoc pRight,
892      RelationalOperator pOperator,
893      Logger pLogger)
894     throws ELException JavaDoc
895   {
896     if (isBigDecimal(pLeft) || isBigDecimal(pRight)) {
897         BigDecimal JavaDoc left = (BigDecimal JavaDoc)
898             coerceToPrimitiveNumber(pLeft, BigDecimal JavaDoc.class, pLogger);
899         BigDecimal JavaDoc right = (BigDecimal JavaDoc)
900             coerceToPrimitiveNumber(pRight, BigDecimal JavaDoc.class, pLogger);
901         return PrimitiveObjects.getBoolean(pOperator.apply(left, right));
902     }
903
904     else if (isFloatingPointType (pLeft) ||
905     isFloatingPointType (pRight)) {
906       double left =
907     coerceToPrimitiveNumber (pLeft, Double JavaDoc.class, pLogger).
908     doubleValue ();
909       double right =
910     coerceToPrimitiveNumber (pRight, Double JavaDoc.class, pLogger).
911     doubleValue ();
912       return
913     PrimitiveObjects.getBoolean (pOperator.apply (left, right));
914     }
915
916     else if (isBigInteger(pLeft) || isBigInteger(pRight)) {
917         BigInteger JavaDoc left = (BigInteger JavaDoc)
918             coerceToPrimitiveNumber(pLeft, BigInteger JavaDoc.class, pLogger);
919         BigInteger JavaDoc right = (BigInteger JavaDoc)
920             coerceToPrimitiveNumber(pRight, BigInteger JavaDoc.class, pLogger);
921         return PrimitiveObjects.getBoolean(pOperator.apply(left, right));
922     }
923
924     else if (isIntegerType (pLeft) ||
925          isIntegerType (pRight)) {
926       long left =
927     coerceToPrimitiveNumber (pLeft, Long JavaDoc.class, pLogger).
928     longValue ();
929       long right =
930     coerceToPrimitiveNumber (pRight, Long JavaDoc.class, pLogger).
931     longValue ();
932       return
933     PrimitiveObjects.getBoolean (pOperator.apply (left, right));
934     }
935
936     else if (pLeft instanceof String JavaDoc ||
937          pRight instanceof String JavaDoc) {
938       String JavaDoc left = coerceToString (pLeft, pLogger);
939       String JavaDoc right = coerceToString (pRight, pLogger);
940       return
941     PrimitiveObjects.getBoolean (pOperator.apply (left, right));
942     }
943
944     else if (pLeft instanceof Comparable JavaDoc) {
945       try {
946     int result = ((Comparable JavaDoc) pLeft).compareTo (pRight);
947     return
948       PrimitiveObjects.getBoolean
949       (pOperator.apply (result, -result));
950       }
951       catch (Exception JavaDoc exc) {
952     if (pLogger.isLoggingError ()) {
953       pLogger.logError
954         (Constants.COMPARABLE_ERROR,
955          exc,
956          pLeft.getClass ().getName (),
957          (pRight == null) ? "null" : pRight.getClass ().getName (),
958          pOperator.getOperatorSymbol ());
959     }
960     return Boolean.FALSE;
961       }
962     }
963
964     else if (pRight instanceof Comparable JavaDoc) {
965       try {
966     int result = ((Comparable JavaDoc) pRight).compareTo (pLeft);
967     return
968       PrimitiveObjects.getBoolean
969       (pOperator.apply (-result, result));
970       }
971       catch (Exception JavaDoc exc) {
972     if (pLogger.isLoggingError ()) {
973       pLogger.logError
974         (Constants.COMPARABLE_ERROR,
975          exc,
976          pRight.getClass ().getName (),
977          (pLeft == null) ? "null" : pLeft.getClass ().getName (),
978          pOperator.getOperatorSymbol ());
979     }
980     return Boolean.FALSE;
981       }
982     }
983
984     else {
985       if (pLogger.isLoggingError ()) {
986     pLogger.logError
987       (Constants.ARITH_OP_BAD_TYPE,
988        pOperator.getOperatorSymbol (),
989        pLeft.getClass ().getName (),
990        pRight.getClass ().getName ());
991       }
992       return Boolean.FALSE;
993     }
994   }
995
996   //-------------------------------------
997
/**
998    *
999    * Performs all of the necessary type conversions, then calls on the
1000   * appropriate operator.
1001   **/

1002  public static Object JavaDoc applyEqualityOperator
1003    (Object JavaDoc pLeft,
1004     Object JavaDoc pRight,
1005     EqualityOperator pOperator,
1006     Logger pLogger)
1007    throws ELException JavaDoc
1008  {
1009    if (pLeft == pRight) {
1010      return PrimitiveObjects.getBoolean (pOperator.apply (true, pLogger));
1011    }
1012
1013    else if (pLeft == null ||
1014         pRight == null) {
1015      return PrimitiveObjects.getBoolean (pOperator.apply (false, pLogger));
1016    }
1017
1018    else if (isBigDecimal(pLeft) || isBigDecimal(pRight)) {
1019        BigDecimal JavaDoc left = (BigDecimal JavaDoc)
1020            coerceToPrimitiveNumber(pLeft, BigDecimal JavaDoc.class, pLogger);
1021        BigDecimal JavaDoc right = (BigDecimal JavaDoc)
1022            coerceToPrimitiveNumber(pRight, BigDecimal JavaDoc.class, pLogger);
1023        return PrimitiveObjects.getBoolean(pOperator.apply(left.equals(right), pLogger));
1024    }
1025
1026    else if (isFloatingPointType (pLeft) ||
1027         isFloatingPointType (pRight)) {
1028      double left =
1029    coerceToPrimitiveNumber (pLeft, Double JavaDoc.class, pLogger).
1030    doubleValue ();
1031      double right =
1032    coerceToPrimitiveNumber (pRight, Double JavaDoc.class, pLogger).
1033    doubleValue ();
1034      return
1035    PrimitiveObjects.getBoolean
1036    (pOperator.apply (left == right, pLogger));
1037    }
1038
1039    else if (isBigInteger(pLeft) || isBigInteger(pRight)) {
1040        BigInteger JavaDoc left = (BigInteger JavaDoc)
1041            coerceToPrimitiveNumber(pLeft, BigInteger JavaDoc.class, pLogger);
1042        BigInteger JavaDoc right = (BigInteger JavaDoc)
1043            coerceToPrimitiveNumber(pRight, BigInteger JavaDoc.class, pLogger);
1044        return PrimitiveObjects.getBoolean(pOperator.apply(left.equals(right), pLogger));
1045    }
1046
1047    else if (isIntegerType (pLeft) ||
1048         isIntegerType (pRight)) {
1049      long left =
1050    coerceToPrimitiveNumber (pLeft, Long JavaDoc.class, pLogger).
1051    longValue ();
1052      long right =
1053    coerceToPrimitiveNumber (pRight, Long JavaDoc.class, pLogger).
1054    longValue ();
1055      return
1056    PrimitiveObjects.getBoolean
1057    (pOperator.apply (left == right, pLogger));
1058    }
1059
1060    else if (pLeft instanceof Boolean JavaDoc ||
1061         pRight instanceof Boolean JavaDoc) {
1062      boolean left = coerceToBoolean (pLeft, pLogger).booleanValue ();
1063      boolean right = coerceToBoolean (pRight, pLogger).booleanValue ();
1064      return
1065    PrimitiveObjects.getBoolean
1066    (pOperator.apply (left == right, pLogger));
1067    }
1068
1069    else if (pLeft instanceof String JavaDoc ||
1070         pRight instanceof String JavaDoc) {
1071      String JavaDoc left = coerceToString (pLeft, pLogger);
1072      String JavaDoc right = coerceToString (pRight, pLogger);
1073      return
1074    PrimitiveObjects.getBoolean
1075    (pOperator.apply (left.equals (right), pLogger));
1076    }
1077
1078    else {
1079      try {
1080      return
1081    PrimitiveObjects.getBoolean
1082    (pOperator.apply (pLeft.equals (pRight), pLogger));
1083      }
1084      catch (Exception JavaDoc exc) {
1085    if (pLogger.isLoggingError ()) {
1086      pLogger.logError
1087        (Constants.ERROR_IN_EQUALS,
1088         exc,
1089         pLeft.getClass ().getName (),
1090         pRight.getClass ().getName (),
1091         pOperator.getOperatorSymbol ());
1092    }
1093    return Boolean.FALSE;
1094      }
1095    }
1096  }
1097
1098  //-------------------------------------
1099
/**
1100   *
1101   * Returns true if the given Object is of a floating point type
1102   **/

1103  public static boolean isFloatingPointType (Object JavaDoc pObject)
1104  {
1105    return
1106      pObject != null &&
1107      isFloatingPointType (pObject.getClass ());
1108  }
1109
1110  //-------------------------------------
1111
/**
1112   *
1113   * Returns true if the given class is of a floating point type
1114   **/

1115  public static boolean isFloatingPointType (Class JavaDoc pClass)
1116  {
1117    return
1118      pClass == Float JavaDoc.class ||
1119      pClass == Float.TYPE ||
1120      pClass == Double JavaDoc.class ||
1121      pClass == Double.TYPE;
1122  }
1123
1124  //-------------------------------------
1125
/**
1126   *
1127   * Returns true if the given string might contain a floating point
1128   * number - i.e., it contains ".", "e", or "E"
1129   **/

1130  public static boolean isFloatingPointString (Object JavaDoc pObject)
1131  {
1132    if (pObject instanceof String JavaDoc) {
1133      String JavaDoc str = (String JavaDoc) pObject;
1134      int len = str.length ();
1135      for (int i = 0; i < len; i++) {
1136    char ch = str.charAt (i);
1137    if (ch == '.' ||
1138        ch == 'e' ||
1139        ch == 'E') {
1140      return true;
1141    }
1142      }
1143      return false;
1144    }
1145    else {
1146      return false;
1147    }
1148  }
1149
1150  //-------------------------------------
1151
/**
1152   *
1153   * Returns true if the given Object is of an integer type
1154   **/

1155  public static boolean isIntegerType (Object JavaDoc pObject)
1156  {
1157    return
1158      pObject != null &&
1159      isIntegerType (pObject.getClass ());
1160  }
1161
1162  //-------------------------------------
1163
/**
1164   *
1165   * Returns true if the given class is of an integer type
1166   **/

1167  public static boolean isIntegerType (Class JavaDoc pClass)
1168  {
1169    return
1170      pClass == Byte JavaDoc.class ||
1171      pClass == Byte.TYPE ||
1172      pClass == Short JavaDoc.class ||
1173      pClass == Short.TYPE ||
1174      pClass == Character JavaDoc.class ||
1175      pClass == Character.TYPE ||
1176      pClass == Integer JavaDoc.class ||
1177      pClass == Integer.TYPE ||
1178      pClass == Long JavaDoc.class ||
1179      pClass == Long.TYPE;
1180  }
1181
1182  //-------------------------------------
1183

1184  /**
1185   * Returns true if the given object is BigInteger.
1186   * @param pObject - Object to evaluate
1187   * @return - true if the given object is BigInteger
1188   */

1189  public static boolean isBigInteger(Object JavaDoc pObject) {
1190      return
1191          pObject != null && pObject instanceof BigInteger JavaDoc;
1192  }
1193
1194  /**
1195   * Returns true if the given object is BigDecimal.
1196   * @param pObject - Object to evaluate
1197   * @return - true if the given object is BigDecimal
1198   */

1199  public static boolean isBigDecimal(Object JavaDoc pObject) {
1200      return
1201          pObject != null && pObject instanceof BigDecimal JavaDoc;
1202  }
1203}
1204
Popular Tags