⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ognlruntime.java

📁 此源代码是一个开源项目,可以实现不同类型之间的转换
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
//--------------------------------------------------------------------------
//	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.beans.IndexedPropertyDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.Permission;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * This is an abstract class with static methods that define runtime
 * caching information in OGNL.
 * @author Luke Blanshard (blanshlu@netscape.net)
 * @author Drew Davidson (drew@ognl.org)
 */
public abstract class OgnlRuntime extends Object
{
    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;

    public static final String              NULL_STRING = "" + null;

    private static final String             SET_PREFIX = "set";
    private static final String             GET_PREFIX = "get";
    private static final String             IS_PREFIX = "is";

    /**
        Prefix padding for hexadecimal numbers to HEX_LENGTH.
     */
    private static final Map			    HEX_PADDING = new HashMap();

    /**
        Hexadecimal prefix for printing "pointers".
     */
    private static final String			    HEX_PREFIX = "0x";

    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>";


    private static ClassCache               methodAccessors = new ClassCache();
    private static ClassCache               propertyAccessors = new ClassCache();
    private static ClassCache               elementsAccessors = new ClassCache();
    private static ClassCache               nullHandlers = new ClassCache();
    private static ClassCache               propertyDescriptorCache = new ClassCache();
    private static ClassCache               constructorCache = new ClassCache();
    private static ClassCache               staticMethodCache = new ClassCache();
    private static ClassCache               instanceMethodCache = new ClassCache();
    private static ClassCache               invokePermissionCache = new ClassCache();
    private static ClassCache               fieldCache = new ClassCache();
    private static List                     superclasses = new ArrayList(); /* Used by fieldCache lookup */
    private static ClassCache[]             declaredMethods = new ClassCache[] { new ClassCache(), new ClassCache() };   /* set, get */
    private static Map                      primitiveTypes = new HashMap(101);
    private static ClassCache               primitiveDefaults = new ClassCache();
    private static Map                      methodParameterTypesCache = new HashMap(101);
    private static Map                      ctorParameterTypesCache = new HashMap(101);
    private static SecurityManager          securityManager = System.getSecurityManager();
    private static EvaluationPool           evaluationPool = new EvaluationPool();
    private static ObjectArrayPool          objectArrayPool = new ObjectArrayPool();

    /**
        This is a highly specialized map for storing values keyed by Class objects.
     */
    private static class ClassCache extends Object
    {
        /* this MUST be a power of 2 */
        private static final int    TABLE_SIZE = 512;

        /* ...and now you see why.  The table size is used as a mask for generating hashes */
        private static final int    TABLE_SIZE_MASK = TABLE_SIZE - 1;

        private Entry[]             table;

        private static class Entry extends Object
        {
            protected Entry                 next;
            protected Class                 key;
            protected Object                value;

            public Entry(Class key, Object value)
            {
                super();
                this.key = key;
                this.value = value;
            }
        }

        public ClassCache()
        {
            super();
            this.table = new Entry[TABLE_SIZE];
        }

        public final Object get(Class key)
        {
            Object      result = null;
            int         i = key.hashCode() & TABLE_SIZE_MASK;

            for (Entry entry = table[i]; entry != null; entry = entry.next) {
                if (entry.key == key) {
                    result = entry.value;
                    break;
                }
            }
            return result;
        }

        public final Object put(Class key, Object value)
        {
            Object      result = null;
            int         i = key.hashCode() & TABLE_SIZE_MASK;
            Entry       entry = table[i];

            if (entry == null) {
                table[i] = new Entry(key, value);
            } else {
                if (entry.key == key) {
                    result = entry.value;
                    entry.value = value;
                } else {
                    while (true) {
                        if (entry.key == key) {
                            /* replace value */
                            result = entry.value;
                            entry.value = value;
                            break;
                        } else {
                            if (entry.next == null) {
                                /* add value */
                                entry.next = new Entry(key, value);
                                break;
                            }
                        }
                        entry = entry.next;
                    }
                }
            }
            return result;
        }
    }

