001: /* ========================================================================
002: * JCommon : a free general purpose class library for the Java(tm) platform
003: * ========================================================================
004: *
005: * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
006: *
007: * Project Info: http://www.jfree.org/jcommon/index.html
008: *
009: * This library is free software; you can redistribute it and/or modify it
010: * under the terms of the GNU Lesser General Public License as published by
011: * the Free Software Foundation; either version 2.1 of the License, or
012: * (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but
015: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
016: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
017: * License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
022: * USA.
023: *
024: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
025: * in the United States and other countries.]
026: *
027: * -----------------------
028: * GenericReadHandler.java
029: * -----------------------
030: * (C)opyright 2003, by Thomas Morgner and Contributors.
031: *
032: * Original Author: Thomas Morgner;
033: * Contributor(s): David Gilbert (for Object Refinery Limited);
034: *
035: * $Id: GenericReadHandler.java,v 1.5 2005/10/18 13:33:32 mungady Exp $
036: *
037: * Changes
038: * -------
039: * 23-Sep-2003 : Initial version
040: *
041: */
042:
043: package org.jfree.xml.parser.coretypes;
044:
045: import java.util.ArrayList;
046: import java.util.HashMap;
047:
048: import org.jfree.util.Log;
049: import org.jfree.xml.parser.AbstractXmlReadHandler;
050: import org.jfree.xml.parser.RootXmlReadHandler;
051: import org.jfree.xml.parser.XmlReadHandler;
052: import org.jfree.xml.parser.XmlReaderException;
053: import org.jfree.xml.util.AttributeDefinition;
054: import org.jfree.xml.util.ConstructorDefinition;
055: import org.jfree.xml.util.GenericObjectFactory;
056: import org.jfree.xml.util.LookupDefinition;
057: import org.jfree.xml.util.ObjectDescriptionException;
058: import org.jfree.xml.util.PropertyDefinition;
059: import org.xml.sax.Attributes;
060: import org.xml.sax.SAXException;
061:
062: /**
063: * A SAX handler for reading a generic object from an XML element.
064: */
065: public class GenericReadHandler extends AbstractXmlReadHandler {
066:
067: /** The object under construction. */
068: private Object object;
069:
070: /** The generic object factory. */
071: private GenericObjectFactory objectFactory;
072:
073: /** The object reference handlers. */
074: private ArrayList objectRefHandlers;
075:
076: /** The created handler. */
077: private HashMap createdHandler;
078:
079: /**
080: * Creates a new handler.
081: *
082: * @param factory the generic object factory.
083: */
084: public GenericReadHandler(final GenericObjectFactory factory) {
085: this .createdHandler = new HashMap();
086: this .objectRefHandlers = new ArrayList();
087: this .objectFactory = factory;
088: }
089:
090: /**
091: * Called at the start of parsing.
092: *
093: * @param attrs the attributes.
094: *
095: * @throws SAXException if there is a parsing error.
096: */
097: protected void startParsing(final Attributes attrs)
098: throws SAXException {
099:
100: try {
101: final AttributeDefinition[] attribs = this .objectFactory
102: .getAttributeDefinitions();
103: for (int i = 0; i < attribs.length; i++) {
104: final AttributeDefinition attrDef = attribs[i];
105: final String value = attrs.getValue(attrDef
106: .getAttributeName());
107: if (value == null) {
108: continue;
109: }
110: final Object o = attrDef.getHandler().toPropertyValue(
111: value);
112: this .objectFactory.setProperty(attrDef
113: .getPropertyName(), o);
114: }
115: } catch (ObjectDescriptionException ode) {
116: throw new SAXException(ode);
117: }
118: }
119:
120: /**
121: * Returns the child handler.
122: *
123: * @param tagName the tag name.
124: * @param atts the attributes.
125: *
126: * @return The handler.
127: *
128: * @throws SAXException if there is a parsing problem.
129: */
130: protected XmlReadHandler getHandlerForChild(final String tagName,
131: final Attributes atts) throws SAXException {
132: try {
133: if (tagName.equals("objectRef")) {
134: // store them all and copy the properties later when the object is created
135: final XmlReadHandler handler = new ObjectRefHandler();
136: this .objectRefHandlers.add(handler);
137: return handler;
138: }
139: final XmlReadHandler handler = getRootHandler()
140: .createHandler(
141: this .objectFactory
142: .getTypeForTagName(tagName),
143: tagName, atts);
144: if (handler != null) {
145: this .createdHandler.put(tagName, handler);
146: }
147: // will throw exception if handler is null...
148: return handler;
149: } catch (ObjectDescriptionException ode) {
150: Log.debug("Failed to get handler for child: ", ode);
151: throw new SAXException(ode);
152: }
153: }
154:
155: /**
156: * Returns the object.
157: *
158: * @return The object.
159: *
160: * @throws XmlReaderException ???
161: */
162: public Object getObject() throws XmlReaderException {
163:
164: if (this .object != null) {
165: return this .object;
166: }
167: final RootXmlReadHandler rootHandler = getRootHandler();
168: try {
169: for (int i = 0; i < this .objectRefHandlers.size(); i++) {
170: final ObjectRefHandler handler = (ObjectRefHandler) this .objectRefHandlers
171: .get(i);
172: this .objectFactory.setProperty(handler
173: .getPropertyName(), handler.getObject());
174: }
175:
176: final ArrayList lookups = new ArrayList();
177: final LookupDefinition[] lookupDefs = this .objectFactory
178: .getLookupDefinitions();
179: for (int i = 0; i < lookupDefs.length; i++) {
180: final LookupDefinition ldef = lookupDefs[i];
181: lookups.add(ldef.getPropertyName());
182: Log.debug("lookup object: " + ldef.getPropertyName());
183:
184: final Object value = rootHandler.getHelperObject(ldef
185: .getRegistryKey());
186: if (value == null) {
187: // todo may or may not be fatal -> define it in the xml?
188: Log.warn("Failed to lookup object: " + value);
189: } else {
190: this .objectFactory.setProperty(ldef
191: .getPropertyName(), value);
192: }
193: }
194:
195: final ConstructorDefinition[] conDefs = this .objectFactory
196: .getConstructorDefinitions();
197: for (int i = 0; i < conDefs.length; i++) {
198: final ConstructorDefinition cDef = conDefs[i];
199: // if this is a lookup, then ignore
200: if (lookups.contains(cDef.getPropertyName())) {
201: continue;
202: }
203: if (this .objectFactory.isPropertyDefinition(cDef
204: .getPropertyName())) {
205: final PropertyDefinition pd = this .objectFactory
206: .getPropertyDefinitionByPropertyName(cDef
207: .getPropertyName());
208: final XmlReadHandler handler = (XmlReadHandler) this .createdHandler
209: .get(pd.getElementName());
210: if (handler != null) {
211: this .objectFactory
212: .setProperty(pd.getPropertyName(),
213: handler.getObject());
214: }
215: }
216: // hoping that the attribute is set ..
217: }
218:
219: this .object = this .objectFactory.createObject();
220: Object oldValue = null;
221: if (this .objectFactory.getRegisterName() != null) {
222: oldValue = rootHandler
223: .getHelperObject(this .objectFactory
224: .getRegisterName());
225: rootHandler.setHelperObject(this .objectFactory
226: .getRegisterName(), this .object);
227: }
228:
229: final PropertyDefinition[] propertyDefs = this .objectFactory
230: .getPropertyDefinitions();
231: for (int i = 0; i < propertyDefs.length; i++) {
232: final PropertyDefinition pdef = propertyDefs[i];
233: final XmlReadHandler handler = (XmlReadHandler) this .createdHandler
234: .get(pdef.getElementName());
235: if (handler == null) {
236: continue;
237: }
238: this .objectFactory.setProperty(pdef.getPropertyName(),
239: handler.getObject());
240: }
241:
242: this .objectFactory.writeObjectProperties(this .object);
243:
244: if (this .objectFactory.getRegisterName() != null) {
245: rootHandler.setHelperObject(this .objectFactory
246: .getRegisterName(), oldValue);
247: }
248: } catch (ObjectDescriptionException ode) {
249: Log.error("Unable to create object.", ode);
250: throw new XmlReaderException("Unable to create object.",
251: ode);
252: }
253: return this.object;
254: }
255:
256: }
|