001: package org.conform.mdl;
002:
003: import org.xml.sax.*;
004:
005: import java.util.*;
006: import java.beans.ExceptionListener;
007:
008: class ObjectHandler extends ScopeHandler {
009: private Hashtable environment = new Hashtable();
010: private Vector expStack = new Vector();
011: private StringBuffer chars = new StringBuffer();
012: private int itemsRead = 0;
013:
014: public ObjectHandler(ExceptionListener exceptionListener) {
015: super (exceptionListener);
016: }
017:
018: public void reset() {
019: environment.clear();
020: expStack.clear();
021: chars.setLength(0);
022: itemsRead = 0;
023: }
024:
025: private Object getValue(Expression exp) {
026: try {
027: return exp.getValue();
028: } catch (Exception e) {
029: exceptionListener.exceptionThrown(e);
030: return null;
031: }
032: }
033:
034: private void addArg(Object arg) {
035: // logger.finest("addArg: " + instanceName(arg));
036: lastExp().addArg(arg);
037: }
038:
039: private Object pop(Vector v) {
040: int last = v.size() - 1;
041: Object result = v.get(last);
042: v.remove(last);
043: return result;
044: }
045:
046: private Object eval() {
047: return getValue(lastExp());
048: }
049:
050: private MutableExpression lastExp() {
051: return (MutableExpression) expStack.lastElement();
052: }
053:
054: Object dequeueResult() {
055: // logger.finest("dequeueResult: " + expStack);
056: Object[] results = lastExp().getArguments();
057: reset();
058: return results[itemsRead++];
059: }
060:
061: private boolean isPrimitive(String name) {
062: return name != "void"
063: && Statement.typeNameToClass(name) != null;
064: }
065:
066: private void simulateException(String message) {
067: Exception e = new Exception(message);
068: e.fillInStackTrace();
069: exceptionListener.exceptionThrown(e);
070: }
071:
072: private Class classForName(String name) {
073: try {
074: return Statement.classForName(name);
075: } catch (ClassNotFoundException e) {
076: exceptionListener.exceptionThrown(e);
077: }
078: return null;
079: }
080:
081: private HashMap getAttributes(AttributeList attrs) {
082: HashMap attributes = new HashMap();
083: if (attrs != null && attrs.getLength() > 0) {
084: for (int i = 0; i < attrs.getLength(); i++) {
085: attributes.put(attrs.getName(i), attrs.getValue(i));
086: }
087: }
088: return attributes;
089: }
090:
091: public void startElement(String name, AttributeList attrs)
092: throws SAXException {
093: // logger.finest("startElement" + name);
094: name = name.intern(); // Xerces parser does not supply unique tag names.
095: chars.setLength(0);
096: if (name == "null" || name == "string" || name == "class"
097: || isPrimitive(name)) {
098: return;
099: }
100: HashMap attributes = getAttributes(attrs);
101:
102: MutableExpression e = new MutableExpression();
103:
104: // Target
105: String className = (String) attributes.get("class");
106: if (className != null) {
107: e.setTarget(classForName(className));
108: }
109:
110: // Property
111: Object property = attributes.get("property");
112: String index = (String) attributes.get("index");
113: if (index != null) {
114: property = new Integer(index);
115: e.addArg(property);
116: }
117: e.setProperty(property);
118:
119: // Method
120: String methodName = (String) attributes.get("method");
121: if (methodName == null && property == null) {
122: methodName = "new";
123: }
124: e.setMethodName(methodName);
125:
126: // Tags
127: if (name == "void") {
128: if (e.getTarget() == null) { // this check is for "void class="foo" method= ..."
129: e.setTarget(eval());
130: }
131: } else if (name == "array") {
132: // The class attribute means sub-type for arrays.
133: String subtypeName = (String) attributes.get("class");
134: Class subtype = (subtypeName == null) ? Object.class
135: : classForName(subtypeName);
136: String length = (String) attributes.get("length");
137: if (length != null) {
138: e.setTarget(java.lang.reflect.Array.class);
139: e.addArg(subtype);
140: e.addArg(new Integer(length));
141: } else {
142: Class arrayClass = java.lang.reflect.Array.newInstance(
143: subtype, 0).getClass();
144: e.setTarget(arrayClass);
145: }
146: } else if (name == "java") {
147: // TODO: getScope() ???
148: e.setValue(null); // The outermost scope is null.
149: } else if (name == "object") {
150: } else {
151: simulateException("Unrecognized opening tag: " + name + " "
152: + attrsToString(attrs));
153: return;
154: }
155:
156: // ids
157: String idName = (String) attributes.get("id");
158: if (idName != null) {
159: environment.put(idName, e);
160: }
161:
162: // idrefs
163: String idrefName = (String) attributes.get("idref");
164: if (idrefName != null) {
165: e.setValue(lookup(idrefName));
166: }
167:
168: // fields
169: String fieldName = (String) attributes.get("property");
170: if (fieldName != null) {
171: e.setValue(getFieldValue(e.getTarget(), fieldName));
172: }
173: expStack.add(e);
174: }
175:
176: private Object getFieldValue(Object target, String fieldName) {
177: try {
178: Class type = target.getClass();
179: if (type == Class.class) {
180: type = (Class) target;
181: }
182: java.lang.reflect.Field f = type.getField(fieldName);
183: return f.get(target);
184: } catch (Exception e) {
185: exceptionListener.exceptionThrown(e);
186: return null;
187: }
188: }
189:
190: private String attrsToString(AttributeList attrs) {
191: StringBuffer b = new StringBuffer();
192: for (int i = 0; i < attrs.getLength(); i++) {
193: b.append(attrs.getName(i) + "=\"" + attrs.getValue(i)
194: + "\" ");
195: }
196: return b.toString();
197: }
198:
199: public void characters(char buf[], int offset, int len)
200: throws SAXException {
201: chars.append(new String(buf, offset, len));
202: }
203:
204: private Object lookup(String s) {
205: Expression e = (Expression) environment.get(s);
206: if (e == null) {
207: simulateException("Unbound variable: " + s);
208: }
209: return getValue(e);
210: }
211:
212: public void endElement(String name) throws SAXException {
213: // logger.finest("endElement: " + expStack);
214: name = name.intern(); // Xerces parser does not supply unique tag names.
215: if (name == "null") {
216: addArg(null);
217: return;
218: }
219: if (name == "java") {
220: ObjectScope scope = (ObjectScope) getScope();
221: scope.setObject(dequeueResult());
222: return;
223: }
224: if (name == "string") {
225: addArg(chars.toString());
226: return;
227: }
228: if (name == "class") {
229: addArg(classForName(chars.toString()));
230: return;
231: }
232: if (isPrimitive(name)) {
233: Class wrapper = Expression.typeNameToClass(name);
234: Expression e = new Expression(wrapper, "new",
235: new Object[] { chars.toString() });
236: addArg(getValue(e));
237: return;
238: }
239: if (name == "object" || name == "array" || name == "void") {
240: Expression e = (Expression) pop(expStack);
241: Object value = getValue(e);
242: if (name == "object" || name == "array") {
243: addArg(value);
244: }
245: } else {
246: simulateException("Unrecognized closing tag: " + name);
247: }
248: }
249: }
|