    static
    {
        PropertyAccessor p = new ArrayPropertyAccessor();
        setPropertyAccessor( Object.class, new ObjectPropertyAccessor() );
        setPropertyAccessor( byte[].class, p );
        setPropertyAccessor( short[].class, p );
        setPropertyAccessor( char[].class, p );
        setPropertyAccessor( int[].class, p );
        setPropertyAccessor( long[].class, p );
        setPropertyAccessor( float[].class, p );
        setPropertyAccessor( double[].class, p );
        setPropertyAccessor( Object[].class, p );
        setPropertyAccessor( List.class, new ListPropertyAccessor() );
        setPropertyAccessor( Map.class, new MapPropertyAccessor() );
        setPropertyAccessor( Set.class, new SetPropertyAccessor() );
        setPropertyAccessor( Iterator.class, new IteratorPropertyAccessor() );
        setPropertyAccessor( Enumeration.class, new EnumerationPropertyAccessor() );

        ElementsAccessor e = new ArrayElementsAccessor();
        setElementsAccessor( Object.class, new ObjectElementsAccessor() );
        setElementsAccessor( byte[].class, e );
        setElementsAccessor( short[].class, e );
        setElementsAccessor( char[].class, e );
        setElementsAccessor( int[].class, e );
        setElementsAccessor( long[].class, e );
        setElementsAccessor( float[].class, e );
        setElementsAccessor( double[].class, e );
        setElementsAccessor( Object[].class, e );
        setElementsAccessor( Collection.class, new CollectionElementsAccessor() );
        setElementsAccessor( Map.class, new MapElementsAccessor() );
        setElementsAccessor( Iterator.class, new IteratorElementsAccessor() );
        setElementsAccessor( Enumeration.class, new EnumerationElementsAccessor() );
        setElementsAccessor( Number.class, new NumberElementsAccessor() );

        NullHandler nh = new ObjectNullHandler();
        setNullHandler( Object.class,  nh);
        setNullHandler( byte[].class, nh );
        setNullHandler( short[].class, nh );
        setNullHandler( char[].class, nh );
        setNullHandler( int[].class, nh );
        setNullHandler( long[].class, nh );
        setNullHandler( float[].class, nh );
        setNullHandler( double[].class, nh );
        setNullHandler( Object[].class, nh );

        MethodAccessor  ma = new ObjectMethodAccessor();
        setMethodAccessor( Object.class, ma );
        setMethodAccessor( byte[].class, ma );
        setMethodAccessor( short[].class, ma );
        setMethodAccessor( char[].class, ma );
        setMethodAccessor( int[].class, ma );
        setMethodAccessor( long[].class, ma );
        setMethodAccessor( float[].class, ma );
        setMethodAccessor( double[].class, ma );
        setMethodAccessor( Object[].class, ma );

        primitiveTypes.put("boolean", Boolean.TYPE );
        primitiveTypes.put("byte", Byte.TYPE );
        primitiveTypes.put("short", Short.TYPE );
        primitiveTypes.put("char", Character.TYPE );
        primitiveTypes.put("int", Integer.TYPE );
        primitiveTypes.put("long", Long.TYPE );
        primitiveTypes.put("float", Float.TYPE );
        primitiveTypes.put("double", Double.TYPE );

        primitiveDefaults.put(Boolean.TYPE, Boolean.FALSE);
        primitiveDefaults.put(Byte.TYPE, new Byte((byte)0));
        primitiveDefaults.put(Short.TYPE, new Short((short)0));
        primitiveDefaults.put(Character.TYPE, new Character((char)0));
        primitiveDefaults.put(Integer.TYPE, new Integer(0));
        primitiveDefaults.put(Long.TYPE, new Long(0L));
        primitiveDefaults.put(Float.TYPE, new Float(0.0f));
        primitiveDefaults.put(Double.TYPE, new Double(0.0));
        primitiveDefaults.put(BigInteger.class, new BigInteger("0"));
        primitiveDefaults.put(BigDecimal.class, new BigDecimal(0.0));
    }

    /**
        Gets the "target" class of an object for looking up accessors that
        are registered on the target.  If the object is a Class object this
        will return the Class itself, else it will return object's getClass()
        result.
     */
    public static Class getTargetClass(Object o)
    {
        return (o == null) ? null : ((o instanceof Class) ? (Class)o : o.getClass());
    }

    /**
        Returns the base name (the class name without the
        package name prepended) of the object given.
     */
    public static String getBaseName(Object o)
    {
        return (o == null) ? null : getClassBaseName(o.getClass());
    }

    /**
        Returns the base name (the class name without the
        package name prepended) of the class given.
     */
    public static String getClassBaseName(Class c)
    {
        String      s = c.getName();

        return s.substring(s.lastIndexOf('.') + 1);
    }

    public static String getClassName(Object o, boolean fullyQualified)
    {
        if (!(o instanceof Class)) {
            o = o.getClass();
        }
        return getClassName((Class)o, fullyQualified);
    }

    public static String getClassName(Class c, boolean fullyQualified)
    {
        return fullyQualified ? c.getName() : getClassBaseName(c);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -