package cc.smtweb.framework.core.util;

import org.dom4j.*;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by Akmm at 2011-1-19 10:16:01
 */
public class XmlUtil {
    /**
     * 按缩减格式写xml文件
     *
     * @param document
     * @param fileName
     * @throws IOException
     */
    public static void saveToFileCompact(Document document, String fileName) throws IOException {
        saveToFile(document, fileName, OutputFormat.createCompactFormat());
    }

    /**
     * 按美化格式写xml
     *
     * @param document
     * @param fileName
     * @throws IOException
     */
    public static void saveToFilePretty(Document document, String fileName) throws IOException {
        // 指定文件 美化格式
        saveToFile(document, fileName, OutputFormat.createPrettyPrint());
    }

    /**
     * 直接写xml，无格式
     *
     * @param document
     * @param fileName
     * @throws IOException
     */
    public static void saveToFile(Document document, String fileName, OutputFormat format) throws IOException {
        XMLWriter xmlWriter;
        if (format == null) xmlWriter = new XMLWriter(new FileOutputStream(fileName));
        else xmlWriter = new XMLWriter(new FileOutputStream(fileName), format);

        xmlWriter.write(document);
        xmlWriter.close();
    }

    /**
     * 直接写xml，无格式
     *
     * @param document
     * @param fileName
     * @throws IOException
     */
    public static void saveToFile(Document document, String fileName) throws IOException {
        saveToFile(document, fileName, null);
    }

    /**
     * 创建一个Document
     *
     * @return
     */
    public static Document createDocument() {
        return DocumentHelper.createDocument();
    }

    /**
     * 解析string为一个Document
     *
     * @return
     */
    public static Document parseXml(String xml) throws DocumentException {
        return DocumentHelper.parseText(xml);
    }

    public static Document readXmlDocument(String fileName) throws MalformedURLException, DocumentException {
        SAXReader reader = new SAXReader();
        return reader.read(new File(fileName));
    }

    public static Document readXmlDocument(InputStream file) throws MalformedURLException, DocumentException {
        SAXReader reader = new SAXReader();
        return reader.read(file);
    }

    public static Document readXmlDocument(URL url) throws MalformedURLException, DocumentException {
        SAXReader reader = new SAXReader();
        return reader.read(url);
    }

    public static Document readXmlDocument(File file) throws MalformedURLException, DocumentException {
        SAXReader reader = new SAXReader();
        return reader.read(file);
    }

    //获取节点属性
    public static String getChildValue(Element e, String chileName) {
        Element ec = e.element(chileName);
        if (ec != null) return ec.getTextTrim();
        return null;
    }

    //获取节点属性
    public static String getAttribute(Element e, String attrName) {
        Attribute a = e.attribute(attrName);
        if (a != null) return a.getValue();
        return null;
    }

    //获取节点属性，转为字符串数组
    public static String[] getAttrStrArray(Element e, String attrName) {
        String s = getAttribute(e, attrName);
        if (StringUtil.isNotEmpty(s)) return StringUtil.split(s, ",").toArray(new String[]{});
        return new String[0];
    }

    //获取节点属性，转为int数组
    public static int[] getAttrIntArray(Element e, String attrName) {
        String[] ss = getAttrStrArray(e, attrName);
        int[] ret = new int[ss.length];
        for (int i = 0, len = ss.length; i < len; i++) {
            ret[i] = NumberUtil.getIntIgnoreErr(ss[i]);
        }
        return ret;
    }

    public static int getAttributeInt(Element e, String attrName) {
        return NumberUtil.getIntIgnoreErr(getAttribute(e, attrName));
    }

    public static double getAttributeDbl(Element e, String attrName) {
        return NumberUtil.getDoubleIgnoreErr(getAttribute(e, attrName));
    }

