Source Code Cross Referenced for OgnlOps.java in  » Scripting » OGNL » ognl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Scripting » OGNL » ognl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        //--------------------------------------------------------------------------
002:        //	Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
003:        //  All rights reserved.
004:        //
005:        //	Redistribution and use in source and binary forms, with or without
006:        //  modification, are permitted provided that the following conditions are
007:        //  met:
008:        //
009:        //	Redistributions of source code must retain the above copyright notice,
010:        //  this list of conditions and the following disclaimer.
011:        //	Redistributions in binary form must reproduce the above copyright
012:        //  notice, this list of conditions and the following disclaimer in the
013:        //  documentation and/or other materials provided with the distribution.
014:        //	Neither the name of the Drew Davidson nor the names of its contributors
015:        //  may be used to endorse or promote products derived from this software
016:        //  without specific prior written permission.
017:        //
018:        //	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
019:        //  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
020:        //  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
021:        //  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
022:        //  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
023:        //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
024:        //  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
025:        //  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
026:        //  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
027:        //  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
028:        //  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
029:        //  DAMAGE.
030:        //--------------------------------------------------------------------------
031:        package ognl;
032:
033:        import java.lang.reflect.Array;
034:        import java.math.BigDecimal;
035:        import java.math.BigInteger;
036:        import java.util.Enumeration;
037:
038:        /**
039:         * This is an abstract class with static methods that define the operations of OGNL.
040:         * @author Luke Blanshard (blanshlu@netscape.net)
041:         * @author Drew Davidson (drew@ognl.org)
042:         */
043:        public abstract class OgnlOps implements  NumericTypes {
044:            /**
045:             * Compares two objects for equality, even if it has to convert
046:             * one of them to the other type.  If both objects are numeric
047:             * they are converted to the widest type and compared.  If
048:             * one is non-numeric and one is numeric the non-numeric is
049:             * converted to double and compared to the double numeric
050:             * value.  If both are non-numeric and Comparable and the
051:             * types are compatible (i.e. v1 is of the same or superclass
052:             * of v2's type) they are compared with Comparable.compareTo().
053:             * If both values are non-numeric and not Comparable or of
054:             * incompatible classes this will throw and IllegalArgumentException.
055:             *
056:             * @param v1    First value to compare
057:             * @param v2    second value to compare
058:             *
059:             * @return integer describing the comparison between the two objects.
060:             *          A negative number indicates that v1 < v2.  Positive indicates
061:             *          that v1 > v2.  Zero indicates v1 == v2.
062:             *
063:             * @throws IllegalArgumentException if the objects are both non-numeric
064:             *              yet of incompatible types or do not implement Comparable.
065:             */
066:            public static int compareWithConversion(Object v1, Object v2) {
067:                return compareWithConversion(v1, v2, false);
068:            }
069:
070:            /**
071:             * Compares two objects for equality, even if it has to convert
072:             * one of them to the other type.  If both objects are numeric
073:             * they are converted to the widest type and compared.  If
074:             * one is non-numeric and one is numeric the non-numeric is
075:             * converted to double and compared to the double numeric
076:             * value.  If both are non-numeric and Comparable and the
077:             * types are compatible (i.e. v1 is of the same or superclass
078:             * of v2's type) they are compared with Comparable.compareTo().
079:             * If both values are non-numeric and not Comparable or of
080:             * incompatible classes this will throw and IllegalArgumentException.
081:             *
082:             * @param v1    First value to compare
083:             * @param v2    second value to compare
084:             *
085:             * @return integer describing the comparison between the two objects.
086:             *          A negative number indicates that v1 < v2.  Positive indicates
087:             *          that v1 > v2.  Zero indicates v1 == v2.
088:             *
089:             * @throws IllegalArgumentException if the objects are both non-numeric
090:             *              yet of incompatible types or do not implement Comparable.
091:             */
092:            public static int compareWithConversion(Object v1, Object v2,
093:                    boolean equals) {
094:                int result;
095:
096:                if (v1 == v2) {
097:                    result = 0;
098:                } else {
099:                    int t1 = getNumericType(v1), t2 = getNumericType(v2), type = getNumericType(
100:                            t1, t2, true);
101:
102:                    switch (type) {
103:                    case BIGINT:
104:                        result = bigIntValue(v1).compareTo(bigIntValue(v2));
105:                        break;
106:
107:                    case BIGDEC:
108:                        result = bigDecValue(v1).compareTo(bigDecValue(v2));
109:                        break;
110:
111:                    case NONNUMERIC:
112:                        if ((t1 == NONNUMERIC) && (t2 == NONNUMERIC)) {
113:                            if ((v1 == null) || (v2 == null)) {
114:                                result = (v1 == v2) ? 0 : 1;
115:                            } else {
116:                                if (v1.getClass().isAssignableFrom(
117:                                        v2.getClass())
118:                                        || v2.getClass().isAssignableFrom(
119:                                                v1.getClass())) {
120:                                    if (v1 instanceof  Comparable) {
121:                                        result = ((Comparable) v1)
122:                                                .compareTo(v2);
123:                                        break;
124:                                    } else {
125:                                        if (equals) {
126:                                            result = v1.equals(v2) ? 0 : 1;
127:                                            break;
128:                                        }
129:                                    }
130:                                }
131:                                if (equals) {
132:                                    // Equals comparison between non-numerics that are not of a common
133:                                    // superclass return not equal
134:                                    result = 1;
135:                                    break;
136:                                } else {
137:                                    throw new IllegalArgumentException(
138:                                            "invalid comparison: "
139:                                                    + v1.getClass().getName()
140:                                                    + " and "
141:                                                    + v2.getClass().getName());
142:                                }
143:                            }
144:                        }
145:                        // else fall through
146:                    case FLOAT:
147:                    case DOUBLE:
148:                        double dv1 = doubleValue(v1),
149:                        dv2 = doubleValue(v2);
150:
151:                        return (dv1 == dv2) ? 0 : ((dv1 < dv2) ? -1 : 1);
152:
153:                    default:
154:                        long lv1 = longValue(v1),
155:                        lv2 = longValue(v2);
156:
157:                        return (lv1 == lv2) ? 0 : ((lv1 < lv2) ? -1 : 1);
158:                    }
159:                }
160:                return result;
161:            }
162:
163:            /**
164:             * Returns true if object1 is equal to object2 in either the
165:             * sense that they are the same object or, if both are non-null
166:             * if they are equal in the <CODE>equals()</CODE> sense.
167:             *
168:             * @param v1 First object to compare
169:             * @param v2 Second object to compare
170:             *
171:             * @return true if v1 == v2
172:             */
173:            public static boolean isEqual(Object object1, Object object2) {
174:                boolean result = false;
175:
176:                if (object1 == object2) {
177:                    result = true;
178:                } else {
179:                    if ((object1 != null) && (object2 != null)) {
180:                        if (object1.getClass().isArray()
181:                                && object2.getClass().isArray()
182:                                && (object2.getClass() == object1.getClass())) {
183:                            result = (Array.getLength(object1) == Array
184:                                    .getLength(object2));
185:                            if (result) {
186:                                for (int i = 0, icount = Array
187:                                        .getLength(object1); result
188:                                        && (i < icount); i++) {
189:                                    result = isEqual(Array.get(object1, i),
190:                                            Array.get(object2, i));
191:                                }
192:                            }
193:                        } else {
194:                            if ((object1 != null) && (object2 != null)) {
195:                                // Check for converted equivalence first, then equals() equivalence
196:                                result = (compareWithConversion(object1,
197:                                        object2, true) == 0)
198:                                        || object1.equals(object2);
199:                            }
200:                        }
201:                    }
202:                }
203:                return result;
204:            }
205:
206:            /**
207:             * Evaluates the given object as a boolean: if it is a Boolean object, it's easy; if
208:             * it's a Number or a Character, returns true for non-zero objects; and otherwise
209:             * returns true for non-null objects.
210:             *
211:             * @param value an object to interpret as a boolean
212:             * @return the boolean value implied by the given object
213:             */
214:            public static boolean booleanValue(Object value) {
215:                if (value == null)
216:                    return false;
217:                Class c = value.getClass();
218:                if (c == Boolean.class)
219:                    return ((Boolean) value).booleanValue();
220:                //        if ( c == String.class )
221:                //            return ((String)value).length() > 0;
222:                if (c == Character.class)
223:                    return ((Character) value).charValue() != 0;
224:                if (value instanceof  Number)
225:                    return ((Number) value).doubleValue() != 0;
226:                return true; // non-null
227:            }
228:
229:            /**
230:             * Evaluates the given object as a long integer.
231:             *
232:             * @param value an object to interpret as a long integer
233:             * @return the long integer value implied by the given object
234:             * @throws NumberFormatException if the given object can't be understood as a long integer
235:             */
236:            public static long longValue(Object value)
237:                    throws NumberFormatException {
238:                if (value == null)
239:                    return 0L;
240:                Class c = value.getClass();
241:                if (c.getSuperclass() == Number.class)
242:                    return ((Number) value).longValue();
243:                if (c == Boolean.class)
244:                    return ((Boolean) value).booleanValue() ? 1 : 0;
245:                if (c == Character.class)
246:                    return ((Character) value).charValue();
247:                return Long.parseLong(stringValue(value, true));
248:            }
249:
250:            /**
251:             * Evaluates the given object as a double-precision floating-point number.
252:             *
253:             * @param value an object to interpret as a double
254:             * @return the double value implied by the given object
255:             * @throws NumberFormatException if the given object can't be understood as a double
256:             */
257:            public static double doubleValue(Object value)
258:                    throws NumberFormatException {
259:                if (value == null)
260:                    return 0.0;
261:                Class c = value.getClass();
262:                if (c.getSuperclass() == Number.class)
263:                    return ((Number) value).doubleValue();
264:                if (c == Boolean.class)
265:                    return ((Boolean) value).booleanValue() ? 1 : 0;
266:                if (c == Character.class)
267:                    return ((Character) value).charValue();
268:                String s = stringValue(value, true);
269:
270:                return (s.length() == 0) ? 0.0 : Double.parseDouble(s);
271:                /*
272:                    For 1.1 parseDouble() is not available
273:                 */
274:                //return Double.valueOf( value.toString() ).doubleValue();
275:            }
276:
277:            /**
278:             * Evaluates the given object as a BigInteger.
279:             *
280:             * @param value an object to interpret as a BigInteger
281:             * @return the BigInteger value implied by the given object
282:             * @throws NumberFormatException if the given object can't be understood as a BigInteger
283:             */
284:            public static BigInteger bigIntValue(Object value)
285:                    throws NumberFormatException {
286:                if (value == null)
287:                    return BigInteger.valueOf(0L);
288:                Class c = value.getClass();
289:                if (c == BigInteger.class)
290:                    return (BigInteger) value;
291:                if (c == BigDecimal.class)
292:                    return ((BigDecimal) value).toBigInteger();
293:                if (c.getSuperclass() == Number.class)
294:                    return BigInteger.valueOf(((Number) value).longValue());
295:                if (c == Boolean.class)
296:                    return BigInteger
297:                            .valueOf(((Boolean) value).booleanValue() ? 1 : 0);
298:                if (c == Character.class)
299:                    return BigInteger.valueOf(((Character) value).charValue());
300:                return new BigInteger(stringValue(value, true));
301:            }
302:
303:            /**
304:             * Evaluates the given object as a BigDecimal.
305:             *
306:             * @param value an object to interpret as a BigDecimal
307:             * @return the BigDecimal value implied by the given object
308:             * @throws NumberFormatException if the given object can't be understood as a BigDecimal
309:             */
310:            public static BigDecimal bigDecValue(Object value)
311:                    throws NumberFormatException {
312:                if (value == null)
313:                    return BigDecimal.valueOf(0L);
314:                Class c = value.getClass();
315:                if (c == BigDecimal.class)
316:                    return (BigDecimal) value;
317:                if (c == BigInteger.class)
318:                    return new BigDecimal((BigInteger) value);
319:                if (c.getSuperclass() == Number.class)
320:                    return new BigDecimal(((Number) value).doubleValue());
321:                if (c == Boolean.class)
322:                    return BigDecimal
323:                            .valueOf(((Boolean) value).booleanValue() ? 1 : 0);
324:                if (c == Character.class)
325:                    return BigDecimal.valueOf(((Character) value).charValue());
326:                return new BigDecimal(stringValue(value, true));
327:            }
328:
329:            /**
330:             * Evaluates the given object as a String and trims it if the trim flag is true.
331:             *
332:             * @param value an object to interpret as a String
333:             * @return the String value implied by the given object as returned by the toString() method,
334:                      or "null" if the object is null.
335:             */
336:            public static String stringValue(Object value, boolean trim) {
337:                String result;
338:
339:                if (value == null) {
340:                    result = OgnlRuntime.NULL_STRING;
341:                } else {
342:                    result = value.toString();
343:                    if (trim) {
344:                        result = result.trim();
345:                    }
346:                }
347:                return result;
348:            }
349:
350:            /**
351:             * Evaluates the given object as a String.
352:             *
353:             * @param value an object to interpret as a String
354:             * @return the String value implied by the given object as returned by the toString() method,
355:                      or "null" if the object is null.
356:             */
357:            public static String stringValue(Object value) {
358:                return stringValue(value, false);
359:            }
360:
361:            /**
362:             * Returns a constant from the NumericTypes interface that represents the numeric
363:             * type of the given object.
364:             *
365:             * @param value an object that needs to be interpreted as a number
366:             * @return the appropriate constant from the NumericTypes interface
367:             */
368:            public static int getNumericType(Object value) {
369:                int result = NONNUMERIC;
370:
371:                if (value != null) {
372:                    Class c = value.getClass();
373:                    if (c == Integer.class)
374:                        return INT;
375:                    if (c == Double.class)
376:                        return DOUBLE;
377:                    if (c == Boolean.class)
378:                        return BOOL;
379:                    if (c == Byte.class)
380:                        return BYTE;
381:                    if (c == Character.class)
382:                        return CHAR;
383:                    if (c == Short.class)
384:                        return SHORT;
385:                    if (c == Long.class)
386:                        return LONG;
387:                    if (c == Float.class)
388:                        return FLOAT;
389:                    if (c == BigInteger.class)
390:                        return BIGINT;
391:                    if (c == BigDecimal.class)
392:                        return BIGDEC;
393:                }
394:                return NONNUMERIC;
395:            }
396:
397:            /**
398:             * Returns the value converted numerically to the given class type
399:             *
400:             * This method also detects when arrays are being converted and
401:             * converts the components of one array to the type of the other.
402:             *
403:             * @param value an object to be converted to the given type
404:             * @param toType class type to be converted to
405:             * @return converted value of the type given, or value if the value
406:             *                cannot be converted to the given type.
407:             */
408:            public static Object convertValue(Object value, Class toType) {
409:                Object result = null;
410:
411:                if (value != null) {
412:                    /* If array -> array then convert components of array individually */
413:                    if (value.getClass().isArray() && toType.isArray()) {
414:                        Class componentType = toType.getComponentType();
415:
416:                        result = Array.newInstance(componentType, Array
417:                                .getLength(value));
418:                        for (int i = 0, icount = Array.getLength(value); i < icount; i++) {
419:                            Array.set(result, i, convertValue(Array.get(value,
420:                                    i), componentType));
421:                        }
422:                    } else {
423:                        if ((toType == Integer.class)
424:                                || (toType == Integer.TYPE))
425:                            result = new Integer((int) longValue(value));
426:                        if ((toType == Double.class) || (toType == Double.TYPE))
427:                            result = new Double(doubleValue(value));
428:                        if ((toType == Boolean.class)
429:                                || (toType == Boolean.TYPE))
430:                            result = booleanValue(value) ? Boolean.TRUE
431:                                    : Boolean.FALSE;
432:                        if ((toType == Byte.class) || (toType == Byte.TYPE))
433:                            result = new Byte((byte) longValue(value));
434:                        if ((toType == Character.class)
435:                                || (toType == Character.TYPE))
436:                            result = new Character((char) longValue(value));
437:                        if ((toType == Short.class) || (toType == Short.TYPE))
438:                            result = new Short((short) longValue(value));
439:                        if ((toType == Long.class) || (toType == Long.TYPE))
440:                            result = new Long(longValue(value));
441:                        if ((toType == Float.class) || (toType == Float.TYPE))
442:                            result = new Float(doubleValue(value));
443:                        if (toType == BigInteger.class)
444:                            result = bigIntValue(value);
445:                        if (toType == BigDecimal.class)
446:                            result = bigDecValue(value);
447:                        if (toType == String.class)
448:                            result = stringValue(value);
449:                    }
450:                } else {
451:                    if (toType.isPrimitive()) {
452:                        result = OgnlRuntime.getPrimitiveDefaultValue(toType);
453:                    }
454:                }
455:                return result;
456:            }
457:
458:            /**
459:             * Returns the constant from the NumericTypes interface that best expresses the type
460:             * of a numeric operation on the two given objects.
461:             *
462:             * @param v1 one argument to a numeric operator
463:             * @param v2 the other argument
464:             * @return the appropriate constant from the NumericTypes interface
465:             */
466:            public static int getNumericType(Object v1, Object v2) {
467:                return getNumericType(v1, v2, false);
468:            }
469:
470:            /**
471:             * Returns the constant from the NumericTypes interface that best expresses the type
472:             * of an operation, which can be either numeric or not, on the two given types.
473:             *
474:             * @param t1 type of one argument to an operator
475:             * @param t2 type of the other argument
476:             * @param canBeNonNumeric whether the operator can be interpreted as non-numeric
477:             * @return the appropriate constant from the NumericTypes interface
478:             */
479:            public static int getNumericType(int t1, int t2,
480:                    boolean canBeNonNumeric) {
481:                if (t1 == t2)
482:                    return t1;
483:
484:                if (canBeNonNumeric
485:                        && (t1 == NONNUMERIC || t2 == NONNUMERIC || t1 == CHAR || t2 == CHAR))
486:                    return NONNUMERIC;
487:
488:                if (t1 == NONNUMERIC)
489:                    t1 = DOUBLE; // Try to interpret strings as doubles...
490:                if (t2 == NONNUMERIC)
491:                    t2 = DOUBLE; // Try to interpret strings as doubles...
492:
493:                if (t1 >= MIN_REAL_TYPE) {
494:                    if (t2 >= MIN_REAL_TYPE)
495:                        return Math.max(t1, t2);
496:                    if (t2 < INT)
497:                        return t1;
498:                    if (t2 == BIGINT)
499:                        return BIGDEC;
500:                    return Math.max(DOUBLE, t1);
501:                } else if (t2 >= MIN_REAL_TYPE) {
502:                    if (t1 < INT)
503:                        return t2;
504:                    if (t1 == BIGINT)
505:                        return BIGDEC;
506:                    return Math.max(DOUBLE, t2);
507:                } else
508:                    return Math.max(t1, t2);
509:            }
510:
511:            /**
512:             * Returns the constant from the NumericTypes interface that best expresses the type
513:             * of an operation, which can be either numeric or not, on the two given objects.
514:             *
515:             * @param v1 one argument to an operator
516:             * @param v2 the other argument
517:             * @param canBeNonNumeric whether the operator can be interpreted as non-numeric
518:             * @return the appropriate constant from the NumericTypes interface
519:             */
520:            public static int getNumericType(Object v1, Object v2,
521:                    boolean canBeNonNumeric) {
522:                return getNumericType(getNumericType(v1), getNumericType(v2),
523:                        canBeNonNumeric);
524:            }
525:
526:            /**
527:             * Returns a new Number object of an appropriate type to hold the given integer
528:             * value.  The type of the returned object is consistent with the given type
529:             * argument, which is a constant from the NumericTypes interface.
530:             *
531:             * @param type    the nominal numeric type of the result, a constant from the NumericTypes interface
532:             * @param value   the integer value to convert to a Number object
533:             * @return        a Number object with the given value, of type implied by the type argument
534:             */
535:            public static Number newInteger(int type, long value) {
536:                switch (type) {
537:                case BOOL:
538:                case CHAR:
539:                case INT:
540:                    return new Integer((int) value);
541:
542:                case FLOAT:
543:                    if ((long) (float) value == value) {
544:                        return new Float((float) value);
545:                    }
546:                    // else fall through:
547:                case DOUBLE:
548:                    if ((long) (double) value == value) {
549:                        return new Double((double) value);
550:                    }
551:                    // else fall through:
552:                case LONG:
553:                    return new Long(value);
554:
555:                case BYTE:
556:                    return new Byte((byte) value);
557:
558:                case SHORT:
559:                    return new Short((short) value);
560:
561:                default:
562:                    return BigInteger.valueOf(value);
563:                }
564:            }
565:
566:            /**
567:             * Returns a new Number object of an appropriate type to hold the given real value.
568:             * The type of the returned object is always either Float or Double, and is only
569:             * Float if the given type tag (a constant from the NumericTypes interface) is
570:             * FLOAT.
571:             *
572:             * @param type    the nominal numeric type of the result, a constant from the NumericTypes interface
573:             * @param value   the real value to convert to a Number object
574:             * @return        a Number object with the given value, of type implied by the type argument
575:             */
576:            public static Number newReal(int type, double value) {
577:                if (type == FLOAT)
578:                    return new Float((float) value);
579:                return new Double(value);
580:            }
581:
582:            public static Object binaryOr(Object v1, Object v2) {
583:                int type = getNumericType(v1, v2);
584:                if (type == BIGINT || type == BIGDEC)
585:                    return bigIntValue(v1).or(bigIntValue(v2));
586:                return newInteger(type, longValue(v1) | longValue(v2));
587:            }
588:
589:            public static Object binaryXor(Object v1, Object v2) {
590:                int type = getNumericType(v1, v2);
591:                if (type == BIGINT || type == BIGDEC)
592:                    return bigIntValue(v1).xor(bigIntValue(v2));
593:                return newInteger(type, longValue(v1) ^ longValue(v2));
594:            }
595:
596:            public static Object binaryAnd(Object v1, Object v2) {
597:                int type = getNumericType(v1, v2);
598:                if (type == BIGINT || type == BIGDEC)
599:                    return bigIntValue(v1).and(bigIntValue(v2));
600:                return newInteger(type, longValue(v1) & longValue(v2));
601:            }
602:
603:            public static boolean equal(Object v1, Object v2) {
604:                if (v1 == null)
605:                    return v2 == null;
606:                if (v1 == v2 || isEqual(v1, v2))
607:                    return true;
608:                if (v1 instanceof  Number && v2 instanceof  Number)
609:                    return ((Number) v1).doubleValue() == ((Number) v2)
610:                            .doubleValue();
611:                return false;
612:            }
613:
614:            public static boolean less(Object v1, Object v2) {
615:                return compareWithConversion(v1, v2) < 0;
616:            }
617:
618:            public static boolean greater(Object v1, Object v2) {
619:                return compareWithConversion(v1, v2) > 0;
620:            }
621:
622:            public static boolean in(Object v1, Object v2) throws OgnlException {
623:                if (v2 == null) // A null collection is always treated as empty
624:                    return false;
625:
626:                ElementsAccessor elementsAccessor = OgnlRuntime
627:                        .getElementsAccessor(OgnlRuntime.getTargetClass(v2));
628:                for (Enumeration e = elementsAccessor.getElements(v2); e
629:                        .hasMoreElements();) {
630:                    Object o = e.nextElement();
631:
632:                    if (equal(v1, o))
633:                        return true;
634:                }
635:                return false;
636:            }
637:
638:            public static Object shiftLeft(Object v1, Object v2) {
639:                int type = getNumericType(v1);
640:                if (type == BIGINT || type == BIGDEC)
641:                    return bigIntValue(v1).shiftLeft((int) longValue(v2));
642:                return newInteger(type, longValue(v1) << (int) longValue(v2));
643:            }
644:
645:            public static Object shiftRight(Object v1, Object v2) {
646:                int type = getNumericType(v1);
647:                if (type == BIGINT || type == BIGDEC)
648:                    return bigIntValue(v1).shiftRight((int) longValue(v2));
649:                return newInteger(type, longValue(v1) >> (int) longValue(v2));
650:            }
651:
652:            public static Object unsignedShiftRight(Object v1, Object v2) {
653:                int type = getNumericType(v1);
654:                if (type == BIGINT || type == BIGDEC)
655:                    return bigIntValue(v1).shiftRight((int) longValue(v2));
656:                if (type <= INT)
657:                    return newInteger(INT,
658:                            ((int) longValue(v1)) >>> (int) longValue(v2));
659:                return newInteger(type, longValue(v1) >>> (int) longValue(v2));
660:            }
661:
662:            public static Object add(Object v1, Object v2) {
663:                int type = getNumericType(v1, v2, true);
664:                switch (type) {
665:                case BIGINT:
666:                    return bigIntValue(v1).add(bigIntValue(v2));
667:                case BIGDEC:
668:                    return bigDecValue(v1).add(bigDecValue(v2));
669:                case FLOAT:
670:                case DOUBLE:
671:                    return newReal(type, doubleValue(v1) + doubleValue(v2));
672:                case NONNUMERIC:
673:                    int t1 = getNumericType(v1),
674:                    t2 = getNumericType(v2);
675:
676:                    if (((t1 != NONNUMERIC) && (v2 == null))
677:                            || ((t2 != NONNUMERIC) && (v1 == null))) {
678:                        throw new NullPointerException();
679:                    }
680:                    return stringValue(v1) + stringValue(v2);
681:                default:
682:                    return newInteger(type, longValue(v1) + longValue(v2));
683:                }
684:            }
685:
686:            public static Object subtract(Object v1, Object v2) {
687:                int type = getNumericType(v1, v2);
688:                switch (type) {
689:                case BIGINT:
690:                    return bigIntValue(v1).subtract(bigIntValue(v2));
691:                case BIGDEC:
692:                    return bigDecValue(v1).subtract(bigDecValue(v2));
693:                case FLOAT:
694:                case DOUBLE:
695:                    return newReal(type, doubleValue(v1) - doubleValue(v2));
696:                default:
697:                    return newInteger(type, longValue(v1) - longValue(v2));
698:                }
699:            }
700:
701:            public static Object multiply(Object v1, Object v2) {
702:                int type = getNumericType(v1, v2);
703:                switch (type) {
704:                case BIGINT:
705:                    return bigIntValue(v1).multiply(bigIntValue(v2));
706:                case BIGDEC:
707:                    return bigDecValue(v1).multiply(bigDecValue(v2));
708:                case FLOAT:
709:                case DOUBLE:
710:                    return newReal(type, doubleValue(v1) * doubleValue(v2));
711:                default:
712:                    return newInteger(type, longValue(v1) * longValue(v2));
713:                }
714:            }
715:
716:            public static Object divide(Object v1, Object v2) {
717:                int type = getNumericType(v1, v2);
718:                switch (type) {
719:                case BIGINT:
720:                    return bigIntValue(v1).divide(bigIntValue(v2));
721:                case BIGDEC:
722:                    return bigDecValue(v1).divide(bigDecValue(v2),
723:                            BigDecimal.ROUND_HALF_EVEN);
724:                case FLOAT:
725:                case DOUBLE:
726:                    return newReal(type, doubleValue(v1) / doubleValue(v2));
727:                default:
728:                    return newInteger(type, longValue(v1) / longValue(v2));
729:                }
730:            }
731:
732:            public static Object remainder(Object v1, Object v2) {
733:                int type = getNumericType(v1, v2);
734:                switch (type) {
735:                case BIGDEC:
736:                case BIGINT:
737:                    return bigIntValue(v1).remainder(bigIntValue(v2));
738:                default:
739:                    return newInteger(type, longValue(v1) % longValue(v2));
740:                }
741:            }
742:
743:            public static Object negate(Object value) {
744:                int type = getNumericType(value);
745:                switch (type) {
746:                case BIGINT:
747:                    return bigIntValue(value).negate();
748:                case BIGDEC:
749:                    return bigDecValue(value).negate();
750:                case FLOAT:
751:                case DOUBLE:
752:                    return newReal(type, -doubleValue(value));
753:                default:
754:                    return newInteger(type, -longValue(value));
755:                }
756:            }
757:
758:            public static Object bitNegate(Object value) {
759:                int type = getNumericType(value);
760:                switch (type) {
761:                case BIGDEC:
762:                case BIGINT:
763:                    return bigIntValue(value).not();
764:                default:
765:                    return newInteger(type, ~longValue(value));
766:                }
767:            }
768:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.