/**
* Mule Development Kit
* Copyright 2010-2011 (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.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.mule.devkit.dynamic.api.helper;
import org.mule.util.StringUtils;
import java.lang.reflect.Field;
import java.util.Map;
/**
* Helper methods for reflection.
*/
public final class Reflections {
private Reflections() {
}
public static Field setAccessible(final Object object, final String propertyName) {
try {
final Field field = object.getClass().getDeclaredField(propertyName);
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
throw new RuntimeException("Failed to make <"+propertyName+"> accessible", e);
}
}
/**
* @param propertyName
* @return default getter name for specified property
*/
public static String getterMethodName(final String propertyName) {
return "get"+StringUtils.capitalize(propertyName);
}
/**
* Get value of property for specified object.
* @param object
* @param propertyName
*/
public static Object get(final Object object, final String propertyName) {
try {
return Reflections.invoke(object, Reflections.getterMethodName(propertyName), void.class);
} catch (RuntimeException e) {
final Field field = Reflections.setAccessible(object, propertyName);
try {
return field.get(object);
} catch(IllegalAccessException ee) {
throw new RuntimeException(ee);
}
}
}
/**
* @param propertyName
* @return default setter name for specified property
*/
public static String setterMethodName(final String propertyName) {
return "set"+StringUtils.capitalize(propertyName);
}
/**
* Sets property to value for specified object.
* @param object
* @param propertyName
* @param value
*/
public static void set(final Object object, final String propertyName, final Object value) {
try {
Reflections.invoke(object, Reflections.setterMethodName(propertyName), value);
} catch (RuntimeException e) {
final Field field = Reflections.setAccessible(object, propertyName);
try {
field.set(object, value);
} catch(IllegalAccessException ee) {
throw new RuntimeException(ee);
}
}
}
/**
* Sets parameters for specified object.
* @param object
* @param parameters
*/
public static void set(final Object object, final Map<String, Object> parameters) {
for (final Map.Entry<String, Object> entry : parameters.entrySet()) {
final String parameterName = entry.getKey();
try {
Reflections.invoke(object, Reflections.setterMethodName(parameterName), entry.getValue(), Object.class);
} catch (Exception e) {
throw new RuntimeException("Failed to set parameter <"+parameterName+">", e);
}
}
}
/**
* @param type
* @return primitive equivalent type for specified {@link Class}
* @throws IllegalArgumentException ig specified {@link Class} is not {@link Class#isPrimitive() }
*/
public static Class<?> toPrimitive(final Class<?> type) {
if (type.equals(Integer.class)) {
return int.class;
} else if (type.equals(Float.class)) {
return float.class;
} else if (type.equals(Long.class)) {
return long.class;
} else if (type.equals(Double.class)) {
return double.class;
} else if (type.equals(Character.class)) {
return char.class;
} else if (type.equals(Byte.class)) {
return byte.class;
} else if (type.equals(Short.class)) {
return short.class;
} else if (type.equals(Boolean.class)) {
return boolean.class;
}
throw new IllegalArgumentException("Unrecognized primitive type <"+type+">");
}
/**
* @param type
* @return bridge equivalent type for specified {@link Class}
* @throws IllegalArgumentException ig specified {@link Class} is not {@link Class#isPrimitive() }
*/
public static Class<?> toType(final Class<?> type) {
if (type.equals(int.class)) {
return Integer.class;
} else if (type.equals(float.class)) {
return Float.class;
} else if (type.equals(long.class)) {
return Long.class;
} else if (type.equals(double.class)) {
return Double.class;
} else if (type.equals(char.class)) {
return Character.class;
} else if (type.equals(byte.class)) {
return Byte.class;
} else if (type.equals(short.class)) {
return Short.class;
} else if (type.equals(boolean.class)) {
return Boolean.class;
}
throw new IllegalArgumentException("Unrecognized primitive type <"+type+">");
}
/**
* @param type
* @return type representation of provided {@link Class}. Namely convert primitive to their type counterpart.
* @see Class#isPrimitive()
* @see #toType(java.lang.Class)
*/
public static Class<?> asType(final Class<?> type) {
if (type.isPrimitive()) {
return toType(type);
}
return type;
}
/**
* @param <T>
* @param object
* @param method
* @param argument
* @return result of dynamic invocation of `method` on `object` with `argument`.
* @see #asTypes(java.lang.Object[]) for inferred type from arguments
*/
public static <T> T invoke(final Object object, final String method, final Object argument) {
try {
return Reflections.<T>invoke(object, method, argument, argument.getClass());
} catch (RuntimeException e) {
if (!argument.getClass().isPrimitive()) {
throw e;
} else {
return Reflections.<T>invoke(object, method, argument, Reflections.toPrimitive(argument.getClass()));
}
}
}
/**
* @param <T>
* @param object
* @param method
* @param argument
* @param argumentType
* @return result of dynamic invocation of `method` on `object` with `argument`.
*/
public static <T> T invoke(final Object object, final String method, final Object argument, final Class<?> argumentType) {
try {
return (T) object.getClass().getMethod(method, argumentType).invoke(object, argument);
} catch (Exception e) {
throw new RuntimeException("Failed to invoke <"+method+"> with arguments <"+argument+"> on <"+object+">", e);
}
}
/**
* @param <T>
* @param object
* @param method
* @return result of dynamic invocation of `method` on `object` with no argument.
*/
public static <T> T invoke(final Object object, final String method) {
try {
return (T) object.getClass().getMethod(method).invoke(object);
} catch (Exception e) {
throw new RuntimeException("Failed to invoke <"+method+"> on <"+object+">", e);
}
}
}