// --------------------------------------------------------------------------
// 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 ognl.enhance.ExpressionCompiler;
import ognl.enhance.OgnlExpressionCompiler;
import ognl.internal.ClassCache;
import ognl.internal.ClassCacheImpl;
import java.beans.*;
import java.lang.reflect.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.Permission;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* Utility class used by internal OGNL API to do various things like:
*
* <ul>
* <li>Handles majority of reflection logic / caching. </li>
* <li>Utility methods for casting strings / various numeric types used by {@link OgnlExpressionCompiler}.</li.
* <li>Core runtime configuration point for setting/using global {@link TypeConverter} / {@link OgnlExpressionCompiler} /
* {@link NullHandler} instances / etc.. </li>
*</ul>
*
* @author Luke Blanshard (blanshlu@netscape.net)
* @author Drew Davidson (drew@ognl.org)
*/
public class OgnlRuntime {
/**
* Constant expression used to indicate that a given method / property couldn't be found
* during reflection operations.
*/
public static final Object NotFound = new Object();
public static final List NotFoundList = new ArrayList();
public static final Map NotFoundMap = new HashMap();
public static final Object[] NoArguments = new Object[]{};
public static final Class[] NoArgumentTypes = new Class[]{};
/**
* Token returned by TypeConverter for no conversion possible
*/
public static final Object NoConversionPossible = "ognl.NoConversionPossible";
/**
* Not an indexed property
*/
public static int INDEXED_PROPERTY_NONE = 0;
/**
* JavaBeans IndexedProperty
*/
public static int INDEXED_PROPERTY_INT = 1;
/**
* OGNL ObjectIndexedProperty
*/
public static int INDEXED_PROPERTY_OBJECT = 2;
/**
* Constant string representation of null string.
*/
public static final String NULL_STRING = "" + null;
/**
* Java beans standard set method prefix.
*/
private static final String SET_PREFIX = "set";
/**
* Java beans standard get method prefix.
*/
private static final String GET_PREFIX = "get";
/**
* Java beans standard is<Foo> boolean getter prefix.
*/
private static final String IS_PREFIX = "is";
/**
* Prefix padding for hexadecimal numbers to HEX_LENGTH.
*/
private static final Map HEX_PADDING = new HashMap();
private static final int HEX_LENGTH = 8;
/**
* Returned by <CODE>getUniqueDescriptor()</CODE> when the object is <CODE>null</CODE>.
*/
private static final String NULL_OBJECT_STRING = "<null>";
/**
* Used to store the result of determining if current jvm is 1.5 language compatible.
*/
private static boolean _jdk15 = false;
private static boolean _jdkChecked = false;
static final ClassCache _methodAccessors = new ClassCacheImpl();
static final ClassCache _propertyAccessors = new ClassCacheImpl();
static final ClassCache _elementsAccessors = new ClassCacheImpl();
static final ClassCache _nullHandlers = new ClassCacheImpl();
static final ClassCache _propertyDescriptorCache = new ClassCacheImpl();
static final ClassCache _constructorCache = new ClassCacheImpl();
static final ClassCache _staticMethodCache = new ClassCacheImpl();
static final ClassCache _instanceMethodCache = new ClassCacheImpl();
static final ClassCache _invokePermissionCache = new ClassCacheImpl();
static final ClassCache _fieldCache = new ClassCacheImpl();
static final List _superclasses = new ArrayList(); /* Used by fieldCache lookup */
static final ClassCache[] _declaredMethods = new ClassCache[]{new ClassCacheImpl(), new ClassCacheImpl()};
static final Map _primitiveTypes = new HashMap(101);
static final ClassCache _primitiveDefaults = new ClassCacheImpl();
static final Map _methodParameterTypesCache = new HashMap(101);
static final Map _genericMethodParameterTypesCache = new HashMap(101);
static final Map _ctorParameterTypesCache = new HashMap(101);
static SecurityManager _securityManager = System.getSecurityManager();
static final EvaluationPool _evaluationPool = new EvaluationPool();
static final ObjectArrayPool _objectArrayPool = new ObjectArrayPool();
static final Map<Method, Boolean> _methodAccessCache = new ConcurrentHashMap<Method, Boolean>();
static final Map<Method, Boolean> _methodPermCache = new ConcurrentHashMap<Method, Boolean>();
static final ClassPropertyMethodCache cacheSetMethod = new ClassPropertyMethodCache();
static final ClassPropertyMethodCache cacheGetMethod = new ClassPropertyMethodCache();
static ClassCacheInspector _cacheInspector;
/**
* Expression compiler used by {@link Ognl#compileExpression(OgnlContext, Object, String)} calls.
*/
private static OgnlExpressionCompiler _compiler;
/**
* Lazy loading of Javassist library
*/
static {
try {
Class.forName("javassist.ClassPool");
_compiler = new ExpressionCompiler();
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Javassist library is missing in classpath! Please add missed dependency!",e);
}
}
private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
private static IdentityHashMap PRIMITIVE_WRAPPER_CLASSES = new IdentityHashMap();
/**
* Used to provide primitive type equivalent conversions into and out of
* native / object types.
*/
static {
PRIMITIVE_WRAPPER_CLASSES.put(Boolean.TYPE, Boolean.class);
PRIMITIVE_WRAPPER_CLASSES.put(Boolean.class, Boolean.TYPE);
PRIMITIVE_WRAPPER_CLASSES.put(Byte.TYPE, Byte.class);
PRIMITIVE_WRAPPER_CLASSES.put(Byte.class, Byte.TYPE);
PRIMITIVE_WRAPPER_CLASSES.put(Character.TYPE, Character.class);
PRIMITIVE_WRAPPER_CLASSES.put(Character.class, Character.TYPE);
PRIMITIVE_WRAPPER_CLASSES.put(Short.TYPE, Short.clas