Package org.vietspider.serialize

Source Code of org.vietspider.serialize.Bean2XML

/***************************************************************************
* Copyright 2003-2006 by VietSpider - All rights reserved.  *
*    *
**************************************************************************/
package org.vietspider.serialize;

import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.vietspider.parser.xml.XMLDocument;
import org.vietspider.parser.xml.XMLNode;
import org.vietspider.token.TypeToken;
import org.vietspider.token.attribute.Attribute;
import org.vietspider.token.attribute.AttributeParser;
import org.vietspider.token.attribute.Attributes;

/**
*  Author : Nhu Dinh Thuan
*          Email:nhudinhthuan@yahoo.com
* Apr 9, 2007
*/
public class Bean2XML implements XMLMapper {
 
  private static Bean2XML MAPPER = new Bean2XML();
 
  public final static Bean2XML getInstance() { return MAPPER; }
 
  private ReflectUtil reflectUtil;
//  private HashMap<Class<?>, XMLMapper> mappers;
 
  public Bean2XML() {
    reflectUtil = new ReflectUtil();
//    mappers = new HashMap<Class<?>, XMLMapper>();
  }
 
  public XMLDocument toXMLDocument(Object bean) throws Exception {
    NodeMap map = bean.getClass().getAnnotation(NodeMap.class);
    if(map == null) return null;
    XMLNode node = new XMLNode(map.value().toCharArray(), map.value(), TypeToken.TAG);
    toXML(bean, node);
    return new XMLDocument(node);
  }

