package dom4wspart3;


import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

import java.util.*;
import java.io.File;

import java.net.Socket;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;


public class SOAPMessage {

    public static void main(String argv[]) {
        try {
            DataWrapper dataWrapper = new DataWrapper();
            dataWrapper.add("String_1", "", "Faheem");
            SOAPMessage msg = new SOAPMessage("sayHelloBack",
                                              "http://hello.org/wsdl",
                                               dataWrapper);

            System.out.println("The getSOAPRequest output: \r\n"+
                               msg.getSOAPRequestText(msg.getSOAPDocument()));
            System.out.println("The SOAP response: \r\n"+
                               msg.getSOAPResponse("localhost",8080,"/jaxrpc-HelloWorld/hello")
                               );

        }//try
        catch (Exception e) {
            e.printStackTrace(System.err);
        }//catch

    }//main


    private Document doc;


    public SOAPMessage(String methodName, String methodNamespace, DataWrapper parameters) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            doc = db.newDocument();

            Element envElement = doc.createElementNS(
                        "http://schemas.xmlsoap.org/soap/envelope/",
                        "env:Envelope");
            doc.appendChild(envElement);

            envElement.setAttributeNS("http://schemas.xmlsoap.org/soap/envelope/",
                "env:encodingStyle", "http://schemas.xmlsoap.org/soap/encoding/");

            Element bodyElement = doc.createElementNS(
                "http://schemas.xmlsoap.org/soap/envelope/","env:Body");
            envElement.appendChild(bodyElement);

            Element methodElement = doc.createElementNS(methodNamespace, methodName);
            methodElement.setPrefix("ns1");
            bodyElement.appendChild(methodElement);
            parameters.appendAsChildren(methodElement);
        }//try
        catch (Exception e) {
            e.printStackTrace(System.err);
        }//catch

    }//SOAPMessage


    public String getSOAPRequestText (Document doc) {
        StringBuffer XMLText = new StringBuffer();
        XMLText.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n");
        Element e = doc.getDocumentElement();
        XMLText.append(getElementAsText(e));
        return XMLText.toString();
    }//getSOAPRequestText


    private StringBuffer getElementAsText(Element element) {
        StringBuffer elementText = new StringBuffer();
        if (element == null)
            return elementText;

        //Author name of the element.
        elementText.append("<"+element.getTagName());

        //Author attributes.
        NamedNodeMap attributes = element.getAttributes();
        int attCount = attributes.getLength();
        for (int j = 0; j<attCount; j++) {
            elementText.append(" "+attributes.item(j).getNodeName()+"=\"");
            elementText.append(attributes.item(j).getNodeValue()+"\"");
        }//for

        // Author the namespace node.
        if (element.getNamespaceURI()!=null) {
            elementText.append(" ");
            elementText.append("xmlns");
            if (element.getPrefix()!=null) {
                elementText.append(":");
                elementText.append(element.getPrefix());
            }//if
            elementText.append("=\"");
            elementText.append(element.getNamespaceURI());
            elementText.append("\" ");
        }

        elementText.append(">");

        //Author child nodes.
        for (int i=0;i<element.getChildNodes().getLength();i++) {
            Node child = element.getChildNodes().item(i);
            if (child.getNodeType() == Node.ELEMENT_NODE) elementText.append(
                getElementAsText((Element)child));
            if (child.getNodeType() == Node.TEXT_NODE) elementText.append(child.getNodeValue());
            // Process other types of child nodes if required.
        }//for

        elementText.append("</"+element.getTagName()+">");
        return elementText;
    }//getElementAsText


    public String getSOAPResponse(String host,
                                  int port,
                                  String webServiceEndPoint) {

       String SOAPResponse;
       try {

            Socket s = new Socket(host,port);

     
               String request = "POST "+webServiceEndPoint+" HTTP/1.1\r\n";
request+="Host: "+host+"\r\n";
            request+="Content-type: text/xml"+"; charset=utf-8\r\n";
            request+="Content-length: "+String.valueOf(getSOAPRequestText(doc).length())+"\r\n";
            request+="SOAPAction: \"\"\r\n\r\n";

            request+=getSOAPRequestText(doc);

            System.out.println("The complete SOAP request:");
            System.out.println(request);

            PrintWriter out   = new PrintWriter(s.getOutputStream());
            BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
            out.println(request);
            out.flush();

            StringBuffer sc = new StringBuffer();
            String line = null;

            // Receiving respone .
            while((line=in.readLine())!=null) {
                sc.append(line);
                sc.append("\r\n");
            }//while

            SOAPResponse = sc.toString();
            in.close();
            out.close();

        }//try
        catch (Exception e) {
            e.printStackTrace(System.err);
            return "exception";
        }//catch

        return SOAPResponse;

    }//getSOAPResponse


    public Document getSOAPDocument() {
        return doc;
    }//getSOAPDocument


    public void printDocument(String title, Document doc) {
        System.out.println("");
        System.out.println("");
        System.out.println("*********************");

        System.out.println(title+":");

        try {
            OutputFormat outputFormat = new OutputFormat(doc);
            outputFormat.setPreserveSpace(true);
            XMLSerializer serializer = new XMLSerializer(System.out, outputFormat);
            serializer.serialize(doc);
            System.out.println("");
        }//try

        catch (Exception e) {
            e.printStackTrace(System.err);
        }//catch

        System.out.println("*********************");
        System.out.println("");
        System.out.println("");

    }//printDocument    

}//SOAPMessage