/*
 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.corba.se.impl.presentation.rmi ;

import java.io.Serializable ;
import java.io.Externalizable ;

import javax.rmi.PortableRemoteObject ;
import javax.rmi.CORBA.Util ;

import java.rmi.RemoteException ;
import java.rmi.UnexpectedException ;

import org.omg.CORBA.UserException ;

import org.omg.CORBA_2_3.portable.InputStream ;
import org.omg.CORBA_2_3.portable.OutputStream ;
import org.omg.CORBA.portable.ApplicationException ;

import java.lang.reflect.Method ;

import com.sun.corba.se.spi.logging.CORBALogDomains ;
import com.sun.corba.se.impl.logging.ORBUtilSystemException ;

public class ExceptionHandlerImpl implements ExceptionHandler
{
    private ExceptionRW[] rws ;

    private final ORBUtilSystemException wrapper ;

///////////////////////////////////////////////////////////////////////////////
// ExceptionRW interface and implementations.
// Used to read and write exceptions.
///////////////////////////////////////////////////////////////////////////////

    public interface ExceptionRW
    {
        Class getExceptionClass() ;

        String getId() ;

        void write( OutputStream os, Exception ex ) ;

        Exception read( InputStream is ) ;
    }

    public abstract class ExceptionRWBase implements ExceptionRW
    {
        private Class cls ;
        private String id ;

        public ExceptionRWBase( Class cls )
        {
            this.cls = cls ;
        }

        public Class getExceptionClass()
        {
            return cls ;
        }

        public String getId()
        {
            return id ;
        }

        void setId( String id )
        {
            this.id = id ;
        }
    }

    public class ExceptionRWIDLImpl extends ExceptionRWBase
    {
        private Method readMethod ;
        private Method writeMethod ;

        public ExceptionRWIDLImpl( Class cls )
        {
            super( cls ) ;

            String helperName = cls.getName() + "Helper" ;
            ClassLoader loader = cls.getClassLoader() ;
            Class helperClass ;

            try {
                helperClass = Class.forName( helperName, true, loader ) ;
                Method idMethod = helperClass.getDeclaredMethod( "id", (Class[])null ) ;
                setId( (String)idMethod.invoke( null, (Object[])null ) ) ;
            } catch (Exception ex) {
                throw wrapper.badHelperIdMethod( ex, helperName ) ;
            }

            try {
                Class[] argTypes = new Class[] {
                    org.omg.CORBA.portable.OutputStream.class, cls } ;
                writeMethod = helperClass.getDeclaredMethod( "write",
                    argTypes ) ;
            } catch (Exception ex) {
                throw wrapper.badHelperWriteMethod( ex, helperName ) ;
            }

            try {
                Class[] argTypes = new Class[] {
                    org.omg.CORBA.portable.InputStream.class } ;
                readMethod = helperClass.getDeclaredMethod( "read", argTypes ) ;
            } catch (Exception ex) {
                throw wrapper.badHelperReadMethod( ex, helperName ) ;
            }
        }

        public void write( OutputStream os, Exception ex )
        {
            try {
                Object[] args = new Object[] { os, ex } ;
                writeMethod.invoke( null, args ) ;
            } catch (Exception exc) {
                throw wrapper.badHelperWriteMethod( exc,
                    writeMethod.getDeclaringClass().getName() ) ;
            }
        }

        public Exception read( InputStream is )
        {
            try {
                Object[] args = new Object[] { is } ;
                return (Exception)readMethod.invoke( null, args ) ;
            } catch (Exception ex) {
                throw wrapper.badHelperReadMethod( ex,
                    readMethod.getDeclaringClass().getName() ) ;
            }
        }
    }

    public class ExceptionRWRMIImpl extends ExceptionRWBase
    {
        public ExceptionRWRMIImpl( Class cls )
        {
            super( cls ) ;
            setId( IDLNameTranslatorImpl.getExceptionId( cls ) ) ;
        }

        public void write( OutputStream os, Exception ex )
        {
            os.write_string( getId() ) ;
            os.write_value( ex, getExceptionClass() ) ;
        }

        public Exception read( InputStream is )
        {
            is.read_string() ; // read and ignore!
            return (Exception)is.read_value( getExceptionClass() ) ;
        }
    }

///////////////////////////////////////////////////////////////////////////////

    public ExceptionHandlerImpl( Class[] exceptions )
    {
        wrapper = ORBUtilSystemException.get(
            CORBALogDomains.RPC_PRESENTATION ) ;

        int count = 0 ;
        for (int ctr=0; ctr<exceptions.length; ctr++) {
            Class cls = exceptions[ctr] ;
            if (!RemoteException.class.isAssignableFrom(cls))
                count++ ;
        }

        rws = new ExceptionRW[count] ;

        int index = 0 ;
        for (int ctr=0; ctr<exceptions.length; ctr++) {
            Class cls = exceptions[ctr] ;
            if (!RemoteException.class.isAssignableFrom(cls)) {
                ExceptionRW erw = null ;
                if (UserException.class.isAssignableFrom(cls))
                    erw = new ExceptionRWIDLImpl( cls ) ;
                else
                    erw = new ExceptionRWRMIImpl( cls ) ;

                /* The following check is not performed
                 * in order to maintain compatibility with
                 * rmic.  See bug 4989312.

                // Check for duplicate repository ID
                String repositoryId = erw.getId() ;
                int duplicateIndex = findDeclaredException( repositoryId ) ;
                if (duplicateIndex > 0) {
                    ExceptionRW duprw = rws[duplicateIndex] ;
                    String firstClassName =
                        erw.getExceptionClass().getName() ;
                    String secondClassName =
                        duprw.getExceptionClass().getName() ;
                    throw wrapper.duplicateExceptionRepositoryId(
                        firstClassName, secondClassName, repositoryId ) ;
                }

                */

                rws[index++] = erw ;
            }
        }
    }

    private int findDeclaredException( Class cls )
    {
        for (int ctr = 0; ctr < rws.length; ctr++) {
            Class next = rws[ctr].getExceptionClass() ;
            if (next.isAssignableFrom(cls))
                return ctr ;
        }

        return -1 ;
    }

    private int findDeclaredException( String repositoryId )
    {
        for (int ctr=0; ctr<rws.length; ctr++) {
            // This may occur when rws has not been fully
            // populated, in which case the search should just fail.
            if (rws[ctr]==null)
                return -1 ;

            String rid = rws[ctr].getId() ;
            if (repositoryId.equals( rid ))
                return ctr ;
        }

        return -1 ;
    }

    public boolean isDeclaredException( Class cls )
    {
        return findDeclaredException( cls ) >= 0 ;
    }

    public void writeException( OutputStream os, Exception ex )
    {
        int index = findDeclaredException( ex.getClass() ) ;
        if (index < 0)
            throw wrapper.writeUndeclaredException( ex,
                ex.getClass().getName() ) ;

        rws[index].write( os, ex ) ;
    }

    public Exception readException( ApplicationException ae )
    {
        // Note that the exception ID is present in both ae
        // and in the input stream from ae.  The exception
        // reader must actually read the exception ID from
        // the stream.
        InputStream is = (InputStream)ae.getInputStream() ;
        String excName = ae.getId() ;
        int index = findDeclaredException( excName ) ;
        if (index < 0) {
            excName = is.read_string() ;
            Exception res = new UnexpectedException( excName ) ;
            res.initCause( ae ) ;
            return res ;
        }

        return rws[index].read( is ) ;
    }

    // This is here just for the dynamicrmiiiop test
    public ExceptionRW getRMIExceptionRW( Class cls )
    {
        return new ExceptionRWRMIImpl( cls ) ;
    }
}
