1:
42: package ;
43:
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60:
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78: import ;
79: import ;
80: import ;
81: import ;
82: import ;
83:
84:
87: public abstract class RootXmlReadHandler extends FrontendDefaultHandler {
88:
89:
90: private Stack currentHandlers;
91:
92:
93: private Stack outerScopes;
94:
95:
96: private XmlReadHandler rootHandler;
97:
98:
99: private HashMap objectRegistry;
100:
101:
102: private SimpleObjectFactory classToHandlerMapping;
103:
104: private boolean rootHandlerInitialized;
105:
106:
109: public RootXmlReadHandler() {
110: this.objectRegistry = new HashMap();
111: this.classToHandlerMapping = new SimpleObjectFactory();
112: }
113:
114:
117: protected void addDefaultMappings () {
118:
119: final MultiplexMappingEntry[] paintEntries = new MultiplexMappingEntry[2];
120: paintEntries[0] = new MultiplexMappingEntry("color", Color.class.getName());
121: paintEntries[1] = new MultiplexMappingEntry("gradientPaint", GradientPaint.class.getName());
122: addMultiplexMapping(Paint.class, "type", paintEntries);
123: addManualMapping(Color.class, ColorReadHandler.class);
124: addManualMapping(GradientPaint.class, GradientPaintReadHandler.class);
125:
126: final MultiplexMappingEntry[] point2DEntries = new MultiplexMappingEntry[2];
127: point2DEntries[0] = new MultiplexMappingEntry("float", Point2D.Float.class.getName());
128: point2DEntries[1] = new MultiplexMappingEntry("double", Point2D.Double.class.getName());
129: addMultiplexMapping(Point2D.class, "type", point2DEntries);
130: addManualMapping(Point2D.Float.class, Point2DReadHandler.class);
131: addManualMapping(Point2D.Double.class, Point2DReadHandler.class);
132:
133: final MultiplexMappingEntry[] rectangle2DEntries = new MultiplexMappingEntry[2];
134: rectangle2DEntries[0] = new MultiplexMappingEntry(
135: "float", Rectangle2D.Float.class.getName()
136: );
137: rectangle2DEntries[1] = new MultiplexMappingEntry(
138: "double", Rectangle2D.Double.class.getName()
139: );
140: addMultiplexMapping(Rectangle2D.class, "type", rectangle2DEntries);
141: addManualMapping(Rectangle2D.Float.class, Rectangle2DReadHandler.class);
142: addManualMapping(Rectangle2D.Double.class, Rectangle2DReadHandler.class);
143:
144:
145: final MultiplexMappingEntry[] listEntries = new MultiplexMappingEntry[4];
146: listEntries[0] = new MultiplexMappingEntry("array-list", ArrayList.class.getName());
147: listEntries[1] = new MultiplexMappingEntry("linked-list", LinkedList.class.getName());
148: listEntries[2] = new MultiplexMappingEntry("vector", Vector.class.getName());
149: listEntries[3] = new MultiplexMappingEntry("stack", Stack.class.getName());
150: addMultiplexMapping(List.class, "type", listEntries);
151: addManualMapping(LinkedList.class, ListReadHandler.class);
152: addManualMapping(Vector.class, ListReadHandler.class);
153: addManualMapping(ArrayList.class, ListReadHandler.class);
154: addManualMapping(Stack.class, ListReadHandler.class);
155:
156: final MultiplexMappingEntry[] strokeEntries = new MultiplexMappingEntry[1];
157: strokeEntries[0] = new MultiplexMappingEntry("basic", BasicStroke.class.getName());
158: addMultiplexMapping(Stroke.class, "type", strokeEntries);
159: addManualMapping(BasicStroke.class, BasicStrokeReadHandler.class);
160:
161: addManualMapping(Font.class, FontReadHandler.class);
162: addManualMapping(Insets.class, InsetsReadHandler.class);
163: addManualMapping(RenderingHints.class, RenderingHintsReadHandler.class);
164: addManualMapping(String.class, StringReadHandler.class);
165: }
166:
167:
172: public abstract ObjectFactory getFactoryLoader();
173:
174:
180: protected void addManualMapping(final Class classToRead, final Class handler) {
181: if (handler == null) {
182: throw new NullPointerException("handler must not be null.");
183: }
184: if (classToRead == null) {
185: throw new NullPointerException("classToRead must not be null.");
186: }
187: if (!XmlReadHandler.class.isAssignableFrom(handler)) {
188: throw new IllegalArgumentException("The given handler is no XmlReadHandler.");
189: }
190: this.classToHandlerMapping.addManualMapping
191: (new ManualMappingDefinition(classToRead, handler.getName(), null));
192: }
193:
194:
201: protected void addMultiplexMapping(final Class baseClass,
202: final String typeAttr,
203: final MultiplexMappingEntry[] mdef) {
204:
205: this.classToHandlerMapping.addMultiplexMapping(
206: new MultiplexMappingDefinition(baseClass, typeAttr, mdef)
207: );
208: }
209:
210:
216: public void setHelperObject(final String key, final Object value) {
217: if (value == null) {
218: this.objectRegistry.remove(key);
219: }
220: else {
221: this.objectRegistry.put(key, value);
222: }
223: }
224:
225:
232: public Object getHelperObject(final String key) {
233: return this.objectRegistry.get(key);
234: }
235:
236:
247: public XmlReadHandler createHandler(final Class classToRead, final String tagName, final Attributes atts)
248: throws XmlReaderException {
249:
250: final XmlReadHandler retval = findHandlerForClass(classToRead, atts, new ArrayList());
251: if (retval == null) {
252: throw new NullPointerException("Unable to find handler for class: " + classToRead);
253: }
254: retval.init(this, tagName);
255: return retval;
256: }
257:
258:
269: private XmlReadHandler findHandlerForClass(final Class classToRead, final Attributes atts,
270: final ArrayList history)
271: throws XmlReaderException {
272: final ObjectFactory genericFactory = getFactoryLoader();
273:
274: if (history.contains(classToRead)) {
275: throw new IllegalStateException("Circular reference detected: " + history);
276: }
277: history.add(classToRead);
278:
279: ManualMappingDefinition manualDefinition =
280: this.classToHandlerMapping.getManualMappingDefinition(classToRead);
281: if (manualDefinition == null) {
282: manualDefinition = genericFactory.getManualMappingDefinition(classToRead);
283: }
284: if (manualDefinition != null) {
285:
286: return loadHandlerClass(manualDefinition.getReadHandler());
287: }
288:
289:
290:
291: MultiplexMappingDefinition mplex =
292: getFactoryLoader().getMultiplexDefinition(classToRead);
293: if (mplex == null) {
294: mplex = this.classToHandlerMapping.getMultiplexDefinition(classToRead);
295: }
296: if (mplex != null) {
297: final String attributeValue = atts.getValue(mplex.getAttributeName());
298: if (attributeValue == null) {
299: throw new XmlReaderException(
300: "Multiplexer type attribute is not defined: " + mplex.getAttributeName()
301: + " for " + classToRead
302: );
303: }
304: final MultiplexMappingEntry entry =
305: mplex.getEntryForType(attributeValue);
306: if (entry == null) {
307: throw new XmlReaderException(
308: "Invalid type attribute value: " + mplex.getAttributeName() + " = "
309: + attributeValue
310: );
311: }
312: final Class c = loadClass(entry.getTargetClass());
313: if (!c.equals(mplex.getBaseClass())) {
314: return findHandlerForClass(c, atts, history);
315: }
316: }
317:
318:
319:
320: if (this.classToHandlerMapping.isGenericHandler(classToRead)) {
321: return new GenericReadHandler
322: (this.classToHandlerMapping.getFactoryForClass(classToRead));
323: }
324: if (getFactoryLoader().isGenericHandler(classToRead)) {
325: return new GenericReadHandler
326: (getFactoryLoader().getFactoryForClass(classToRead));
327: }
328: return null;
329: }
330:
331:
336: protected void setRootHandler(final XmlReadHandler handler) {
337: this.rootHandler = handler;
338: this.rootHandlerInitialized = false;
339: }
340:
341:
346: protected XmlReadHandler getRootHandler() {
347: return this.rootHandler;
348: }
349:
350:
360: public void recurse(final XmlReadHandler handler, final String tagName, final Attributes attrs)
361: throws XmlReaderException, SAXException {
362:
363: this.outerScopes.push(this.currentHandlers);
364: this.currentHandlers = new Stack();
365: this.currentHandlers.push(handler);
366: handler.startElement(tagName, attrs);
367:
368: }
369:
370:
380: public void delegate(final XmlReadHandler handler, final String tagName, final Attributes attrs)
381: throws XmlReaderException, SAXException {
382: this.currentHandlers.push(handler);
383: handler.init(this, tagName);
384: handler.startElement(tagName, attrs);
385: }
386:
387:
395: public void unwind(final String tagName) throws SAXException, XmlReaderException {
396:
397: this.currentHandlers.pop();
398: if (this.currentHandlers.isEmpty() && !this.outerScopes.isEmpty()) {
399:
400:
401: this.currentHandlers = (Stack) this.outerScopes.pop();
402: }
403: else if (!this.currentHandlers.isEmpty()) {
404:
405: getCurrentHandler().endElement(tagName);
406: }
407: }
408:
409:
414: protected XmlReadHandler getCurrentHandler() {
415: return (XmlReadHandler) this.currentHandlers.peek();
416: }
417:
418:
423: public void startDocument() throws SAXException {
424: this.outerScopes = new Stack();
425: this.currentHandlers = new Stack();
426: this.currentHandlers.push(this.rootHandler);
427: }
428:
429:
439: public void startElement(final String uri, final String localName,
440: final String qName, final Attributes attributes)
441: throws SAXException {
442: if (this.rootHandlerInitialized == false) {
443: this.rootHandler.init(this, qName);
444: this.rootHandlerInitialized = true;
445: }
446:
447: try {
448: getCurrentHandler().startElement(qName, attributes);
449: }
450: catch (XmlReaderException xre) {
451: throw new ParseException(xre, getLocator());
452: }
453: }
454:
455:
464: public void characters(final char[] ch, final int start, final int length) throws SAXException {
465: try {
466: getCurrentHandler().characters(ch, start, length);
467: }
468: catch (SAXException se) {
469: throw se;
470: }
471: catch (Exception e) {
472: throw new ParseException(e, getLocator());
473: }
474: }
475:
476:
485: public void endElement(final String uri, final String localName, final String qName)
486: throws SAXException {
487: try {
488: getCurrentHandler().endElement(qName);
489: }
490: catch (XmlReaderException xre) {
491: throw new ParseException(xre, getLocator());
492: }
493: }
494:
495:
503: protected XmlReadHandler loadHandlerClass(final String className)
504: throws XmlReaderException {
505: try {
506: final Class c = loadClass(className);
507: return (XmlReadHandler) c.newInstance();
508: }
509: catch (Exception e) {
510:
511: throw new XmlReaderException("LoadHanderClass: Unable to instantiate " + className, e);
512: }
513: }
514:
515:
523: protected Class loadClass(final String className)
524: throws XmlReaderException {
525: if (className == null) {
526: throw new XmlReaderException("LoadHanderClass: Class name not defined");
527: }
528: try {
529: final Class c = ObjectUtilities.getClassLoader(getClass()).loadClass(className);
530: return c;
531: }
532: catch (Exception e) {
533:
534: throw new XmlReaderException("LoadHanderClass: Unable to load " + className, e);
535: }
536: }
537:
538:
545: public Object getResult () throws SAXException
546: {
547: if (this.rootHandler != null) {
548: try
549: {
550: return this.rootHandler.getObject();
551: }
552: catch (XmlReaderException e)
553: {
554: throw new ElementDefinitionException(e);
555: }
556: }
557: return null;
558: }
559: }