dain 2005/06/21 14:59:30
Added: modules/core/src/java/org/openejb/corba StandardServant.java
Log:
Standard servant to connect corba directly to EjbContainer... NOT TESTED
Revision Changes Path
1.1
openejb/modules/core/src/java/org/openejb/corba/StandardServant.java
Index: StandardServant.java
===================================================================
/**
* Redistribution and use of this software and associated documentation
* ("Software"), with or without modification, are permitted provided
* that the following conditions are met:
*
* 1. Redistributions of source code must retain copyright
* statements and notices. Redistributions must also contain a
* copy of this document.
*
* 2. Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. The name "OpenEJB" must not be used to endorse or promote
* products derived from this Software without prior written
* permission of The OpenEJB Group. For written permission,
* please contact [EMAIL PROTECTED]
*
* 4. Products derived from this Software may not be called "OpenEJB"
* nor may "OpenEJB" appear in their names without prior written
* permission of The OpenEJB Group. OpenEJB is a registered
* trademark of The OpenEJB Group.
*
* 5. Due credit should be given to the OpenEJB Project
* (http://openejb.org/).
*
* THIS SOFTWARE IS PROVIDED BY THE OPENEJB GROUP AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE OPENEJB GROUP OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Copyright 2005 (C) The OpenEJB Group. All Rights Reserved.
*
* $Id: StandardServant.java,v 1.1 2005/06/21 18:59:30 dain Exp $
*/
package org.openejb.corba;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.rmi.AccessException;
import java.rmi.MarshalException;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.rmi.CORBA.Util;
import javax.rmi.PortableRemoteObject;
import javax.transaction.InvalidTransactionException;
import javax.transaction.TransactionRequiredException;
import javax.transaction.TransactionRolledbackException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.INVALID_TRANSACTION;
import org.omg.CORBA.MARSHAL;
import org.omg.CORBA.NO_PERMISSION;
import org.omg.CORBA.OBJECT_NOT_EXIST;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.TRANSACTION_REQUIRED;
import org.omg.CORBA.TRANSACTION_ROLLEDBACK;
import org.omg.CORBA.UNKNOWN;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ResponseHandler;
import org.omg.CORBA.portable.UnknownException;
import org.omg.PortableServer.Servant;
import org.openejb.EJBContainer;
import org.openejb.corba.compiler.IiopOperation;
import org.openejb.corba.compiler.PortableStubCompiler;
/**
* @version $Revision: 1.1 $ $Date: 2005/06/21 18:59:30 $
*/
public class StandardServant extends Servant implements
org.omg.CORBA.portable.InvokeHandler {
private static final Log log = LogFactory.getLog(StandardServant.class);
private final EJBContainer ejbContainer;
private final Object primaryKey;
private final String[] typeIds;
private final Map operations;
public StandardServant(Class type, EJBContainer ejbContainer) {
this(type, ejbContainer, null);
}
public StandardServant(Class type, EJBContainer ejbContainer, Object
primaryKey) {
this.ejbContainer = ejbContainer;
this.primaryKey = primaryKey;
IiopOperation[] iiopOperations =
PortableStubCompiler.createIiopOperations(type);
Map operations = new HashMap(iiopOperations.length);
for (int i = 0; i < iiopOperations.length; i++) {
IiopOperation iiopOperation = iiopOperations[i];
operations.put(iiopOperation.getName(),
iiopOperation.getMethod());
}
this.operations = Collections.unmodifiableMap(operations);
List ids = new LinkedList();
for (Iterator iterator =
PortableStubCompiler.getAllInterfaces(type).iterator(); iterator.hasNext();) {
Class superInterface = (Class) iterator.next();
if (Remote.class.isAssignableFrom(superInterface) &&
superInterface != Remote.class) {
ids.add("\"RMI:" + superInterface.getName() +
":0000000000000000\"");
}
}
typeIds = (String[]) ids.toArray(new String[ids.size()]);
}
public String[] _all_interfaces(org.omg.PortableServer.POA poa, byte[]
objectId) {
return typeIds;
}
public OutputStream _invoke(String operationName, InputStream _in,
ResponseHandler reply) throws SystemException {
try {
// get the method object
Method method = (Method) operations.get(operationName);
if (method == null) {
throw new BAD_OPERATION();
}
org.omg.CORBA_2_3.portable.InputStream in =
(org.omg.CORBA_2_3.portable.InputStream) _in;
// read in all of the arguments
Object[] args = readArguments(method, in);
// invoke the method
Object result = null;
ClassLoader oldClassLoader =
Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(ejbContainer.getClassLoader());
if (log.isDebugEnabled()) log.debug("Calling " +
method.getName());
result = ejbContainer.invoke(method, args, primaryKey);
} catch (TransactionRolledbackException e) {
log.debug("TransactionRolledbackException", e);
throw new TRANSACTION_ROLLEDBACK(e.toString());
} catch (TransactionRequiredException e) {
log.debug("TransactionRequiredException", e);
throw new TRANSACTION_REQUIRED(e.toString());
} catch (InvalidTransactionException e) {
log.debug("InvalidTransactionException", e);
throw new INVALID_TRANSACTION(e.toString());
} catch (NoSuchObjectException e) {
log.debug("NoSuchObjectException", e);
throw new OBJECT_NOT_EXIST(e.toString());
} catch (AccessException e) {
log.debug("AccessException", e);
throw new NO_PERMISSION(e.toString());
} catch (MarshalException e) {
log.debug("MarshalException", e);
throw new MARSHAL(e.toString());
} catch (RemoteException e) {
log.debug("RemoteException", e);
throw new UNKNOWN(e.toString());
} catch (Exception e) {
// all other exceptions are written to stream
// if this is an unknown exception type it will
// be thrown out of writeException
return writeException(method, reply, e);
} finally {
Thread.currentThread().setContextClassLoader(oldClassLoader);
}
// creat the output stream
org.omg.CORBA_2_3.portable.OutputStream out =
(org.omg.CORBA_2_3.portable.OutputStream) reply.createReply();
// write the output value
writeResult(method.getReturnType(), result, out);
return out;
} catch (SystemException ex) {
throw ex;
} catch (Throwable ex) {
throw new UnknownException(ex);
}
}
private Object[] readArguments(Method method,
org.omg.CORBA_2_3.portable.InputStream in) {
Class[] parameterTypes = method.getParameterTypes();
Object[] arguments = new Object[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
Class parameterType = parameterTypes[i];
arguments[i] = readArgument(parameterType, in);
}
return arguments;
}
private Object readArgument(Class type,
org.omg.CORBA_2_3.portable.InputStream in) {
if (type == boolean.class) {
return new Boolean(in.read_boolean());
} else if (type == byte.class) {
return new Byte(in.read_octet());
} else if (type == char.class) {
return new Character(in.read_wchar());
} else if (type == double.class) {
return new Double(in.read_double());
} else if (type == float.class) {
return new Float(in.read_float());
} else if (type == int.class) {
return new Integer(in.read_long());
} else if (type == long.class) {
return new Long(in.read_longlong());
} else if (type == short.class) {
return new Short(in.read_short());
} else if (type == Object.class) {
return Util.readAny(in);
} else if (Remote.class.isAssignableFrom(type)) {
return PortableRemoteObject.narrow(in.read_Object(), type);
} else {
return in.read_value(type);
}
}
private void writeResult(Class type, Object result,
org.omg.CORBA_2_3.portable.OutputStream out) {
if (type == void.class) {
// do nothing for a void
} else if (type == boolean.class) {
out.write_boolean(((Boolean)result).booleanValue());
} else if (type == byte.class) {
out.write_octet(((Byte)result).byteValue());
} else if (type == char.class) {
out.write_wchar(((Character)result).charValue());
} else if (type == double.class) {
out.write_double(((Double)result).doubleValue());
} else if (type == float.class) {
out.write_float(((Float)result).floatValue());
} else if (type == int.class) {
out.write_long(((Integer)result).intValue());
} else if (type == long.class) {
out.write_longlong(((Long)result).longValue());
} else if (type == short.class) {
out.write_short(((Short)result).shortValue());
} else if (type == Object.class) {
Util.writeAny(out, result);
} else if (Remote.class.isAssignableFrom(type)) {
Util.writeRemoteObject(out, result);
} else {
out.write_value((Serializable)result, type);
}
}
private OutputStream writeException(Method method, ResponseHandler reply,
Exception exception) throws Throwable {
Class[] exceptionTypes = method.getExceptionTypes();
for (int i = 0; i < exceptionTypes.length; i++) {
Class exceptionType = exceptionTypes[i];
if (RemoteException.class.isAssignableFrom(exceptionType) ||
RuntimeException.class.isAssignableFrom(exceptionType) ) {
continue;
}
// Determine the exception id
String exceptionName = exceptionType.getName().replace('.', '/');
if (exceptionName.endsWith("Exception")) {
exceptionName = exceptionName.substring(0,
exceptionName.length() - "Exception".length());
}
exceptionName += "Ex";
String id = "IDL:" + exceptionName + ":1.0";
org.omg.CORBA_2_3.portable.OutputStream out =
(org.omg.CORBA_2_3.portable.OutputStream) reply.createExceptionReply();
out.write_string(id);
out.write_value(exception, exceptionType);
return out;
}
throw exception;
}
}