/*
* Copyright (c) 2010 Red Hat, Inc.
*
* 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.ovirt.engine.api.utils;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import org.ovirt.engine.api.model.BaseResource;
public class ReflectionHelper {
private static final String GET_ROOT = "get";
private static final String SET_ROOT = "set";
private static final String IS_ROOT = "is";
private static final String IS_SET_ROOT = "isSet";
private ReflectionHelper() {}
public static <R extends BaseResource> R newModel(Class<R> clz) {
R ret = null;
try {
ret = clz.newInstance();
} catch (Exception ignore) {
}
return ret;
}
@SuppressWarnings("unchecked")
public static <R extends BaseResource> R newModel(Object resource) {
return newModel((Class<R>) ((ParameterizedType) resource.getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
}
public static <R extends BaseResource> R assignChildModel(BaseResource parent, Class<R> childType) {
Method setter = getMethod(parent,
SET_ROOT + capitalize(childType.getSimpleName().toLowerCase()));
R child = newModel(childType);
try {
setter.invoke(parent, child);
} catch (Exception e) {
// InvocationTargetException etc. should never occur
// as this is a simple setter
}
return child;
}
public static String capitalize(String s) {
return Character.isLowerCase(s.charAt(0))
? s.substring(0, 1).toUpperCase() + s.substring(1)
: s;
}
public static boolean isSet(Object o, String name) {
boolean set = false;
if(o != null){
Method m = getMethod(o, IS_SET_ROOT + name);
Object ret = invoke(o, m);
if (ret != null && ret instanceof Boolean && ((Boolean) ret).booleanValue()) {
// (isSetX() method only tells us if the value is not null).
// for Strings we also have to check that the value is not empty.
if (getReturnType(o, name).equals(String.class)) {
Object result = invoke(o, getGetter(o, name));
String resultAsString = (String) result;
if (!resultAsString.isEmpty()) {
set = true;
}
} else {
set = true;
}
}
}
return set;
}
public static Method getGetter(Object o, String name) {
String capitalizedName = capitalize(name);
Method method = getMethod(o, GET_ROOT + capitalizedName);
return method != null ? method : getMethod(o, IS_ROOT + capitalizedName);
}
public static Class<?> getReturnType(Object o, String name) {
Method getter = getGetter(o, name);
return getter.getReturnType();
}
public static boolean different(Object lhs, Object rhs, String name) {
Method lhsm = getMethod(lhs, GET_ROOT + name);
Method rhsm = getMethod(rhs, GET_ROOT + name);
Object lhsr = lhsm != null ? invoke(lhs, lhsm) : null;
Object rhsr = rhsm != null ? invoke(rhs, rhsm) : null;
return !(lhsr == null || lhsr.equals(rhsr));
}
public static Object invoke(Object o, Method m) {
Object ret = null;
try {
ret = m.invoke(o);
} catch (Exception e) {
// InvocationTargetException etc. should never occur
// as this is a simple getter
}
return ret;
}
public static boolean set(Object o, String field, String value) {
boolean success = false;
String name = SET_ROOT + capitalize(field);
for (Method m : o.getClass().getMethods()) {
if (m.getName().equals(name) && isPrimitive(m)) {
Object arg = isString(m)
? value
: isBoolean(m)
? Boolean.parseBoolean(value)
: isInteger(m)
? Integer.parseInt(value)
: null;
if (arg != null) {
try {
m.invoke(o, arg);
success = true;
} catch (Exception e) {
// InvocationTargetException etc. should never occur
// as this is a simple getter
}
}
break;
}
}
return success;
}
public static Object get(Object o, String field) {
Object ret = null;
String name = GET_ROOT + capitalize(field);
for (Method m : o.getClass().getMethods()) {
if (m.getName().equals(name)) {
try {
ret = m.invoke(o);
} catch (Exception e) {
// InvocationTargetException etc. should never occur
// as this is a simple getter
}
break;
}
}
return ret;
}
private static boolean isPrimitive(Method m) {
Class<?>[] params = m.getParameterTypes();
return params.length == 1
&& (String.class.equals(params[0])
|| Boolean.TYPE.equals(params[0])
|| Integer.TYPE.equals(params[0]));
}
private static boolean isString(Method m) {
return String.class.equals(m.getParameterTypes()[0]);
}
private static boolean isInteger(Method m) {
return Integer.TYPE.equals(m.getParameterTypes()[0]);
}
private static boolean isBoolean(Method m) {
return Boolean.TYPE.equals(m.getParameterTypes()[0]);
}
private static Method getMethod(Object o, String name) {
Method ret = null;
for (Method m : o.getClass().getMethods()) {
if (m.getName().equals(name)) {
ret = m;
break;
}
}
return ret;
}
}