RemoteContextFactory.java
package nl.tudelft.simulation.naming.context;
import java.net.InetAddress;
import java.net.URL;
import java.rmi.ConnectException;
import java.rmi.NotBoundException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.Hashtable;
import java.util.Iterator;
import javax.naming.Context;
import org.djutils.logger.CategoryLogger;
import nl.tudelft.simulation.naming.context.event.InitialEventContext;
/**
* A factory for RemoteContextClient instances, automatically invoked by JNDI when the correct jndi.properties file has been
* used.
* <p>
* Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
* for project information <a href="https://simulation.tudelft.nl/" target="_blank"> https://simulation.tudelft.nl</a>. The DSOL
* project is distributed under a three-clause BSD-style license, which can be found at
* <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">
* https://https://simulation.tudelft.nl/dsol/docs/latest/license.html</a>.
* </p>
* @author <a href="https://www.linkedin.com/in/peterhmjacobs">Peter Jacobs </a>
* @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
*/
public class RemoteContextFactory implements ContextFactory
{
/** context refers to the static RemoteContextClient. */
private static RemoteContext context = null;
/** {@inheritDoc} */
@Override
public synchronized ContextInterface getInitialContext(final Hashtable<?, ?> environment, final String atomicName)
{
// If the context is already looked up, let's return immediately
if (RemoteContextFactory.context != null)
{
return RemoteContextFactory.context;
}
// Let's look for our remote partner
try
{
URL url = new URL(environment.get(Context.PROVIDER_URL).toString());
Registry registry = LocateRegistry.getRegistry(url.getHost(), url.getPort());
// If there is no registry, registry!=null, so we have to test the registry
// to make sure whether there is one or not. We test by requesting a list. This code might be improved.
try
{
registry.list();
}
catch (ConnectException connectException)
{
// Since we cannot find the registry, we must perhaps create one.
// This is only allowed if the host is our localhost. We cannot create a registry on a remote host.
if (!(url.getHost().equals("localhost") || url.getHost().equals("127.0.0.1")
|| url.getHost().equals(InetAddress.getLocalHost().getHostName())
|| url.getHost().equals(InetAddress.getLocalHost().getHostAddress())))
{
throw new IllegalArgumentException("cannot create registry on remote host");
}
registry = LocateRegistry.createRegistry(url.getPort());
}
// We now have a registry. Let's resolve the context object
RemoteContext remoteContext = null;
try
{
remoteContext = (RemoteContext) registry.lookup(url.getFile());
}
catch (NotBoundException notBoundException)
{
// Since we cannot find the context, we must create one.
// This is done based on the java.naming.wrapped properties in jndi.properties
Hashtable<Object, Object> wrappedEnvironment = new Hashtable<Object, Object>();
for (Iterator<?> iterator = environment.keySet().iterator(); iterator.hasNext();)
{
String key = iterator.next().toString();
if (key.equals(InitialEventContext.WRAPPED_CONTEXT_FACTORY))
{
wrappedEnvironment.put(InitialEventContext.INITIAL_CONTEXT_FACTORY, environment.get(key));
}
}
if (wrappedEnvironment.isEmpty())
{
// If we do not throw this exception and accept an empty
// environment, we'll get in an infinite loop
throw new IllegalArgumentException("no wrapped initial context factory defined");
}
ContextInterface wrappedContext = InitialEventContext.instantiate(wrappedEnvironment, atomicName);
remoteContext = new RemoteContext(url, wrappedContext, url.getFile() + "_producer");
// registry.bind(url.getFile(), remoteContext);
}
RemoteContextFactory.context = remoteContext;
return RemoteContextFactory.context;
}
catch (Exception exception)
{
CategoryLogger.always().error(exception, "getInitialContext");
return null;
}
}
}