/**   
* @Title: JaxbUtil2.java 
* @Package com.platform.util 
* @Description: TODO(用一句话描述该文件做什么) 
* @author kiosk
* @date 2017年12月14日 上午10:16:26 
* @version V1.0   
*/
package com.platform.util;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.Collection;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.namespace.QName;  
import org.apache.commons.lang.StringUtils; 
/** 
* @ClassName: JaxbUtil2 
* @Description: TODO(这里用一句话描述这个类的作用) 
* @author kiosk
* @date 2017年12月14日 上午10:16:26 
*  
*/
public class JaxbUtil2 {

	// 多线程安全的Context.  
    private JAXBContext jaxbContext;  
  
    /** 
     * @param types 
     *            所有需要序列化的Root对象的类型. 
     * @return 
     */  
    public  JaxbUtil2(Class<?>... types) {
        try {  
            jaxbContext = JAXBContext.newInstance(types);  
        } catch (JAXBException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * Java Object->Xml. 
     */  
    public String toXml(Object root, String encoding) {  
        try {  
            StringWriter writer = new StringWriter();  
            createMarshaller(encoding).marshal(root, writer);  
            return writer.toString();  
        } catch (JAXBException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * Java Object->Xml, 特别支持对Root Element是Collection的情形. 
     */  
    @SuppressWarnings("unchecked")  
    public String toXml(Collection root, String rootName, String encoding) {  
        try {  
            CollectionWrapper wrapper = new CollectionWrapper();  
            wrapper.collection = root;  
  
            JAXBElement<CollectionWrapper> wrapperElement = new JAXBElement<CollectionWrapper>(  
                    new QName(rootName), CollectionWrapper.class, wrapper);  
  
            StringWriter writer = new StringWriter();  
            createMarshaller(encoding).marshal(wrapperElement, writer);  
  
            return writer.toString();  
        } catch (JAXBException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * Xml->Java Object. 
     */  
    @SuppressWarnings("unchecked")  
    public <T> T fromXml(String xml) {  
        try {  
            StringReader reader = new StringReader(xml);  
            return (T) createUnmarshaller().unmarshal(reader);  
        } catch (JAXBException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * Xml->Java Object, 支持大小写敏感或不敏感. 
     */  
    @SuppressWarnings("unchecked")  
    public <T> T fromXml(String xml, boolean caseSensitive) {  
        try {  
            String fromXml = xml;  
            if (!caseSensitive)  
                fromXml = xml.toLowerCase();  
            StringReader reader = new StringReader(fromXml);  
            return (T) createUnmarshaller().unmarshal(reader);  
        } catch (JAXBException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 创建Marshaller, 设定encoding(可为Null). 
     */  
    public Marshaller createMarshaller(String encoding) {  
        try {  
            Marshaller marshaller = jaxbContext.createMarshaller();  
            marshaller.setListener(new MarshallerListener()); //空字符串处理，在返回的xml文件中，空字符串属性复制null
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
            
            if (StringUtils.isNotBlank(encoding)) {  
                marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);  
            }  
            return marshaller;  
        } catch (JAXBException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 创建UnMarshaller. 
     */  
    public Unmarshaller createUnmarshaller() {  
        try {  
            return jaxbContext.createUnmarshaller();  
        } catch (JAXBException e) {  
            throw new RuntimeException(e);  
        }  
    }  
  
    /** 
     * 封装Root Element 是 Collection的情况. 
     */  
    public static class CollectionWrapper {  
        @SuppressWarnings("unchecked")  
        @XmlAnyElement  
        protected Collection collection;  
    }  
}
