package org.jacorb.orb;
/*
* JacORB - a free Java ORB
*
* Copyright (C) 1997-2004 Gerald Brose.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.jacorb.config.*;
import org.slf4j.Logger;
import org.jacorb.ir.RepositoryID;
import org.jacorb.orb.giop.ReplyInputStream;
import org.jacorb.util.ObjectUtil;
import org.omg.CORBA.BAD_PARAM;
import org.omg.CORBA.ExceptionList;
import org.omg.CORBA.UserException;
import org.omg.GIOP.ReplyStatusType_1_2;
/**
* JacORB-specific implementation of
* <code>org.omg.Messaging.ExceptionHolder</code>. An instance of this
* type is used to pass an exception to a reply handler.
*
* @author Andre Spiegel <spiegel@gnu.org>
* @version $Id: ExceptionHolderImpl.java,v 1.19 2009-05-03 21:35:54 andre.spiegel Exp $
*/
public class ExceptionHolderImpl
extends org.omg.Messaging.ExceptionHolder
implements Configurable
{
private Logger logger = null;
/**
* No-arg constructor for demarshaling.
*/
public ExceptionHolderImpl()
{
super();
}
/**
* Constructs an ExceptionHolderImpl object from an input stream.
* It is assumed that the reply status of this input stream is
* either USER_EXCEPTION or SYSTEM_EXCEPTION. If it has another
* status, a RuntimeException is thrown.
*/
public ExceptionHolderImpl( ReplyInputStream inputStream )
{
this();
int status = inputStream.getStatus().value();
if ( status == ReplyStatusType_1_2._USER_EXCEPTION )
{
is_system_exception = false;
}
else if ( status == ReplyStatusType_1_2._SYSTEM_EXCEPTION )
{
is_system_exception = true;
}
else
{
throw new BAD_PARAM( "attempt to create ExceptionHolder " +
"for non-exception reply" );
}
byte_order = inputStream.littleEndian;
marshaled_exception = inputStream.getBody();
}
public ExceptionHolderImpl(org.omg.CORBA.SystemException exception)
{
this();
is_system_exception = true;
byte_order = false;
final CDROutputStream output = new CDROutputStream();
try
{
SystemExceptionHelper.write(output, exception);
marshaled_exception = output.getBufferCopy();
}
finally
{
output.close();
}
}
public void configure(Configuration configuration)
throws ConfigurationException
{
logger =
((org.jacorb.config.Configuration)configuration).getLogger("jacorb.orb.exc_holder");
}
public void raise_exception()
throws UserException
{
final CDRInputStream input =
new CDRInputStream (marshaled_exception, byte_order);
try
{
if ( is_system_exception )
{
throw SystemExceptionHelper.read( input );
}
input.mark( 0 );
String id = input.read_string();
try
{
input.reset();
}
catch( IOException e )
{
logger.warn( "Unexpected IOException: ", e);
}
org.omg.CORBA.UserException result = null;
try
{
result = exceptionFromHelper( id, input );
}
catch( Exception e )
{
throw new org.omg.CORBA.UnknownUserException();
}
throw result;
}
finally
{
input.close();
}
}
public void raise_exception_with_list( ExceptionList exc_list )
throws UserException
{
throw new org.omg.CORBA.NO_IMPLEMENT(
"raise_exception_with_list not yet implemented" );
}
/**
* For testing.
*/
public String toString()
{
StringBuffer result = new StringBuffer();
for (int i=0; i<marshaled_exception.length; i++)
{
result.append (marshaled_exception[i]);
result.append ('(');
result.append ((char)marshaled_exception[i]);
result.append (") ");
}
return result.toString();
}
/**
* Given a repository id, tries to find a helper for the corresponding
* class and uses it to unmarshal an instance of this class from
* the given InputStream.
*/
public org.omg.CORBA.UserException exceptionFromHelper
( String id,
org.omg.CORBA.portable.InputStream input )
throws ClassNotFoundException,
NoSuchMethodException,
IllegalAccessException,
InvocationTargetException
{
String name = RepositoryID.className(id, "Helper", null);
// if class doesn't exist, let exception propagate
Class helperClazz = ObjectUtil.classForName (name);
// helper must not be null from here on
// get read method from helper and invoke it,
// i.e. read the object from the stream
Method readMethod =
helperClazz.getMethod( "read",
new Class[]{
ObjectUtil.classForName("org.omg.CORBA.portable.InputStream")
} );
java.lang.Object result =
readMethod.invoke( null,
new java.lang.Object[]{ input }
);
return ( org.omg.CORBA.UserException ) result;
}
/**
* Marshals this object into a new buffer and returns that buffer.
*/
public byte[] marshal()
{
final CDROutputStream output = new CDROutputStream();
try
{
output.write_value( this, "IDL:omg.org/Messaging/ExceptionHolder:1.0" );
return output.getBufferCopy();
}
finally
{
output.close();
}
}
}