Java tutorial
/* * Copyright (c) 2014 Alexander Gulko <kirhog at gmail dot com>. * * 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.fastmongo.odm.util; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * Simple utility class for working with the reflection API and handling * reflection exceptions. * <p/> * Copy from org.springframework.util.ReflectionUtils (spring 3.2.5) */ public abstract class ReflectionUtils { /** * Determine whether the given method is an "equals" method. * * @see java.lang.Object#equals(Object) */ public static boolean isEqualsMethod(Method method) { if (method == null || !method.getName().equals("equals")) { return false; } Class<?>[] paramTypes = method.getParameterTypes(); return (paramTypes.length == 1 && paramTypes[0] == Object.class); } /** * Determine whether the given method is a "hashCode" method. * * @see java.lang.Object#hashCode() */ public static boolean isHashCodeMethod(Method method) { return (method != null && method.getName().equals("hashCode") && method.getParameterTypes().length == 0); } /** * Determine whether the given method is a "toString" method. * * @see java.lang.Object#toString() */ public static boolean isToStringMethod(Method method) { return (method != null && method.getName().equals("toString") && method.getParameterTypes().length == 0); } /** * Determine whether the given method is originally declared by {@link java.lang.Object}. */ public static boolean isObjectMethod(Method method) { try { Object.class.getDeclaredMethod(method.getName(), method.getParameterTypes()); return true; } catch (SecurityException ex) { return false; } catch (NoSuchMethodException ex) { return false; } } /** * Attempt to find a {@link Field field} on the supplied {@link Class} with the * supplied {@code name}. Searches all superclasses up to {@link Object}. * * @param clazz the class to introspect * @param name the name of the field * @return the corresponding Field object, or {@code null} if not found */ public static Field findField(Class<?> clazz, String name) { return findField(clazz, name, null); } /** * Attempt to find a {@link Field field} on the supplied {@link Class} with the * supplied {@code name} and/or {@link Class type}. Searches all superclasses * up to {@link Object}. * * @param clazz the class to introspect * @param name the name of the field (may be {@code null} if type is specified) * @param type the type of the field (may be {@code null} if name is specified) * @return the corresponding Field object, or {@code null} if not found */ public static Field findField(Class<?> clazz, String name, Class<?> type) { Class<?> searchType = clazz; while (!Object.class.equals(searchType) && searchType != null) { Field[] fields = searchType.getDeclaredFields(); for (Field field : fields) { if ((name == null || name.equals(field.getName())) && (type == null || type.equals(field.getType()))) { return field; } } searchType = searchType.getSuperclass(); } return null; } /** * Invoke the given callback on all fields in the target class, going up the * class hierarchy to get all declared fields. * * @param clazz the target class to analyze * @param fc the callback to invoke for each field * @param ff the filter that determines the fields to apply the callback to */ public static void doWithFields(Class<?> clazz, FieldCallback fc, FieldFilter ff) throws IllegalArgumentException { // Keep backing up the inheritance hierarchy. Class<?> targetClass = clazz; do { Field[] fields = targetClass.getDeclaredFields(); for (Field field : fields) { // Skip static and final fields. if (ff != null && !ff.matches(field)) { continue; } try { fc.doWith(field); } catch (IllegalAccessException ex) { throw new IllegalStateException( "Shouldn't be illegal to access field '" + field.getName() + "': " + ex); } } targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); } /** * Callback interface invoked on each field in the hierarchy. */ public interface FieldCallback { /** * Perform an operation using the given field. * * @param field the field to operate on */ void doWith(Field field) throws IllegalArgumentException, IllegalAccessException; } /** * Callback optionally used to filter fields to be operated on by a field callback. */ public interface FieldFilter { /** * Determine whether the given field matches. * * @param field the field to check */ boolean matches(Field field); } }