Source for org.jfree.xml.factory.objects.ClassFactoryImpl

   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:  * ClassFactoryImpl.java
  29:  * ---------------------
  30:  * (C)opyright 2003, 2004, by Thomas Morgner and Contributors.
  31:  *
  32:  * Original Author:  Thomas Morgner;
  33:  * Contributor(s):   David Gilbert (for Object Refinery Limited);
  34:  *
  35:  * $Id: ClassFactoryImpl.java,v 1.6 2006/01/25 23:15:03 taqua Exp $
  36:  *
  37:  * Changes (from 19-Feb-2003)
  38:  * -------------------------
  39:  * 19-Feb-2003 : Added standard header and Javadocs (DG);
  40:  * 29-Apr-2003 : Distilled from the JFreeReport project and moved into JCommon
  41:  * 29-Jul-2004 : Replaced 'enum' variable name (reserved word in JDK 1.5) (DG);
  42:  *
  43:  */
  44: 
  45: package org.jfree.xml.factory.objects;
  46: 
  47: import java.util.HashMap;
  48: import java.util.Iterator;
  49: 
  50: import org.jfree.util.Configuration;
  51: import org.jfree.util.ClassComparator;
  52: /**
  53:  * An abstract class that implements the {@link ClassFactory} interface.
  54:  *
  55:  * @author Thomas Morgner.
  56:  */
  57: public abstract class ClassFactoryImpl implements ClassFactory {
  58: 
  59:     /** Storage for the classes. */
  60:     private HashMap classes;
  61:     /** A class comparator for searching the super class */
  62:     private ClassComparator comparator;
  63:     /** The parser/report configuration */
  64:     private Configuration config;
  65: 
  66:     /**
  67:      * Creates a new class factory.
  68:      */
  69:     public ClassFactoryImpl() {
  70:         this.classes = new HashMap();
  71:         this.comparator = new ClassComparator();
  72:     }
  73: 
  74:     /**
  75:      * Returns the class comparator used to sort the super classes of an object.
  76:      *
  77:      * @return the class comparator.
  78:      */
  79:     public ClassComparator getComparator() {
  80:         return this.comparator;
  81:     }
  82: 
  83:     /**
  84:      * Returns an object-description for a class.
  85:      *
  86:      * @param c  the class.
  87:      *
  88:      * @return An object description.
  89:      */
  90:     public ObjectDescription getDescriptionForClass(final Class c) {
  91:         final ObjectDescription od = (ObjectDescription) this.classes.get(c);
  92:         if (od == null) {
  93:             return null;
  94:         }
  95:         return od.getInstance();
  96:     }
  97: 
  98:     /**
  99:      * Returns the most concrete object-description for the super class of a class.
 100:      *
 101:      * @param d  the class.
 102:      * @param knownSuperClass a known supported superclass or null, if no superclass
 103:      * is known yet.
 104:      *
 105:      * @return The object description.
 106:      */
 107:     public ObjectDescription getSuperClassObjectDescription
 108:         (final Class d, ObjectDescription knownSuperClass) {
 109: 
 110:         if (d == null) {
 111:             throw new NullPointerException("Description class must not be null.");
 112:         }
 113:         final Iterator iterator = this.classes.keySet().iterator();
 114:         while (iterator.hasNext()) {
 115:             final Class keyClass = (Class) iterator.next();
 116:             if (keyClass.isAssignableFrom(d)) {
 117:                 final ObjectDescription od = (ObjectDescription) this.classes.get(keyClass);
 118:                 if (knownSuperClass == null) {
 119:                     knownSuperClass = od;
 120:                 }
 121:                 else {
 122:                     if (this.comparator.isComparable
 123:                         (knownSuperClass.getObjectClass(), od.getObjectClass())) {
 124:                         if (this.comparator.compare
 125:                             (knownSuperClass.getObjectClass(), od.getObjectClass()) < 0) {
 126:                             knownSuperClass = od;
 127:                         }
 128:                     }
 129:                 }
 130:             }
 131:         }
 132:         if (knownSuperClass == null) {
 133:             return null;
 134:         }
 135:         return knownSuperClass.getInstance();
 136:     }
 137: 
 138:     /**
 139:      * Registers an object description with the factory.
 140:      *
 141:      * @param key  the key.
 142:      * @param od  the object description.
 143:      */
 144:     protected void registerClass(final Class key, final ObjectDescription od) {
 145:         this.classes.put(key, od);
 146:         if (this.config != null) {
 147:             od.configure(this.config);
 148:         }
 149:     }
 150: 
 151:     /**
 152:      * Returns an iterator that provides access to the registered object definitions.
 153:      *
 154:      * @return The iterator.
 155:      */
 156:     public Iterator getRegisteredClasses() {
 157:         return this.classes.keySet().iterator();
 158:     }
 159: 
 160: 
 161:     /**
 162:      * Configures this factory. The configuration contains several keys and
 163:      * their defined values. The given reference to the configuration object
 164:      * will remain valid until the report parsing or writing ends.
 165:      * <p>
 166:      * The configuration contents may change during the reporting.
 167:      *
 168:      * @param config the configuration, never null
 169:      */
 170:     public void configure(final Configuration config) {
 171:         if (config == null) {
 172:             throw new NullPointerException("The given configuration is null");
 173:         }
 174:         if (this.config != null) {
 175:             // already configured ... ignored
 176:             return;
 177:         }
 178: 
 179:         this.config = config;
 180:         final Iterator it = this.classes.values().iterator();
 181:         while (it.hasNext()) {
 182:             final ObjectDescription od = (ObjectDescription) it.next();
 183:             od.configure(config);
 184:         }
 185:     }
 186: 
 187:     /**
 188:      * Returns the currently set configuration or null, if none was set.
 189:      *
 190:      * @return the configuration.
 191:      */
 192:     public Configuration getConfig() {
 193:         return this.config;
 194:     }
 195: 
 196:     /**
 197:      * Tests for equality.
 198:      * 
 199:      * @param o  the object to test.
 200:      * 
 201:      * @return A boolean.
 202:      */
 203:     public boolean equals(final Object o) {
 204:         if (this == o) {
 205:             return true;
 206:         }
 207:         if (!(o instanceof ClassFactoryImpl)) {
 208:             return false;
 209:         }
 210: 
 211:         final ClassFactoryImpl classFactory = (ClassFactoryImpl) o;
 212: 
 213:         if (!this.classes.equals(classFactory.classes)) {
 214:             return false;
 215:         }
 216: 
 217:         return true;
 218:     }
 219: 
 220:     /**
 221:      * Returns a hash code.
 222:      * 
 223:      * @return A hash code.
 224:      */
 225:     public int hashCode() {
 226:         return this.classes.hashCode();
 227:     }
 228: }