package org.obe.sql;
import org.obe.OBERuntimeException;
import org.obe.client.api.repository.RepositoryException;
import org.obe.spi.model.AttributeInstance;
import org.obe.spi.model.AttributedEntity;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author Adrian Price
*/
public class SQLLvalueTerm extends SimpleNode {
private List path = new ArrayList();
public SQLLvalueTerm(int id) {
super(id);
}
public void addPathElement(String elem) {
path.add(elem);
}
public List getPath() {
return path;
}
public void write(Writer out) throws IOException {
boolean dot = false;
for (int i = 0, n = path.size(); i < n; i++) {
if (dot)
out.write('.');
out.write((String)path.get(i));
dot = true;
}
}
public Object execute(Object context) {
// For now, we won't support the concept of table.
if (path.size() != 1)
throw new UnsupportedOperationException(toString() + ": " + path);
// The semantics of SQLvalueTerm is essentially that of retrieving the
// value of a row, optionally qualified with a table name. Mapping the
// former concept from SQL to JavaBeans suggests the retrieval of a
// JavaBean property from the context bean. The latter concept is
// beyond the scope of the current SQL evaluator because it implies
// supporting the concept of tables and operations thereon.
try {
String attrName = (String)path.get(0);
if (context instanceof AttributedEntity) {
AttributedEntity entity = (AttributedEntity)context;
Map map = entity.getAttributeInstances();
AttributeInstance attr = (AttributeInstance)map.get(attrName);
return attr == null ? null : attr.getValue();
} else {
// TODO: initialize the property descriptors statically.
Object value = null;
BeanInfo bi = Introspector.getBeanInfo(context.getClass());
PropertyDescriptor[] propDescs = bi.getPropertyDescriptors();
for (int i = 0; i < propDescs.length; i++) {
PropertyDescriptor propDesc = propDescs[i];
if (propDesc.getName().equals(attrName)) {
Method getter = propDesc.getReadMethod();
// Cast required to suppress JDK1.5 varargs compiler warning.
value = getter.invoke(context, (Object[])null);
break;
}
}
return value;
}
} catch (IntrospectionException e) {
throw new OBERuntimeException(e);
} catch (IllegalAccessException e) {
throw new OBERuntimeException(e);
} catch (InvocationTargetException e) {
throw new OBERuntimeException(e);
} catch (RepositoryException e) {
throw new OBERuntimeException(e);
}
}
}
|