package com.zzsmart.qomo.kn.cost.manage.plugin.webservice;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.xml.sax.InputSource;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import java.io.*;
import java.util.*;

public class SoapUtil {

    //public static String responseXml;
    /**
     * 获取SOAP的请求头，并替换其中的标志符号为用户输入的城市
     *
     * @return 客户将要发送给服务器的SOAP请求
     */
    private static String getSoapRequest() {
        StringBuilder sb = new StringBuilder();
        sb.append("<?xml version=\"1.0\" encoding=\"utf-8\"?>"
                + "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:hror=\"hrorg\">"
                + "<soapenv:Header/>"
                + "<soapenv:Body>"
                + "<hror:getOrgcrude_jidian/>"
                + "</soapenv:Body>"
                + "</soapenv:Envelope>");
        return sb.toString();
    }

    /**
     * 测试用户名密码密码授权访问webservice规范
     * @param wsdl
     * @param xml
     * @return
     * @throws Exception
     */
    public SoapResult getUPSoapInputStream(String wsdl, String xml){
        SoapResult result=new SoapResult();
        try {
            String soap = xml;
            if (soap == null) {
                return result;
            }
            int timeout = 1000000;

            HttpClient client = new HttpClient();
            PostMethod postMethod = new PostMethod(wsdl);
            // 设置连接超时
            client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
            client.getState().setCredentials(AuthScope.ANY,new UsernamePasswordCredentials("SAP_MES", "q123456789"));
            // 设置读取时间超时
            client.getHttpConnectionManager().getParams().setSoTimeout(timeout);
            //设置HTTP请求超时时不进行自动重发
            client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0,false));
            // 然后把Soap请求数据添加到PostMethod中
            RequestEntity requestEntity = new StringRequestEntity(soap, "application/soap+xml", "UTF-8");
            //设置请求头部，否则可能会报 “no SOAPAction header” 的错误
            postMethod.setRequestHeader("SOAPAction","");
            // 设置请求体
            postMethod.setRequestEntity(requestEntity);
            int status = client.executeMethod(postMethod);
            // 打印请求状态码
            //System.out.println("status:" + status);
            // 获取响应体输入流
            //String soapResponseInfo = postMethod.getResponseBodyAsString();

            // 获取响应体输入流
            InputStream is = postMethod.getResponseBodyAsStream();
            // 获取请求结果字符串
            //InputStreamReader inputStreamReader = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));

            String responseLine = "";
            String soapResponseInfo = "";
            while((responseLine = bufferedReader.readLine()) != null) {
                soapResponseInfo = soapResponseInfo + responseLine ;
            }
            result.setStatus(status + "");
            result.setContent(soapResponseInfo);

