com.atomikos.util.IntraVmObjectFactory Maven / Gradle / Ivy
/**
* Copyright (C) 2000-2020 Atomikos
*
* LICENSE CONDITIONS
*
* See http://www.atomikos.com/Main/WhichLicenseApplies for details.
*/
package com.atomikos.util;
import java.io.Serializable;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
/**
* An intra-VM object factory. Objects registered in the
* IntraVmObjectRegistry can be restored from a reference
* with the help of this factory.
*
*
*/
public class IntraVmObjectFactory implements ObjectFactory
{
private static final String NAME_REF_ADDRESS_TYPE = "uniqueResourceName";
private static SerializableObjectFactory serializableObjectFactory = new SerializableObjectFactory();
//synchronized static to avoid race conditions between concurrent retrievals
@SuppressWarnings("rawtypes")
private static synchronized Object retrieveObjectInstance (
Object obj, Name name, Context nameCtx, Hashtable environment)
throws Exception
{
Object ret = null;
if ( obj instanceof Reference ) {
String resourceName = null;
Reference ref = ( Reference ) obj;
StringRefAddr nameAsRefAddr = ( StringRefAddr ) ref.get ( NAME_REF_ADDRESS_TYPE );
resourceName = (String) nameAsRefAddr.getContent();
try {
ret = IntraVmObjectRegistry.getResource ( resourceName );
} catch ( NameNotFoundException notYetInited ) {
//not registered in this VM -> init and return the deserialized instance
Object resource = serializableObjectFactory.getObjectInstance(obj, name, nameCtx, environment);
IntraVmObjectRegistry.addResource ( resourceName, resource );
ret = resource;
}
}
return ret;
}
public static synchronized Reference createReference ( Serializable object , String name ) throws NamingException
{
Reference ret = null;
if ( object == null ) throw new IllegalArgumentException ( "invalid resource: null" );
if ( name == null ) throw new IllegalArgumentException ( "name should not be null" );
//make sure that lookup works - add the bean to the registry if needed
try {
Object existing = IntraVmObjectRegistry.getResource ( name );
if ( existing != object ) {
//another instance with the same name already there
String msg = "Another resource already exists with name " + name + " - pick a different name";
throw new NamingException ( msg );
}
} catch ( NameNotFoundException notThere ) {
// make sure this bean is registered for JNDI lookups to find the same instance
// otherwise, concurrent lookups would create race conditions during init
// and the thread that creates a bean might not be able to use it (unfair?)
IntraVmObjectRegistry.addResource ( name , object );
}
ret = SerializableObjectFactory.createReference ( object , IntraVmObjectFactory.class.getName() );
//also add the unique resource name for helping during retrieval
ret.add ( new StringRefAddr ( NAME_REF_ADDRESS_TYPE , name ) );
return ret;
}
@SuppressWarnings("rawtypes")
public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception
{
return retrieveObjectInstance(obj, name, nameCtx, environment);
}
}