Source for org.jfree.xml.parser.coretypes.GenericReadHandler

   1: /* ========================================================================
   2:  * JCommon : a free general purpose class library for the Java(tm) platform
   3:  * ========================================================================
   4:  *
   5:  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
   6:  * 
   7:  * Project Info:  http://www.jfree.org/jcommon/index.html
   8:  *
   9:  * This library is free software; you can redistribute it and/or modify it 
  10:  * under the terms of the GNU Lesser General Public License as published by 
  11:  * the Free Software Foundation; either version 2.1 of the License, or 
  12:  * (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but 
  15:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
  16:  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
  17:  * License for more details.
  18:  *
  19:  * You should have received a copy of the GNU Lesser General Public
  20:  * License along with this library; if not, write to the Free Software
  21:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
  22:  * USA.  
  23:  *
  24:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
  25:  * in the United States and other countries.]
  26:  * 
  27:  * -----------------------
  28:  * GenericReadHandler.java
  29:  * -----------------------
  30:  * (C)opyright 2003, by Thomas Morgner and Contributors.
  31:  *
  32:  * Original Author:  Thomas Morgner;
  33:  * Contributor(s):   David Gilbert (for Object Refinery Limited);
  34:  *
  35:  * $Id: GenericReadHandler.java,v 1.5 2005/10/18 13:33:32 mungady Exp $
  36:  *
  37:  * Changes
  38:  * -------
  39:  * 23-Sep-2003 : Initial version
  40:  *
  41:  */
  42: 
  43: package org.jfree.xml.parser.coretypes;
  44: 
  45: import java.util.ArrayList;
  46: import java.util.HashMap;
  47: 
  48: import org.jfree.util.Log;
  49: import org.jfree.xml.parser.AbstractXmlReadHandler;
  50: import org.jfree.xml.parser.RootXmlReadHandler;
  51: import org.jfree.xml.parser.XmlReadHandler;
  52: import org.jfree.xml.parser.XmlReaderException;
  53: import org.jfree.xml.util.AttributeDefinition;
  54: import org.jfree.xml.util.ConstructorDefinition;
  55: import org.jfree.xml.util.GenericObjectFactory;
  56: import org.jfree.xml.util.LookupDefinition;
  57: import org.jfree.xml.util.ObjectDescriptionException;
  58: import org.jfree.xml.util.PropertyDefinition;
  59: import org.xml.sax.Attributes;
  60: import org.xml.sax.SAXException;
  61: 
  62: /**
  63:  * A SAX handler for reading a generic object from an XML element.
  64:  */
  65: public class GenericReadHandler extends AbstractXmlReadHandler {
  66: 
  67:     /** The object under construction. */
  68:     private Object object;
  69:     
  70:     /** The generic object factory. */
  71:     private GenericObjectFactory objectFactory;
  72:     
  73:     /** The object reference handlers. */
  74:     private ArrayList objectRefHandlers;
  75:     
  76:     /** The created handler. */
  77:     private HashMap createdHandler;
  78: 
  79:     /**
  80:      * Creates a new handler.
  81:      *
  82:      * @param factory  the generic object factory.
  83:      */
  84:     public GenericReadHandler(final GenericObjectFactory factory) {
  85:         this.createdHandler = new HashMap();
  86:         this.objectRefHandlers = new ArrayList();
  87:         this.objectFactory = factory;
  88:     }
  89: 
  90:     /**
  91:      * Called at the start of parsing.
  92:      * 
  93:      * @param attrs  the attributes.
  94:      * 
  95:      * @throws SAXException if there is a parsing error.
  96:      */
  97:     protected void startParsing(final Attributes attrs) throws SAXException {
  98: 
  99:         try {
 100:             final AttributeDefinition[] attribs = this.objectFactory.getAttributeDefinitions();
 101:             for (int i = 0; i < attribs.length; i++) {
 102:                 final AttributeDefinition attrDef = attribs[i];
 103:                 final String value = attrs.getValue(attrDef.getAttributeName());
 104:                 if (value == null) {
 105:                     continue;
 106:                 }
 107:                 final Object o = attrDef.getHandler().toPropertyValue(value);
 108:                 this.objectFactory.setProperty(attrDef.getPropertyName(), o);
 109:             }
 110:         }
 111:         catch (ObjectDescriptionException ode) {
 112:             throw new SAXException(ode);
 113:         }
 114:     }
 115: 
 116:     /**
 117:      * Returns the child handler.
 118:      * 
 119:      * @param tagName  the tag name.
 120:      * @param atts  the attributes.
 121:      * 
 122:      * @return The handler.
 123:      * 
 124:      * @throws SAXException if there is a parsing problem.
 125:      */
 126:     protected XmlReadHandler getHandlerForChild(final String tagName, final Attributes atts)
 127:         throws SAXException {
 128:         try {
 129:             if (tagName.equals("objectRef")) {
 130:                 // store them all and copy the properties later when the object is created
 131:                 final XmlReadHandler handler = new ObjectRefHandler();
 132:                 this.objectRefHandlers.add(handler);
 133:                 return handler;
 134:             }
 135:             final XmlReadHandler handler = getRootHandler().createHandler
 136:                 (this.objectFactory.getTypeForTagName(tagName), tagName, atts);
 137:             if (handler != null) {
 138:                 this.createdHandler.put(tagName, handler);
 139:             }
 140:             // will throw exception if handler is null...
 141:             return handler;
 142:         }
 143:         catch (ObjectDescriptionException ode) {
 144:             Log.debug ("Failed to get handler for child: ", ode);
 145:             throw new SAXException(ode);
 146:         }
 147:     }
 148: 
 149:     /**
 150:      * Returns the object.
 151:      * 
 152:      * @return The object.
 153:      * 
 154:      * @throws XmlReaderException ???
 155:      */
 156:     public Object getObject() throws XmlReaderException {
 157: 
 158:         if (this.object != null) {
 159:             return this.object;
 160:         }
 161:         final RootXmlReadHandler rootHandler = getRootHandler();
 162:         try {
 163:             for (int i = 0; i < this.objectRefHandlers.size(); i++) {
 164:                 final ObjectRefHandler handler = (ObjectRefHandler) this.objectRefHandlers.get(i);
 165:                 this.objectFactory.setProperty(handler.getPropertyName(), handler.getObject());
 166:             }
 167: 
 168:             final ArrayList lookups = new ArrayList();
 169:             final LookupDefinition[] lookupDefs = this.objectFactory.getLookupDefinitions();
 170:             for (int i = 0; i < lookupDefs.length; i++) {
 171:                 final LookupDefinition ldef = lookupDefs[i];
 172:                 lookups.add(ldef.getPropertyName());
 173:                 Log.debug ("lookup object: " + ldef.getPropertyName());
 174: 
 175:                 final Object value = rootHandler.getHelperObject(ldef.getRegistryKey());
 176:                 if (value == null) {
 177:                     // todo may or may not be fatal -> define it in the xml?
 178:                     Log.warn ("Failed to lookup object: " + value);
 179:                 }
 180:                 else {
 181:                     this.objectFactory.setProperty(ldef.getPropertyName(), value);
 182:                 }
 183:             }
 184: 
 185:             final ConstructorDefinition[] conDefs = this.objectFactory.getConstructorDefinitions();
 186:             for (int i = 0; i < conDefs.length; i++) {
 187:                 final ConstructorDefinition cDef = conDefs[i];
 188:                 // if this is a lookup, then ignore
 189:                 if (lookups.contains(cDef.getPropertyName())) {
 190:                     continue;
 191:                 }
 192:                 if (this.objectFactory.isPropertyDefinition(cDef.getPropertyName())) {
 193:                     final PropertyDefinition pd = this.objectFactory.getPropertyDefinitionByPropertyName(
 194:                         cDef.getPropertyName()
 195:                     );
 196:                     final XmlReadHandler handler = (XmlReadHandler) this.createdHandler.get(
 197:                         pd.getElementName()
 198:                     );
 199:                     if (handler != null) {
 200:                         this.objectFactory.setProperty(pd.getPropertyName(), handler.getObject());
 201:                     }
 202:                 }
 203:                 // hoping that the attribute is set ..
 204:             }
 205: 
 206:             this.object = this.objectFactory.createObject();
 207:             Object oldValue = null;
 208:             if (this.objectFactory.getRegisterName() != null) {
 209:                 oldValue = rootHandler.getHelperObject(this.objectFactory.getRegisterName());
 210:                 rootHandler.setHelperObject(this.objectFactory.getRegisterName(), this.object);
 211:             }
 212: 
 213:             final PropertyDefinition[] propertyDefs = this.objectFactory.getPropertyDefinitions();
 214:             for (int i = 0; i < propertyDefs.length; i++) {
 215:                 final PropertyDefinition pdef = propertyDefs[i];
 216:                 final XmlReadHandler handler = (XmlReadHandler) this.createdHandler.get(
 217:                     pdef.getElementName()
 218:                 );
 219:                 if (handler == null) {
 220:                     continue;
 221:                 }
 222:                 this.objectFactory.setProperty(pdef.getPropertyName(), handler.getObject());
 223:             }
 224: 
 225:             this.objectFactory.writeObjectProperties(this.object);
 226: 
 227:             if (this.objectFactory.getRegisterName() != null) {
 228:                 rootHandler.setHelperObject(this.objectFactory.getRegisterName(), oldValue);
 229:             }
 230:         }
 231:         catch (ObjectDescriptionException ode) {
 232:             Log.error ("Unable to create object.", ode);
 233:             throw new XmlReaderException("Unable to create object.", ode);
 234:         }
 235:         return this.object;
 236:     }
 237: 
 238: }