package org.jboss.invocation.iiop;
import java.net.InetAddress;
import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
import org.omg.CORBA.LocalObject;
import org.omg.CORBA.Policy;
import org.omg.CORBA.SetOverrideType;
import org.omg.CORBA.UNKNOWN;
import org.omg.PortableServer.IdAssignmentPolicyValue;
import org.omg.PortableServer.IdUniquenessPolicyValue;
import org.omg.PortableServer.LifespanPolicyValue;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;
import org.omg.PortableServer.RequestProcessingPolicyValue;
import org.omg.PortableServer.Servant;
import org.omg.PortableServer.ServantLocator;
import org.omg.PortableServer.ServantLocatorPackage.CookieHolder;
import org.omg.PortableServer.ServantRetentionPolicyValue;
import org.jboss.iiop.CorbaORBService;
import org.jboss.naming.Util;
import org.jboss.system.ServiceMBeanSupport;
import org.jboss.system.Registry;
public class IIOPInvoker
extends ServiceMBeanSupport
implements IIOPInvokerMBean, ServantRegistries, ObjectFactory
{
private static IIOPInvoker theIIOPInvoker;
private POA rootPOA;
private ServantRegistry registryWithSharedTransientPOA;
private POA transientPOA;
private Map transientServantMap;
private ServantRegistry registryWithSharedPersistentPOA;
private POA persistentPOA;
private Map persistentServantMap;
private ServantRegistry registryWithTransientPOAPerServant;
private Map transientPoaMap;
private Policy[] transientPoaPolicies;
private ServantRegistry registryWithPersistentPOAPerServant;
private Map persistentPoaMap;
private Policy[] persistentPoaPolicies;
public void createService()
throws Exception
{
theIIOPInvoker = this;
transientServantMap = Collections.synchronizedMap(new HashMap());
persistentServantMap = Collections.synchronizedMap(new HashMap());
transientPoaMap = Collections.synchronizedMap(new HashMap());
persistentPoaMap = Collections.synchronizedMap(new HashMap());
}
public void startService()
throws Exception
{
try {
rootPOA = (POA)new InitialContext().lookup("java:/"
+ CorbaORBService.POA_NAME);
}
catch (NamingException e) {
throw new RuntimeException("Cannot lookup java:/"
+ CorbaORBService.POA_NAME + ": " + e);
}
transientPoaPolicies = new Policy[] {
rootPOA.create_lifespan_policy(
LifespanPolicyValue.TRANSIENT),
rootPOA.create_id_assignment_policy(
IdAssignmentPolicyValue.USER_ID),
rootPOA.create_servant_retention_policy(
ServantRetentionPolicyValue.NON_RETAIN),
rootPOA.create_request_processing_policy(
RequestProcessingPolicyValue.USE_DEFAULT_SERVANT),
rootPOA.create_id_uniqueness_policy(
IdUniquenessPolicyValue.MULTIPLE_ID),
};
persistentPoaPolicies = new Policy[] {
rootPOA.create_lifespan_policy(
LifespanPolicyValue.PERSISTENT),
rootPOA.create_id_assignment_policy(
IdAssignmentPolicyValue.USER_ID),
rootPOA.create_servant_retention_policy(
ServantRetentionPolicyValue.NON_RETAIN),
rootPOA.create_request_processing_policy(
RequestProcessingPolicyValue.USE_DEFAULT_SERVANT),
rootPOA.create_id_uniqueness_policy(
IdUniquenessPolicyValue.MULTIPLE_ID),
};
Policy[] policies = new Policy[] {
rootPOA.create_lifespan_policy(
LifespanPolicyValue.TRANSIENT),
rootPOA.create_id_assignment_policy(
IdAssignmentPolicyValue.USER_ID),
rootPOA.create_servant_retention_policy(
ServantRetentionPolicyValue.NON_RETAIN),
rootPOA.create_request_processing_policy(
RequestProcessingPolicyValue.USE_SERVANT_MANAGER),
rootPOA.create_id_uniqueness_policy(
IdUniquenessPolicyValue.MULTIPLE_ID)
};
transientPOA = rootPOA.create_POA("TPOA", null, policies);
transientPOA.set_servant_manager(new TransientServantLocator());
policies[0] = rootPOA.create_lifespan_policy(
LifespanPolicyValue.PERSISTENT);
persistentPOA = rootPOA.create_POA("PPOA", null, policies);
persistentPOA.set_servant_manager(new PersistentServantLocator());
registryWithSharedTransientPOA =
new ServantRegistryWithSharedTransientPOA();
registryWithSharedPersistentPOA =
new ServantRegistryWithSharedPersistentPOA();
registryWithTransientPOAPerServant =
new ServantRegistryWithTransientPOAPerServant();
registryWithPersistentPOAPerServant =
new ServantRegistryWithPersistentPOAPerServant();
Registry.bind(getServiceName(), this);
transientPOA.the_POAManager().activate();
persistentPOA.the_POAManager().activate();
Context context = new InitialContext();
Util.rebind(
context,
"invokers/" + InetAddress.getLocalHost().getHostName() + "/iiop",
new Reference(getClass().getName(),
getClass().getName(),
null));
if (getLog().isDebugEnabled())
getLog().debug("Bound IIOP invoker for JMX node");
}
public void stopService()
throws Exception
{
try {
transientPOA.the_POAManager().deactivate(
false,
true );
persistentPOA.the_POAManager().deactivate(
false,
true );
transientPOA.destroy(false,
false );
persistentPOA.destroy(false,
false );
}
catch (AdapterInactive adapterInactive) {
getLog().error("Cannot deactivate home POA", adapterInactive);
}
}
private static Policy[] concatPolicies(Policy[] policies1,
Policy[] policies2)
{
Policy[] policies = new Policy[policies1.length + policies2.length];
int j = 0;
for (int i = 0; i < policies1.length; i++, j++) {
policies[j] = policies1[i];
}
for (int i = 0; i < policies2.length; i++, j++) {
policies[j] = policies2[i];
}
return policies;
}
public ServantRegistry getServantRegistry(ServantRegistryKind kind)
{
if (kind == ServantRegistryKind.SHARED_TRANSIENT_POA) {
return registryWithSharedTransientPOA;
}
else if (kind == ServantRegistryKind.SHARED_PERSISTENT_POA) {
return registryWithSharedPersistentPOA;
}
else if (kind == ServantRegistryKind.TRANSIENT_POA_PER_SERVANT) {
return registryWithTransientPOAPerServant;
}
else if (kind == ServantRegistryKind.PERSISTENT_POA_PER_SERVANT) {
return registryWithPersistentPOAPerServant;
}
else {
return null;
}
}
public Object getObjectInstance(Object obj, Name name,
Context nameCtx, Hashtable environment)
throws Exception
{
String s = name.toString();
if (getLog().isTraceEnabled())
getLog().trace("getObjectInstance: obj.getClass().getName=\"" +
obj.getClass().getName() +
"\n name=" + s);
if (s.equals("iiop"))
return theIIOPInvoker;
else
return null;
}
static class PoaAndPoliciesReferenceFactory
implements ReferenceFactory
{
private POA poa;
private String servantName;
private Policy[] policies;
private byte[] servantId;
PoaAndPoliciesReferenceFactory(POA poa,
String servantName, Policy[] policies)
{
this.poa = poa;
this.servantName = servantName;
this.policies = policies;
servantId = ReferenceData.create(servantName);
}
PoaAndPoliciesReferenceFactory(POA poa, Policy[] policies)
{
this(poa, null, policies);
}
public org.omg.CORBA.Object createReference(String interfId)
throws Exception
{
org.omg.CORBA.Object corbaRef =
poa.create_reference_with_id(servantId, interfId);
return corbaRef._set_policy_override(policies,
SetOverrideType.ADD_OVERRIDE);
}
public org.omg.CORBA.Object createReferenceWithId(Object id,
String interfId)
throws Exception
{
byte[] referenceData =
(servantName == null) ? ReferenceData.create(id)
: ReferenceData.create(servantName, id);
org.omg.CORBA.Object corbaRef =
poa.create_reference_with_id(referenceData, interfId);
return corbaRef._set_policy_override(policies,
SetOverrideType.ADD_OVERRIDE);
}
public POA getPOA()
{
return poa;
}
}
static class PoaReferenceFactory
implements ReferenceFactory
{
private POA poa;
private String servantName;
private byte[] servantId;
PoaReferenceFactory(POA poa, String servantName)
{
this.poa = poa;
this.servantName = servantName;
servantId = ReferenceData.create(servantName);
}
PoaReferenceFactory(POA poa)
{
this(poa, null);
}
public org.omg.CORBA.Object createReference(String interfId)
throws Exception
{
return poa.create_reference_with_id(servantId, interfId);
}
public org.omg.CORBA.Object createReferenceWithId(Object id,
String interfId)
throws Exception
{
byte[] referenceData =
(servantName == null) ? ReferenceData.create(id)
: ReferenceData.create(servantName, id);
return poa.create_reference_with_id(referenceData, interfId);
}
public POA getPOA()
{
return poa;
}
}
class ServantRegistryWithSharedTransientPOA
implements ServantRegistry
{
public ReferenceFactory bind(String name,
Servant servant,
Policy[] policies)
{
if (servant instanceof ServantWithMBeanServer) {
((ServantWithMBeanServer)servant).setMBeanServer(getServer());
}
transientServantMap.put(name, servant);
return new PoaAndPoliciesReferenceFactory(transientPOA,
name, policies);
}
public ReferenceFactory bind(String name, Servant servant)
{
if (servant instanceof ServantWithMBeanServer) {
((ServantWithMBeanServer)servant).setMBeanServer(getServer());
}
transientServantMap.put(name, servant);
return new PoaReferenceFactory(transientPOA, name);
}
public void unbind(String name)
{
transientServantMap.remove(name);
}
}
class ServantRegistryWithSharedPersistentPOA
implements ServantRegistry
{
public ReferenceFactory bind(String name,
Servant servant,
Policy[] policies)
{
if (servant instanceof ServantWithMBeanServer) {
((ServantWithMBeanServer)servant).setMBeanServer(getServer());
}
persistentServantMap.put(name, servant);
return new PoaAndPoliciesReferenceFactory(persistentPOA,
name, policies);
}
public ReferenceFactory bind(String name, Servant servant)
{
if (servant instanceof ServantWithMBeanServer) {
((ServantWithMBeanServer)servant).setMBeanServer(getServer());
}
persistentServantMap.put(name, servant);
return new PoaReferenceFactory(persistentPOA, name);
}
public void unbind(String name)
{
persistentServantMap.remove(name);
}
}
class ServantRegistryWithTransientPOAPerServant
implements ServantRegistry
{
public ReferenceFactory bind(String name,
Servant servant,
Policy[] policies)
throws Exception
{
if (servant instanceof ServantWithMBeanServer) {
((ServantWithMBeanServer)servant).setMBeanServer(getServer());
}
Policy[] poaPolicies = concatPolicies(transientPoaPolicies, policies);
POA poa = rootPOA.create_POA(name, null, poaPolicies);
transientPoaMap.put(name, poa);
poa.set_servant(servant);
poa.the_POAManager().activate();
return new PoaReferenceFactory(poa); }
public ReferenceFactory bind(String name, Servant servant)
throws Exception
{
if (servant instanceof ServantWithMBeanServer) {
((ServantWithMBeanServer)servant).setMBeanServer(getServer());
}
POA poa = rootPOA.create_POA(name, null, transientPoaPolicies);
transientPoaMap.put(name, poa);
poa.set_servant(servant);
poa.the_POAManager().activate();
return new PoaReferenceFactory(poa); }
public void unbind(String name)
throws Exception
{
POA poa = (POA) transientPoaMap.remove(name);
if (poa != null) {
poa.the_POAManager().deactivate(false,
true );
poa.destroy(false,
false );
}
}
}
class ServantRegistryWithPersistentPOAPerServant
implements ServantRegistry
{
public ReferenceFactory bind(String name,
Servant servant,
Policy[] policies)
throws Exception
{
if (servant instanceof ServantWithMBeanServer) {
((ServantWithMBeanServer)servant).setMBeanServer(getServer());
}
Policy[] poaPolicies =
concatPolicies(persistentPoaPolicies, policies);
POA poa = rootPOA.create_POA(name, null, poaPolicies);
persistentPoaMap.put(name, poa);
poa.set_servant(servant);
poa.the_POAManager().activate();
return new PoaReferenceFactory(poa); }
public ReferenceFactory bind(String name, Servant servant)
throws Exception
{
if (servant instanceof ServantWithMBeanServer) {
((ServantWithMBeanServer)servant).setMBeanServer(getServer());
}
POA poa = rootPOA.create_POA(name, null, persistentPoaPolicies);
persistentPoaMap.put(name, poa);
poa.set_servant(servant);
poa.the_POAManager().activate();
return new PoaReferenceFactory(poa); }
public void unbind(String name)
throws Exception
{
POA poa = (POA) persistentPoaMap.remove(name);
if (poa != null) {
poa.the_POAManager().deactivate(false,
true );
poa.destroy(false,
false );
}
}
}
class TransientServantLocator
extends LocalObject
implements ServantLocator
{
public Servant preinvoke(byte[] oid,
POA adapter,
String operation,
CookieHolder the_cookie)
{
try {
the_cookie.value = null;
Object id = ReferenceData.extractServantId(oid);
return (Servant)transientServantMap.get(id);
}
catch (Exception e) {
getLog().trace("Unexpected exception in preinvoke:", e);
throw new UNKNOWN(e.toString());
}
}
public void postinvoke(byte[] oid,
POA adapter,
String operation,
Object the_cookie,
Servant the_servant)
{
}
}
class PersistentServantLocator
extends LocalObject
implements ServantLocator
{
public Servant preinvoke(byte[] oid,
POA adapter,
String operation,
CookieHolder the_cookie)
{
try {
the_cookie.value = null;
Object id = ReferenceData.extractServantId(oid);
return (Servant)persistentServantMap.get(id);
}
catch (Exception e) {
getLog().trace("Unexpected exception in preinvoke:", e);
throw new UNKNOWN(e.toString());
}
}
public void postinvoke(byte[] oid,
POA adapter,
String operation,
Object the_cookie,
Servant the_servant)
{
}
}
}