/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



package ifc.connection;

import java.io.PrintWriter;

import lib.MultiMethodTest;
import lib.StatusException;

import com.sun.star.connection.XAcceptor;
import com.sun.star.connection.XConnection;
import com.sun.star.connection.XConnector;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;

/**
* Tests methods of <code>XAcceptor</code> interface. <p>
* Required relations :
* <ul>
* <li> <code>'XAcceptor.connectStr'</code> : String variable. Has
*   the following format :
*   <code>'socket,host=<SOHost>,port=<UniquePort>' where <SOHost> is
*   the host where StarOffice is started. This string must be passed
*   as parameter to <code>accept()</code> method. </li>
* <ul> <p>
* This test <b>can not</b> be run in multiply threads.
*/
public class _XAcceptor extends MultiMethodTest {

    protected PrintWriter log_ ;

    /**
    * Calls <code>accept()</code> method in a separate thread.
    * Then stores exception thrown by call if it occured, or
    * return value.
    */
    protected class AcceptorThread extends Thread {
        /**
        * If exception occured during method call it is
        * stored in this field.
        */
        public Exception ex = null ;
        private XAcceptor acc = null ;
        /**
        * If method call returns some value it stores in this field.
        */
        public XConnection acceptedCall = null ;

        /**
        * Creates object which can call <code>accept</code> method
        * of the Acceptor object specified.
        */
        public AcceptorThread(XAcceptor acc) {
            this.acc = acc ;
        }

        /**
        * Call <code>accept()</code> method.
        */
        public void run() {
            try {
                acceptedCall = acc.accept(connectString) ;
            } catch (com.sun.star.lang.IllegalArgumentException e) {
                ex = e ;
            } catch (com.sun.star.connection.ConnectionSetupException e) {
                ex = e ;
            } catch (com.sun.star.connection.AlreadyAcceptingException e) {
                ex = e ;
            }
        }
    }

    public XAcceptor oObj = null;
    protected String connectString = null ;

    /**
    * Retrieves object relation.
    */
    public void before() throws StatusException {
        connectString = (String)
            tEnv.getObjRelation("XAcceptor.connectStr") ;

        log_ = log ;

        if (connectString == null)
            throw new StatusException("No object relation found",
                new NullPointerException()) ;
    }