            return result;
        } catch (Exception e) {
            e.printStackTrace();
            result.setContent(e.getMessage());
            return result;
        }
    }


    /**
     * 用户名密码授权访问webservice规范
     * 新增返回状态标识
     * @param xml
     * @return
     * @throws Exception
     */
    public SoapResult getUPTSoapStream(String xml, String url, String u, String p) {
        SoapResult result = new SoapResult();
        try {
            String soap = xml;
            if (soap == null) {
                return result;
            }
            int timeout = 1000000;

            HttpClient client = new HttpClient();
            PostMethod postMethod = new PostMethod(url);
            // 设置连接超时
            client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
            client.getState().setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(u,p));
            //设置HTTP请求超时时不进行自动重发
            client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0,false));
            // 设置读取时间超时
            client.getHttpConnectionManager().getParams().setSoTimeout(timeout);
            // 然后把Soap请求数据添加到PostMethod中
            RequestEntity requestEntity = new StringRequestEntity(soap, "application/soap+xml", "UTF-8");
            //设置请求头部，否则可能会报 “no SOAPAction header” 的错误
            postMethod.setRequestHeader("SOAPAction","");
            // 设置请求体
            postMethod.setRequestEntity(requestEntity);
            int status = client.executeMethod(postMethod);
            // 打印请求状态码
            System.out.println("status:" + status);
            // 获取响应体输入流
            //String soapResponseInfo = postMethod.getResponseBodyAsString();

            // 获取响应体输入流
            InputStream is = postMethod.getResponseBodyAsStream();
            // 获取请求结果字符串
            //InputStreamReader inputStreamReader = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));

            String responseLine = "";
            String soapResponseInfo = "";
            while((responseLine = bufferedReader.readLine()) != null) {
                soapResponseInfo = soapResponseInfo + responseLine ;
            }
            System.out.println("return:" +  new Date());
            result.setStatus(status +"");
            result.setContent(soapResponseInfo);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            result.setContent(e.getMessage());
            return result;
        }
    }

    /**
     * 用户名密码授权访问webservice规范
     * @param xml
     * @return
     */
    public SoapResult getUPSoapStream(String xml, String url, String u, String p,String functions) {
        SoapResult result = new SoapResult();
        try {
            String soap = xml;
            if (soap == null) {
                return result;
            }
            int timeout = 1000000;

            HttpClient client = new HttpClient();
            PostMethod postMethod = new PostMethod(url);
            // 设置连接超时
            client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
            client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(u, p));
            //if(!u.equals("")) {
            //    client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(u, p));
            //}
            //设置HTTP请求超时时不进行自动重发
            client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0,false));

            // 设置读取时间超时
            client.getHttpConnectionManager().getParams().setSoTimeout(timeout);
            // 然后把Soap请求数据添加到PostMethod中
            String contentType="text/xml";
            //String contentType="application/soap+xml;charset=UTF-8;action=\"urn:sap-com:document:sap:soap:functions:mc-style:ZSAP_DSJ_001:ZsapDsj001Request\"";
            RequestEntity requestEntity = new StringRequestEntity(soap, contentType, "UTF-8");
            //设置请求头部，否则可能会报 “no SOAPAction header” 的错误
            //postMethod.setRequestHeader("SOAPAction","urn:sap-com:document:sap:soap:functions:mc-style:ZSAP_DSJ_001:ZsapDsj001Request");
            postMethod.setRequestHeader("SOAPAction",functions);


            System.out.println(requestEntity);
            // 设置请求体
            postMethod.setRequestEntity(requestEntity);
            int status = client.executeMethod(postMethod);
            // 打印请求状态码
            System.out.println("status:" + status);
            // 获取响应体输入流
            //String soapResponseInfo = postMethod.getResponseBodyAsString();

            // 获取响应体输入流
            InputStream is = postMethod.getResponseBodyAsStream();
            // 获取请求结果字符串
            //InputStreamReader inputStreamReader = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));

            String responseLine = "";
            String soapResponseInfo = "";
            while((responseLine = bufferedReader.readLine()) != null) {
                soapResponseInfo = soapResponseInfo + responseLine ;
            }
            result.setStatus(status + "");
            result.setContent(soapResponseInfo);

            return result;
        } catch (Exception e) {
            e.printStackTrace();
            result.setContent(e.getMessage());
            return result;
        }
    }

    /**
     * 用户把SOAP请求发送给服务器端，并返回服务器点返回的输入流数据
     * @param wsdl 服务器的wsdl地址
     * @param xml 请求的报文信息
     * @return 服务器端返回的输入流，供客户端读取
     * @throws Exception
     */
    public SoapResult getSoapInputStream(String wsdl, String xml) {
        SoapResult result = new SoapResult();
        try {
            String soap = xml;
            if (soap == null) {
                return result;
            }
            int timeout = 100000;

            HttpClient client = new HttpClient();
            PostMethod postMethod = new PostMethod(wsdl);
            // 设置连接超时
            client.getHttpConnectionManager().getParams().setConnectionTimeout(timeout);
            client.getState().setCredentials(AuthScope.ANY,new UsernamePasswordCredentials("ESB_MES","q123456789"));
            //设置HTTP请求超时时不进行自动重发
            client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0,false));
            // 设置读取时间超时
            client.getHttpConnectionManager().getParams().setSoTimeout(timeout);
//            client.getHttpConnectionManager().getParams().setParameter("Name", "LP02");
            // 然后把Soap请求数据添加到PostMethod中
            RequestEntity requestEntity = new StringRequestEntity(soap, "application/soap+xml", "UTF-8");
            //设置请求头部，否则可能会报 “no SOAPAction header” 的错误
            postMethod.setRequestHeader("SOAPAction","");
