org.apache.camel.util.ReflectionHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of camel-core Show documentation
Show all versions of camel-core Show documentation
The Core Camel Java DSL based router
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.camel.util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* Helper for working with reflection on classes.
*
* This code is based on org.apache.camel.spring.util.ReflectionUtils class.
*/
public final class ReflectionHelper {
private ReflectionHelper() {
// utility 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;
}
/**
* Action to take on each method.
*/
public interface MethodCallback {
/**
* Perform an operation using the given method.
*
* @param method the method to operate on
*/
void doWith(Method method) throws IllegalArgumentException, IllegalAccessException;
}
/**
* 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
*/
public static void doWithFields(Class clazz, FieldCallback fc) throws IllegalArgumentException {
// Keep backing up the inheritance hierarchy.
Class targetClass = clazz;
do {
Field[] fields = targetClass.getDeclaredFields();
for (Field field : fields) {
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);
}
/**
* Perform the given callback operation on all matching methods of the given
* class and superclasses (or given interface and super-interfaces).
*
* Important: This method does not take the
* {@link java.lang.reflect.Method#isBridge() bridge methods} into account.
*
* @param clazz class to start looking at
* @param mc the callback to invoke for each method
*/
public static void doWithMethods(Class clazz, MethodCallback mc) throws IllegalArgumentException {
// Keep backing up the inheritance hierarchy.
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (method.isBridge()) {
// skip the bridge methods which in Java 8 leads to problems with inheritance
// see https://bugs.openjdk.java.net/browse/JDK-6695379
continue;
}
try {
mc.doWith(method);
} catch (IllegalAccessException ex) {
throw new IllegalStateException("Shouldn't be illegal to access method '" + method.getName() + "': " + ex);
}
}
if (clazz.getSuperclass() != null) {
doWithMethods(clazz.getSuperclass(), mc);
} else if (clazz.isInterface()) {
for (Class superIfc : clazz.getInterfaces()) {
doWithMethods(superIfc, mc);
}
}
}
public static void setField(Field f, Object instance, Object value) {
try {
boolean oldAccessible = f.isAccessible();
boolean shouldSetAccessible = !Modifier.isPublic(f.getModifiers()) && !oldAccessible;
if (shouldSetAccessible) {
f.setAccessible(true);
}
f.set(instance, value);
if (shouldSetAccessible) {
f.setAccessible(oldAccessible);
}
} catch (Exception ex) {
throw new UnsupportedOperationException("Cannot inject value of class: " + value.getClass() + " into: " + f);
}
}
}