import java.io.FileInputStream;
import java.security.Security;
import java.util.Vector;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.rpc.Call;
import javax.xml.rpc.Service;
import javax.xml.rpc.ServiceFactory;

import org.apache.axis.message.SOAPBodyElement;
import org.apache.xml.serialize.LineSeparator;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;

import com.sun.net.ssl.internal.ssl.Provider;

/**
 * @author Sven
 *
 * Dies ist eine Beispielklasse die den Zugriff auf MOA-SPSS mittels AXIS erkl�rt. <br>
 * Die Daten�bertragung erfolgt �ber eine sichere Verbindung (Clientauthentisierung)
 */
public class HTTPSClientExampleClientAuth {

        // SOAP Konstanten
        // CreationServer
        private static final QName SERVICE_QNAME = new QName("SignatureCreation");
        private static final String ENDPOINT = "http://localhost:8080/moa-spss/services/SignatureCreation";
        // Secure Endpoint
        private static final String SECURE_ENDPOINT = "https://localhost:8443/moa-spss/services/SignatureCreation";
        
        /* 
           VerificationService
           wenn Sie diese Werte f�r ENDPOINT und SERVICE verwenden k�nnen Sie eine
           Signaturpr�fung anstatt einer Signaturerstellung durchf�hren (entweder mit
           ENDPOINT f�r eine nicht sichere Verbindung bzw. SECURE_ENDPOINT f�r eine
           sichere Verbindung)
        
           private static final QName SERVICE_QNAME = new QName("SignatureVerification");
           private static final String ENDPOINT =
                "http://localhost:8080/moa-spss/services/SignatureVerification";
           private static final String SECURE_ENDPOINT =
                "https://localhost:8443/moa-spss/services/SignatureVerification";
        */
        public static final String HANDLER = "java.protocol.handler.pkgs";
        public static final String KEYSTORE = "javax.net.ssl.keyStore";
        public static final String KEYSTOREPASSWORD = "javax.net.ssl.keyStorePassword";
        public static final String TRUSTSTORE = "javax.net.ssl.trustStore";
        public static final String TRUSTSTOREPASSWORD = "javax.net.ssl.trustStorePassword";


        /**
         * Methode main.
         * 
         * Enth�lt den Beispielcode der n�tig ist um von Java aus auf MOA-SPSS zugreifen zu k�nnen.
         * Der Zugriff passiert �ber das AXIS-Framework. Die Verbindung ist eine SSL Verbindung mit Clientauthentisierung.
         * 
         * @param args wird nicht verwendet
         */

        public static void main(String[] args) {
                
                try {
                        /* 
                           Einrichten der SSL Verbindungseigenschaften
                           
                           Die Verbindung wird �ber SSL hergestellt, als TrustStore und als Keystore
                           wird ein JavaKeyStore verwendet der die notwendigen Daten enth�lt
                        */

                    Security.addProvider(new Provider());
                    System.setProperty(HANDLER,"com.sun.net.ssl.internal.www.protocol");
                    System.setProperty(KEYSTORE, "client.keystore");
                    System.setProperty(KEYSTOREPASSWORD, "changeit");
                    System.setProperty(TRUSTSTORE, "client.keystore");
                    System.setProperty(TRUSTSTOREPASSWORD, "changeit");
                        
                    // Datei mit Request einlesen
                    FileInputStream inputStream = new FileInputStream("example_request.xml");
                        
                    // Parser/DOMBuilder instanzieren
                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                    factory.setNamespaceAware(true);
                    DocumentBuilder builder = factory.newDocumentBuilder();
                    
                    // XML Datei in einen DOM-Baum umwandeln            
                    Document root_request = builder.parse(inputStream);
                    
                    // AXIS-Server instanzieren
                    Service service = ServiceFactory.newInstance().createService(SERVICE_QNAME);
                    
                    // Call �ffnen
                    Call call = service.createCall();
                
                    // Neues BodyElement anlegen und mit dem DOM-Baum f�llen
                    SOAPBodyElement body = new SOAPBodyElement(root_request.getDocumentElement());
                    SOAPBodyElement[] params = new SOAPBodyElement[] {body};
                    
                    // Call mit Endpoint verkn�pfen
                    call.setTargetEndpointAddress(SECURE_ENDPOINT);
                    
                    // Call ausl�sen und die Antworten speichern
                    System.out.println("Calling ...");
                    Vector responses = (Vector) call.invoke(params);
                    
                    // erstes BodyElement auslesen
                    SOAPBodyElement response = (SOAPBodyElement) responses.get(0);
                    
                    // aus der Response den DOM-Baum lesen
                    Document root_response =  response.getAsDocument();
                    System.out.println("Return ...");
                    
                    // Ausgabe auf System.out zum Testen
                    OutputFormat format = new OutputFormat((Document)root_response);

                    format.setLineSeparator("\n");
                    format.setIndenting(false);
                    format.setPreserveSpace(true);
                    format.setOmitXMLDeclaration(false);
                    format.setEncoding("UTF-8");

                    XMLSerializer serializer = new XMLSerializer (System.out, format);
                    serializer.asDOMSerializer();
                    serializer.serialize(root_response);
                    
                    // Antwort verarbeiten
                    // ...
                    // ...
                }
                catch(Exception e)
                {
                        e.printStackTrace();
                }           
            
        }
}