package net.sourceforge.javautil.groovy.expression.walker;
import org.codehaus.groovy.runtime.InvokerHelper;
import groovy.lang.MetaClass;
import groovy.lang.MetaProperty;
/**
* An instance of this object will be created by the {@link ObjectWalker} when a named property
* is called allowing one to walk whatever is returned by the property.
*
* @author ponder
* @author $Author: ponderator $
* @version $Id: PropertyWalker.java 1852 2009-09-13 16:51:22Z ponderator $
*/
public class PropertyWalker extends ObjectWalker {
private String name;
private ObjectWalker parent;
private Class expectedType;
/**
* @param name The name of the property of the parent object
* @param parent The parent walker which generated this one
*/
public PropertyWalker(String name, ObjectWalker parent) {
this.parent = parent;
this.name = name;
}
public MetaClass getTargetMetaClass () {
return InvokerHelper.getMetaClass( this.getExpectedType() );
}
public String toString () { return parent.toString() + "." + name; }
/**
* @return The true parent object of this property
*/
public Object getParent () {
Object p = parent.get();
//if (p == null) throw new NullPointerException("Could not get " + this + ", " + parent + " is null");
return p;
}
@Override public Object get() {
return getParent() == null ? null : InvokerHelper.getProperty(getParent(), name);
}
@Override public void set(Object value) {
if (getParent() == null)
throw new NullPointerException("Could not get " + this + ", " + parent + " is null");
InvokerHelper.setProperty(getParent(), name, value);
}
@Override public Object getProperty(String property) {
return new PropertyWalker(property, this);
}
@Override public Object invokeMethod(String name, Object args) {
return InvokerHelper.invokeMethod(get(), name, args);
}
@Override public void setProperty(String property, Object newValue) {
InvokerHelper.setProperty(get(), property, newValue);
}
public Class getExpectedType () {
if (expectedType != null) return expectedType;
if (parent == null) return expectedType = Object.class;
Object p = this.parent.get();
if (p == null) return Object.class;
MetaClass mc = InvokerHelper.getMetaClass(p);
MetaProperty mp = mc.getMetaProperty(name);
return expectedType = (mp == null ? Object.class : mp.getType());
// try {
// return expectedType = p.getClass().getField(name).getType();
// } catch (NoSuchFieldException e) {
// try {
// Method m = p.getClass().getMethod("get" + name.substring(0, 1).toUpperCase() + name.substring(1));
// return expectedType = m.getReturnType();
// } catch (Exception ex) {
// throw new RuntimeException(ex);
// }
// } catch (Exception e) {
// throw new RuntimeException(e);
// }
}
}