/**************************************************************
 * 
 * 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 mod._stm;

import java.io.PrintWriter;
import java.util.Vector;

import lib.StatusException;
import lib.TestCase;
import lib.TestEnvironment;
import lib.TestParameters;

import com.sun.star.io.XActiveDataSink;
import com.sun.star.io.XActiveDataSource;
import com.sun.star.io.XInputStream;
import com.sun.star.io.XObjectInputStream;
import com.sun.star.io.XObjectOutputStream;
import com.sun.star.io.XOutputStream;
import com.sun.star.io.XPersistObject;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.registry.CannotRegisterImplementationException;
import com.sun.star.registry.XImplementationRegistration;
import com.sun.star.registry.XSimpleRegistry;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;

/**
* Test for object which is represented by service
* <code>com.sun.star.io.ObjectOutputStream</code>. <p>
* Object implements the following interfaces :
* <ul>
*  <li> <code>com::sun::star::io::XActiveDataSource</code></li>
*  <li> <code>com::sun::star::io::XOutputStream</code></li>
*  <li> <code>com::sun::star::io::XConnectable</code></li>
*  <li> <code>com::sun::star::io::XDataOutputStream</code></li>
*  <li> <code>com::sun::star::io::XObjectOutputStream</code></li>
* </ul>
* The following files used by this test :
* <ul>
*  <li><b> MyPersistObjectImpl.jar </b> : the implementation of the persist
*       object</li>
* </ul> <p>
* @see com.sun.star.io.ObjectOutputStream
* @see com.sun.star.io.XActiveDataSource
* @see com.sun.star.io.XOutputStream
* @see com.sun.star.io.XConnectable
* @see com.sun.star.io.XDataOutputStream
* @see com.sun.star.io.XObjectOutputStream
* @see ifc.io._XActiveDataSource
* @see ifc.io._XOutputStream
* @see ifc.io._XConnectable
* @see ifc.io._XDataOutputStream
* @see ifc.io._XObjectOutputStream
*/
public class ObjectOutputStream extends TestCase {

    /**
    * Register the implementation of service
    * <code>com.sun.star.cmp.PersistObject</code> if not yet registered.
    * @see com.sun.star.cmp.PersistObject
    */
    public void initialize(TestParameters tParam, PrintWriter log) {
        XMultiServiceFactory xMSF = (XMultiServiceFactory)tParam.getMSF();
        Object oPersObj = null;
        // test first if object is already registered
        try {
            oPersObj = xMSF.createInstance("com.sun.star.cmp.PersistObject");
        }
        catch( com.sun.star.uno.Exception e ) {
            log.println("Could not create instance of PersistObject");
            e.printStackTrace(log);
            log.println("Going on with test...");
        }
        if ( oPersObj == null ) {
            // object is  not available: it has to be registered
            String url = util.utils.getFullTestURL
                ("qadevlibs/MyPersistObjectImpl.jar");
            XImplementationRegistration xir;
            try {
                Object o = xMSF.createInstance(
                        "com.sun.star.registry.ImplementationRegistration");
                xir = (XImplementationRegistration)
                                    UnoRuntime.queryInterface(
                                    XImplementationRegistration.class, o);
            }
            catch (com.sun.star.uno.Exception e) {
                System.err.println(
                            "Couldn't create implementation registration");
                e.printStackTrace();
                throw new StatusException("Couldn't create ImplReg", e);
            }

            XSimpleRegistry xReg = null;
            try {
                System.out.println("Register library: " + url);
                xir.registerImplementation(
                                    "com.sun.star.loader.Java2", url, xReg);
                System.out.println("...done");
            } catch (CannotRegisterImplementationException e) {
                System.err.println("Name: " + url + "  msg: " +
                                    e.getMessage());
                e.printStackTrace();
                throw new StatusException(
                                    "Couldn't register MyPersistObject", e);
            }
        }
    }

