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 (Serverauthentisierung)
 */
public class HTTPSClientExampleServerAuth {

        // 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";
        
        /*
           Secure Endpoint
           dieser Endpoint kann alternativ zum ersten ENDPOINT verwendet werden
           um eine sichere Verbindung zum Server herzustellen
           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";
        */

        // SSL Konstanten
        public static final String HANDLER = "java.protocol.handler.pkgs";
        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 Serverauthentisierung.
         * 
         * @param args wird nicht verwendet
         */
        public static void main(String[] args) {
                
                try {
                    /* 
                           Einrichten der SSL Verbindungseigenschaften
                           
                           Die Verbindung wird �ber SSL hergestellt, als TrustStore 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(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();
                }           
            
        }
}