/* * @(#)ExceptionHandlerImpl.java 1.10 04/06/21 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ 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", null ) ; setId( (String)idMethod.invoke( null, 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 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= 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 ) ; } }