package com.skaringa.javaxml.serializers;
import java.io.PrintStream;
import java.util.Iterator;
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.DocumentOutputHandlerInterface;
/**
* Implementation of ComponentSerializer for maps
*/
public final class MapSerializer extends AbstractSerializer {
private String _xmlTypeName;
/**
* Construct a new MapSerializer.
* @param xmlTypeName The XML type name of the map.
*/
MapSerializer(String xmlTypeName) {
_xmlTypeName = xmlTypeName;
}
/**
* @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, getXMLTypeName(), name, propertyMap, output);
if (obj != null) {
Map m = (java.util.Map) obj;
Set s = m.entrySet();
Iterator it = s.iterator();
while (it.hasNext()) {
java.util.Map.Entry comp = (java.util.Map.Entry) it.next();
ComponentSerializer ser =
SerializerRegistry.getInstance().getSerializer(
java.util.Map.Entry.class);
ser.serialize(
comp,
comp.getClass(),
"mapentry",
propertyMap,
objectIdMap,
output);
}
}
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 {
Map map = null;
String nullAttr = attrs.getValue("xsi:nil");
if (nullAttr == null || nullAttr.equals("false")) {
try {
// get the map target type
Class targetType = Class.forName(_xmlTypeName, true, classLoader);
map = (Map) targetType.newInstance();
}
catch (ClassNotFoundException e) {
// fall through
}
catch (InstantiationException e) {
// fall through
}
catch (IllegalAccessException e) {
// fall through
}
catch (NullPointerException e) {
// fall through
}
if (map == null) {
map = new java.util.HashMap();
}
}
return map;
}
/**
* @see ComponentSerializer#setMember(Object, String, Object)
*/
public void setMember(Object parent, String name, Object value)
throws DeserializerException {
if (name == null) {
throw new DeserializerException("member of map must have an name");
}
if (!name.equals("mapentry")) {
value = new MapEntryHelper(name, value);
}
if (parent == null) {
throw new DeserializerException("child of null object is forbidden");
}
try {
MapEntryHelper entry = (MapEntryHelper) value;
Map map = (Map) parent;
map.put(entry.getKey(), entry.getValue());
}
catch (ClassCastException e) {
throw new DeserializerException("invalid sequence: " + e.toString());
}
}
/**
* @see ComponentSerializer#endDeserialize(Object, String)
*/
public Object endDeserialize(Object obj, String text)
throws DeserializerException {
return obj;
}
/**
* @see com.skaringa.javaxml.serializers.ComponentSerializer#writeXMLTypeDefinition(Class, Map, DocumentOutputHandlerInterface)
*/
public void writeXMLTypeDefinition(
Class type,
Map propertyMap,
DocumentOutputHandlerInterface output)
throws SerializerException {
if (Map.class.equals(type)) {
writeXMLCollectionDef("mapentry", java.util.Map.Entry.class, output);
}
else {
writeXMLExtensionDef(
output,
SerializerRegistry
.getInstance()
.getSerializer(Map.class)
.getXMLTypeName());
}
}
/**
* @see ComponentSerializer#addUsedClasses(Class, Set)
*/
public void addUsedClasses(Class base, Set usedClasses)
throws SerializerException {
usedClasses.add(base);
usedClasses.add(java.util.Map.class);
usedClasses.add(java.util.Map.Entry.class);
}
/**
* @see CollectionSerializer#toJson(Object, Class, Map, PrintStream)
*/
public void toJson(Object obj, Class type, Map propertyMap,
PrintStream output) throws SerializerException {
// map is serialized as Object
output.print("{");
if (obj != null) {
Map m = (java.util.Map) obj;
Set s = m.entrySet();
Iterator it = s.iterator();
while (it.hasNext()) {
java.util.Map.Entry comp = (java.util.Map.Entry) it.next();
ComponentSerializer ser =
SerializerRegistry.getInstance().getSerializer(
java.util.Map.Entry.class);
ser.toJson(
comp,
comp.getClass(),
propertyMap,
output);
if (it.hasNext()) {
output.print(",");
}
}
} else {
output.print("null");
}
output.print("}");
}
}