View Javadoc
1   package nl.tudelft.simulation.naming.context;
2   
3   import java.net.InetAddress;
4   import java.net.URL;
5   import java.rmi.ConnectException;
6   import java.rmi.NotBoundException;
7   import java.rmi.registry.LocateRegistry;
8   import java.rmi.registry.Registry;
9   import java.util.Hashtable;
10  import java.util.Iterator;
11  
12  import javax.naming.Context;
13  
14  import org.djutils.logger.CategoryLogger;
15  
16  import nl.tudelft.simulation.naming.context.event.InitialEventContext;
17  
18  /**
19   * A factory for RemoteContextClient instances, automatically invoked by JNDI when the correct jndi.properties file has been
20   * used.
21   * <p>
22   * Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
23   * for project information <a href="https://simulation.tudelft.nl/" target="_blank"> https://simulation.tudelft.nl</a>. The DSOL
24   * project is distributed under a three-clause BSD-style license, which can be found at
25   * <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">
26   * https://https://simulation.tudelft.nl/dsol/docs/latest/license.html</a>.
27   * </p>
28   * @author <a href="https://www.linkedin.com/in/peterhmjacobs">Peter Jacobs </a>
29   * @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
30   */
31  public class RemoteContextFactory implements ContextFactory
32  {
33      /** context refers to the static RemoteContextClient. */
34      private static RemoteContext context = null;
35  
36      /** {@inheritDoc} */
37      @Override
38      public synchronized ContextInterface getInitialContext(final Hashtable<?, ?> environment, final String atomicName)
39      {
40          // If the context is already looked up, let's return immediately
41          if (RemoteContextFactory.context != null)
42          {
43              return RemoteContextFactory.context;
44          }
45  
46          // Let's look for our remote partner
47          try
48          {
49              URL url = new URL(environment.get(Context.PROVIDER_URL).toString());
50              Registry registry = LocateRegistry.getRegistry(url.getHost(), url.getPort());
51  
52              // If there is no registry, registry!=null, so we have to test the registry
53              // to make sure whether there is one or not. We test by requesting a list. This code might be improved.
54              try
55              {
56                  registry.list();
57              }
58              catch (ConnectException connectException)
59              {
60                  // Since we cannot find the registry, we must perhaps create one.
61                  // This is only allowed if the host is our localhost. We cannot create a registry on a remote host.
62                  if (!(url.getHost().equals("localhost") || url.getHost().equals("127.0.0.1")
63                          || url.getHost().equals(InetAddress.getLocalHost().getHostName())
64                          || url.getHost().equals(InetAddress.getLocalHost().getHostAddress())))
65                  {
66                      throw new IllegalArgumentException("cannot create registry on remote host");
67                  }
68                  registry = LocateRegistry.createRegistry(url.getPort());
69              }
70              // We now have a registry. Let's resolve the context object
71  
72              RemoteContext remoteContext = null;
73              try
74              {
75                  remoteContext = (RemoteContext) registry.lookup(url.getFile());
76              }
77              catch (NotBoundException notBoundException)
78              {
79                  // Since we cannot find the context, we must create one.
80                  // This is done based on the java.naming.wrapped properties in jndi.properties
81                  Hashtable<Object, Object> wrappedEnvironment = new Hashtable<Object, Object>();
82                  for (Iterator<?> iterator = environment.keySet().iterator(); iterator.hasNext();)
83                  {
84                      String key = iterator.next().toString();
85                      if (key.equals(InitialEventContext.WRAPPED_CONTEXT_FACTORY))
86                      {
87                          wrappedEnvironment.put(InitialEventContext.INITIAL_CONTEXT_FACTORY, environment.get(key));
88                      }
89                  }
90                  if (wrappedEnvironment.isEmpty())
91                  {
92                      // If we do not throw this exception and accept an empty
93                      // environment, we'll get in an infinite loop
94                      throw new IllegalArgumentException("no wrapped initial context factory defined");
95                  }
96                  ContextInterface wrappedContext = InitialEventContext.instantiate(wrappedEnvironment, atomicName);
97                  remoteContext = new RemoteContext(url, wrappedContext, url.getFile() + "_producer");
98                  // registry.bind(url.getFile(), remoteContext);
99              }
100             RemoteContextFactory.context = remoteContext;
101             return RemoteContextFactory.context;
102         }
103         catch (Exception exception)
104         {
105             CategoryLogger.always().error(exception, "getInitialContext");
106             return null;
107         }
108     }
109 }