/* * Copyright 2004-2015 the Seasar Foundation and the Others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.seasar.framework.util; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.seasar.framework.exception.IllegalAccessRuntimeException; import org.seasar.framework.exception.SIllegalArgumentException; /** * {@link Field}用のユーティリティクラスです。 * * @author higa * */ public class FieldUtil { /** * ReflectUtilのクラス名です。 */ protected static final String REFLECTION_UTIL_CLASS_NAME = "org.seasar.framework.util.tiger.ReflectionUtil"; /** * {@link #getElementTypeOfCollectionFromFieldType(Field)}への定数参照です */ protected static final Method GET_ELEMENT_TYPE_OF_COLLECTION_FROM_FIELD_TYPE_METHOD = getElementTypeFromFieldTypeMethod("Collection"); /** * {@link #getElementTypeOfListFromFieldType(Field)}への定数参照です */ protected static final Method GET_ELEMENT_TYPE_OF_LIST_FROM_FIELD_TYPE_METHOD = getElementTypeFromFieldTypeMethod("List"); /** * {@link #getElementTypeOfSetFromFieldType(Field)}への定数参照です */ protected static final Method GET_ELEMENT_TYPE_OF_SET_FROM_FIELD_TYPE_METHOD = getElementTypeFromFieldTypeMethod("Set"); /** * インスタンスを構築します。 */ protected FieldUtil() { } /** * {@link Field}の値をオブジェクトとして取得します。 * * @param field * @param target * @return {@link Object} * @throws IllegalAccessRuntimeException * {@link IllegalAccessException}がおきた場合 * @see Field#get(Object) */ public static Object get(Field field, Object target) throws IllegalAccessRuntimeException { try { return field.get(target); } catch (IllegalAccessException ex) { throw new IllegalAccessRuntimeException(field.getDeclaringClass(), ex); } } /** * staticな {@link Field}の値をintとして取得します。 * * @param field * @return intの値 * @throws IllegalAccessRuntimeException * {@link IllegalAccessException}が発生した場合 * @see #getInt(Field, Object) */ public static int getInt(Field field) throws IllegalAccessRuntimeException { return getInt(field, null); } /** * {@link Field}の値をintとして取得します。 * * @param field * @param target * @return intの値 * @throws IllegalAccessRuntimeException * {@link IllegalAccessException}が発生した場合 * @see Field#getInt(Object) */ public static int getInt(Field field, Object target) throws IllegalAccessRuntimeException { try { return field.getInt(target); } catch (IllegalAccessException ex) { throw new IllegalAccessRuntimeException(field.getDeclaringClass(), ex); } } /** * staticな {@link Field}の値を {@link String}として取得します。 * * @param field * @return {@link String}の値 * @throws IllegalAccessRuntimeException * {@link IllegalAccessException}が発生した場合 * @see #getString(Field, Object) */ public static String getString(Field field) throws IllegalAccessRuntimeException { return getString(field, null); } /** * {@link Field}の値を {@link String}として取得します。 * * @param field * @param target * @return {@link String}の値 * @throws IllegalAccessRuntimeException * {@link IllegalAccessException}が発生した場合 * @see Field#get(Object) */ public static String getString(Field field, Object target) throws IllegalAccessRuntimeException { try { return (String) field.get(target); } catch (IllegalAccessException ex) { throw new IllegalAccessRuntimeException(field.getDeclaringClass(), ex); } } /** * {@link Field}に値を設定します。 * * @param field * @param target * @param value * @throws IllegalAccessRuntimeException * {@link IllegalAccessException}が発生した場合 * @see Field#set(Object, Object) */ public static void set(Field field, Object target, Object value) throws IllegalAccessRuntimeException { try { field.set(target, value); } catch (IllegalAccessException e) { throw new IllegalAccessRuntimeException(field.getDeclaringClass(), e); } catch (IllegalArgumentException e) { Class clazz = field.getDeclaringClass(); Class fieldClass = field.getType(); Class valueClass = value == null ? null : value.getClass(); Class targetClass = target == null ? null : target.getClass(); throw new SIllegalArgumentException("ESSR0094", new Object[] { clazz.getName(), clazz.getClassLoader(), fieldClass.getName(), fieldClass.getClassLoader(), field.getName(), valueClass == null ? null : valueClass.getName(), valueClass == null ? null : valueClass .getClassLoader(), value, targetClass == null ? null : targetClass.getName(), targetClass == null ? null : targetClass .getClassLoader() }, e); } } /** * インスタンスフィールドかどうか返します。 * * @param field * @return インスタンスフィールドかどうか */ public static boolean isInstanceField(Field field) { int mod = field.getModifiers(); return !Modifier.isStatic(mod) && !Modifier.isFinal(mod); } /** * パブリックフィールドかどうか返します。 * * @param field * @return パブリックフィールドかどうか */ public static boolean isPublicField(Field field) { int mod = field.getModifiers(); return Modifier.isPublic(mod); } /** * Java5以上の場合は、指定されたフィールドのパラメタ化されたコレクションの要素型を返します。 * * @param field * フィールド * @return フィールドのパラメタ化されたコレクションの要素型 */ public static Class getElementTypeOfCollectionFromFieldType( final Field field) { if (GET_ELEMENT_TYPE_OF_COLLECTION_FROM_FIELD_TYPE_METHOD == null) { return null; } return (Class) MethodUtil.invoke( GET_ELEMENT_TYPE_OF_COLLECTION_FROM_FIELD_TYPE_METHOD, null, new Object[] { field }); } /** * Java5以上の場合は、指定されたフィールドのパラメタ化されたリストの要素型を返します。 * * @param field * フィールド * @return フィールドのパラメタ化されたリストの要素型 */ public static Class getElementTypeOfListFromFieldType(final Field field) { if (GET_ELEMENT_TYPE_OF_LIST_FROM_FIELD_TYPE_METHOD == null) { return null; } return (Class) MethodUtil.invoke( GET_ELEMENT_TYPE_OF_LIST_FROM_FIELD_TYPE_METHOD, null, new Object[] { field }); } /** * Java5以上の場合は、指定されたフィールドのパラメタ化されたセットの要素型を返します。 * * @param field * フィールド * @return フィールドのパラメタ化されたセットの要素型 */ public static Class getElementTypeOfSetFromFieldType(final Field field) { if (GET_ELEMENT_TYPE_OF_SET_FROM_FIELD_TYPE_METHOD == null) { return null; } return (Class) MethodUtil.invoke( GET_ELEMENT_TYPE_OF_SET_FROM_FIELD_TYPE_METHOD, null, new Object[] { field }); } /** * <code>ReflectionUtil#getElementTypeOf<var>Xxx</var>FromFieldType()</code> * の {@link Method}を返します。 * * @param type * 取得するメソッドが対象とする型名 * @return * <code>ReflectionUtil#getElementTypeOf<var>Xxx</var>FromFieldType()</code> * の{@link Method} */ protected static Method getElementTypeFromFieldTypeMethod(final String type) { try { final Class reflectionUtilClass = Class .forName(REFLECTION_UTIL_CLASS_NAME); return reflectionUtilClass.getMethod("getElementTypeOf" + type + "FromFieldType", new Class[] { Field.class }); } catch (final Throwable ignore) { } return null; } }