    /**
    * First part : Thread with acceptor created, and it starts listening.
    * The main thread tries to connect to acceptor. Acception thread must
    * return and valid connection must be returned by Acceptor. <p>
    *
    * Second part : Trying to create second acceptor which listen on
    * the same port. Calling <code>accept()</code> method of the second
    * Acceptor must rise appropriate exception. <p>
    *
    * Has OK status if both test parts executed properly.
    */
    public void _accept() {
        boolean result = true ;
        AcceptorThread acception = null,
                       dupAcception = null ;
        XAcceptor dupAcceptor = null ;
        XConnector xConnector = null ;

        // creating services requierd
        try {
            Object oConnector = ((XMultiServiceFactory)tParam.getMSF()).
                createInstance("com.sun.star.connection.Connector") ;

            xConnector = (XConnector) UnoRuntime.queryInterface
                (XConnector.class, oConnector) ;

            XInterface acceptor = (XInterface) ((XMultiServiceFactory)
                tParam.getMSF()).createInstance
                ("com.sun.star.connection.Acceptor") ;

            dupAcceptor = (XAcceptor) UnoRuntime.queryInterface
                (XAcceptor.class, acceptor) ;
        } catch (com.sun.star.uno.Exception e) {
            e.printStackTrace(log) ;
            throw new StatusException("Can't create service", e) ;
        }

        // Testing connection to the acceptor
        try {
            acception = new AcceptorThread(oObj) ;
            acception.start() ;

            try {
                Thread.sleep(500);
            }
            catch (java.lang.InterruptedException e) {}

            XConnection con = xConnector.connect(connectString) ;

            if (con == null)
                log.println("Connector returned : null") ;
            else
                log.println("Connector returned : " + con.getDescription()) ;

            try {
                acception.join(5 * 1000) ;
            } catch(InterruptedException e) {}

            if (acception.isAlive()) {

                result = false ;
                log.println("Method call haven't returned") ;

                if (acception.acceptedCall == null)
                    log.println("Acceptor returned : null") ;
                else
                    log.println("Acceptor returned : " +
                        acception.acceptedCall.getDescription()) ;
            } else {
                if (acception.ex != null) {
                    log.println("Exception occured in accept() thread :") ;
                    acception.ex.printStackTrace(log) ;
                }

                if (acception.acceptedCall == null)
                    log.println("Method returned : null") ;
                else
                    log.println("Method returned : " +
                        acception.acceptedCall.getDescription()) ;

                result &= acception.acceptedCall != null ;
            }
        } catch (com.sun.star.connection.ConnectionSetupException e) {
            e.printStackTrace(log) ;
            result =  false ;
        } catch (com.sun.star.connection.NoConnectException e) {
            e.printStackTrace(log) ;
            result =  false ;
        } finally {
            oObj.stopAccepting();
            if (acception.isAlive()) {
                acception.interrupt();
            }
        }

        // duplicate acceptor test
        // creating the additional acceptor which listens
        // on the same port

        log.println("___ Testing for accepting on the same port ...") ;

        try {
            dupAcception = new AcceptorThread(dupAcceptor) ;
            dupAcception.start() ;

            try {
                dupAcception.join(1 * 1000) ;
            } catch(InterruptedException e) {}


            if (dupAcception.isAlive()) {
                log.println("Duplicate acceptor is listening ...") ;

                // now trying to accept on the same port as additional
                // acceptor
                acception = new AcceptorThread(oObj) ;
                acception.start() ;

                try {
                    acception.join(3 * 1000) ;
                } catch(InterruptedException e) {}

                if (acception.isAlive()) {
                    oObj.stopAccepting() ;
                    acception.interrupt() ;

                    log.println("Acceptor with the same port must cause"+
                    " an error but didn't") ;
                    result = false ;
                } else {
                    log.println("Accepted call = " + acception.acceptedCall) ;
                    if (acception.ex == null) {
                        //result = false ;
                        log.println("No exception was thrown when trying"+
                         " to listen on the same port") ;
                    } else {
                        if (acception.ex instanceof
                            com.sun.star.connection.AlreadyAcceptingException ||
                            acception.ex instanceof
                            com.sun.star.connection.ConnectionSetupException) {

                            log.println("Rigth exception was thrown when trying"+
                            " to listen on the same port") ;
                        } else {
                            result = false ;
                            log.println("Wrong exception was thrown when trying"+
                            " to listen on the same port :") ;
                            acception.ex.printStackTrace(log) ;
                        }
                    }
                }
            }
        } finally {
            dupAcceptor.stopAccepting() ;
            if (dupAcception.isAlive()) {
                dupAcception.interrupt() ;
            }
        }

        tRes.tested("accept()", result) ;
    }

    /**
    * Starts thread with Acceptor and then calls <code>stopListening</code>
    * method. <p>
    * Has OK status if <code>accept</code> method successfully returns and
    * rises no exceptions.
    */
    public void _stopAccepting() {
        boolean result = true ;


        AcceptorThread acception = new AcceptorThread(oObj) ;

        acception.start() ;

        oObj.stopAccepting() ;

        try {
            acception.join(3 * 1000) ;
        } catch (InterruptedException e) {}

        if (acception.isAlive()) {
            acception.interrupt() ;

            result = false ;
            log.println("Method call haven't returned") ;

        } else {
            if (acception.ex != null) {
                log.println("Exception occured in accept() thread :") ;
                acception.ex.printStackTrace(log) ;
                result = false ;
            } else {
                result = true ;
            }

            if (acception.acceptedCall == null)
                log.println("accept() returned : null") ;
            else
                log.println("accept() returned : " +
                    acception.acceptedCall.getDescription()) ;
        }

        tRes.tested("stopAccepting()", result) ;
    }
}

