/*
* (c) Copyright 2004 by Heng Yuan
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package cookxml.common.helper;
import java.util.LinkedList;
import cookxml.common.exception.InvalidClassTypeException;
import cookxml.core.interfaces.NoAdd;
import cookxml.core.util.ClassUtils;
/**
* @cxdoc
* This tag is to generate object arrays. If all the elements within the tag
* are from the same class, then that class is used in generating that object
* array. Primitive arrays can be generated as well, by specifying the primitive
* class name (i.e. int, double, etc).
*
* @cxexample
* A String[] array:
* <codeblock type="xml">
* <array>
* <string text="one"/>
* <string text="two"/>
* <string text="three"/>
* </array>
* </codeblock>
*
* @cxexample
* An int[] array:
* <codeblock type="xml">
* <array type="int">
* <int value="1"/>
* <int value="2"/>
* <int value="3"/>
* </array>
* </codeblock>
*
* @cxhelper [Ljava.lang.Object;
*
* @author Heng Yuan
* @version $Id: ArrayHelper.java 264 2007-06-10 17:36:57Z coconut $
* @since CookXml 1.0
*/
public class ArrayHelper implements NoAdd
{
private boolean m_sameTypes;
private LinkedList m_list;
private Class m_classType;
private String m_primitiveType;
private boolean m_primitive;
private int m_size;
private final ClassLoader m_classLoader;
public ArrayHelper (ClassLoader classLoader)
{
m_sameTypes = true;
m_list = new LinkedList ();
m_primitive = false;
m_size = -1;
m_classLoader = classLoader;
}
/**
* Set the size of the array. This parameter is optional since the
* array size is usually the same as the number of the elements inside
* the tag unless this attribute is set.
*
* @param size
* the desired size of the array.
*/
public void setSize (int size)
{
m_size = size;
}
/**
* Set the type of the array. If the type is a primitive type,
* then primitve arrays are generated.
*
* @param type
* the fully qualified class name.
* @throws InvalidClassTypeException
* in case of Error.
*/
public void setType (String type) throws InvalidClassTypeException
{
try
{
Class cl = ClassUtils.getEquivalentClass (type);
if (cl == null)
{
cl = m_classLoader.loadClass (type);
}
else
{
m_primitiveType = type;
m_primitive = true;
}
m_classType = cl;
}
catch (Exception ex)
{
throw new InvalidClassTypeException (type);
}
}
/**
* Add an object to the array.
*
* @param obj
* the object to be added to the array.
*/
public void add (Object obj)
{
m_list.add (obj);
if (obj == null)
return;
if (!m_sameTypes)
return;
if (m_classType == null)
m_classType = obj.getClass ();
else if (!m_classType.isInstance (obj))
{
m_classType = Object.class;
m_sameTypes = false;
}
}
public Object getFinalObject () throws Exception
{
LinkedList list = m_list;
int size = m_size;
if (size < 0)
size = list.size ();
Object array;
if (m_primitive)
array = ClassUtils.getArray (m_primitiveType, size);
else
array = ClassUtils.getArray (m_classType, size);
if (array == null)
return null;
ClassUtils.setArray (array, size, list);
return array;
}
}