package com.mosty.base.utils;


import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class XStreamUtil {
	private static Map<Class, Class> mClasses = new HashMap<Class, Class>();
	private static XStream xStream = new XStream(new DomDriver());
	private static Map<String, Class> wClasses = new HashMap<String, Class>();

	/**
	 * 
	 * @param clsz
	 *            每一层的标签对应的class (注意! 不是每一个标签!)
	 * @param fileName
	 *            文件路径("/sdcard/test.xml")
	 * @param NULL
	 *            暂没用到;
	 * @return 返回的是最外层对象：
	 */
	public static Object Xml2Object(List<Class> clsz, String fileName, String NULL) {
		for (Class cls : clsz) {
			if (mClasses.containsKey(cls))
				continue;
			mClasses.put(cls, cls);
			xStream.processAnnotations(cls);
		}
		try {
			// 这个是设置编码,因为可能编码不同会显现乱码，这个应该还没有具体解决乱码问题
			BufferedReader br = new BufferedReader(
					new InputStreamReader(new FileInputStream(fileName), "GBK"));
			return xStream.fromXML(br);
			// return xStream.fromXML(new FileReader(new
			// File(fileName)));//这个是直接读
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 
	 * @param clsz
	 *            : 每一层的标签对应的class
	 * @param str
	 *            : xml 解析出来的String
	 * @return 返回的是最外层对象：
	 */
	public static Object Xml2Object(List<Class> clsz, String str) {
		for (Class cls : clsz) {
//			if (mClasses.containsKey(cls))
//				continue;
			mClasses.put(cls, cls);
			xStream.processAnnotations(cls);
		}
		
		return xStream.fromXML(str);
	}
	public static Object Xml2Object(Map<String, Class> data,String str) {
		 for (Map.Entry<String, Class> entry:data.entrySet() ) {
			 xStream.alias(entry.getKey(),entry.getValue());
		}
		
		return xStream.fromXML(str);
	}
	
	/*--------------------------------------------*/
	/*
	 * Xml2Object 与 Object2Xml 的区别在于
	 * xStream.processAnnotations(cls);
	 * xStream.alias(cls.node, cls.cls);
	 */
	/*-------------------------------------------*/
	/**
	 * 
	 * @param clsz
	 *            这个和上面的不同就是，这个写入的时候需要 标签 和 type(class); 所以定义了一个类，方便点;
	 * @param obj
	 *            这个是读取到的对象
	 * @return
	 */
	public static String Object2Xml(List<XStreamNode> clsz, Object obj) {
		for (XStreamNode cls : clsz) {
			if (wClasses.containsKey(cls.node))
				continue;
			wClasses.put(cls.node, cls.cls);
			xStream.alias(cls.node, cls.cls);
		}
		return xStream.toXML(obj);

	}

	static class XStreamNode {
		public XStreamNode(String node, Class cls) {
			// TODO Auto-generated constructor stub
			this.node = node;
			this.cls = cls;
		}

		public String node;
		public Class cls;
	}
	
	 public static <T> T  toBean(String xmlStr,Class<T> cls){
         //注意：不是new Xstream(); 否则报错：java.lang.NoClassDefFoundError: org/xmlpull/v1/XmlPullParserFactory
         XStream xstream=new XStream(new DomDriver());
         xstream.processAnnotations(cls);
         T obj=(T)xstream.fromXML(xmlStr);
         return obj;         
     } 

}
