All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.excel.util.FieldUtils Maven / Gradle / Ivy

package com.alibaba.excel.util;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;

import com.alibaba.excel.metadata.NullObject;

import org.springframework.cglib.beans.BeanMap;

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 *
 * @author Apache Software Foundation (ASF)
 */
public class FieldUtils {

    public static Class nullObjectClass = NullObject.class;

    private static final int START_RESOLVE_FIELD_LENGTH = 2;

    public static Class getFieldClass(Map dataMap, String fieldName, Object value) {
        if (dataMap instanceof BeanMap) {
            Class fieldClass = ((BeanMap)dataMap).getPropertyType(fieldName);
            if (fieldClass != null) {
                return fieldClass;
            }
        }
        return getFieldClass(value);
    }

    public static Class getFieldClass(Object value) {
        if (value != null) {
            return value.getClass();
        }
        return nullObjectClass;
    }

    /**
     * Parsing the name matching cglib。
     * 
     *     null -> null
     *     string1 -> string1
     *     String2 -> string2
     *     sTring3 -> STring3
     *     STring4 -> STring4
     *     STRING5 -> STRING5
     *     STRing6 -> STRing6
     * 
* * @param field field * @return field name. */ public static String resolveCglibFieldName(Field field) { if (field == null) { return null; } String fieldName = field.getName(); if (StringUtils.isBlank(fieldName) || fieldName.length() < START_RESOLVE_FIELD_LENGTH) { return fieldName; } char firstChar = fieldName.charAt(0); char secondChar = fieldName.charAt(1); if (Character.isUpperCase(firstChar) == Character.isUpperCase(secondChar)) { return fieldName; } if (Character.isUpperCase(firstChar)) { return buildFieldName(Character.toLowerCase(firstChar), fieldName); } return buildFieldName(Character.toUpperCase(firstChar), fieldName); } private static String buildFieldName(char firstChar, String fieldName) { return firstChar + fieldName.substring(1); } /** * Gets an accessible {@link Field} by name respecting scope. Superclasses/interfaces will be considered. * * @param cls the {@link Class} to reflect, must not be {@code null} * @param fieldName the field name to obtain * @return the Field object * @throws IllegalArgumentException if the class is {@code null}, or the field name is blank or empty */ public static Field getField(final Class cls, final String fieldName) { final Field field = getField(cls, fieldName, false); MemberUtils.setAccessibleWorkaround(field); return field; } /** * Gets an accessible {@link Field} by name, breaking scope if requested. Superclasses/interfaces will be * considered. * * @param cls the {@link Class} to reflect, must not be {@code null} * @param fieldName the field name to obtain * @param forceAccess whether to break scope restrictions using the * {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)} method. {@code false} will * only * match {@code public} fields. * @return the Field object * @throws NullPointerException if the class is {@code null} * @throws IllegalArgumentException if the field name is blank or empty or is matched at multiple places * in the inheritance hierarchy */ public static Field getField(final Class cls, final String fieldName, final boolean forceAccess) { Validate.isTrue(cls != null, "The class must not be null"); Validate.isTrue(StringUtils.isNotBlank(fieldName), "The field name must not be blank/empty"); // FIXME is this workaround still needed? lang requires Java 6 // Sun Java 1.3 has a bugged implementation of getField hence we write the // code ourselves // getField() will return the Field object with the declaring class // set correctly to the class that declares the field. Thus requesting the // field on a subclass will return the field from the superclass. // // priority order for lookup: // searchclass private/protected/package/public // superclass protected/package/public // private/different package blocks access to further superclasses // implementedinterface public // check up the superclass hierarchy for (Class acls = cls; acls != null; acls = acls.getSuperclass()) { try { final Field field = acls.getDeclaredField(fieldName); // getDeclaredField checks for non-public scopes as well // and it returns accurate results if (!Modifier.isPublic(field.getModifiers())) { if (forceAccess) { field.setAccessible(true); } else { continue; } } return field; } catch (final NoSuchFieldException ex) { // NOPMD // ignore } } // check the public interface case. This must be manually searched for // incase there is a public supersuperclass field hidden by a private/package // superclass field. Field match = null; for (final Class class1 : ClassUtils.getAllInterfaces(cls)) { try { final Field test = class1.getField(fieldName); Validate.isTrue(match == null, "Reference to field %s is ambiguous relative to %s" + "; a matching field exists on two or more implemented interfaces.", fieldName, cls); match = test; } catch (final NoSuchFieldException ex) { // NOPMD // ignore } } return match; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy