/* * Copyright 2013 Klarna AB * * 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 com.klarna.reflection; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import javax.annotation.Nullable; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.Set; import static com.google.common.collect.Lists.newArrayList; /** * Collection of Reflection related helper functions. */ public final class ReflectionUtils { /** * Private constructor */ private ReflectionUtils() { } public static void setStaticField(Class clazz, String fieldName, Object value) { setField(clazz, null, fieldName, value); } public static void setField(Object instance, String fieldName, Object value) { setField(instance.getClass(), instance, fieldName, value); } private static void setField(Class clazz, Object instance, String fieldName, Object value) { try { final Optional<Field> optional = getField(clazz, fieldName); Preconditions.checkArgument(optional.isPresent(), "Failed to set field '" + fieldName + "' on '" + instance); final Field field = optional.get(); boolean accessible = field.isAccessible(); field.setAccessible(true); field.set(instance, value); field.setAccessible(accessible); } catch (IllegalAccessException e) { throw new IllegalStateException( "Failed to set field '" + fieldName + "' on '" + instance + "': " + e.getMessage(), e); } } /** * Finds the first Field with given field name in the Class and in its super classes. * * @param type The Class type * @param fieldName The field name to get * @return an Optional<Field>. Use isPresent() to find out if the field name was found. */ public static Optional<Field> getField(Class<?> type, final String fieldName) { Optional<Field> field = Iterables.tryFind(newArrayList(type.getDeclaredFields()), havingFieldName(fieldName)); if (!field.isPresent() && type.getSuperclass() != null){ field = getField(type.getSuperclass(), fieldName); } return field; } public static Set<Field> getAllFields(Class aClass, Predicate<? super Field> predicate) { return org.reflections.ReflectionUtils.getAllFields(aClass, predicate); } public static <T> T getFieldValue(Object testCase, String name, Class<T> type) { return getFieldValue(testCase, testCase.getClass(), name, type, false); } public static <T> T getStaticFieldValue(Class testCaseClass, String name, Class<T> type) { return getFieldValue(null, testCaseClass, name, type, true); } private static <T> T getFieldValue(Object testCase, Class testCaseClass, String name, Class<T> type, boolean isStatic) { try { Field field = testCaseClass.getDeclaredField(name); boolean accessible = field.isAccessible(); Preconditions.checkState(field.getType().isAssignableFrom(type), "Field %s must be assignable from ", type); Preconditions.checkState(!isStatic || Modifier.isStatic(field.getModifiers()), "Field %s must be static ", field); field.setAccessible(true); Object value = field.get(testCase); field.setAccessible(accessible); return (T) value; } catch (NoSuchFieldException e) { throw new IllegalArgumentException( "Failed to lookup field '" + name + "' for '" + testCaseClass + "': " + e.getMessage(), e); } catch (IllegalAccessException e) { throw new IllegalArgumentException( "Failed to get value of field '" + name + "' for '" + testCaseClass + "': " + e.getMessage(), e); } } public static boolean isOfType(Field setupScriptField, Class type) { return setupScriptField.getType().isAssignableFrom(type); } private static Predicate<Field> havingFieldName(final String fieldName) { return new Predicate<Field>() { @Override public boolean apply(@Nullable Field field) { return fieldName.equals(field.getName()); } }; } }