    /**
    * Creating a Testenvironment for the interfaces to be tested.
    * Creates an instances of services
    * <code>com.sun.star.io.ObjectOutputStream</code>,
    * <code>com.sun.star.io.Pipe</code> and
    * <code>com.sun.star.io.MarkableOutputStream</code>. Plugs the created
    * markable output stream as output stream for the created
    * <code>ObjectOutputStream</code>. Plugs the created pipe as output stream
    * for the created <code>MarkableOutputStream</code>. Creates an instance
    * of the service <code>com.sun.star.cmp.PersistObject</code>.
    * Object relations created :
    * <ul>
    *  <li> <code>'StreamData'</code> for
    *      {@link ifc.io._XDataOutputStream}(the data that should
    *      be written into the stream) </li>
    *  <li> <code>'ByteData'</code> for
    *      {@link ifc.io._XOutputStream}(the data that should be written into
    *      the stream) </li>
    *  <li> <code>'Connectable'</code> for
    *      {@link ifc.io._XConnectable}
    *       (another object that can be connected) </li>
    *  <li> <code>'OutputStream'</code> for
    *      {@link ifc.io._XActiveDataSource}
    *       (an input stream to set and get) </li>
    *  <li> <code>'PersistObject'</code> for
    *      {@link ifc.io._XObjectOutputStream}(the created instance of the
    *  <li> <code>'InputStream'</code> for
    *      {@link ifc.io._XObjectInputStream}(the created instance of the
    *      persist object ) </li>
    *  <li> <code>'XOutputStream.StreamChecker'</code> for
    *      {@link ifc.io._XOutputStream}( implementation of the interface
    *      ifc.io._XOutputStream.StreamChecker ) </li>
    * </ul>
    * @see com.sun.star.io.ObjectInputStream
    * @see com.sun.star.io.ObjectOutputStream
    * @see com.sun.star.io.Pipe
    * @see com.sun.star.io.MarkableInputStream
    * @see com.sun.star.io.MarkableOutputStream
    * @see com.sun.star.cmp.PersistObject
    */
    public TestEnvironment createTestEnvironment(
        TestParameters Param, PrintWriter log) throws StatusException {

        XInterface oObj = null;

        XObjectOutputStream oStream = null;

        XMultiServiceFactory xMSF = (XMultiServiceFactory)Param.getMSF();
        Object ostream = null, istream = null;
        Object aPipe = null;
        Object mostream = null;
        XInterface aConnect = null;
        Object minstream = null;

        try {
            ostream = xMSF.createInstance
                ( "com.sun.star.io.ObjectOutputStream" );
            istream = xMSF.createInstance
                ("com.sun.star.io.ObjectInputStream");
            aPipe = xMSF.createInstance("com.sun.star.io.Pipe");
            mostream = xMSF.createInstance
                ("com.sun.star.io.MarkableOutputStream");
            aConnect = (XInterface)xMSF.createInstance
                ("com.sun.star.io.DataInputStream");
            minstream = xMSF.createInstance
                ("com.sun.star.io.MarkableInputStream");
        } catch( com.sun.star.uno.Exception e ) {
            e.printStackTrace(log);
            throw new StatusException("Couldn't create instance", e);
        }

        // creating the pipe where object has to be written to
        XActiveDataSource xdSo = (XActiveDataSource)
            UnoRuntime.queryInterface(XActiveDataSource.class, ostream);

        XActiveDataSource xdSmo = (XActiveDataSource)
            UnoRuntime.queryInterface(XActiveDataSource.class, mostream);

        XOutputStream moStream = (XOutputStream)
            UnoRuntime.queryInterface(XOutputStream.class, mostream);

        XActiveDataSink markIn = (XActiveDataSink)
            UnoRuntime.queryInterface(XActiveDataSink.class, minstream);
        XActiveDataSink inStream = (XActiveDataSink)
            UnoRuntime.queryInterface(XActiveDataSink.class, istream);
        XInputStream markInStream = (XInputStream)
            UnoRuntime.queryInterface(XInputStream.class, minstream);

        final XOutputStream PipeOut = (XOutputStream)
            UnoRuntime.queryInterface(XOutputStream.class,aPipe);
        final XInputStream PipeIn = (XInputStream)
            UnoRuntime.queryInterface(XInputStream.class,aPipe);

        markIn.setInputStream(PipeIn);
        inStream.setInputStream(markInStream);
        XObjectInputStream objInputStream = (XObjectInputStream)
            UnoRuntime.queryInterface(XObjectInputStream.class, istream);
        xdSo.setOutputStream(moStream);
        xdSmo.setOutputStream(PipeOut);

        oStream = (XObjectOutputStream)
            UnoRuntime.queryInterface(XObjectOutputStream.class, ostream);

        // creating Persistent object which has to be written
        XPersistObject xPersObj = null ;
        try {
            Object oPersObj = xMSF.createInstance
                ("com.sun.star.cmp.PersistObject");
            xPersObj = (XPersistObject)
                UnoRuntime.queryInterface(XPersistObject.class, oPersObj);
        } catch (com.sun.star.uno.Exception e) {
            e.printStackTrace(log);
            throw new StatusException("Can't write persist object.", e) ;
        }

        oObj = oStream;

        // all data types for writing to an XDataInputStream
        Vector data = new Vector() ;
        data.add(new Boolean(true)) ;
        data.add(new Byte((byte)123)) ;
        data.add(new Character((char)1234)) ;
        data.add(new Short((short)1234)) ;
        data.add(new Integer(123456)) ;
        data.add(new Float(1.234)) ;
        data.add(new Double(1.23456)) ;
        data.add("DataInputStream") ;
        // information for writing to the pipe
        byte[] byteData = new byte[] {
            1, 2, 3, 4, 5, 6, 7, 8 } ;

        log.println("creating a new environment for object");
        TestEnvironment tEnv = new TestEnvironment( oObj );

        tEnv.addObjRelation("PersistObject", xPersObj);
        tEnv.addObjRelation("StreamData", data);
        tEnv.addObjRelation("ByteData", byteData);
        tEnv.addObjRelation("OutputStream", aPipe);
        tEnv.addObjRelation("Connectable", aConnect);

        tEnv.addObjRelation("InputStream", objInputStream);

        //add relation for io.XOutputStream
        final XMultiServiceFactory msf = xMSF;
        tEnv.addObjRelation("XOutputStream.StreamChecker",
            new ifc.io._XOutputStream.StreamChecker() {
                XInputStream xInStream = null;
                public void resetStreams() {
                    if (xInStream != null) {
                        try {
                            xInStream.closeInput();
                            xInStream = null;
                        } catch(com.sun.star.io.IOException e) {
                        }
                    } else {
                        try {
                            PipeOut.closeOutput();
                        } catch(com.sun.star.io.IOException e) {
                        }
                    }
                }

                public XInputStream getInStream() {
                    resetStreams();
                    try {
                        Object oInStream = msf.createInstance(
                            "com.sun.star.io.ObjectInputStream");
                        xInStream = (XInputStream) UnoRuntime.queryInterface
                            (XInputStream.class, oInStream);
                    } catch(com.sun.star.uno.Exception e) {
                        return null;
                    }

                    XActiveDataSink xDataSink = (XActiveDataSink)
                        UnoRuntime.queryInterface(
                            XActiveDataSink.class, xInStream);
                    xDataSink.setInputStream(PipeIn);

                    return xInStream;
                }
            });

        return tEnv;
    } // finish method getTestEnvironment

}

