com.feilong.core.lang.reflect.FieldUtil.java Source code

Java tutorial

Introduction

Here is the source code for com.feilong.core.lang.reflect.FieldUtil.java

Source

/*
 * Copyright (C) 2008 feilong
 *
 * 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 com.feilong.core.lang.reflect;

import static org.apache.commons.lang3.StringUtils.EMPTY;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.collections4.Predicate;
import org.apache.commons.collections4.PredicateUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.feilong.core.util.CollectionsUtil;
import com.feilong.core.util.predicate.BeanPredicateUtil;
import com.feilong.tools.slf4j.Slf4jUtil;

import static com.feilong.core.Validator.isNullOrEmpty;

/**
 * focus on {@link Field} ??
 * 
 * <p>
 * The ability is provided to break the scoping restrictions coded by the programmer.<br>
 * This can allow fields to be changed that shouldn't be.
 * This facility should be used with care.
 * </p>
 * 
 * <h3> {@link Field} :</h3>
 * 
 * <blockquote>
 * <table border="1" cellspacing="0" cellpadding="4" summary="">
 * <tr style="background-color:#ccccff">
 * <th align="left"></th>
 * <th align="left"></th>
 * </tr>
 * <tr valign="top">
 * <td>{@link Class#getDeclaredFields() getDeclaredFields}</td>
 * <td> {@link Field} ,?? Class ?<span style="color:green"></span>.
 * 
 * <p>
 * <span style="color:green"><b></b>?<b>?</b>?<b>()</b><b>?</b></span>, <span style="color:red">?</span>.
 * </p>
 * 
 * <b>?,?.</b><br>
 * ??, Class ? void, 0 .</td>
 * </tr>
 * 
 * <tr valign="top" style="background-color:#eeeeff">
 * <td>{@link Class#getFields() getFields}</td>
 * <td>?? {@link Field} ,?? Class ? <span style="color:red">?</span>.
 * 
 * <p>
 * , Class <b></b>,<span style="color:red">?</span>.<br>
 *  Class <b>?</b>,<span style="color:red">???</span>.
 * </p>
 * 
 * <p>
 * ?,?.
 * </p>
 * <br>
 * 
 * ??,? void, 0 . <br>
 * ?????.? {@link java.lang.reflect.Array} ??.</td>
 * </tr>
 * 
 * <tr valign="top">
 * <td>{@link Class#getDeclaredField(String) getDeclaredField}</td>
 * <td> {@link Field} ,?? Class ?.<br>
 * ?,??? length .</td>
 * </tr>
 * 
 * <tr valign="top" style="background-color:#eeeeff">
 * <td>{@link Class#getField(String) getField}</td>
 * <td> {@link Field} ,?? Class ?<span style="color:green">?</span>.<br>
 * ????.<br>
 *  C : <br>
 *  C ??,???. <br>
 *  1 , C ?<b>?</b>.???. <br>
 *  1?2 , C <b> S</b>, S . C , NoSuchFieldException.<br>
 * </td>
 * </tr>
 * </table>
 * </blockquote>
 * 
 * @author <a href="http://feitianbenyue.iteye.com/">feilong</a>
 * @see org.apache.commons.lang3.reflect.FieldUtils
 * @see "org.springframework.util.ReflectionUtils"
 * @since 1.0.7
 */
public final class FieldUtil {

    /** The Constant LOGGER. */
    private static final Logger LOGGER = LoggerFactory.getLogger(FieldUtil.class);

    /** Don't let anyone instantiate this class. */
    private FieldUtil() {
        //AssertionError?. ?????. ???.
        //see Effective Java 2nd
        throw new AssertionError("No " + getClass().getName() + " instances for you!");
    }

