| /* |
| * Copyright (c) 2007 Mockito contributors |
| * This program is made available under the terms of the MIT License. |
| */ |
| package org.mockito.internal.util.reflection; |
| |
| import org.mockito.internal.util.Checks; |
| import org.mockito.internal.util.collections.ListUtil; |
| import org.mockito.internal.util.collections.ListUtil.Filter; |
| |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.Field; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| /** |
| * Small fluent reflection tools to work with fields. |
| * |
| * Code is very new and might need rework. |
| */ |
| public abstract class Fields { |
| |
| /** |
| * Instance fields declared in the class and superclasses of the given instance. |
| * |
| * @param instance Instance from which declared fields will be retrieved. |
| * @return InstanceFields of this object instance. |
| */ |
| public static InstanceFields allDeclaredFieldsOf(Object instance) { |
| List<InstanceField> instanceFields = new ArrayList<InstanceField>(); |
| for (Class<?> clazz = instance.getClass(); clazz != Object.class; clazz = clazz.getSuperclass()) { |
| instanceFields.addAll(instanceFieldsIn(instance, clazz.getDeclaredFields())); |
| } |
| return new InstanceFields(instance, instanceFields); |
| } |
| |
| /** |
| * Instance fields declared in the class of the given instance. |
| * |
| * @param instance Instance from which declared fields will be retrieved. |
| * @return InstanceFields of this object instance. |
| */ |
| public static InstanceFields declaredFieldsOf(Object instance) { |
| List<InstanceField> instanceFields = new ArrayList<InstanceField>(); |
| instanceFields.addAll(instanceFieldsIn(instance, instance.getClass().getDeclaredFields())); |
| return new InstanceFields(instance, instanceFields); |
| } |
| |
| private static List<InstanceField> instanceFieldsIn(Object instance, Field[] fields) { |
| List<InstanceField> instanceDeclaredFields = new ArrayList<InstanceField>(); |
| for (Field field : fields) { |
| InstanceField instanceField = new InstanceField(field, instance); |
| instanceDeclaredFields.add(instanceField); |
| } |
| return instanceDeclaredFields; |
| } |
| |
| /** |
| * Accept fields annotated by the given annotations. |
| * |
| * @param annotations Annotation types to check. |
| * @return The filter. |
| */ |
| public static Filter<InstanceField> annotatedBy(final Class<? extends Annotation>... annotations) { |
| return new Filter<InstanceField>() { |
| public boolean isOut(InstanceField instanceField) { |
| Checks.checkNotNull(annotations, "Provide at least one annotation class"); |
| |
| for (Class<? extends Annotation> annotation : annotations) { |
| if(instanceField.isAnnotatedBy(annotation)) { |
| return false; |
| } |
| } |
| return true; |
| } |
| }; |
| } |
| |
| /** |
| * Accept fields with non null value. |
| * |
| * @return The filter. |
| */ |
| private static Filter<InstanceField> nullField() { |
| return new Filter<InstanceField>() { |
| public boolean isOut(InstanceField instanceField) { |
| return instanceField.isNull(); |
| } |
| }; |
| } |
| |
| public static class InstanceFields { |
| private final Object instance; |
| |
| private final List<InstanceField> instanceFields; |
| |
| public InstanceFields(Object instance, List<InstanceField> instanceFields) { |
| this.instance = instance; |
| this.instanceFields = instanceFields; |
| } |
| |
| public InstanceFields filter(Filter<InstanceField> withFilter) { |
| return new InstanceFields(instance, ListUtil.filter(instanceFields, withFilter)); |
| } |
| |
| public InstanceFields notNull() { |
| return filter(nullField()); |
| } |
| |
| public List<InstanceField> instanceFields() { |
| return new ArrayList<InstanceField>(instanceFields); |
| } |
| |
| public List<Object> assignedValues() { |
| List<Object> values = new ArrayList<Object>(instanceFields.size()); |
| for (InstanceField instanceField : instanceFields) { |
| values.add(instanceField.read()); |
| } |
| return values; |
| } |
| |
| public List<String> names() { |
| List<String> fieldNames = new ArrayList<String>(instanceFields.size()); |
| for (InstanceField instanceField : instanceFields) { |
| fieldNames.add(instanceField.name()); |
| } |
| return fieldNames; |
| } |
| } |
| } |