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

   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:  * AbstractObjectDescription.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: AbstractObjectDescription.java,v 1.3 2005/11/14 10:58:37 mungady 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:  *
  42:  */
  43: 
  44: package org.jfree.xml.factory.objects;
  45: 
  46: import java.util.ArrayList;
  47: import java.util.Collections;
  48: import java.util.HashMap;
  49: import java.util.Iterator;
  50: 
  51: import org.jfree.util.Configuration;
  52: import org.jfree.util.Log;
  53: import org.jfree.util.ReadOnlyIterator;
  54: 
  55: /**
  56:  * An abstract base class for object descriptions.
  57:  *
  58:  * @author Thomas Morgner.
  59:  */
  60: public abstract class AbstractObjectDescription implements ObjectDescription, Cloneable {
  61: 
  62:     /** The class. */
  63:     private Class className;
  64: 
  65:     /** Storage for parameters. */
  66:     private HashMap parameters;
  67: 
  68:     /** Storage for parameter definitions. */
  69:     private HashMap parameterDefs;
  70: 
  71:     /** The configuration for the object description. */
  72:     private Configuration config;
  73: 
  74:     /**
  75:      * Creates a new object description.
  76:      *
  77:      * @param className  the class.
  78:      */
  79:     public AbstractObjectDescription(final Class className) {
  80:         this.className = className;
  81:         this.parameters = new HashMap();
  82:         this.parameterDefs = new HashMap();
  83:     }
  84: 
  85:     /**
  86:      * Returns a parameter class.
  87:      *
  88:      * @param name  the parameter definition.
  89:      *
  90:      * @return The class.
  91:      */
  92:     public Class getParameterDefinition(final String name) {
  93:         return (Class) this.parameterDefs.get(name);
  94:     }
  95: 
  96:     /**
  97:      * Sets the class for a parameter.
  98:      *
  99:      * @param name  the parameter name.
 100:      * @param obj  the parameter class.
 101:      */
 102:     public void setParameterDefinition(final String name, final Class obj) {
 103:         if (obj == null) {
 104:             this.parameterDefs.remove(name);
 105:         }
 106:         else {
 107:             this.parameterDefs.put(name, obj);
 108:         }
 109:     }
 110: 
 111:     /**
 112:      * Converts primitives to corresponding object class.
 113:      *
 114:      * @param obj  the class.
 115:      *
 116:      * @return The class.
 117:      */
 118:     public static Class convertPrimitiveClass(final Class obj) {
 119:         if (!obj.isPrimitive()) {
 120:             return obj;
 121:         }
 122:         if (obj == Boolean.TYPE) {
 123:             return Boolean.class;
 124:         }
 125:         if (obj == Byte.TYPE) {
 126:             return Byte.class;
 127:         }
 128:         if (obj == Character.TYPE) {
 129:             return Character.class;
 130:         }
 131:         if (obj == Short.TYPE) {
 132:             return Short.class;
 133:         }
 134:         if (obj == Integer.TYPE) {
 135:             return Integer.class;
 136:         }
 137:         if (obj == Long.TYPE) {
 138:             return Long.class;
 139:         }
 140:         if (obj == Float.TYPE) {
 141:             return Float.class;
 142:         }
 143:         if (obj == Double.TYPE) {
 144:             return Double.class;
 145:         }
 146:         throw new IllegalArgumentException("Class 'void' is not allowed here");
 147:     }
 148: 
 149:     /**
 150:      * Sets a parameter.
 151:      *
 152:      * @param name  the name.
 153:      * @param value  the value.
 154:      */
 155:     public void setParameter(final String name, final Object value) {
 156:         if (getParameterDefinition(name) == null) {
 157:             throw new IllegalArgumentException("No such Parameter defined: " + name
 158:                 + " in class " + getObjectClass());
 159:         }
 160:         final Class parameterClass = convertPrimitiveClass(getParameterDefinition(name));
 161:         if (!parameterClass.isAssignableFrom(value.getClass())) {
 162:             throw new ClassCastException("In Object " + getObjectClass()
 163:                 + ": Value is not assignable: " + value.getClass()
 164:                 + " is not assignable from " + parameterClass);
 165:         }
 166:         this.parameters.put(name, value);
 167:     }
 168: 
 169:     /**
 170:      * Returns an iterator for the parameter names.
 171:      *
 172:      * @return The iterator.
 173:      */
 174:     public synchronized Iterator getParameterNames() {
 175:         final ArrayList parameterNames = new ArrayList(this.parameterDefs.keySet());
 176:         Collections.sort(parameterNames);
 177:         return new ReadOnlyIterator (parameterNames.iterator());
 178:     }
 179: 
 180:     /**
 181:      * Returns an iterator for the parameter names.
 182:      *
 183:      * @return The iterator.
 184:      */
 185:     protected Iterator getDefinedParameterNames() {
 186:         return new ReadOnlyIterator (this.parameters.keySet().iterator());
 187:     }
 188: 
 189:     /**
 190:      * Returns a parameter value.
 191:      *
 192:      * @param name  the parameter name.
 193:      *
 194:      * @return The parameter value.
 195:      */
 196:     public Object getParameter(final String name) {
 197:         return this.parameters.get(name);
 198:     }
 199: 
 200:     /**
 201:      * Returns the class for the object.
 202:      *
 203:      * @return The class.
 204:      */
 205:     public Class getObjectClass() {
 206:         return this.className;
 207:     }
 208: 
 209:     /**
 210:      * Returns a cloned instance of the object description. The contents
 211:      * of the parameter objects collection are cloned too, so that any
 212:      * already defined parameter value is copied to the new instance.
 213:      * <p>
 214:      * Parameter definitions are not cloned, as they are considered read-only.
 215:      * <p>
 216:      * The newly instantiated object description is not configured. If it
 217:      * need to be configured, then you have to call configure on it.
 218:      *
 219:      * @return A cloned instance.
 220:      */
 221:     public ObjectDescription getInstance() {
 222:         try {
 223:             final AbstractObjectDescription c = (AbstractObjectDescription) super.clone();
 224:             c.parameters = (HashMap) this.parameters.clone();
 225:             return c;
 226:         }
 227:         catch (Exception e) {
 228:             Log.error("Should not happen: Clone Error: ", e);
 229:             return null;
 230:         }
 231:     }
 232: 
 233: 
 234:     /**
 235:      * Returns a cloned instance of the object description. The contents
 236:      * of the parameter objects collection are cloned too, so that any
 237:      * already defined parameter value is copied to the new instance.
 238:      * <p>
 239:      * Parameter definitions are not cloned, as they are considered read-only.
 240:      * <p>
 241:      * The newly instantiated object description is not configured. If it
 242:      * need to be configured, then you have to call configure on it.
 243:      *
 244:      * @return A cloned instance.
 245:      */
 246:     public ObjectDescription getUnconfiguredInstance() {
 247:         try {
 248:             final AbstractObjectDescription c = (AbstractObjectDescription) super.clone();
 249:             c.parameters = (HashMap) this.parameters.clone();
 250:             c.config = null;
 251:             return c;
 252:         }
 253:         catch (Exception e) {
 254:             Log.error("Should not happen: Clone Error: ", e);
 255:             return null;
 256:         }
 257:     }
 258: 
 259:     /**
 260:      * Configures this factory. The configuration contains several keys and
 261:      * their defined values. The given reference to the configuration object
 262:      * will remain valid until the report parsing or writing ends.
 263:      * <p>
 264:      * The configuration contents may change during the reporting.
 265:      *
 266:      * @param config the configuration, never null
 267:      */
 268:     public void configure(final Configuration config) {
 269:         if (config == null) {
 270:             throw new NullPointerException("The given configuration is null");
 271:         }
 272:         this.config = config;
 273:     }
 274: 
 275:     /**
 276:      * Returns the configuration for that object description.
 277:      *
 278:      * @return the configuration or null, if not yet set.
 279:      */
 280:     public Configuration getConfig() {
 281:         return this.config;
 282:     }
 283: 
 284:     /**
 285:      * Tests for equality.
 286:      * 
 287:      * @param o  the object to test.
 288:      * 
 289:      * @return A boolean.
 290:      */
 291:     public boolean equals(final Object o) {
 292:         if (this == o) {
 293:             return true;
 294:         }
 295:         if (!(o instanceof AbstractObjectDescription)) {
 296:             return false;
 297:         }
 298: 
 299:         final AbstractObjectDescription abstractObjectDescription = (AbstractObjectDescription) o;
 300: 
 301:         if (!this.className.equals(abstractObjectDescription.className)) {
 302:             return false;
 303:         }
 304: 
 305:         return true;
 306:     }
 307: 
 308:     /**
 309:      * Returns a hash code for the object.
 310:      * 
 311:      * @return The hash code.
 312:      */
 313:     public int hashCode() {
 314:         return this.className.hashCode();
 315:     }
 316: }