package com.kmall.manager.manager.express.sf;

import com.kmall.manager.manager.express.sf.entity.SfRouteServiceResponseEntity;
import org.apache.log4j.Logger;

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

public class XmlUtil {
    private static final Logger logger = Logger.getLogger(XmlUtil.class);

    /**
     * xml 转对象
     *
     * @param xml
     * @param c
     * @return
     */
    public static <T> Object toObject(String xml, Class<T> c) throws Exception {
        Object xmlObject = null;
        Reader reader = null;
        JAXBContext context = JAXBContext.newInstance(c);
        // XML 转为对象的接口
        Unmarshaller unmarshaller = context.createUnmarshaller();

        reader = new StringReader(xml);
        xmlObject = unmarshaller.unmarshal(reader);

        if (null != reader) {
            reader.close();
        }

        return xmlObject;
    }

    /**
     * 对象转xml
     *
     * @param
     * @param object
     * @return
     */
    public static <T> String toXml(T object) throws RuntimeException {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        try {
            JAXBContext context = JAXBContext.newInstance(object.getClass());
            Marshaller m = context.createMarshaller();
            m.marshal(object, output);
            return output.toString();
        } catch (JAXBException e) {
            logger.error("对象转xml 异常:" + e.getMessage());
            throw new RuntimeException("对象转xml 异常:" + e.getMessage());
        } finally {
            try {
                output.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @author zengjun
     * @version 1.0
     * 2017-10-12 14:27
     * @desc encoding为gbk
     */
    public static String toXML(Object obj, boolean format) throws Exception {
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            Marshaller marshaller = context.createMarshaller();

            //编码格式
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "GBK");

            // 是否格式化生成的xml串
            if (format) {
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            } else {
                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);
            }

            // 是否省略xm头声明信息
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);

            StringWriter writer = new StringWriter();
            marshaller.marshal(obj, writer);
            return writer.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @author zengjun
     * @version 1.0
     * 2017-10-12 14:27
     * @desc 没有头部
     */
    public static String toXmlNotHead(Object obj) throws Exception {
        try {
            JAXBContext context = JAXBContext.newInstance(obj.getClass());
            Marshaller marshaller = context.createMarshaller();
            //编码格式
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);
            // 是否省略xm头声明信息
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
            StringWriter writer = new StringWriter();
            marshaller.marshal(obj, writer);
            return writer.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static void main(String args[]) throws Exception{
        String xml="<?xml version='1.0' encoding='UTF-8'?><Response service=\"RouteService\"><Head>OK</Head><Body><RouteResponse mailno=\"444072971585\"><Route remark=\"顺丰速运 已收取快件\" accept_time=\"2019-04-01 10:10:40\" accept_address=\"深圳市\" opcode=\"50\"/></RouteResponse></Body></Response>";
//         Map<String, Object> map = com.kmall.common.utils.XmlUtil.xmlStrToMap(xml);
        System.out.println(xml);

        SfRouteServiceResponseEntity entity2 = (SfRouteServiceResponseEntity)toObject(xml, SfRouteServiceResponseEntity.class);
        System.out.println(entity2.toString());
        System.out.println(entity2.getBody());
    }
}
