package com.arondor.common.reflection.xstream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Logger;
import com.arondor.common.reflection.bean.config.ListConfigurationBean;
import com.arondor.common.reflection.bean.config.ObjectConfigurationBean;
import com.arondor.common.reflection.bean.config.PrimitiveConfigurationBean;
import com.arondor.common.reflection.model.config.ElementConfiguration;
import com.arondor.common.reflection.model.config.ListConfiguration;
import com.arondor.common.reflection.model.config.ObjectConfiguration;
import com.arondor.common.reflection.model.config.PrimitiveConfiguration;
import com.google.gwt.xml.client.Element;
import com.google.gwt.xml.client.Node;
import com.google.gwt.xml.client.NodeList;
public class GWTXStream2ObjectDefinitionConverterLL
{
private static final Logger LOG = Logger.getLogger(GWTXStream2ObjectDefinitionConverterLL.class.getName());
private String classAttributeName = "class";
private static void debug(String message)
{
LOG.info("GWTX2OLL " + message);
}
public String getClassAttributeName()
{
return classAttributeName;
}
public void setClassAttributeName(String classAttributeName)
{
this.classAttributeName = classAttributeName;
}
private TypeOracle typeOracle;
public TypeOracle getTypeOracle()
{
return typeOracle;
}
public void setTypeOracle(TypeOracle typeOracle)
{
this.typeOracle = typeOracle;
}
private String guessClassName(String className, String fieldName)
{
if (getTypeOracle() == null)
{
return null;
}
return getTypeOracle().guessType(className, fieldName);
}
protected ObjectConfiguration parseObject(Element objectElement, String guessedParentClass)
{
debug("parseObject() objectElement=" + objectElement.getNodeName());
ObjectConfiguration oc = new ObjectConfigurationBean();
if (guessedParentClass == null)
{
guessedParentClass = objectElement.getNodeName();
}
oc.setClassName(guessedParentClass);
oc.setFields(new HashMap<String, ElementConfiguration>());
for (Node childNode = objectElement.getFirstChild(); childNode != null; childNode = childNode.getNextSibling())
{
debug("* parseObject() childNode=" + childNode.getNodeType() + " - " + childNode.getNodeName());
switch (childNode.getNodeType())
{
case Node.TEXT_NODE:
break;
case Node.ELEMENT_NODE:
{
String fieldName = childNode.getNodeName();
Element childElement = (Element) childNode;
String guessedChildClass = null;
if (childElement.hasAttribute("class"))
{
guessedChildClass = childElement.getAttribute("class");
}
if (guessedChildClass == null)
{
guessedChildClass = guessClassName(guessedParentClass, fieldName);
}
ElementConfiguration ec = parseElement(childElement, guessedChildClass);
oc.getFields().put(fieldName, ec);
break;
}
default:
debug("Not handled : typpe " + childNode.getNodeType());
}
}
return oc;
}
private List<Element> elementsList(NodeList nodeList)
{
List<Element> elementsList = new ArrayList<Element>();
for (int nodeIndex = 0; nodeIndex < nodeList.getLength(); nodeIndex++)
{
Node node = nodeList.item(nodeIndex);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
elementsList.add((Element) node);
}
}
return elementsList;
}
private ElementConfiguration parseElement(Element element, String guessedClass)
{
debug("* parseElement() element=" + element.getNodeName() + ", guessedClass=" + guessedClass);
if (element.getChildNodes().getLength() == 1 && element.getFirstChild().getNodeType() == Node.TEXT_NODE)
{
String nodeValue = element.getFirstChild().getNodeValue();
debug("Primitive type : " + element.getNodeName() + "=" + nodeValue);
PrimitiveConfiguration pc = new PrimitiveConfigurationBean();
pc.setValue(nodeValue);
return pc;
}
if (guessedClass != null && !isList(guessedClass))
{
debug("* parseElement() this is an explicit object : '" + guessedClass + "'");
return parseObject(element, guessedClass);
}
List<Element> elements = elementsList(element.getChildNodes());
if (elements.size() > 1 || (elements.size() == 1 && isPrimitive(elements.get(0))) || isList(guessedClass))
{
debug("* parseElement() this is a list !");
return parseList(elements);
}
debug("* parseElement() this is a ... I don't know, object ?");
return parseObject(element, guessedClass);
}
private boolean isList(String guessedClass)
{
return java.util.List.class.getName().equals(guessedClass);
}
private boolean isPrimitive(Element element)
{
String nodeName = element.getNodeName();
debug("isPrimitive(" + nodeName + ")");
if (nodeName.equals("float") || nodeName.equals("int") || nodeName.equals("string"))
{
debug("isPrimitive(" + nodeName + ") => true");
return true;
}
debug("isPrimitive(" + nodeName + ") => false");
return false;
}
private ElementConfiguration parseList(List<Element> elements)
{
List<ElementConfiguration> lec = new ArrayList<ElementConfiguration>();
for (Element childElement : elements)
{
lec.add(parseElement(childElement, null));
}
ListConfiguration lc = new ListConfigurationBean();
lc.setListConfiguration(lec);
return lc;
}
}