View Javadoc

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 }