//            postMethod.setRequestHeader("SOAPAction","");
//            postMethod.setRequestHeader("Binding","LP02");
            // 设置请求体
            postMethod.setRequestEntity(requestEntity);
            int status = client.executeMethod(postMethod);
            // 打印请求状态码
            //System.out.println("status:" + status);
            // 获取响应体输入流
            //String soapResponseInfo = postMethod.getResponseBodyAsString();

            // 获取响应体输入流
            InputStream is = postMethod.getResponseBodyAsStream();
            // 获取请求结果字符串
            //InputStreamReader inputStreamReader = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, "UTF-8"));

            String responseLine = "";
            String soapResponseInfo = "";
            while((responseLine = bufferedReader.readLine()) != null) {
                soapResponseInfo = soapResponseInfo + responseLine ;
            }
            result.setStatus(status+"");
            result.setContent(soapResponseInfo);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            result.setContent(e.getMessage());
            return result;
        }
    }


    /**
     * 通过返回的报文数据解析获取xml根节点
     * @param xml 返回的报文xml
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public Element getRootElement(String xml) throws JDOMException, IOException {
        StringReader read = new StringReader(xml);
        //创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入
        InputSource source = new InputSource(read);
        SAXBuilder builder=new SAXBuilder(false);

        Document doc=builder.build(source);
        Element root = doc.getRootElement();
        return root;
    }

    /**
     * 通过父节点NODE值，获取子级NODE节点的List<HashMap<>>列表
     * @param root 解析的文档xml根节点
     * @param node 父节点标签值
     * @param slist list子节点标签值
     * @return List<HashMap<String,String>>
     * @throws Exception
     */
    public List<HashMap<String,String>> getListParse(Element root,String node,String slist) throws Exception{
        //返回的列表定义
        List<HashMap<String,String>> alist = new ArrayList<HashMap<String,String>>();

        //返回指定节点的标签Element值
        Element name = getNodeElement(root,node);
//		System.out.println("指定节点的值："+name);

        List booklist=name.getChildren(slist);
//		List booklist=name.getChildren();
//		System.out.println("指定节点的值11："+booklist);
        for (Iterator iter = booklist.iterator(); iter.hasNext();) {
            Element book = (Element) iter.next();
            List<Element> list = book.getChildren();
            HashMap<String,String> map = new HashMap<String,String>();
            for(Element child : list)
            {
                map.put(child.getName(), child.getTextTrim());
            }
            alist.add(map);
        }
//		System.out.println("获取数据行数："+booklist.size());

        return alist;
    }


    /**
     * 通过父节点NODE值，获取子级NODE节点的List<HashMap<>>列表
     * @param root 解析的文档xml根节点
     * @param node 父节点标签值
     * @param slist list子节点标签值
     * @return List<HashMap<String,String>>
     * @throws Exception
     */
    public List<HashMap<String,String>> getListBarcode(Element root,String node,String slist) throws Exception{
        //返回的列表定义
        List<HashMap<String,String>> alist = new ArrayList<HashMap<String,String>>();

        //返回指定节点的标签Element值
        Element name = getNodeElement(root,node);
//		System.out.println("指定节点的值："+name);

//		List booklist=name.getChildren(slist);
        List booklist=name.getChildren();
//		System.out.println("指定节点的值11："+booklist);
        for (Iterator iter = booklist.iterator(); iter.hasNext();) {
            Element book = (Element) iter.next();
            List<Element> list = book.getChildren();
            HashMap<String,String> map = new HashMap<String,String>();
            for(Element child : list)
            {
                map.put(child.getName(), child.getTextTrim());
            }
            alist.add(map);
        }
//		System.out.println("获取数据行数："+booklist.size());

        return alist;
    }

    public HashMap<String, String> getMapParse(Element root, String node) throws JDOMException, IOException
    {
        Element key = getNodeElement(root, node);
        List<Element> list = key.getChildren();
        HashMap<String, String> map = new HashMap();
        for (Element e : list) {
            map.put(e.getName(), e.getTextTrim());
        }
        return map;
    }

    /**
     * 通过节点名称获取 对应的节点值
     * @param root 解析的文档xml根节点
     * @param node 节点的名称
     * @return
     * @throws JDOMException
     * @throws IOException
     */
    public String getKeyParse(Element root,String node) throws JDOMException, IOException{

        //返回指定节点的标签Element值
        Element key = getNodeElement(root,node);
        //System.out.println(key);
        return key.getTextTrim();
    }

    /**
     * 返回指定的节点名称的Element标签
     * @param e 根节点值
     * @param name 获取的标签值
     * @return
     */
    //
    public static Element getNodeElement(Element e,String name){
        Element ee = null ;
        if (e != null)
        {
            if(e.getName() == name)
            {
                ee = e;
            }else{
                if (e.getChildren() != null)   //如果存在子节点
                {
                    List<Element> list = e.getChildren();
                    for (Element el : list)    //循环输出
                    {
                        if(el.getName()== name)   //如果子节点还存在子节点，则递归获取
                        {
                            ee = el;
                            return ee;
                        }
                        else
                        {
//							System.out.println(el.getName()+", ");
                            ee = getNodeElement(el, name);  //将叶子节点值压入map
                        }
                    }
                }
            }
        }
        return ee;
    }

    public HashMap<String,Object> sendData(String status, String message, List list, Map map){
        HashMap<String,Object> send = new HashMap<String,Object>();
        //请求状态
        send.put("status", status);
        //请求状态信息
        send.put("message", message);
        //请求的列表数据
        send.put("list", list);
        //请求的单列数据
        send.put("map", map);

        return send;
    }

}
