valueutils.java

来自「JXPath」· Java 代码 · 共 619 行 · 第 1/2 页

JAVA
619
字号
        collection = getValue(collection);
        if (collection != null) {
            if (collection.getClass().isArray()) {
                Array.set(
                    collection,
                    index,
                    convert(value, collection.getClass().getComponentType()));
            }
            else if (collection instanceof List) {
                ((List) collection).set(index, value);
            }
            else if (collection instanceof Collection) {
                throw new UnsupportedOperationException(
                    "Cannot set value of an element of a "
                        + collection.getClass().getName());
            }
        }
    }

    /**
     * Returns the value of the bean's property represented by
     * the supplied property descriptor.
     */
    public static Object getValue(
        Object bean,
        PropertyDescriptor propertyDescriptor) 
    {
        Object value;
        try {
            Method method =
                getAccessibleMethod(propertyDescriptor.getReadMethod());
            if (method == null) {
                throw new JXPathException("No read method");
            }
            value = method.invoke(bean, new Object[0]);
        }
        catch (Exception ex) {
            throw new JXPathException(
                "Cannot access property: "
                    + (bean == null ? "null" : bean.getClass().getName())
                    + "."
                    + propertyDescriptor.getName(),
                ex);
        }
        return value;
    }

    /**
     * Modifies the value of the bean's property represented by
     * the supplied property descriptor.
     */
    public static void setValue(
        Object bean,
        PropertyDescriptor propertyDescriptor,
        Object value) 
    {
        try {
            Method method =
                getAccessibleMethod(propertyDescriptor.getWriteMethod());
            if (method == null) {
                throw new JXPathException("No write method");
            }
            value = convert(value, propertyDescriptor.getPropertyType());
            value = method.invoke(bean, new Object[] { value });
        }
        catch (Exception ex) {
            throw new JXPathException(
                "Cannot modify property: "
                    + (bean == null ? "null" : bean.getClass().getName())
                    + "."
                    + propertyDescriptor.getName(),
                ex);
        }
    }

    private static Object convert(Object value, Class type) {
        try {
            return TypeUtils.convert(value, type);
        }
        catch (Exception ex) {
            throw new JXPathException(
                "Cannot convert value of class "
                    + (value == null ? "null" : value.getClass().getName())
                    + " to type "
                    + type,
                ex);
        }
    }

    /**
     * Returns the index'th element of the bean's property represented by
     * the supplied property descriptor.
     */
    public static Object getValue(
        Object bean,
        PropertyDescriptor propertyDescriptor,
        int index) 
    {
        if (propertyDescriptor instanceof IndexedPropertyDescriptor) {
            try {
                IndexedPropertyDescriptor ipd =
                    (IndexedPropertyDescriptor) propertyDescriptor;
                Method method = ipd.getIndexedReadMethod();
                if (method != null) {
                    return method.invoke(
                        bean,
                        new Object[] { new Integer(index)});
                }
            }            
            catch (InvocationTargetException ex) {
                Throwable t =
                    ((InvocationTargetException) ex).getTargetException();
                if (t instanceof ArrayIndexOutOfBoundsException) {
                    return null;
                }
                
                throw new JXPathException(
                    "Cannot access property: " + propertyDescriptor.getName(),
                    t);
            }
            catch (Throwable ex) {
                throw new JXPathException(
                    "Cannot access property: " + propertyDescriptor.getName(),
                    ex);
            }
        }

        // We will fall through if there is no indexed read

        return getValue(getValue(bean, propertyDescriptor), index);
    }

    /**
     * Modifies the index'th element of the bean's property represented by
     * the supplied property descriptor. Converts the value to the required
     * type if necessary.
     */
    public static void setValue(
        Object bean,
        PropertyDescriptor propertyDescriptor,
        int index,
        Object value) 
    {
        if (propertyDescriptor instanceof IndexedPropertyDescriptor) {
            try {
                IndexedPropertyDescriptor ipd =
                    (IndexedPropertyDescriptor) propertyDescriptor;
                Method method = ipd.getIndexedWriteMethod();
                if (method != null) {
                    method.invoke(
                        bean,
                        new Object[] {
                            new Integer(index),
                            convert(value, ipd.getIndexedPropertyType())});
                    return;
                }
            }
            catch (Exception ex) {
                throw new RuntimeException(
                    "Cannot access property: "
                        + propertyDescriptor.getName()
                        + ", "
                        + ex.getMessage());
            }
        }
        // We will fall through if there is no indexed read
        Object collection = getValue(bean, propertyDescriptor);
        if (isCollection(collection)) {
            setValue(collection, index, value);
        }
        else if (index == 0) {
            setValue(bean, propertyDescriptor, value);
        }
        else {
            throw new RuntimeException(
                "Not a collection: " + propertyDescriptor.getName());
        }
    }

    /**
     * If the parameter is a container, opens the container and
     * return the contents.  The method is recursive.
     */
    public static Object getValue(Object object) {
        while (object instanceof Container) {
            object = ((Container) object).getValue();
        }
        return object;
    }
    
    /**
     * Returns a shared instance of the dynamic property handler class
     * returned by <code>getDynamicPropertyHandlerClass()</code>.
     */
    public static DynamicPropertyHandler getDynamicPropertyHandler(Class clazz) 
    {
        DynamicPropertyHandler handler =
            (DynamicPropertyHandler) dynamicPropertyHandlerMap.get(clazz);
        if (handler == null) {
            try {
                handler = (DynamicPropertyHandler) clazz.newInstance();
            }
            catch (Exception ex) {
                throw new JXPathException(
                    "Cannot allocate dynamic property handler of class "
                        + clazz.getName(),
                    ex);
            }
            dynamicPropertyHandlerMap.put(clazz, handler);
        }
        return handler;
    }

    // -------------------------------------------------------- Private Methods
    //
    //  The rest of the code in this file was copied FROM
    //  org.apache.commons.beanutils.PropertyUtil. We don't want to introduce
    //  a dependency on BeanUtils yet - DP.
    //

    /**
     * Return an accessible method (that is, one that can be invoked via
     * reflection) that implements the specified Method.  If no such method
     * can be found, return <code>null</code>.
     *
     * @param method The method that we wish to call
     */
    public static Method getAccessibleMethod(Method method) {

        // Make sure we have a method to check
        if (method == null) {
            return (null);
        }

        // If the requested method is not public we cannot call it
        if (!Modifier.isPublic(method.getModifiers())) {
            return (null);
        }

        // If the declaring class is public, we are done
        Class clazz = method.getDeclaringClass();
        if (Modifier.isPublic(clazz.getModifiers())) {
            return (method);
        }

        // Check the implemented interfaces and subinterfaces
        method =
            getAccessibleMethodFromInterfaceNest(
                clazz,
                method.getName(),
                method.getParameterTypes());
        return (method);
    }


    /**
     * Return an accessible method (that is, one that can be invoked via
     * reflection) that implements the specified method, by scanning through
     * all implemented interfaces and subinterfaces.  If no such Method
     * can be found, return <code>null</code>.
     *
     * @param clazz Parent class for the interfaces to be checked
     * @param methodName Method name of the method we wish to call
     * @param parameterTypes The parameter type signatures
     */
    private static Method getAccessibleMethodFromInterfaceNest(
        Class clazz,
        String methodName,
        Class parameterTypes[]) 
    {

        Method method = null;

        // Check the implemented interfaces of the parent class
        Class interfaces[] = clazz.getInterfaces();
        for (int i = 0; i < interfaces.length; i++) {

            // Is this interface public?
            if (!Modifier.isPublic(interfaces[i].getModifiers())) {
                continue;
            }

            // Does the method exist on this interface?
            try {
                method =
                    interfaces[i].getDeclaredMethod(methodName, parameterTypes);
            }
            catch (NoSuchMethodException e) {
                ;
            }
            if (method != null) {
                break;
            }
            
            // Recursively check our parent interfaces
            method =
                getAccessibleMethodFromInterfaceNest(
                    interfaces[i],
                    methodName,
                    parameterTypes);
            if (method != null) {
                break;
            }
        }

        // Return whatever we have found
        return (method);
    }
}

⌨️ 快捷键说明

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