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 * ArrayObjectDescription.java
029 * ---------------------------
030 * (C)opyright 2003, 2004, by Thomas Morgner and Contributors.
031 *
032 * Original Author: Thomas Morgner (taquera@sherito.org);
033 * Contributor(s): David Gilbert (for Object Refinery Limited);
034 *
035 * $Id: ArrayObjectDescription.java,v 1.4 2006/01/27 18:53:15 taqua Exp $
036 *
037 * Changes
038 * -------
039 * 14-Apr-2003 : Initial version
040 * 29-Apr-2003 : Distilled from the JFreeReport project and moved into JCommon
041 */
042 package org.jfree.xml.factory.objects;
043
044 import java.lang.reflect.Array;
045 import java.util.ArrayList;
046 import java.util.Iterator;
047
048 import org.jfree.util.Log;
049
050 /**
051 * Describes an Object- or primitive value array. This object description is
052 * not intended to be created outside the ArrayClassFactory.
053 *
054 * @author Thomas Morgner
055 */
056 public class ArrayObjectDescription extends AbstractObjectDescription {
057
058 /**
059 * Constructs a new array objet description for the given array class.
060 * <P>
061 * Note: throws <code>IllegalArgumentException</code> if the given class is no array.
062 *
063 * @param c the array class object.
064 */
065 public ArrayObjectDescription(final Class c) {
066 super(c);
067 if (!c.isArray()) {
068 throw new IllegalArgumentException("Need an array class");
069 }
070 }
071
072 /**
073 * Creates an object based on the description.
074 *
075 * @return The object.
076 */
077 public Object createObject() {
078 try {
079 final Integer size = (Integer) getParameter("size");
080 if (size == null) {
081 final ArrayList l = new ArrayList();
082 int counter = 0;
083 while (getParameterDefinition(String.valueOf(counter)) != null) {
084 final Object value = getParameter(String.valueOf(counter));
085 if (value == null) {
086 break;
087 }
088
089 l.add(value);
090 counter += 1;
091 }
092
093 final Object o = Array.newInstance
094 (getObjectClass().getComponentType(), l.size());
095 for (int i = 0; i < l.size(); i++) {
096 Array.set(o, i, l.get(i));
097 }
098 return o;
099 }
100 else {
101 // a size is given, so we can assume that all values are defined.
102 final Object o = Array.newInstance
103 (getObjectClass().getComponentType(), size.intValue());
104 for (int i = 0; i < size.intValue(); i++) {
105 Array.set(o, i, getParameter(String.valueOf(i)));
106 }
107 return o;
108 }
109 }
110 catch (Exception ie) {
111 Log.warn("Unable to instantiate Object", ie);
112 return null;
113 }
114 }
115
116 /**
117 * Sets the parameters of this description object to match the supplied object.
118 *
119 * @param o the object.
120 *
121 * @throws ObjectFactoryException if there is a
122 * problem while reading the properties of the given object.
123 */
124 public void setParameterFromObject(final Object o) throws ObjectFactoryException {
125 if (o == null) {
126 throw new ObjectFactoryException("Given object is null.");
127 }
128
129 if (!o.getClass().isArray()) {
130 throw new ObjectFactoryException("Given object is no array");
131 }
132
133 if (!getObjectClass().isAssignableFrom(o.getClass())) {
134 throw new ObjectFactoryException("Given object is incompatible with base class");
135 }
136
137 final int size = Array.getLength(o);
138 setParameter("size", new Integer(size));
139 for (int i = 0; i < size; i++) {
140 setParameter(String.valueOf(i), Array.get(o, i));
141 }
142 }
143
144 /**
145 * Tries to parse the given parameter string into a positive integer.
146 * Returns -1 if the parsing failed for some reason.
147 *
148 * @param name the name of the parameter.
149 * @return the parsed int value or -1 on errors.
150 */
151 private int parseParameterName(final String name) {
152 try {
153 return Integer.parseInt(name);
154 }
155 catch (Exception e) {
156 return -1;
157 }
158 }
159
160 /**
161 * Returns a parameter definition. If the parameter is invalid, this
162 * function returns null.
163 *
164 * @param name the definition name.
165 *
166 * @return The parameter class or null, if the parameter is not defined.
167 */
168 public Class getParameterDefinition(final String name) {
169 if (name.equals("size")) {
170 return Integer.TYPE;
171 }
172 final int par = parseParameterName(name);
173 if (par < 0) {
174 return null;
175 }
176 return getObjectClass().getComponentType();
177 }
178
179 /**
180 * Returns an iterator for the parameter names.
181 *
182 * @return The iterator.
183 */
184 public Iterator getParameterNames() {
185 final Integer size = (Integer) getParameter("size");
186 if (size == null) {
187 return getDefinedParameterNames();
188 }
189 else {
190 final ArrayList l = new ArrayList();
191 l.add("size");
192 for (int i = 0; i < size.intValue(); i++) {
193 l.add(String.valueOf(i));
194 }
195 return l.iterator();
196 }
197 }
198
199 /**
200 * Returns a new instance of the object description.
201 *
202 * @return The object description.
203 */
204 public ObjectDescription getInstance() {
205 return new ArrayObjectDescription(getObjectClass());
206 }
207 }