package org.jboss.proxy.ejb;
import java.security.Principal;
import java.util.Map;
import javax.ejb.HomeHandle;
import javax.management.MBeanException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.transaction.Transaction;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.InterfaceDef;
import org.omg.CORBA.ORBPackage.InvalidName;
import org.omg.CORBA.portable.InvokeHandler;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ResponseHandler;
import org.omg.PortableServer.POA;
import org.omg.CSI.IdentityToken;
import org.jboss.iiop.CorbaORB;
import org.jboss.iiop.csiv2.SASCurrent;
import org.jboss.iiop.rmi.RmiIdlUtil;
import org.jboss.iiop.rmi.marshal.strategy.SkeletonStrategy;
import org.jboss.invocation.Invocation;
import org.jboss.invocation.InvocationContext;
import org.jboss.invocation.InvocationKey;
import org.jboss.invocation.InvocationType;
import org.jboss.invocation.PayloadKey;
import org.jboss.invocation.iiop.ServantWithMBeanServer;
import org.jboss.logging.Logger;
import org.jboss.tm.iiop.TxServerInterceptor;
import org.jboss.security.SimplePrincipal;
public class EjbHomeCorbaServant
extends ServantWithMBeanServer
implements InvokeHandler, LocalIIOPInvoker {
private final ObjectName containerName;
private final ClassLoader containerClassLoader;
private final Map methodInvokerMap;
private final String[] repositoryIds;
private final InterfaceDef interfaceDef;
private final Logger logger;
private final boolean traceEnabled;
private HomeHandle homeHandle = null;
private MBeanServer mbeanServer;
private SASCurrent sasCurrent;
public EjbHomeCorbaServant(ObjectName containerName,
ClassLoader containerClassLoader,
Map methodInvokerMap,
String[] repositoryIds,
InterfaceDef interfaceDef,
Logger logger)
{
this.containerName = containerName;
this.containerClassLoader = containerClassLoader;
this.methodInvokerMap = methodInvokerMap;
this.repositoryIds = repositoryIds;
this.interfaceDef = interfaceDef;
this.logger = logger;
this.traceEnabled = logger.isTraceEnabled();
try
{
this.sasCurrent = (SASCurrent)
CorbaORB.getInstance().resolve_initial_references("SASCurrent");
}
catch (InvalidName invalidName)
{
this.sasCurrent = null;
}
}
public void setHomeHandle(HomeHandle homeHandle)
{
this.homeHandle = homeHandle;
}
public void setMBeanServer(MBeanServer mbeanServer)
{
this.mbeanServer = mbeanServer;
}
public org.omg.CORBA.Object _get_interface_def()
{
if (interfaceDef != null)
return interfaceDef;
else
return super._get_interface_def();
}
public String[] _all_interfaces(POA poa, byte[] objectId)
{
return (String[])repositoryIds.clone();
}
public OutputStream _invoke(String opName,
InputStream in,
ResponseHandler handler)
{
if (traceEnabled) {
logger.trace("EJBHome invocation: " + opName);
}
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(containerClassLoader);
try {
SkeletonStrategy op = (SkeletonStrategy) methodInvokerMap.get(opName);
if (op == null) {
logger.debug("Unable to find opname '" + opName + "' valid operations:" + methodInvokerMap.keySet());
throw new BAD_OPERATION(opName);
}
org.omg.CORBA_2_3.portable.OutputStream out;
try {
Object retVal;
if (opName.equals("_get_homeHandle"))
{
retVal = homeHandle;
}
else
{
Transaction tx = TxServerInterceptor.getCurrentTransaction();
SimplePrincipal principal = null;
char[] password = null;
if (sasCurrent != null)
{
byte[] username = sasCurrent.get_incoming_username();
byte[] credential = sasCurrent.get_incoming_password();
String name = new String(username, "UTF-8");
int domainIndex = name.indexOf('@');
if (domainIndex > 0)
name = name.substring(0, domainIndex);
if (name.length() == 0)
{
byte[] incomingName =
sasCurrent.get_incoming_principal_name();
if (incomingName.length > 0)
{
name = new String(incomingName, "UTF-8");
domainIndex = name.indexOf('@');
if (domainIndex > 0)
name = name.substring(0, domainIndex);
principal = new SimplePrincipal(name);
password = name.toCharArray();
}
}
else
{
principal = new SimplePrincipal(name);
password = new String(credential, "UTF-8").toCharArray();
}
}
Object[] params = op.readParams(
(org.omg.CORBA_2_3.portable.InputStream)in);
Invocation inv = new Invocation(null,
op.getMethod(),
params,
tx,
principal,
password );
inv.setValue(InvocationKey.INVOKER_PROXY_BINDING,
"iiop",
PayloadKey.AS_IS);
inv.setType(InvocationType.HOME);
retVal = mbeanServer.invoke(containerName,
"invoke",
new Object[] {inv},
Invocation.INVOKE_SIGNATURE);
}
out = (org.omg.CORBA_2_3.portable.OutputStream)
handler.createReply();
if (op.isNonVoid()) {
op.writeRetval(out, retVal);
}
}
catch (Exception e) {
if (traceEnabled) {
logger.trace("Exception in EJBHome invocation", e);
}
if (e instanceof MBeanException) {
e = ((MBeanException)e).getTargetException();
}
RmiIdlUtil.rethrowIfCorbaSystemException(e);
out = (org.omg.CORBA_2_3.portable.OutputStream)
handler.createExceptionReply();
op.writeException(out, e);
}
return out;
}
finally {
Thread.currentThread().setContextClassLoader(oldCl);
}
}
public Object invoke(String opName,
Object[] arguments,
Transaction tx,
Principal identity,
Object credential)
throws Exception
{
if (traceEnabled) {
logger.trace("EJBHome local invocation: " + opName);
}
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(containerClassLoader);
try {
SkeletonStrategy op =
(SkeletonStrategy) methodInvokerMap.get(opName);
if (op == null) {
throw new BAD_OPERATION(opName);
}
Invocation inv = new Invocation(null,
op.getMethod(),
arguments,
tx,
null,
null );
inv.setValue(InvocationKey.INVOKER_PROXY_BINDING,
"iiop",
PayloadKey.AS_IS);
inv.setType(InvocationType.HOME);
return mbeanServer.invoke(containerName,
"invoke",
new Object[] {inv},
Invocation.INVOKE_SIGNATURE);
}
catch (MBeanException e) {
throw e.getTargetException();
}
finally {
Thread.currentThread().setContextClassLoader(oldCl);
}
}
}