📄 ognlops.java
字号:
//--------------------------------------------------------------------------
// Copyright (c) 1998-2004, Drew Davidson and Luke Blanshard
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// Neither the name of the Drew Davidson nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
// OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//--------------------------------------------------------------------------
package ognl;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Enumeration;
/**
* This is an abstract class with static methods that define the operations of OGNL.
* @author Luke Blanshard (blanshlu@netscape.net)
* @author Drew Davidson (drew@ognl.org)
*/
public abstract class OgnlOps implements NumericTypes
{
/**
* Compares two objects for equality, even if it has to convert
* one of them to the other type. If both objects are numeric
* they are converted to the widest type and compared. If
* one is non-numeric and one is numeric the non-numeric is
* converted to double and compared to the double numeric
* value. If both are non-numeric and Comparable and the
* types are compatible (i.e. v1 is of the same or superclass
* of v2's type) they are compared with Comparable.compareTo().
* If both values are non-numeric and not Comparable or of
* incompatible classes this will throw and IllegalArgumentException.
*
* @param v1 First value to compare
* @param v2 second value to compare
*
* @return integer describing the comparison between the two objects.
* A negative number indicates that v1 < v2. Positive indicates
* that v1 > v2. Zero indicates v1 == v2.
*
* @throws IllegalArgumentException if the objects are both non-numeric
* yet of incompatible types or do not implement Comparable.
*/
public static int compareWithConversion( Object v1, Object v2 )
{
int result;
if (v1 == v2) {
result = 0;
} else {
int t1 = getNumericType(v1),
t2 = getNumericType(v2),
type = getNumericType(t1, t2, true);
switch (type) {
case BIGINT:
result = bigIntValue(v1).compareTo(bigIntValue(v2));
break;
case BIGDEC:
result = bigDecValue(v1).compareTo(bigDecValue(v2));
break;
case NONNUMERIC:
if ((t1 == NONNUMERIC) && (t2 == NONNUMERIC)) {
if ((v1 instanceof Comparable) && v1.getClass().isAssignableFrom(v2.getClass())) {
result = ((Comparable)v1).compareTo(v2);
break;
} else {
throw new IllegalArgumentException("invalid comparison: " + v1.getClass().getName() + " and " + v2.getClass().getName());
}
}
// else fall through
case FLOAT:
case DOUBLE:
double dv1 = doubleValue(v1),
dv2 = doubleValue(v2);
return (dv1 == dv2) ? 0 : ((dv1 < dv2) ? -1 : 1);
default:
long lv1 = longValue(v1),
lv2 = longValue(v2);
return (lv1 == lv2) ? 0 : ((lv1 < lv2) ? -1 : 1);
}
}
return result;
}
/**
* Returns true if object1 is equal to object2 in either the
* sense that they are the same object or, if both are non-null
* if they are equal in the <CODE>equals()</CODE> sense.
*
* @param v1 First object to compare
* @param v2 Second object to compare
*
* @return true if v1 == v2
*/
public static boolean isEqual(Object object1, Object object2)
{
boolean result = false;
if (object1 == object2) {
result = true;
} else {
if ((object1 != null) && object1.getClass().isArray()) {
if ((object2 != null) && object2.getClass().isArray() && (object2.getClass() == object1.getClass())) {
result = (Array.getLength(object1) == Array.getLength(object2));
if (result) {
for (int i = 0, icount = Array.getLength(object1); result && (i < icount); i++) {
result = isEqual(Array.get(object1, i), Array.get(object2, i));
}
}
}
} else {
// Check for converted equivalence first, then equals() equivalence
result = (object1 != null) && (object2 != null) &&
((compareWithConversion(object1, object2) == 0) || object1.equals(object2));
}
}
return result;
}
/**
* Evaluates the given object as a boolean: if it is a Boolean object, it's easy; if
* it's a Number or a Character, returns true for non-zero objects; and otherwise
* returns true for non-null objects.
*
* @param value an object to interpret as a boolean
* @return the boolean value implied by the given object
*/
public static boolean booleanValue( Object value )
{
if ( value == null )
return false;
Class c = value.getClass();
if ( c == Boolean.class )
return ((Boolean)value).booleanValue();
// if ( c == String.class )
// return ((String)value).length() > 0;
if ( c == Character.class )
return ((Character)value).charValue() != 0;
if ( value instanceof Number )
return ((Number)value).doubleValue() != 0;
return true; // non-null
}
/**
* Evaluates the given object as a long integer.
*
* @param value an object to interpret as a long integer
* @return the long integer value implied by the given object
* @throws NumberFormatException if the given object can't be understood as a long integer
*/
public static long longValue( Object value ) throws NumberFormatException
{
if (value == null)
return 0L;
Class c = value.getClass();
if ( c.getSuperclass() == Number.class )
return ((Number)value).longValue();
if ( c == Boolean.class )
return ((Boolean)value).booleanValue()? 1 : 0;
if ( c == Character.class )
return ((Character)value).charValue();
return Long.parseLong( stringValue(value, true) );
}
/**
* Evaluates the given object as a double-precision floating-point number.
*
* @param value an object to interpret as a double
* @return the double value implied by the given object
* @throws NumberFormatException if the given object can't be understood as a double
*/
public static double doubleValue( Object value ) throws NumberFormatException
{
if (value == null)
return 0.0;
Class c = value.getClass();
if ( c.getSuperclass() == Number.class )
return ((Number)value).doubleValue();
if ( c == Boolean.class )
return ((Boolean)value).booleanValue()? 1 : 0;
if ( c == Character.class )
return ((Character)value).charValue();
String s = stringValue(value, true);
return (s.length() == 0) ? 0.0 : Double.parseDouble( s );
/*
For 1.1 parseDouble() is not available
*/
//return Double.valueOf( value.toString() ).doubleValue();
}
/**
* Evaluates the given object as a BigInteger.
*
* @param value an object to interpret as a BigInteger
* @return the BigInteger value implied by the given object
* @throws NumberFormatException if the given object can't be understood as a BigInteger
*/
public static BigInteger bigIntValue( Object value ) throws NumberFormatException
{
if (value == null)
return BigInteger.valueOf(0L);
Class c = value.getClass();
if ( c == BigInteger.class )
return (BigInteger)value;
if ( c == BigDecimal.class )
return ((BigDecimal)value).toBigInteger();
if ( c.getSuperclass() == Number.class )
return BigInteger.valueOf( ((Number)value).longValue() );
if ( c == Boolean.class )
return BigInteger.valueOf( ((Boolean)value).booleanValue()? 1 : 0 );
if ( c == Character.class )
return BigInteger.valueOf( ((Character)value).charValue() );
return new BigInteger( stringValue(value, true) );
}
/**
* Evaluates the given object as a BigDecimal.
*
* @param value an object to interpret as a BigDecimal
* @return the BigDecimal value implied by the given object
* @throws NumberFormatException if the given object can't be understood as a BigDecimal
*/
public static BigDecimal bigDecValue( Object value ) throws NumberFormatException
{
if (value == null)
return BigDecimal.valueOf(0L);
Class c = value.getClass();
if ( c == BigDecimal.class )
return (BigDecimal)value;
if ( c == BigInteger.class )
return new BigDecimal( (BigInteger)value );
if ( c.getSuperclass() == Number.class )
return new BigDecimal( ((Number)value).doubleValue() );
if ( c == Boolean.class )
return BigDecimal.valueOf( ((Boolean)value).booleanValue()? 1 : 0 );
if ( c == Character.class )
return BigDecimal.valueOf( ((Character)value).charValue() );
return new BigDecimal( stringValue(value, true) );
}
/**
* Evaluates the given object as a String and trims it if the trim flag is true.
*
* @param value an object to interpret as a String
* @return the String value implied by the given object as returned by the toString() method,
or "null" if the object is null.
*/
public static String stringValue( Object value, boolean trim )
{
String result;
if (value == null) {
result = OgnlRuntime.NULL_STRING;
} else {
result = value.toString();
if (trim) {
result = result.trim();
}
}
return result;
}
/**
* Evaluates the given object as a String.
*
* @param value an object to interpret as a String
* @return the String value implied by the given object as returned by the toString() method,
or "null" if the object is null.
*/
public static String stringValue( Object value )
{
return stringValue(value, false);
}
/**
* Returns a constant from the NumericTypes interface that represents the numeric
* type of the given object.
*
* @param value an object that needs to be interpreted as a number
* @return the appropriate constant from the NumericTypes interface
*/
public static int getNumericType( Object value )
{
int result = NONNUMERIC;
if (value != null) {
Class c = value.getClass();
if ( c == Integer.class ) return INT;
if ( c == Double.class ) return DOUBLE;
if ( c == Boolean.class ) return BOOL;
if ( c == Byte.class ) return BYTE;
if ( c == Character.class ) return CHAR;
if ( c == Short.class ) return SHORT;
if ( c == Long.class ) return LONG;
if ( c == Float.class ) return FLOAT;
if ( c == BigInteger.class ) return BIGINT;
if ( c == BigDecimal.class ) return BIGDEC;
}
return NONNUMERIC;
}
/**
* Returns the value converted numerically to the given class type
*
* This method also detects when arrays are being converted and
* converts the components of one array to the type of the other.
*
* @param value an object to be converted to the given type
* @param toType class type to be converted to
* @return converted value of the type given, or value if the value
* cannot be converted to the given type.
*/
public static Object convertValue( Object value, Class toType)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -