package com.robonobo.common.util;
/*
* Robonobo Common Utils
* Copyright (C) 2008 Will Morton (macavity@well.com) & Ray Hilton (ray@wirestorm.net)
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class BeanPropertyAccessor {
Object o;
Log log = LogFactory.getLog(getClass());
public BeanPropertyAccessor(Object o) {
this.o = o;
}
/**
* Attempts to copy properties from the object from to object to
* @param from
* @param to
*/
public static void copy(Object from, Object to) throws Exception {
BeanPropertyAccessor fromAccessor = new BeanPropertyAccessor(from);
BeanPropertyAccessor toAccessor = new BeanPropertyAccessor(to);
Iterator i = fromAccessor.getPropertyNames().iterator();
while(i.hasNext()) {
String property = (String)i.next();
Method m = fromAccessor.getGetterMethod(property);
if(fromAccessor.getProperty(property) != null) {
toAccessor.setProperty(property, m.getReturnType(), fromAccessor.getProperty(property));
}
}
}
public Collection getPropertyNames() {
List methodNames = new Vector();
Method[] methods = o.getClass().getMethods();
for(int i = 0; i < methods.length; i++) {
if(methods[i].getName().startsWith("set") && methods[i].getParameterTypes().length == 1) {
String name = getName(methods[i]);
methodNames.add(name);
// descend down hierachy
try {
Method m = getGetterMethod(name);
Object obj = m.invoke(this.o, new Object[] {});
if(obj != null) {
Iterator j = new BeanPropertyAccessor(obj).getPropertyNames().iterator();
while(j.hasNext()) {
String subName = (String)j.next();
methodNames.add(name + "." + subName);
}
}
}
catch(NoSuchMethodException e) {
// do nothing, no such method
}
catch(Exception e) {
log.error("Cannot invoke getter methd",e);
}
}
}
return methodNames;
}
public void setProperty(String name, Object value) throws Exception {
setProperty(name, value.getClass(), value);
}
public void setProperty(String name, int value) throws Exception {
setProperty(name, int.class, new Integer(value));
}
public void setProperty(String name, boolean value) throws Exception {
setProperty(name, boolean.class, new Boolean(value));
}
public void setProperty(String name, float value) throws Exception {
setProperty(name, float.class, new Float(value));
}
public Object getProperty(String name) throws Exception {
String[] bits = name.split("\\.", 2);
Method m = getGetterMethod(bits[0]);
Object rtn = m.invoke(o, new Object[] {});
if(bits.length == 1)
return rtn;
else
return new BeanPropertyAccessor(rtn).getProperty(bits[1]);
}
protected void setProperty(String name, Class cl, Object value) throws Exception {
String[] bits = name.split("\\.", 2);
if(bits.length == 1) {
Method m = getSetterMethod(bits[0], cl);
m.invoke(o, new Object[] {value});
} else {
new BeanPropertyAccessor(getProperty(bits[0])).setProperty(bits[1], cl, value);
}
}
protected String getName(Method m) {
return m.getName().substring(3,4).toLowerCase() + m.getName().substring(4);
}
protected String getSetterMethodName(String name) {
return "set" + name.substring(0,1).toUpperCase() + name.substring(1);
}
protected Method getSetterMethod(String name, Class cl) throws NoSuchMethodException{
String method = getSetterMethodName(name);
return o.getClass().getMethod(method, new Class[] {cl});
}
// protected String getGetterMethodName(String name) {
// return "get" + name.substring(0,1).toUpperCase() + name.substring(1);
// }
protected Method getGetterMethod(String name) throws NoSuchMethodException {
String[] nominations = new String[] {
"get" + name.substring(0,1).toUpperCase() + name.substring(1),
"is" + name.substring(0,1).toUpperCase() + name.substring(1)
};
for(int i = 0; i < nominations.length; i++) {
try {
String method = nominations[i];
return o.getClass().getMethod(method, new Class[] {});
}
catch(NoSuchMethodException e) {
// nope. couldnt find it
}
}
throw new NoSuchMethodException("Tried to find methods " + nominations + " but failed");
}
}