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 */ 042package org.jfree.xml.factory.objects; 043 044import java.lang.reflect.Array; 045import java.util.ArrayList; 046import java.util.Iterator; 047 048import 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 */ 056public 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}