/* * Copyright 2013 Chris Pheby * * 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.jadira.reflection.core.misc; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.net.URI; import java.net.URL; import java.util.HashSet; import java.util.Set; import java.util.UUID; import java.util.regex.Pattern; /** * Utility methods for inspecting and interpreting classes */ public final class ClassUtils { private ClassUtils() { } /** * Indicate if the class is a known non-primitive, JDK immutable type * @param type Class to test * @return True if the type is an immutable from the JDK class libraries */ public static boolean isJdkImmutable(Class<?> type) { if (Class.class == type) { return true; } if (String.class == type) { return true; } if (BigInteger.class == type) { return true; } if (BigDecimal.class == type) { return true; } if (URL.class == type) { return true; } if (UUID.class == type) { return true; } if (URI.class == type) { return true; } if (Pattern.class == type) { return true; } return false; } /** * Indicate if the class is a known primitive wrapper type * @param type Class to test * @return True if the type is a primitive wrapper type */ public static boolean isWrapper(Class<?> type) { if (Boolean.class == type) { return true; } if (Byte.class == type) { return true; } if (Character.class == type) { return true; } if (Short.class == type) { return true; } if (Integer.class == type) { return true; } if (Long.class == type) { return true; } if (Float.class == type) { return true; } if (Double.class == type) { return true; } return false; } /** * Produces an array with all the instance fields of the specified class * @param c The class specified * @return The array of matched Fields */ public static Field[] collectDeclaredInstanceFields(Class<?> c) { return collectInstanceFields(c, c.getSuperclass()); } /** * Produces an array with all the instance fields of the specified class * @param c The class specified * @return The array of matched Fields */ public static Field[] collectInstanceFields(Class<?> c) { return collectFields(c, 0, Modifier.STATIC); } /** * Produces an array with all the instance fields of the specified class * @param c The class specified * @param limitExclusive Fields from this class or higher in the hierarchy will not be returned * @return The array of matched Fields */ public static Field[] collectInstanceFields(Class<?> c, Class<?> limitExclusive) { return collectFields(c, 0, Modifier.STATIC, limitExclusive); } /** * Produces an array with all the instance fields of the specified class which match the supplied rules * @param c The class specified * @param excludePublic Exclude public fields if true * @param excludeProtected Exclude protected fields if true * @param excludePrivate Exclude private fields if true * @return The array of matched Fields */ public static Field[] collectInstanceFields(Class<?> c, boolean excludePublic, boolean excludeProtected, boolean excludePrivate) { int inclusiveModifiers = 0; int exclusiveModifiers = Modifier.STATIC; if (excludePrivate) { exclusiveModifiers += Modifier.PRIVATE; } if (excludePublic) { exclusiveModifiers += Modifier.PUBLIC; } if (excludeProtected) { exclusiveModifiers += Modifier.PROTECTED; } return collectFields(c, inclusiveModifiers, exclusiveModifiers); } /** * Produces an array with all the fields of the specified class * @param c The class specified * @return The array of matched Fields */ public static Field[] collectDeclaredFields(Class<?> c) { return collectFields(c, c.getSuperclass()); } /** * Produces an array with all the fields of the specified class * @param c The class specified * @return The array of matched Fields */ public static Field[] collectFields(Class<?> c) { return collectFields(c, 0, 0); } /** * Produces an array with all the fields of the specified class * @param c The class specified * @param limitExclusive Fields from this class or higher in the hierarchy will not be returned * @return The array of matched Fields */ public static Field[] collectFields(Class<?> c, Class<?> limitExclusive) { return collectFields(c, 0, 0, limitExclusive); } /** * Produces an array with all the instance fields of the specified class which match the supplied rules * @param c The class specified * @param inclusiveModifiers An int indicating the {@link Modifier}s that may be applied * @param exclusiveModifiers An int indicating the {@link Modifier}s that must be excluded * @return The array of matched Fields */ public static Field[] collectFields(Class<?> c, int inclusiveModifiers, int exclusiveModifiers) { return collectFields(c, inclusiveModifiers, exclusiveModifiers, Object.class); } /** * Produces an array with all the instance fields of the specified class which match the supplied rules * @param c The class specified * @param inclusiveModifiers An int indicating the {@link Modifier}s that may be applied * @param exclusiveModifiers An int indicating the {@link Modifier}s that must be excluded * @param limitExclusive Fields from this class or higher in the hierarchy will not be returned * @return The array of matched Fields */ public static Field[] collectFields(Class<?> c, int inclusiveModifiers, int exclusiveModifiers, Class<?> limitExclusive) { Set<Field> fields = new HashSet<Field>(); while (c != limitExclusive) { for (Field f : c.getDeclaredFields()) { if (((f.getModifiers() & exclusiveModifiers) == 0) && ((f.getModifiers() & inclusiveModifiers) == inclusiveModifiers)) { fields.add(f); f.setAccessible(true); } } c = c.getSuperclass(); } return fields.toArray(new Field[]{}); } /** * Produces an array with all the methods of the specified class * @param c The class specified * @return The array of matched Methods */ public static Method[] collectDeclaredMethods(Class<?> c) { return collectMethods(c, 0, 0, c.getSuperclass()); } /** * Produces an array with all the methods of the specified class * @param c The class specified * @return The array of matched Methods */ public static Method[] collectMethods(Class<?> c) { return collectMethods(c, 0, 0); } /** * Produces an array with all the methods of the specified class * @param c The class specified * @param limitExclusive Methods from this class or higher in the hierarchy will not be returned * @return The array of matched Methods */ public static Method[] collectMethods(Class<?> c, Class<?> limitExclusive) { return collectMethods(c, 0, 0, limitExclusive); } /** * Produces an array with all the methods of the specified class * @param c The class specified * @param inclusiveModifiers An int indicating the {@link Modifier}s that may be applied * @param exclusiveModifiers An int indicating the {@link Modifier}s that must be excluded * @return The array of matched Methods */ public static Method[] collectMethods(Class<?> c, int inclusiveModifiers, int exclusiveModifiers) { return collectMethods(c, inclusiveModifiers, exclusiveModifiers, Object.class); } /** * Produces an array with all the methods of the specified class * @param c The class specified * @param inclusiveModifiers An int indicating the {@link Modifier}s that may be applied * @param exclusiveModifiers An int indicating the {@link Modifier}s that must be excluded * @param limitExclusive Methods from this class or higher in the hierarchy will not be returned * @return The array of matched Methods */ public static Method[] collectMethods(Class<?> c, int inclusiveModifiers, int exclusiveModifiers, Class<?> limitExclusive) { Set<Method> methods = new HashSet<Method>(); while (c != limitExclusive) { for (Method f : c.getDeclaredMethods()) { if (((f.getModifiers() & exclusiveModifiers) == 0) && ((f.getModifiers() & inclusiveModifiers) == inclusiveModifiers)) { methods.add(f); f.setAccessible(true); } } c = c.getSuperclass(); } return methods.toArray(new Method[]{}); } }