/*
* Copyright (C) 2004 TiongHiang Lee
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Email: thlee@onemindsoft.org
*/
package org.onemind.commons.java.datastructure;
import java.sql.Types;
import java.util.HashMap;
import java.util.Map;
import org.onemind.commons.java.lang.reflect.ReflectUtils;
import org.onemind.commons.java.xml.digest.*;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
/**
* A Sax elemenbt handler that can handle parsing properties specified in an xml file
* This syntax of the xml is something like
* <Property name="defaultvalue" value="default"/>
<Property name="shortvalue" type="short" value="1"/>
<Property name="intvalue" type="int" value="1"/>
<Property name="longvalue" type="long" value="1"/>
<Property name="floatvalue" type="float" value="1"/>
<Property name="doublevalue" type="double" value="1"/>
<Property name="charvalue" type="char" value="c"/>
<Property name="stringvalue" type="string" value="string"/>
* @author TiongHiang Lee (thlee@onemindsoft.org)
*/
public class XmlPropertyElementDigester extends DefaultDigester implements ElementDigester
{
private static final Map _typeMap;
static
{
_typeMap = new HashMap();
_typeMap.put("short", new Integer(Types.SMALLINT));
_typeMap.put("int", new Integer(Types.INTEGER));
_typeMap.put("long", new Integer(Types.BIGINT));
_typeMap.put("float", new Integer(Types.FLOAT));
_typeMap.put("double", new Integer(Types.DOUBLE));
_typeMap.put("boolean", new Integer(Types.BOOLEAN));
_typeMap.put("char", new Integer(Types.CHAR));
_typeMap.put("string", new Integer(Types.VARCHAR));
}
private final Map _prop;
public XmlPropertyElementDigester(String elementName, Map prop)
{
super(elementName);
_prop = prop;
}
/**
* {@inheritDoc}
*/
public void startDigest(SaxDigesterHandler handler, Attributes attrs) throws SAXException
{
String name = attrs.getValue("name");
String type = attrs.getValue("type");
String value = attrs.getValue("value");
String clazz = attrs.getValue("class");
if (name == null)
{
throw new SAXException("name attribute must exists on property");
}
if (type != null && clazz != null)
{
throw new SAXException("Both type and class cannot be specified on same property");
}
if (clazz != null)
{
try
{
Class c = ReflectUtils.getClass(clazz);
Object obj = (Object) ReflectUtils.newInstance(c, null);
String digest = attrs.getValue("digest");
if (digest != null && digest.equalsIgnoreCase("true"))
{
if (clazz != null)
{
if (!ElementDigester.class.isAssignableFrom(obj.getClass()))
{
throw new SAXException("Class " + clazz + " is not a subclass of ElementDigester");
}
ElementDigester dig = (ElementDigester) obj;
handler.addSubDigester(dig);
_prop.put(name, dig);
}
} else
{//just put the object as a property
_prop.put(name, obj);
}
} catch (Exception e)
{
throw new SAXException(e.getMessage(), e);
}
} else if (type != null)
{
Object v = null;
Integer typeInt = (Integer) _typeMap.get(type);
if (typeInt == null)
{
throw new SAXException("Unrecognized property type " + type);
} else
{
switch (typeInt.intValue())
{
case Types.SMALLINT :
v = Short.valueOf(value);
break;
case Types.INTEGER :
v = Integer.valueOf(value);
break;
case Types.BIGINT :
v = Long.valueOf(value);
break;
case Types.FLOAT :
v = Float.valueOf(value);
break;
case Types.DOUBLE :
v = Double.valueOf(value);
break;
case Types.BOOLEAN :
v = Boolean.valueOf(value);
break;
case Types.CHAR :
v = new Character(value.charAt(0));
break;
case Types.VARCHAR :
v = value;
break;
default :
throw new IllegalStateException("Unrecognized property type " + type);
}
}
_prop.put(name, v);
} else
{
_prop.put(name, value);
}
}
/**
* {@inheritDoc}
*/
public void endDigest(SaxDigesterHandler handler) throws SAXException
{
// TODO Auto-generated method stub
}
/**
* {@inheritDoc}
*/
public void characters(SaxDigesterHandler handler, char[] chars, int offset, int length) throws SAXException
{
// TODO Auto-generated method stub
}
}