package com.skaringa.javaxml.serializers;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import org.xml.sax.Attributes;
import com.skaringa.javaxml.DeserializerException;
import com.skaringa.javaxml.SerializerException;
import com.skaringa.javaxml.handler.AttrImpl;
import com.skaringa.javaxml.handler.DocumentOutputHandlerInterface;
/**
* Implementation of ComponentSerializer for the primitive java types plus their
* wrappers and java.lang.String.
*/
public final class PrimitiveTypeSerializer extends AbstractSerializer {
private String _xmlTypeName;
private Class _wrapperType;
private Object _dummy = new Object();
/**
* Construct a new PrimitiveTypeSerializer.
*
* @param xmlTypeName
* The XML type name.
* @param wrapperType
* The class of the wrapper around the primitive type.
*/
PrimitiveTypeSerializer(String xmlTypeName, Class wrapperType) {
_xmlTypeName = xmlTypeName;
_wrapperType = wrapperType;
}
/**
* @see ComponentSerializer#serialize(Object, Class, String, Map, Map,
* DocumentOutputHandlerInterface)
*/
public void serialize(Object obj, Class type, String name, Map propertyMap,
Map objectIdMap, DocumentOutputHandlerInterface output)
throws SerializerException {
startElement(obj, _xmlTypeName, name, propertyMap, output);
if (obj != null) {
output.appendText(obj.toString());
}
output.endElement(name);
}
/**
* @see ComponentSerializer#getXMLTypeName()
*/
public String getXMLTypeName() {
return _xmlTypeName;
}
/**
* @see ComponentSerializer#startDeserialize(String, Attributes, Object,
* Stack, ClassLoader)
*/
public Object startDeserialize(String name, Attributes attrs, Object parent,
Stack objStack, ClassLoader classLoader) throws DeserializerException {
Object obj = null;
String nullAttr = attrs.getValue("xsi:nil");
if (nullAttr == null || nullAttr.equals("false")) {
obj = _dummy;
// defer creation with corrrect value until endDeserialize()
}
return obj;
}
/**
* @see ComponentSerializer#endDeserialize(Object, String)
*/
public Object endDeserialize(Object obj, String text)
throws DeserializerException {
if (obj == null) {
return obj;
}
try {
Class[] ctorArgTypes = new Class[1];
Object[] ctorArgs = new Object[1];
// need to handle Character seperately
if (_wrapperType.equals(Character.class)) {
ctorArgTypes[0] = char.class;
ctorArgs[0] = new Character(text.charAt(0));
} else {
ctorArgTypes[0] = String.class;
ctorArgs[0] = text;
}
// create a new object
Constructor ctor = _wrapperType.getConstructor(ctorArgTypes);
obj = ctor.newInstance(ctorArgs);
// _category.debug(obj.getClass().getName() + ": " + obj.toString());
} catch (NoSuchMethodException e) {
throw new DeserializerException("no ctor(String) found for class: "
+ _wrapperType.getName());
} catch (java.lang.reflect.InvocationTargetException e) {
throw new DeserializerException("exception in initializer: "
+ e.getMessage());
} catch (IllegalAccessException e) {
throw new DeserializerException("can't access ctor(String) for class: "
+ _wrapperType.getName());
} catch (InstantiationException e) {
throw new DeserializerException("can't instantiate class: "
+ _wrapperType.getName());
}
return obj;
}
/**
* @see ComponentSerializer#setMember(Object, String, Object)
*/
public void setMember(Object parent, String name, Object value)
throws DeserializerException {
// not allowed with primitive type
throw new DeserializerException(
"no child element allowed for primitive type");
}
/**
* @see com.skaringa.javaxml.serializers.ComponentSerializer#writeXMLTypeDefinition(Class,
* Map, DocumentOutputHandlerInterface)
*/
public void writeXMLTypeDefinition(Class type, Map propertyMap,
DocumentOutputHandlerInterface output) throws SerializerException {
if (getXMLTypeName().equals("char")) {
// define char (which is not in xsd...
AttrImpl attr = new AttrImpl();
attr.addAttribute("name", "char");
output.startElement("xsd:simpleType", attr);
attr = new AttrImpl();
attr.addAttribute("base", "xsd:string");
output.startElement("xsd:restriction", attr);
attr = new AttrImpl();
attr.addAttribute("value", "1");
output.startElement("xsd:length", attr);
output.endElement("xsd:length");
output.endElement("xsd:restriction");
output.endElement("xsd:simpleType");
}
// else: nothing to define
}
/**
* @see ComponentSerializer#addUsedClasses(Class, Set)
*/
public void addUsedClasses(Class base, Set usedClasses)
throws SerializerException {
if (getXMLTypeName().equals("char")) {
usedClasses.add(char.class);
}
}
/**
* @see ComponentSerializer#toJson(Object, Class, Map, PrintStream)
*/
public void toJson(Object obj, Class type, Map propertyMap,
PrintStream output) throws SerializerException {
if (obj != null && String.class.equals(type)
|| Character.class.equals(type)) {
output.print("\"");
printEncodedStr(obj.toString(), output);
output.print("\"");
} else {
output.print(String.valueOf(obj));
}
}
}