/*
* Copyright (C) 2011 Rhegium Team
*
* 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.rhegium.internal.utils;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.objectweb.asm.Type;
import org.rhegium.api.config.ConfigurationProvisionException;
import org.rhegium.api.typeconverter.TypeConverterManager;
public final class ReflectionUtils {
private ReflectionUtils() {
}
public static final String buildClassLoaderHierachy(final ClassLoader classLoader) {
return new StringBuilder(classLoader.getClass().getCanonicalName()).append(
(classLoader.getParent() != null ? new StringBuilder(" => ").append(
buildClassLoaderHierachy(classLoader.getParent())).toString() : "")).toString();
}
public static void injectValue(String property, Object value, Object injectable,
TypeConverterManager typeConverterManager) {
Class<?> propertyType = getPropertyType(value);
Collection<Method> setters = findSetters(property, propertyType, injectable);
if (setters == null) {
throw new IllegalArgumentException("No legal setter for property " + property + " was found");
}
List<Exception> suppressedExceptions = new ArrayList<Exception>();
for (Method setter : setters) {
try {
setter.setAccessible(true);
if (propertyType == null) {
setter.invoke(injectable);
return;
}
else {
setter.invoke(injectable, typeConverterManager.convert(value, setter.getParameterTypes()[0]));
return;
}
}
catch (Exception e) {
// ignore and try next setter but collect for suppressed
// exceptions (added in Java 7)
suppressedExceptions.add(e);
}
}
ConfigurationProvisionException exception = new ConfigurationProvisionException("Value for property "
+ property + " could not be injected");
for (Exception suppressed : suppressedExceptions) {
exception.addSuppressed(suppressed);
}
throw exception;
}
public static Type getType(String name) {
return Type.getType(name);
}
public static String buildSetter(String property) {
return "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
}
private static Collection<Method> findSetters(String property, Class<?> propertyType, Object injectable) {
Collection<Method> methods = new ArrayList<Method>();
String setterName = buildSetter(property);
for (Method method : injectable.getClass().getMethods()) {
if (method.getName().equals(setterName)) {
if (propertyType == null && method.getParameterTypes().length == 0) {
methods.add(method);
}
else if (method.getParameterTypes().length == 1) {
methods.add(method);
}
}
}
return methods;
}
private static Class<?> getPropertyType(Object value) {
if (value == null) {
return null;
}
if (String.class.isAssignableFrom(value.getClass())) {
if (StringUtils.isEmpty(value.toString().trim())) {
return null;
}
if ("true".equalsIgnoreCase(value.toString().trim()) || "false".equalsIgnoreCase(value.toString().trim())) {
return boolean.class;
}
}
return value.getClass();
}
}