01: package org.obe.sql;
02:
03: import org.obe.OBERuntimeException;
04: import org.obe.client.api.repository.RepositoryException;
05: import org.obe.spi.model.AttributeInstance;
06: import org.obe.spi.model.AttributedEntity;
07:
08: import java.beans.BeanInfo;
09: import java.beans.IntrospectionException;
10: import java.beans.Introspector;
11: import java.beans.PropertyDescriptor;
12: import java.io.IOException;
13: import java.io.Writer;
14: import java.lang.reflect.InvocationTargetException;
15: import java.lang.reflect.Method;
16: import java.util.ArrayList;
17: import java.util.List;
18: import java.util.Map;
19:
20: /**
21: * @author Adrian Price
22: */
23: public class SQLLvalueTerm extends SimpleNode {
24: private List path = new ArrayList();
25:
26: public SQLLvalueTerm(int id) {
27: super (id);
28: }
29:
30: public void addPathElement(String elem) {
31: path.add(elem);
32: }
33:
34: public List getPath() {
35: return path;
36: }
37:
38: public void write(Writer out) throws IOException {
39: boolean dot = false;
40: for (int i = 0, n = path.size(); i < n; i++) {
41: if (dot)
42: out.write('.');
43: out.write((String) path.get(i));
44: dot = true;
45: }
46: }
47:
48: public Object execute(Object context) {
49: // For now, we won't support the concept of table.
50: if (path.size() != 1)
51: throw new UnsupportedOperationException(toString() + ": "
52: + path);
53:
54: // The semantics of SQLvalueTerm is essentially that of retrieving the
55: // value of a row, optionally qualified with a table name. Mapping the
56: // former concept from SQL to JavaBeans suggests the retrieval of a
57: // JavaBean property from the context bean. The latter concept is
58: // beyond the scope of the current SQL evaluator because it implies
59: // supporting the concept of tables and operations thereon.
60: try {
61: String attrName = (String) path.get(0);
62:
63: if (context instanceof AttributedEntity) {
64: AttributedEntity entity = (AttributedEntity) context;
65: Map map = entity.getAttributeInstances();
66: AttributeInstance attr = (AttributeInstance) map
67: .get(attrName);
68: return attr == null ? null : attr.getValue();
69: } else {
70: // TODO: initialize the property descriptors statically.
71: Object value = null;
72: BeanInfo bi = Introspector.getBeanInfo(context
73: .getClass());
74: PropertyDescriptor[] propDescs = bi
75: .getPropertyDescriptors();
76: for (int i = 0; i < propDescs.length; i++) {
77: PropertyDescriptor propDesc = propDescs[i];
78: if (propDesc.getName().equals(attrName)) {
79: Method getter = propDesc.getReadMethod();
80: // Cast required to suppress JDK1.5 varargs compiler warning.
81: value = getter.invoke(context, (Object[]) null);
82: break;
83: }
84: }
85: return value;
86: }
87: } catch (IntrospectionException e) {
88: throw new OBERuntimeException(e);
89: } catch (IllegalAccessException e) {
90: throw new OBERuntimeException(e);
91: } catch (InvocationTargetException e) {
92: throw new OBERuntimeException(e);
93: } catch (RepositoryException e) {
94: throw new OBERuntimeException(e);
95: }
96: }
97: }
|