1 package org.sapia.ubik.rmi.naming.remote; 2 3 import java.io.IOException ; 4 import java.rmi.RemoteException ; 5 import java.util.Hashtable ; 6 7 import javax.naming.Context ; 8 import javax.naming.InitialContext ; 9 import javax.naming.NamingException ; 10 import javax.naming.spi.InitialContextFactory ; 11 12 import org.sapia.ubik.mcast.AsyncEventListener; 13 import org.sapia.ubik.mcast.EventChannel; 14 import org.sapia.ubik.mcast.RemoteEvent; 15 import org.sapia.ubik.net.TCPAddress; 16 import org.sapia.ubik.net.Uri; 17 import org.sapia.ubik.net.UriSyntaxException; 18 import org.sapia.ubik.rmi.naming.ServiceLocator; 19 import org.sapia.ubik.rmi.naming.remote.proxy.ContextResolver; 20 import org.sapia.ubik.rmi.naming.remote.proxy.DefaultContextResolver; 21 import org.sapia.ubik.rmi.naming.remote.proxy.ReliableLocalContext; 22 import org.sapia.ubik.rmi.server.Log; 23 24 25 117 public class RemoteInitialContextFactory implements InitialContextFactory , Consts { 118 private String _scheme = ServiceLocator.UBIK_SCHEME; 119 120 public RemoteInitialContextFactory() { 121 } 122 123 public RemoteInitialContextFactory(String serviceLocatorScheme) { 124 _scheme = serviceLocatorScheme; 125 } 126 127 130 public Context getInitialContext(Hashtable props) throws NamingException { 131 String url = (String ) props.get(InitialContext.PROVIDER_URL); 132 133 if (url == null) { 134 throw new NamingException (InitialContext.PROVIDER_URL + 135 " property not specified"); 136 } 137 138 Uri uri = null; 139 try{ 140 uri = Uri.parse(url); 141 }catch(UriSyntaxException e){ 142 NamingException ne = new NamingException ("Invalid URL:" + url); 143 ne.setRootCause(e); 144 throw ne; 145 } 146 147 uri.setScheme(_scheme); 148 149 String domain; 150 151 if (props.get(UBIK_DOMAIN_NAME) == null) { 152 domain = JNDIServerHelper.DEFAULT_DOMAIN; 153 } else { 154 domain = (String ) props.get(UBIK_DOMAIN_NAME); 155 } 156 157 String mcastAddr = org.sapia.ubik.rmi.Consts.DEFAULT_MCAST_ADDR; 158 int mcastPort = org.sapia.ubik.rmi.Consts.DEFAULT_MCAST_PORT; 159 160 if (props.get(Consts.MCAST_ADDR_KEY) != null) { 161 mcastAddr = (String ) props.get(MCAST_ADDR_KEY); 162 } 163 164 if (props.get(MCAST_PORT_KEY) != null) { 165 try { 166 mcastPort = Integer.parseInt((String ) props.get(MCAST_PORT_KEY)); 167 } catch (NumberFormatException e) { 168 throw new NamingException ("Invalid multicast port: " + mcastPort); 169 } 170 } 171 172 EventChannel ec = null; 173 RemoteContext ctx = null; 174 ContextResolver resolver = doGetResolver(); 175 176 try{ 177 ec = new EventChannel(domain, mcastAddr, mcastPort); 178 ec.start(); 179 }catch(IOException e){ 180 NamingException ne = new NamingException ("Could not start event channel"); 181 ne.setRootCause(e); 182 throw ne; 183 } 184 185 try { 186 ctx = doGetResolver().resolve(uri.getHost(), uri.getPort()); 187 } catch (RemoteException e) { 188 189 Log.warning(getClass(), "Could not find JNDI server for : " + uri.toString() + "; trying to discover"); 190 BlockingEventListener listener = new BlockingEventListener(); 191 ec.registerAsyncListener(JNDI_SERVER_DISCO, listener); 192 TCPAddress addr = null; 193 try{ 194 ec.dispatch(JNDI_CLIENT_PUBLISH, ""); 195 196 RemoteEvent evt = listener.waitForEvent(10000); 197 ec.unregisterListener(listener); 198 199 if (evt == null) { 200 NamingException ne = new NamingException ( 201 "could not connect to JNDI server"); 202 ne.setRootCause(e); 203 throw ne; 204 } 205 206 addr = (TCPAddress) evt.getData(); 207 208 Log.warning(getClass(), "Disovered JNDI server at : " + addr); 209 ctx = resolver.resolve(addr); 210 return new ReliableLocalContext(ec, uri.toString(), ctx, false, resolver); 211 }catch(Exception e2){ 212 NamingException ne = new NamingException ("Could not connect to remote JNDI server: " + addr); 213 ne.setRootCause(e2); 214 throw ne; 215 } 216 } 217 try{ 218 return new ReliableLocalContext(ec, uri.toString(), ctx, true, resolver); 219 }catch(IOException e){ 220 NamingException ne = new NamingException ("Could not instantiate local context"); 221 ne.setRootCause(e); 222 throw ne; 223 } 224 225 } 226 227 protected ContextResolver doGetResolver(){ 228 return new DefaultContextResolver(); 229 } 230 235 236 static final class BlockingEventListener implements AsyncEventListener { 237 private RemoteEvent _evt; 238 239 BlockingEventListener() { 240 } 241 242 245 public synchronized void onAsyncEvent(RemoteEvent evt) { 246 _evt = evt; 247 notify(); 248 } 249 250 public synchronized RemoteEvent waitForEvent(long timeout) { 251 long start = System.currentTimeMillis(); 252 253 try { 254 while (((System.currentTimeMillis() - start) < timeout) && 255 (_evt == null)) { 256 wait(timeout); 257 } 258 } catch (InterruptedException e) { 259 return null; 260 } 261 262 return _evt; 263 } 264 } 265 } 266 | Popular Tags |