package cn.superdesk.uniorder.common.xml;

import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;

/**
 * @Description: Java类作用描述
 * @Author: linjinyu
 * @CreateDate: 2022/5/24 1:58 下午
 * @UpdateUser: linjinyu
 * @UpdateDate: 2022/5/24 1:58 下午
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@NoArgsConstructor
@Slf4j
public class AnXMLUtils {

    /**
     * 对象转XML
     *
     * @param obj 目标对象
     * @return 返回string格式的xml报文
     */
    public static String objToXml(Object obj) {

        StringWriter stringWriter = new StringWriter();
        String       resultXMLStr = null;

        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());

            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");
            marshaller.marshal(obj, stringWriter);

            resultXMLStr = stringWriter.toString();

        } catch (JAXBException e) {
            log.error("对象转XML异常：{}", e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                stringWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultXMLStr;
    }

    /**
     * XML转对象
     *
     * @param xml   目标xml报文
     * @param clazz 需要转换成对象的class
     */
    public static <T> T xmlToObj(String xml, Class clazz) {

        Object       obj          = null;
        StringReader stringReader = null;

        try {
            JAXBContext context = JAXBContext.newInstance(clazz);

            Unmarshaller unmarshaller = context.createUnmarshaller();

            stringReader = new StringReader(xml);

            obj = unmarshaller.unmarshal(stringReader);

        } catch (JAXBException e) {
            log.error("XML转对象异常：{}", e.getMessage());
            e.printStackTrace();
        } finally {
            if (stringReader != null) {
                stringReader.close();
            }
        }
        return (T) obj;
    }


    /**
     * 对象转XML文件
     *
     * @param obj
     * @param path
     * @return
     */
    public static String objToXmlFile(Object obj, String path) {

        FileWriter fileWriter   = null;
        String     resultXMLStr = null;

        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());

            Marshaller marshaller = context.createMarshaller();

            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");


            fileWriter = new FileWriter(path);
            marshaller.marshal(obj, fileWriter);
            resultXMLStr = fileWriter.toString();

        } catch (JAXBException | IOException e) {
            log.error("对象转XML文件异常：{}", e.getMessage());
        } finally {
            if (fileWriter != null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return resultXMLStr;
    }


    /**
     * XML文件转成对象
     *
     * @param <T>
     * @param xmlPath 文件路径
     * @param clazz
     * @return
     */
    public static <T> T xmlFileToObj(String xmlPath, Class<T> clazz) {

        Object     obj        = null;
        FileReader fileReader = null;

        try {
            JAXBContext context = JAXBContext.newInstance(clazz);

            Unmarshaller unmarshaller = context.createUnmarshaller();

            fileReader = new FileReader(xmlPath);
            obj = unmarshaller.unmarshal(fileReader);

        } catch (JAXBException | FileNotFoundException e) {
            log.error("file类型的xml转换对象错误：{}", e.getMessage());
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    log.error("关闭流异常：{}", e.getMessage());
                    e.printStackTrace();
                }
            }
        }
        return (T) obj;
    }
}