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 * ClassFactoryImpl.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: ClassFactoryImpl.java,v 1.6 2006/01/25 23:15:03 taqua 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 * 29-Jul-2004 : Replaced 'enum' variable name (reserved word in JDK 1.5) (DG);
042 *
043 */
044
045 package org.jfree.xml.factory.objects;
046
047 import java.util.HashMap;
048 import java.util.Iterator;
049
050 import org.jfree.util.Configuration;
051 import org.jfree.util.ClassComparator;
052 /**
053 * An abstract class that implements the {@link ClassFactory} interface.
054 *
055 * @author Thomas Morgner.
056 */
057 public abstract class ClassFactoryImpl implements ClassFactory {
058
059 /** Storage for the classes. */
060 private HashMap classes;
061 /** A class comparator for searching the super class */
062 private ClassComparator comparator;
063 /** The parser/report configuration */
064 private Configuration config;
065
066 /**
067 * Creates a new class factory.
068 */
069 public ClassFactoryImpl() {
070 this.classes = new HashMap();
071 this.comparator = new ClassComparator();
072 }
073
074 /**
075 * Returns the class comparator used to sort the super classes of an object.
076 *
077 * @return the class comparator.
078 */
079 public ClassComparator getComparator() {
080 return this.comparator;
081 }
082
083 /**
084 * Returns an object-description for a class.
085 *
086 * @param c the class.
087 *
088 * @return An object description.
089 */
090 public ObjectDescription getDescriptionForClass(final Class c) {
091 final ObjectDescription od = (ObjectDescription) this.classes.get(c);
092 if (od == null) {
093 return null;
094 }
095 return od.getInstance();
096 }
097
098 /**
099 * 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 }