    /**
     *  <code>obj</code> (<b>?</b>),key fieldName,value .
     * 
     * <h3>:</h3>
     * 
     * <blockquote>
     * 
     * <pre class="code">
     * 
     * User user = new User(12L);
     * LOGGER.debug(JsonUtil.format(FieldUtil.getAllFieldNameAndValueMap(user, "date")));
     * 
     * </pre>
     * 
     * <b>:</b>
     * 
     * <pre class="code">
     * {
     * "age": null,
     * "id": 12
     * }
     * 
     * </pre>
     * 
     * </blockquote>
     *
     * @param obj
     *            the obj
     * @param excludeFieldNames
     *            ?field names,?nullOrEmpty ?
     * @return  <code>obj</code> null, {@link NullPointerException}<br>
     *          <code>fieldList</code> nullempty, {@link Collections#emptyMap()}<br>
     * @see #getAllFieldList(Class, String...)
     * @see #getFieldValue(Object, String)
     */
    public static Map<String, Object> getAllFieldNameAndValueMap(Object obj, String... excludeFieldNames) {
        List<Field> fieldList = getAllFieldList(obj.getClass(), excludeFieldNames);
        if (isNullOrEmpty(fieldList)) {
            return Collections.emptyMap();
        }
        Map<String, Object> map = new TreeMap<String, Object>();
        for (Field field : fieldList) {
            map.put(field.getName(), getFieldValue(obj, field.getName()));
        }
        return map;
    }

    /**
     *  <code>klass</code> ? <code>excludeFieldNames</code> ?list.
     *
     * @param klass
     *            the klass
     * @param excludeFieldNames
     *            ?field names,?nullOrEmpty ?
     * @return  <code>obj</code> null, {@link NullPointerException}<br>
     *          {@link FieldUtils#getAllFieldsList(Class)} nullempty, {@link Collections#emptyList()}<br>
     * @see FieldUtils#getAllFieldsList(Class)
     * @since 1.7.1
     */
    //no static
    public static List<Field> getAllFieldList(final Class<?> klass, String... excludeFieldNames) {
        // {@link Field},parents, public/protect/private/inherited...
        List<Field> fieldList = FieldUtils.getAllFieldsList(klass);
        if (isNullOrEmpty(fieldList)) {
            return Collections.emptyList();
        }
        //**********************************************************************************************
        Predicate<Field> excludeFieldPredicate = BeanPredicateUtil.containsPredicate("name", excludeFieldNames);
        Predicate<Field> staticPredicate = new Predicate<Field>() {

            @Override
            public boolean evaluate(Field field) {
                int modifiers = field.getModifiers();
                // ??? log   serialVersionUID
                boolean isStatic = Modifier.isStatic(modifiers);

                String pattern = "[{}.{}],modifiers:[{}]{}";
                LOGGER.trace(pattern, klass.getSimpleName(), field.getName(), modifiers,
                        isStatic ? " [isStatic]" : EMPTY);
                return isStatic;
            }
        };
        return CollectionsUtil.selectRejected(fieldList,
                PredicateUtils.orPredicate(excludeFieldPredicate, staticPredicate));
    }

    /**
     * ? <code>owner</code>  <code>fieldName</code> .
     *
     * @param <T>
     *            the generic type
     * @param obj
     *            the owner
     * @param fieldName
     *            the field name
     * @return  <code>owner</code> null, {@link NullPointerException}<br>
     *          <code>fieldName</code> null, {@link NullPointerException}<br>
     *          <code>fieldName</code> blank, {@link IllegalArgumentException}<br>
     * @see org.apache.commons.lang3.reflect.FieldUtils#readField(Object, String, boolean)
     * @since 1.4.0
     */
    @SuppressWarnings("unchecked")
    public static <T> T getFieldValue(Object obj, String fieldName) {
        try {
            return (T) FieldUtils.readField(obj, fieldName, true);
        } catch (IllegalAccessException e) {
            String message = Slf4jUtil.format("ownerClass:[{}],fieldName:[{}],ownerObj:[{}]",
                    obj.getClass().getName(), fieldName, obj);
            LOGGER.error(message, e);
            throw new ReflectException(message, e);
        }
    }
}