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

gu.sql2java.excel.utils.FieldUtils Maven / Gradle / Ivy

There is a newer version: 5.2.0
Show newest version
package gu.sql2java.excel.utils;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkArgument;
import static net.gdface.utils.ConditionChecks.checkTrue;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;

import com.google.common.base.Strings;


public class FieldUtils {
    /**
     * 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 IllegalArgumentException
     *             if the class is {@code null}, or 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) {
    	checkNotNull(cls, "The class must not be null");
    	checkArgument(!Strings.isNullOrEmpty(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 : getAllInterfaces(cls)) {
            try {
                final Field test = class1.getField(fieldName);
                checkTrue(match == null, IllegalArgumentException.class,"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;
    }
    /**
     * 

Gets a {@code List} of all interfaces implemented by the given * class and its superclasses.

* *

The order is determined by looking through each interface in turn as * declared in the source file and following its hierarchy up. Then each * superclass is considered in the same way. Later duplicates are ignored, * so the order is maintained.

* * @param cls the class to look up, may be {@code null} * @return the {@code List} of interfaces in order, * {@code null} if null input */ public static List> getAllInterfaces(final Class cls) { if (cls == null) { return null; } final LinkedHashSet> interfacesFound = new LinkedHashSet<>(); getAllInterfaces(cls, interfacesFound); return new ArrayList<>(interfacesFound); } /** * Get the interfaces for the specified class. * * @param cls the class to look up, may be {@code null} * @param interfacesFound the {@code Set} of interfaces for the class */ private static void getAllInterfaces(Class cls, final HashSet> interfacesFound) { while (cls != null) { final Class[] interfaces = cls.getInterfaces(); for (final Class i : interfaces) { if (interfacesFound.add(i)) { getAllInterfaces(i, interfacesFound); } } cls = cls.getSuperclass(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy