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: protected void addDefaultMappings () {
115:
116: final MultiplexMappingEntry[] paintEntries = new MultiplexMappingEntry[2];
117: paintEntries[0] = new MultiplexMappingEntry("color", Color.class.getName());
118: paintEntries[1] = new MultiplexMappingEntry("gradientPaint", GradientPaint.class.getName());
119: addMultiplexMapping(Paint.class, "type", paintEntries);
120: addManualMapping(Color.class, ColorReadHandler.class);
121: addManualMapping(GradientPaint.class, GradientPaintReadHandler.class);
122:
123: final MultiplexMappingEntry[] point2DEntries = new MultiplexMappingEntry[2];
124: point2DEntries[0] = new MultiplexMappingEntry("float", Point2D.Float.class.getName());
125: point2DEntries[1] = new MultiplexMappingEntry("double", Point2D.Double.class.getName());
126: addMultiplexMapping(Point2D.class, "type", point2DEntries);
127: addManualMapping(Point2D.Float.class, Point2DReadHandler.class);
128: addManualMapping(Point2D.Double.class, Point2DReadHandler.class);
129:
130: final MultiplexMappingEntry[] rectangle2DEntries = new MultiplexMappingEntry[2];
131: rectangle2DEntries[0] = new MultiplexMappingEntry(
132: "float", Rectangle2D.Float.class.getName()
133: );
134: rectangle2DEntries[1] = new MultiplexMappingEntry(
135: "double", Rectangle2D.Double.class.getName()
136: );
137: addMultiplexMapping(Rectangle2D.class, "type", rectangle2DEntries);
138: addManualMapping(Rectangle2D.Float.class, Rectangle2DReadHandler.class);
139: addManualMapping(Rectangle2D.Double.class, Rectangle2DReadHandler.class);
140:
141:
142: final MultiplexMappingEntry[] listEntries = new MultiplexMappingEntry[4];
143: listEntries[0] = new MultiplexMappingEntry("array-list", ArrayList.class.getName());
144: listEntries[1] = new MultiplexMappingEntry("linked-list", LinkedList.class.getName());
145: listEntries[2] = new MultiplexMappingEntry("vector", Vector.class.getName());
146: listEntries[3] = new MultiplexMappingEntry("stack", Stack.class.getName());
147: addMultiplexMapping(List.class, "type", listEntries);
148: addManualMapping(LinkedList.class, ListReadHandler.class);
149: addManualMapping(Vector.class, ListReadHandler.class);
150: addManualMapping(ArrayList.class, ListReadHandler.class);
151: addManualMapping(Stack.class, ListReadHandler.class);
152:
153: final MultiplexMappingEntry[] strokeEntries = new MultiplexMappingEntry[1];
154: strokeEntries[0] = new MultiplexMappingEntry("basic", BasicStroke.class.getName());
155: addMultiplexMapping(Stroke.class, "type", strokeEntries);
156: addManualMapping(BasicStroke.class, BasicStrokeReadHandler.class);
157:
158: addManualMapping(Font.class, FontReadHandler.class);
159: addManualMapping(Insets.class, InsetsReadHandler.class);
160: addManualMapping(RenderingHints.class, RenderingHintsReadHandler.class);
161: addManualMapping(String.class, StringReadHandler.class);
162: }
163:
164:
169: public abstract ObjectFactory getFactoryLoader();
170:
171:
177: protected void addManualMapping(final Class classToRead, final Class handler) {
178: if (handler == null) {
179: throw new NullPointerException("handler must not be null.");
180: }
181: if (classToRead == null) {
182: throw new NullPointerException("classToRead must not be null.");
183: }
184: if (!XmlReadHandler.class.isAssignableFrom(handler)) {
185: throw new IllegalArgumentException("The given handler is no XmlReadHandler.");
186: }
187: this.classToHandlerMapping.addManualMapping
188: (new ManualMappingDefinition(classToRead, handler.getName(), null));
189: }
190:
191:
198: protected void addMultiplexMapping(final Class baseClass,
199: final String typeAttr,
200: final MultiplexMappingEntry[] mdef) {
201:
202: this.classToHandlerMapping.addMultiplexMapping(
203: new MultiplexMappingDefinition(baseClass, typeAttr, mdef)
204: );
205: }
206:
207:
213: public void setHelperObject(final String key, final Object value) {
214: if (value == null) {
215: this.objectRegistry.remove(key);
216: }
217: else {
218: this.objectRegistry.put(key, value);
219: }
220: }
221:
222:
229: public Object getHelperObject(final String key) {
230: return this.objectRegistry.get(key);
231: }
232:
233:
244: public XmlReadHandler createHandler(final Class classToRead, final String tagName, final Attributes atts)
245: throws XmlReaderException {
246:
247: final XmlReadHandler retval = findHandlerForClass(classToRead, atts, new ArrayList());
248: if (retval == null) {
249: throw new NullPointerException("Unable to find handler for class: " + classToRead);
250: }
251: retval.init(this, tagName);
252: return retval;
253: }
254:
255:
266: private XmlReadHandler findHandlerForClass(final Class classToRead, final Attributes atts,
267: final ArrayList history)
268: throws XmlReaderException {
269: final ObjectFactory genericFactory = getFactoryLoader();
270:
271: if (history.contains(classToRead)) {
272: throw new IllegalStateException("Circular reference detected: " + history);
273: }
274: history.add(classToRead);
275:
276: ManualMappingDefinition manualDefinition =
277: this.classToHandlerMapping.getManualMappingDefinition(classToRead);
278: if (manualDefinition == null) {
279: manualDefinition = genericFactory.getManualMappingDefinition(classToRead);
280: }
281: if (manualDefinition != null) {
282:
283: return loadHandlerClass(manualDefinition.getReadHandler());
284: }
285:
286:
287:
288: MultiplexMappingDefinition mplex =
289: getFactoryLoader().getMultiplexDefinition(classToRead);
290: if (mplex == null) {
291: mplex = this.classToHandlerMapping.getMultiplexDefinition(classToRead);
292: }
293: if (mplex != null) {
294: final String attributeValue = atts.getValue(mplex.getAttributeName());
295: if (attributeValue == null) {
296: throw new XmlReaderException(
297: "Multiplexer type attribute is not defined: " + mplex.getAttributeName()
298: + " for " + classToRead
299: );
300: }
301: final MultiplexMappingEntry entry =
302: mplex.getEntryForType(attributeValue);
303: if (entry == null) {
304: throw new XmlReaderException(
305: "Invalid type attribute value: " + mplex.getAttributeName() + " = "
306: + attributeValue
307: );
308: }
309: final Class c = loadClass(entry.getTargetClass());
310: if (!c.equals(mplex.getBaseClass())) {
311: return findHandlerForClass(c, atts, history);
312: }
313: }
314:
315:
316:
317: if (this.classToHandlerMapping.isGenericHandler(classToRead)) {
318: return new GenericReadHandler
319: (this.classToHandlerMapping.getFactoryForClass(classToRead));
320: }
321: if (getFactoryLoader().isGenericHandler(classToRead)) {
322: return new GenericReadHandler
323: (getFactoryLoader().getFactoryForClass(classToRead));
324: }
325: return null;
326: }
327:
328:
333: protected void setRootHandler(final XmlReadHandler handler) {
334: this.rootHandler = handler;
335: this.rootHandlerInitialized = false;
336: }
337:
338:
343: protected XmlReadHandler getRootHandler() {
344: return this.rootHandler;
345: }
346:
347:
357: public void recurse(final XmlReadHandler handler, final String tagName, final Attributes attrs)
358: throws XmlReaderException, SAXException {
359:
360: this.outerScopes.push(this.currentHandlers);
361: this.currentHandlers = new Stack();
362: this.currentHandlers.push(handler);
363: handler.startElement(tagName, attrs);
364:
365: }
366:
367:
377: public void delegate(final XmlReadHandler handler, final String tagName, final Attributes attrs)
378: throws XmlReaderException, SAXException {
379: this.currentHandlers.push(handler);
380: handler.init(this, tagName);
381: handler.startElement(tagName, attrs);
382: }
383:
384:
392: public void unwind(final String tagName) throws SAXException, XmlReaderException {
393:
394: this.currentHandlers.pop();
395: if (this.currentHandlers.isEmpty() && !this.outerScopes.isEmpty()) {
396:
397:
398: this.currentHandlers = (Stack) this.outerScopes.pop();
399: }
400: else if (!this.currentHandlers.isEmpty()) {
401:
402: getCurrentHandler().endElement(tagName);
403: }
404: }
405:
406:
411: protected XmlReadHandler getCurrentHandler() {
412: return (XmlReadHandler) this.currentHandlers.peek();
413: }
414:
415:
420: public void startDocument() throws SAXException {
421: this.outerScopes = new Stack();
422: this.currentHandlers = new Stack();
423: this.currentHandlers.push(this.rootHandler);
424: }
425:
426:
436: public void startElement(final String uri, final String localName,
437: final String qName, final Attributes attributes)
438: throws SAXException {
439: if (rootHandlerInitialized == false) {
440: rootHandler.init(this, qName);
441: rootHandlerInitialized = true;
442: }
443:
444: try {
445: getCurrentHandler().startElement(qName, attributes);
446: }
447: catch (XmlReaderException xre) {
448: throw new ParseException(xre, getLocator());
449: }
450: }
451:
452:
461: public void characters(final char[] ch, final int start, final int length) throws SAXException {
462: try {
463: getCurrentHandler().characters(ch, start, length);
464: }
465: catch (SAXException se) {
466: throw se;
467: }
468: catch (Exception e) {
469: throw new ParseException(e, getLocator());
470: }
471: }
472:
473:
482: public void endElement(final String uri, final String localName, final String qName)
483: throws SAXException {
484: try {
485: getCurrentHandler().endElement(qName);
486: }
487: catch (XmlReaderException xre) {
488: throw new ParseException(xre, getLocator());
489: }
490: }
491:
492:
500: protected XmlReadHandler loadHandlerClass(final String className)
501: throws XmlReaderException {
502: try {
503: final Class c = loadClass(className);
504: return (XmlReadHandler) c.newInstance();
505: }
506: catch (Exception e) {
507:
508: throw new XmlReaderException("LoadHanderClass: Unable to instantiate " + className, e);
509: }
510: }
511:
512:
520: protected Class loadClass(final String className)
521: throws XmlReaderException {
522: if (className == null) {
523: throw new XmlReaderException("LoadHanderClass: Class name not defined");
524: }
525: try {
526: final Class c = ObjectUtilities.getClassLoader(getClass()).loadClass(className);
527: return c;
528: }
529: catch (Exception e) {
530:
531: throw new XmlReaderException("LoadHanderClass: Unable to load " + className, e);
532: }
533: }
534:
535: public Object getResult () throws SAXException
536: {
537: if (this.rootHandler != null) {
538: try
539: {
540: return this.rootHandler.getObject();
541: }
542: catch (XmlReaderException e)
543: {
544: throw new ElementDefinitionException(e);
545: }
546: }
547: return null;
548: }
549: }