    public static boolean getAttributeBool(Element e, String attrName) {
        String s = getAttribute(e, attrName);
        return "1".equals(s) || "Y".equalsIgnoreCase(s) || "true".equalsIgnoreCase(s) || "yes".equalsIgnoreCase(s);
    }

    //获取节点属性
    public static String getAttributeIgnoreNull(Element e, String attrName) {
        return StringUtil.checkNull(getAttribute(e, attrName));
    }

    //读取节点所有属性，返回map
    public static Map<String, String> getAttributeMap(Element e) {
        Map<String, String> map = new HashMap<>();
        for (Iterator as = e.attributeIterator(); as.hasNext(); ) {
            Attribute a = (Attribute) as.next();
            map.put(a.getName(), a.getValue());
        }
        return map;
    }

    public static void removeAttribute(Element e, String attrName) {
        Attribute a = e.attribute(attrName);
        if (a != null) e.remove(a);
    }

    //设置节点属性
    public static void setAttribute(Element e, String attrName, String attrValue) {
        if (StringUtil.isNotEmpty(attrValue)) e.addAttribute(attrName, attrValue);
        else removeAttribute(e, attrName);
    }

    //设置节点属性
    public static void setAttribute(Element e, String attrName, int attrValue) {
        if (attrValue != 0) e.addAttribute(attrName, String.valueOf(attrValue));
        else removeAttribute(e, attrName);
    }

    //设置节点属性
    public static void setAttribute(Element e, String attrName, double attrValue) {
        if (!NumberUtil.isEqualsZero(attrValue)) e.addAttribute(attrName, String.valueOf(attrValue));
        else removeAttribute(e, attrName);
    }

    //设置节点属性
    public static void setAttribute(Element e, String attrName, boolean attrValue) {
        if (attrValue) e.addAttribute(attrName, "1");
        else removeAttribute(e, attrName);
    }

    //设置节点属性
    public static void removeElement(Element parent, String name) {
        Element e = parent.element(name);
        if (e != null) parent.remove(e);
    }

    //解析节点到Map
    public static void decodeForMap(Element pnode, Map<String, String> map) {
        for (Iterator it = pnode.elementIterator(); it.hasNext(); ) {
            Element el = (Element) it.next();
            String nodename = el.getName();
            map.put(nodename, el.getTextTrim());
        }
    }

    //解析节点到Map
    public static void writeMap(Element pnode, Map<String, Object> map) {
        for (String s : map.keySet()) {
            Element e = pnode.addElement(s);
            final Object o = map.get(s);
            e.setText(o != null ? o.toString(): "");
        }
    }

    //添加节点
    public static void addNode(Element pnode, String name, Object value) {
        Element e = pnode.addElement(name);
        e.setText(value != null ? value.toString(): "");
    }

    public static void main(String[] args) {
        try {
            Document doc = readXmlDocument("f:\\temp\\plugin-developer.xml");
            Element e = doc.getRootElement();
            System.out.println("id:::::::" + getAttribute(e, "id"));
            System.out.println("name:::::::" + getAttribute(e, "name"));
            System.out.println("vvvv:::::::" + getAttribute(e, "呵呵"));
//            e.accept(new VisitorSupport() {
//                public void visit(Element element) {
//                    System.out.println(element.getName() + ":::eee:::" + element.getText());
//                }
//
//                public void visit(Attribute a) {
//                    System.out.println(a.getName() + ":::aaa:::" + a.getValue());
//                }
//            });
            // 枚举所有子节点
            Element e1 = e.element("fields");
            e1 = e1.element("field");
            System.out.println(getAttributeIgnoreNull(e1, "id"));

            setAttribute(e, "vvvv", "tttttttt");
            //e.addCDATA("<a>asdasd</a>");
            saveToFileCompact(doc, "f:\\temp\\plugin-developer1.xml");
            saveToFilePretty(doc, "f:\\temp\\plugin-developer2.xml");
            saveToFile(doc, "f:\\temp\\plugin-developer3.xml");
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}