  public void toXML(Object bean, XMLNode nodethrows Exception  {
    NodeMap map = bean.getClass().getAnnotation(NodeMap.class);
    if (map == null) return;
    toXMLValue(bean.getClass(), map.depth(), bean, node);
  }
 
  private void toXMLValue(Class<?> clazz, int depth, Object bean, XMLNode nodethrows Exception  {
    Field [] fields = clazz.getDeclaredFields();
    for(Field field : fields) {
      NoMap map = field.getAnnotation(NoMap.class);
      if(map != null) continue;
      if(field.getType().isArray()) {
        fromArray(field, bean, node);
      } else if (Collection.class.isAssignableFrom(field.getType())) {
        fromCollection(field, bean, node);
      } else if (Map.class.isAssignableFrom(field.getType())) {
        fromMap(field, bean, node);
      } else {
        toField(field, bean, node);
      }
    }
    depth--;
    if(depth <= 0 || clazz.getSuperclass() == null) return;   
    toXMLValue(clazz.getSuperclass(), depth, bean, node);
  }
 
  protected void toField(Field field, Object bean, XMLNode node) throws Exception {
    if(bean == null) return;
    NodeMap map = field.getAnnotation(NodeMap.class);
    if(map == null) return;
   
    String name = map.value();   
    boolean isAttribute = map.attribute();   
    boolean isCDATA = map.cdata();
   
    Class<?> type = field.getType();
    Object value = null;
    field.setAccessible(true);
 
    if(type.isPrimitive()) {
      try{
        value = getValue(type, field, bean);
      }catch (Exception e) {
      }    
      if(isAttribute){
        setAttribute(node, name, (String)value);
      } else {
        if(isCDATA) value = "<![CDATA[" + value + "]]>";
        setChild(node, name, (String)value);
      }
      return;
    }
   
    value = getValue(field, bean);
   
    if(type.isEnum()) {
      if(value == null) return ;
      if(isAttribute) {
        setAttribute(node, name, value.toString());
      } else {
        if(isCDATA) value = "<![CDATA[" + value + "]]>";
        setChild(node, name, value.toString());
      }
      return;
    }
   
    if(reflectUtil.isPrimitiveType(type)) {
      if(value == null) value = "";
      if(isAttribute) {
        setAttribute(node, name, value.toString());
      } else {
        if(isCDATA) value = "<![CDATA[" + value + "]]>";
        setChild(node, name, value.toString());
      }
      return;
    }
   
//    XMLMapper mapper = mappers.get(type);
//    if(mapper == null) {   
//      if(value == null) value = "";
//      if(isAttribute) {
//        setAttribute(node, name, value.toString());
//      } else {
//        setChild(node, name, value.toString());
//      }
//      return;
//    }
   
    XMLNode child = new XMLNode(name.toCharArray(), name, TypeToken.TAG);  
    node.getChildren().add(child);
    if(value == nullthrow new NullPointerException(field.getName() + " is null");
    NodeMap valueMap = value.getClass().getAnnotation(NodeMap.class);
    if(valueMap == null) {
      toXMLValue(value.getClass(), 1, value, child);
      return;
    }
    XMLNode valueNode  = new XMLNode(valueMap.value().toCharArray(), valueMap.value(), TypeToken.TAG);
    child.addChild(valueNode);
    toXMLValue(value.getClass(), map.depth(), value, valueNode);
  }
 
 
  private void fromCollection(Field field, Object bean, XMLNode parent) {
    NodesMap map = field.getAnnotation(NodesMap.class);
    if(map == null || bean == null) return;
   
    String name = map.value();
    XMLNode node = new XMLNode(name.toCharArray(), name, TypeToken.TAG);
   
    field.setAccessible(true);
    Object values = getValue(field, bean);
    Collection<?> collection = (Collection<?>) values;
    setAttribute(node, "type", values.getClass().getName());
   
    Object [] array = new Object[collection.size()];
    collection.toArray(array);
    fromArray(node, array, map);
    if(collection.size() > 0) parent.getChildren().add(node);
  }
 
  private void fromMap(Field field, Object bean, XMLNode parent) throws Exception {
    field.setAccessible(true);
  
    PropertiesMap propertiesMap = field.getAnnotation(PropertiesMap.class);
    Map<?, ?> map = (Map<?, ?>)getValue(field, bean);
    if(propertiesMap == null || map == null || map.size() < 1) return;
    String itemName = propertiesMap.item();
    boolean isAttribute = propertiesMap.attribute();
    boolean isCDATA = propertiesMap.cdata();
   
    XMLNode node = new XMLNode(propertiesMap.value().toCharArray(), propertiesMap.value(), TypeToken.TAG);
    parent.getChildren().add(node);
    parent = node;
   
    String keyName = "key";
    String keyValue = "value";
   
   
    setAttribute(node, "type", map.getClass().getName());
    Iterator<?> iter = map.keySet().iterator();
   
    while(iter.hasNext()) {
      Object key = iter.next();
      Object value = map.get(key);
      if(value == null) value = "";
      node = new XMLNode(itemName.toCharArray(), itemName, TypeToken.TAG);
      parent.getChildren().add(node);

      mapValue2XMLData(key, keyName, isAttribute, isCDATA, node);
      mapValue2XMLData(value, keyValue, isAttribute, isCDATA, node);
    }
  }
 
  private void mapValue2XMLData(Object value, String name,
      boolean isAttribute, boolean isCDATA, XMLNode node) throws Exception {
    Class<?> type = value.getClass();
    if(type.isPrimitive() || reflectUtil.isPrimitiveType(type) || type.isEnum()) {
      if(isAttribute){
        setAttribute(node, name, String.valueOf(value));
      } else {
        if(isCDATA) value = "<![CDATA[" + value + "]]>";
        setChild(node, name, String.valueOf(value));
      }
      return ;
    }
    NodeMap valueMap = type.getAnnotation(NodeMap.class);
    if(valueMap == null) {
      toXMLValue(type, 1, value, node);
      return;
    }
    XMLNode valueNode  = new XMLNode(valueMap.value().toCharArray(), valueMap.value(), TypeToken.TAG);
    node.addChild(valueNode);
    toXMLValue(type, valueMap.depth(), value, valueNode);
  }
 
  private void fromArray(Field field, Object bean, XMLNode parent) {
    NodesMap map = field.getAnnotation(NodesMap.class);
    if(map == null) return;
    Object values = getValue(field, bean);
    if(values == null) return;
   
    field.setAccessible(true);
    String name = map.value();
    XMLNode node = new XMLNode(name.toCharArray(), name, TypeToken.TAG);
   
    int length = fromArray(node, values, map);
    if(length > 0) parent.getChildren().add(node);
//    System.out.println(values + " : "+ map.value() +" : " + length);
  }
 
  private int fromArray(XMLNode node, Object values, NodesMap map) {
    if(values == null) return 0;
    int length = Array.getLength(values);
    Class<?> type;
    boolean isCDATA = map.cdata();
    for(int i = 0; i < length; i++) {
      String itemName = map.item();
      Object value = Array.get(values, i);
//      if(itemName.length() < 1) {
//        NodeMap itemMap = value.getClass().getAnnotation(NodeMap.class);
//        if(itemMap != null) itemName = itemMap.value();
//      }
      if(value == null) continue;
      type = value.getClass();
     
      if(isCDATA) value = "<![CDATA[" + value.toString() + "]]>";
     
      if(type.isPrimitive() || reflectUtil.isPrimitiveType(type) || type.isEnum()) {
        if(itemName.trim().length() < 1) itemName = type.getSimpleName();
        XMLNode child = new XMLNode(itemName.toCharArray(), itemName, TypeToken.TAG);
        node.getChildren().add(child);
        child.addChild(new XMLNode(value.toString().toCharArray(), null, TypeToken.CONTENT));
        continue;
      }
//      XMLMapper mapper = mappers.get(value.getClass());
//      if(mapper == null) {
//        XMLNode child = new XMLNode(itemName.toCharArray(), itemName, TypeToken.TAG);
//        node.getChildren().add(child);
//        child.addChild(new XMLNode(value.toString().toCharArray(), null, TypeToken.CONTENT));
//        continue;
//      }
      try
        NodeMap valueMap = value.getClass().getAnnotation(NodeMap.class);
        if(valueMap == null) {
          XMLNode child = new XMLNode(itemName.toCharArray(), itemName, TypeToken.TAG);
          node.getChildren().add(child);
          toXML(value, child);
          return length;
        }
        XMLNode child = null;
        XMLNode valueNode  = new XMLNode(valueMap.value().toCharArray(), valueMap.value(), TypeToken.TAG);
        if(itemName.trim().length() < 1)  {
          child = valueNode;
        } else {
          child = new XMLNode(itemName.toCharArray(), itemName, TypeToken.TAG);
          child.addChild(valueNode);            
        }
        toXML(value, valueNode);
        node.getChildren().add(child);
      }catch (Exception e) {
        e.printStackTrace();
      }
    }
    return length;
  }

  private Object getValue(Field field, Object bean) {
    Object value = null;
    Method method = null;
    try {
      method = reflectUtil.getGetterMethod(bean.getClass(), field);
      if(method != null) value = method.invoke(bean);
    } catch (Exception e) {
      e.printStackTrace();
    }
    if(value != nullreturn value;
    try {
      value = field.get(bean);
    }catch (Exception e) {
      value = null;
    }
    return value;
  }
 
  private String getValue(Class<?> type, Field field, Object bean) throws Exception {
    try{
      Method method = reflectUtil.getGetterMethod(bean.getClass(), field);
      if(method != null) return String.valueOf(method.invoke(bean));
    }catch (Exception e) {
      e.printStackTrace();
    }
    if(type == boolean.class) return String.valueOf(field.getBoolean(bean));
    if(type == byte.class) return String.valueOf(field.getByte(bean));
    if(type == char.class) return String.valueOf(field.getChar(bean));
    if(type == short.class) return String.valueOf(field.getShort(bean));
    if(type == int.class) return String.valueOf(field.getInt(bean));
    if(type == long.class) return String.valueOf(field.getLong(bean));
    if(type == float.class) return String.valueOf(field.getFloat(bean));
    if(type == double.class) return String.valueOf(field.getDouble(bean));
    return "";
  }
 
  private void setChild(XMLNode parent, String name, String value) {
    List<XMLNode> children = parent.getChildren();
    for(XMLNode ele : children) {
      if(ele.getName().equals(name)){
        ele.addChild(new XMLNode(value.toCharArray(), null, TypeToken.CONTENT));
        return;
      }
    }  
    XMLNode node = new XMLNode(name.toCharArray(), name, TypeToken.TAG);
    node.addChild(new XMLNode(value.toCharArray(), null, TypeToken.CONTENT));
    children.add(node);
  }
 
  private void setAttribute(XMLNode parent, String name, String value) {
    Attributes attrs = AttributeParser.parse(parent);
    for(Attribute ele : attrs) {
      if(ele.getName().equals(name)){
        ele.setValue(value);
        return ;
      }
    }
    Attribute attr = new Attribute(name, value);
    attrs.add(attr);
  }
 
}
TOP

Related Classes of org.vietspider.serialize.Bean2XML

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.