You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
112 lines
3.1 KiB
112 lines
3.1 KiB
11 years ago
|
package de.timroes.axmlrpc.serializer;
|
||
|
|
||
|
import de.timroes.axmlrpc.XMLRPCException;
|
||
|
import de.timroes.axmlrpc.XMLRPCRuntimeException;
|
||
|
import de.timroes.axmlrpc.XMLUtil;
|
||
|
import de.timroes.axmlrpc.xmlcreator.XmlElement;
|
||
|
import java.util.HashMap;
|
||
|
import java.util.Map;
|
||
|
import org.w3c.dom.Element;
|
||
|
import org.w3c.dom.Node;
|
||
|
|
||
|
/**
|
||
|
*
|
||
|
* @author Tim Roes
|
||
|
*/
|
||
|
public class StructSerializer implements Serializer {
|
||
|
|
||
|
private static final String STRUCT_MEMBER = "member";
|
||
|
private static final String STRUCT_NAME = "name";
|
||
|
private static final String STRUCT_VALUE = "value";
|
||
|
|
||
|
public Object deserialize(Element content) throws XMLRPCException {
|
||
|
|
||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||
|
|
||
|
Node n, m;
|
||
|
String s;
|
||
|
Object o;
|
||
|
for(int i = 0; i < content.getChildNodes().getLength(); i++) {
|
||
|
|
||
|
n = content.getChildNodes().item(i);
|
||
|
|
||
|
// Strip only whitespace text elements and comments
|
||
|
if((n.getNodeType() == Node.TEXT_NODE
|
||
|
&& n.getNodeValue().trim().length() <= 0)
|
||
|
|| n.getNodeType() == Node.COMMENT_NODE)
|
||
|
continue;
|
||
|
|
||
|
if(n.getNodeType() != Node.ELEMENT_NODE
|
||
|
|| !STRUCT_MEMBER.equals(n.getNodeName())) {
|
||
|
throw new XMLRPCException("Only struct members allowed within a struct.");
|
||
|
}
|
||
|
|
||
|
// Grep name and value from member
|
||
|
s = null; o = null;
|
||
|
for(int j = 0; j < n.getChildNodes().getLength(); j++) {
|
||
|
m = n.getChildNodes().item(j);
|
||
|
|
||
|
// Strip only whitespace text elements and comments
|
||
|
if((m.getNodeType() == Node.TEXT_NODE
|
||
|
&& m.getNodeValue().trim().length() <= 0)
|
||
|
|| m.getNodeType() == Node.COMMENT_NODE)
|
||
|
continue;
|
||
|
|
||
|
if(STRUCT_NAME.equals(m.getNodeName())) {
|
||
|
if(s != null) {
|
||
|
throw new XMLRPCException("Name of a struct member cannot be set twice.");
|
||
|
} else {
|
||
|
s = XMLUtil.getOnlyTextContent(m.getChildNodes());
|
||
|
}
|
||
|
} else if(m.getNodeType() == Node.ELEMENT_NODE && STRUCT_VALUE.equals(m.getNodeName())) {
|
||
|
if(o != null) {
|
||
|
throw new XMLRPCException("Value of a struct member cannot be set twice.");
|
||
|
} else {
|
||
|
o = SerializerHandler.getDefault().deserialize((Element)m);
|
||
|
}
|
||
|
} else {
|
||
|
throw new XMLRPCException("A struct member must only contain one name and one value.");
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
map.put(s, o);
|
||
|
|
||
|
}
|
||
|
|
||
|
return map;
|
||
|
|
||
|
}
|
||
|
|
||
|
public XmlElement serialize(Object object) {
|
||
|
|
||
|
XmlElement struct = new XmlElement(SerializerHandler.TYPE_STRUCT);
|
||
|
|
||
|
try {
|
||
|
|
||
|
XmlElement entry, name, value;
|
||
|
|
||
|
// We can safely cast here, this Serializer should only be called when
|
||
|
// the parameter is a map.
|
||
|
@SuppressWarnings("unchecked")
|
||
|
Map<String,Object> map = (Map<String,Object>)object;
|
||
|
|
||
|
for(Map.Entry<String,Object> member : map.entrySet()) {
|
||
|
entry = new XmlElement(STRUCT_MEMBER);
|
||
|
name = new XmlElement(STRUCT_NAME);
|
||
|
value = new XmlElement(STRUCT_VALUE);
|
||
|
name.setContent(member.getKey());
|
||
|
value.addChildren(SerializerHandler.getDefault().serialize(member.getValue()));
|
||
|
entry.addChildren(name);
|
||
|
entry.addChildren(value);
|
||
|
struct.addChildren(entry);
|
||
|
}
|
||
|
|
||
|
} catch(XMLRPCException ex) {
|
||
|
throw new XMLRPCRuntimeException(ex);
|
||
|
}
|
||
|
|
||
|
return struct;
|
||
|
}
|
||
|
|
||
|
}
|