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: * AbstractObjectDescription.java
029: * ------------------------------
030: * (C)opyright 2003, 2004, by Thomas Morgner and Contributors.
031: *
032: * Original Author: Thomas Morgner;
033: * Contributor(s): David Gilbert (for Object Refinery Limited);
034: *
035: * $Id: AbstractObjectDescription.java,v 1.3 2005/11/14 10:58:37 mungady Exp $
036: *
037: * Changes (from 19-Feb-2003)
038: * -------------------------
039: * 19-Feb-2003 : Added standard header and Javadocs (DG);
040: * 29-Apr-2003 : Distilled from the JFreeReport project and moved into JCommon
041: *
042: */
043:
044: package org.jfree.xml.factory.objects;
045:
046: import java.util.ArrayList;
047: import java.util.Collections;
048: import java.util.HashMap;
049: import java.util.Iterator;
050:
051: import org.jfree.util.Configuration;
052: import org.jfree.util.Log;
053: import org.jfree.util.ReadOnlyIterator;
054:
055: /**
056: * An abstract base class for object descriptions.
057: *
058: * @author Thomas Morgner.
059: */
060: public abstract class AbstractObjectDescription implements
061: ObjectDescription, Cloneable {
062:
063: /** The class. */
064: private Class className;
065:
066: /** Storage for parameters. */
067: private HashMap parameters;
068:
069: /** Storage for parameter definitions. */
070: private HashMap parameterDefs;
071:
072: /** The configuration for the object description. */
073: private Configuration config;
074:
075: /**
076: * Creates a new object description.
077: *
078: * @param className the class.
079: */
080: public AbstractObjectDescription(final Class className) {
081: this .className = className;
082: this .parameters = new HashMap();
083: this .parameterDefs = new HashMap();
084: }
085:
086: /**
087: * Returns a parameter class.
088: *
089: * @param name the parameter definition.
090: *
091: * @return The class.
092: */
093: public Class getParameterDefinition(final String name) {
094: return (Class) this .parameterDefs.get(name);
095: }
096:
097: /**
098: * Sets the class for a parameter.
099: *
100: * @param name the parameter name.
101: * @param obj the parameter class.
102: */
103: public void setParameterDefinition(final String name,
104: final Class obj) {
105: if (obj == null) {
106: this .parameterDefs.remove(name);
107: } else {
108: this .parameterDefs.put(name, obj);
109: }
110: }
111:
112: /**
113: * Converts primitives to corresponding object class.
114: *
115: * @param obj the class.
116: *
117: * @return The class.
118: */
119: public static Class convertPrimitiveClass(final Class obj) {
120: if (!obj.isPrimitive()) {
121: return obj;
122: }
123: if (obj == Boolean.TYPE) {
124: return Boolean.class;
125: }
126: if (obj == Byte.TYPE) {
127: return Byte.class;
128: }
129: if (obj == Character.TYPE) {
130: return Character.class;
131: }
132: if (obj == Short.TYPE) {
133: return Short.class;
134: }
135: if (obj == Integer.TYPE) {
136: return Integer.class;
137: }
138: if (obj == Long.TYPE) {
139: return Long.class;
140: }
141: if (obj == Float.TYPE) {
142: return Float.class;
143: }
144: if (obj == Double.TYPE) {
145: return Double.class;
146: }
147: throw new IllegalArgumentException(
148: "Class 'void' is not allowed here");
149: }
150:
151: /**
152: * Sets a parameter.
153: *
154: * @param name the name.
155: * @param value the value.
156: */
157: public void setParameter(final String name, final Object value) {
158: if (getParameterDefinition(name) == null) {
159: throw new IllegalArgumentException(
160: "No such Parameter defined: " + name + " in class "
161: + getObjectClass());
162: }
163: final Class parameterClass = convertPrimitiveClass(getParameterDefinition(name));
164: if (!parameterClass.isAssignableFrom(value.getClass())) {
165: throw new ClassCastException("In Object "
166: + getObjectClass() + ": Value is not assignable: "
167: + value.getClass() + " is not assignable from "
168: + parameterClass);
169: }
170: this .parameters.put(name, value);
171: }
172:
173: /**
174: * Returns an iterator for the parameter names.
175: *
176: * @return The iterator.
177: */
178: public synchronized Iterator getParameterNames() {
179: final ArrayList parameterNames = new ArrayList(
180: this .parameterDefs.keySet());
181: Collections.sort(parameterNames);
182: return new ReadOnlyIterator(parameterNames.iterator());
183: }
184:
185: /**
186: * Returns an iterator for the parameter names.
187: *
188: * @return The iterator.
189: */
190: protected Iterator getDefinedParameterNames() {
191: return new ReadOnlyIterator(this .parameters.keySet().iterator());
192: }
193:
194: /**
195: * Returns a parameter value.
196: *
197: * @param name the parameter name.
198: *
199: * @return The parameter value.
200: */
201: public Object getParameter(final String name) {
202: return this .parameters.get(name);
203: }
204:
205: /**
206: * Returns the class for the object.
207: *
208: * @return The class.
209: */
210: public Class getObjectClass() {
211: return this .className;
212: }
213:
214: /**
215: * Returns a cloned instance of the object description. The contents
216: * of the parameter objects collection are cloned too, so that any
217: * already defined parameter value is copied to the new instance.
218: * <p>
219: * Parameter definitions are not cloned, as they are considered read-only.
220: * <p>
221: * The newly instantiated object description is not configured. If it
222: * need to be configured, then you have to call configure on it.
223: *
224: * @return A cloned instance.
225: */
226: public ObjectDescription getInstance() {
227: try {
228: final AbstractObjectDescription c = (AbstractObjectDescription) super
229: .clone();
230: c.parameters = (HashMap) this .parameters.clone();
231: return c;
232: } catch (Exception e) {
233: Log.error("Should not happen: Clone Error: ", e);
234: return null;
235: }
236: }
237:
238: /**
239: * Returns a cloned instance of the object description. The contents
240: * of the parameter objects collection are cloned too, so that any
241: * already defined parameter value is copied to the new instance.
242: * <p>
243: * Parameter definitions are not cloned, as they are considered read-only.
244: * <p>
245: * The newly instantiated object description is not configured. If it
246: * need to be configured, then you have to call configure on it.
247: *
248: * @return A cloned instance.
249: */
250: public ObjectDescription getUnconfiguredInstance() {
251: try {
252: final AbstractObjectDescription c = (AbstractObjectDescription) super
253: .clone();
254: c.parameters = (HashMap) this .parameters.clone();
255: c.config = null;
256: return c;
257: } catch (Exception e) {
258: Log.error("Should not happen: Clone Error: ", e);
259: return null;
260: }
261: }
262:
263: /**
264: * Configures this factory. The configuration contains several keys and
265: * their defined values. The given reference to the configuration object
266: * will remain valid until the report parsing or writing ends.
267: * <p>
268: * The configuration contents may change during the reporting.
269: *
270: * @param config the configuration, never null
271: */
272: public void configure(final Configuration config) {
273: if (config == null) {
274: throw new NullPointerException(
275: "The given configuration is null");
276: }
277: this .config = config;
278: }
279:
280: /**
281: * Returns the configuration for that object description.
282: *
283: * @return the configuration or null, if not yet set.
284: */
285: public Configuration getConfig() {
286: return this .config;
287: }
288:
289: /**
290: * Tests for equality.
291: *
292: * @param o the object to test.
293: *
294: * @return A boolean.
295: */
296: public boolean equals(final Object o) {
297: if (this == o) {
298: return true;
299: }
300: if (!(o instanceof AbstractObjectDescription)) {
301: return false;
302: }
303:
304: final AbstractObjectDescription abstractObjectDescription = (AbstractObjectDescription) o;
305:
306: if (!this .className.equals(abstractObjectDescription.className)) {
307: return false;
308: }
309:
310: return true;
311: }
312:
313: /**
314: * Returns a hash code for the object.
315: *
316: * @return The hash code.
317: */
318: public int hashCode() {
319: return this.className.hashCode();
320: }
321: }
|