package org.jnp.interfaces;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.Socket;
import java.net.InetSocketAddress;
import java.rmi.ConnectException;
import java.rmi.MarshalledObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.StringTokenizer;
import javax.naming.Binding;
import javax.naming.CannotProceedException;
import javax.naming.CommunicationException;
import javax.naming.ConfigurationException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.InvalidNameException;
import javax.naming.LinkRef;
import javax.naming.Name;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NotContextException;
import javax.naming.OperationNotSupportedException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.ServiceUnavailableException;
import javax.naming.spi.NamingManager;
import javax.naming.spi.ResolveResult;
import javax.net.SocketFactory;
import org.jboss.logging.Logger;
public class NamingContext
implements Context, java.io.Serializable
{
static final long serialVersionUID = 8906455608484282128L;
public static final String JNP_SOCKET_FACTORY = "jnp.socketFactory";
public static final String JNP_LOCAL_ADDRESS = "jnp.localAddress";
public static final String JNP_LOCAL_PORT = "jnp.localPort";
public static final String JNP_DISABLE_DISCOVERY = "jnp.disableDiscovery";
public static final String JNP_PARTITION_NAME = "jnp.partitionName";
public static final String JNP_DISCOVERY_GROUP = "jnp.discoveryGroup";
public static final String JNP_DISCOVERY_PORT = "jnp.discoveryPort";
public static final String JNP_DISCOVERY_TTL = "jnp.discoveryTTL";
public static final String JNP_DISCOVERY_TIMEOUT = "jnp.discoveryTimeout";
public static final String JNP_PARSED_NAME = "jnp.parsedName";
public static final String JNP_USE_RELATIVE_NAME = "jnp.useRelativeName";
public static final String JNP_MAX_RETRIES = "jnp.maxRetries";
public final static String DEFAULT_DISCOVERY_GROUP_ADDRESS = "230.0.0.4";
public final static int DEFAULT_DISCOVERY_GROUP_PORT = 1102;
public final static int DEFAULT_DISCOVERY_TIMEOUT = 5000;
public static int MAX_RETRIES = 1;
private static Logger log = Logger.getLogger(NamingContext.class);
public static Hashtable haServers = new Hashtable();
public static void setHANamingServerForPartition(String partitionName, Naming haServer)
{
haServers.put(partitionName, haServer);
}
public static void removeHANamingServerForPartition(String partitionName)
{
haServers.remove(partitionName);
}
public static Naming getHANamingServerForPartition(String partitionName)
{
return (Naming) haServers.get(partitionName);
}
public static Naming localServer;
Naming naming;
Hashtable env;
Name prefix;
NameParser parser = new NamingParser();
static HashMap cachedServers = new HashMap();
static void addServer(String name, Naming server)
{
synchronized (NamingContext.class)
{
cachedServers.put(name, new WeakReference(server));
}
}
static Naming getServer(String host, int port, Hashtable serverEnv)
throws NamingException
{
String hostKey = host + ":" + port;
WeakReference ref = (WeakReference) cachedServers.get(hostKey);
Naming server;
if (ref != null)
{
server = (Naming) ref.get();
if (server != null)
{
return server;
}
}
try
{
SocketFactory factory = loadSocketFactory(serverEnv);
Socket s;
try
{
InetAddress localAddr = null;
int localPort = 0;
String localAddrStr = (String) serverEnv.get(JNP_LOCAL_ADDRESS);
String localPortStr = (String) serverEnv.get(JNP_LOCAL_PORT);
if (localAddrStr != null)
localAddr = InetAddress.getByName(localAddrStr);
if (localPortStr != null)
localPort = Integer.parseInt(localPortStr);
s = factory.createSocket(host, port, localAddr, localPort);
}
catch (IOException e)
{
NamingException ex = new ServiceUnavailableException("Failed to connect to server " + hostKey);
ex.setRootCause(e);
throw ex;
}
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
ObjectInputStream in = new ObjectInputStream(bis);
MarshalledObject stub = (MarshalledObject) in.readObject();
server = (Naming) stub.get();
s.close();
addServer(hostKey, server);
serverEnv.put("hostKey", hostKey);
return server;
}
catch (IOException e)
{
NamingException ex = new CommunicationException("Failed to retrieve stub from server " + hostKey);
ex.setRootCause(e);
throw ex;
}
catch (Exception e)
{
NamingException ex = new CommunicationException("Failed to connect to server " + hostKey);
ex.setRootCause(e);
throw ex;
}
}
static SocketFactory loadSocketFactory(Hashtable serverEnv)
throws ClassNotFoundException, IllegalAccessException,
InstantiationException, InvocationTargetException
{
SocketFactory factory = null;
String socketFactoryName = (String) serverEnv.get(JNP_SOCKET_FACTORY);
if (socketFactoryName == null ||
socketFactoryName.equals(TimedSocketFactory.class.getName()))
{
factory = new TimedSocketFactory(serverEnv);
return factory;
}
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class factoryClass = loader.loadClass(socketFactoryName);
try
{
Class[] ctorSig = {Hashtable.class};
Constructor ctor = factoryClass.getConstructor(ctorSig);
Object[] ctorArgs = {serverEnv};
factory = (SocketFactory) ctor.newInstance(ctorArgs);
}
catch (NoSuchMethodException e)
{
factory = (SocketFactory) factoryClass.newInstance();
}
return factory;
}
static void removeServer(Hashtable serverEnv)
{
String host = "localhost";
int port = 1099;
if (serverEnv.get(Context.PROVIDER_URL) != null)
{
String providerURL = (String) serverEnv.get(Context.PROVIDER_URL);
StringTokenizer tokenizer = new StringTokenizer(providerURL, ",");
while (tokenizer.hasMoreElements())
{
String url = tokenizer.nextToken();
try
{
Name urlAsName = new NamingParser().parse(url);
String server = parseNameForScheme(urlAsName, null);
if (server != null)
url = server;
int colon = url.indexOf(':');
if (colon < 0)
{
host = url;
}
else
{
host = url.substring(0, colon).trim();
try
{
port = Integer.parseInt(url.substring(colon + 1).trim());
}
catch (Exception ex)
{
}
}
synchronized (NamingContext.class)
{
cachedServers.remove(host + ":" + port);
}
}
catch (NamingException ignored)
{
}
}
Object hostKey = serverEnv.remove("hostKey");
if (hostKey != null)
{
synchronized (NamingContext.class)
{
cachedServers.remove(hostKey);
}
}
}
else
{
}
}
static String parseNameForScheme(Name n, Hashtable nameEnv)
throws InvalidNameException
{
String serverInfo = null;
if (n.size() > 0)
{
String scheme = n.get(0);
int schemeLength = 0;
if (scheme.startsWith("java:"))
schemeLength = 5;
else if (scheme.startsWith("jnp:"))
schemeLength = 4;
else if (scheme.startsWith("jnps:"))
schemeLength = 5;
else if (scheme.startsWith("jnp-http:"))
schemeLength = 9;
else if (scheme.startsWith("jnp-https:"))
schemeLength = 10;
if (schemeLength > 0)
{
n = (Name) n.clone();
String suffix = scheme.substring(schemeLength);
if (suffix.length() == 0)
{
n.remove(0);
if (n.size() > 1 && n.get(0).equals(""))
{
serverInfo = n.get(1);
n.remove(0);
n.remove(0);
if (n.size() == 1 && n.get(0).length() == 0)
n.remove(0);
}
}
else
{
n.remove(0);
n.add(0, suffix);
}
if (nameEnv != null)
nameEnv.put(JNP_PARSED_NAME, n);
}
}
return serverInfo;
}
public static void setLocal(Naming server)
{
localServer = server;
}
public NamingContext(Hashtable e, Name baseName, Naming server)
throws NamingException
{
if (baseName == null)
this.prefix = parser.parse("");
else
this.prefix = baseName;
if (e != null)
this.env = (Hashtable) e.clone();
else
this.env = new Hashtable();
this.naming = server;
}
public Naming getNaming()
{
return this.naming;
}
public void setNaming(Naming server)
{
this.naming = server;
}
public void rebind(String name, Object obj)
throws NamingException
{
rebind(getNameParser(name).parse(name), obj);
}
public void rebind(Name name, Object obj)
throws NamingException
{
Hashtable refEnv = getEnv(name);
checkRef(refEnv);
Name parsedName = (Name) refEnv.get(JNP_PARSED_NAME);
if (parsedName != null)
name = parsedName;
obj = getStateToBind(obj, name, refEnv);
try
{
String className;
if (obj instanceof Referenceable)
obj = ((Referenceable) obj).getReference();
if (!(obj instanceof Reference))
{
className = obj.getClass().getName();
obj = new MarshalledValuePair(obj);
}
else
{
className = ((Reference) obj).getClassName();
}
naming.rebind(getAbsoluteName(name), obj, className);
}
catch (CannotProceedException cpe)
{
cpe.setEnvironment(refEnv);
Context cctx = NamingManager.getContinuationContext(cpe);
cctx.rebind(cpe.getRemainingName(), obj);
}
catch (IOException e)
{
naming = null;
removeServer(refEnv);
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
}
public void bind(String name, Object obj)
throws NamingException
{
bind(getNameParser(name).parse(name), obj);
}
public void bind(Name name, Object obj)
throws NamingException
{
Hashtable refEnv = getEnv(name);
checkRef(refEnv);
Name parsedName = (Name) refEnv.get(JNP_PARSED_NAME);
if (parsedName != null)
name = parsedName;
obj = getStateToBind(obj, name, refEnv);
try
{
String className;
if (obj instanceof Referenceable)
obj = ((Referenceable) obj).getReference();
if (!(obj instanceof Reference))
{
className = obj.getClass().getName();
obj = new MarshalledValuePair(obj);
}
else
{
className = ((Reference) obj).getClassName();
}
name = getAbsoluteName(name);
naming.bind(name, obj, className);
}
catch (CannotProceedException cpe)
{
cpe.setEnvironment(refEnv);
Context cctx = NamingManager.getContinuationContext(cpe);
cctx.bind(cpe.getRemainingName(), obj);
}
catch (IOException e)
{
naming = null;
removeServer(refEnv);
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
}
public Object lookup(String name)
throws NamingException
{
return lookup(getNameParser(name).parse(name));
}
public Object lookup(Name name)
throws NamingException
{
Hashtable refEnv = getEnv(name);
checkRef(refEnv);
Name parsedName = (Name) refEnv.get(JNP_PARSED_NAME);
if (parsedName != null)
name = parsedName;
if (name.isEmpty())
return new NamingContext(refEnv, prefix, naming);
try
{
int maxTries = 1;
try
{
String n = (String) refEnv.get(JNP_MAX_RETRIES);
if( n != null )
maxTries = Integer.parseInt(n);
if( maxTries <= 0 )
maxTries = 1;
}
catch(Exception e)
{
log.debug("Failed to get JNP_MAX_RETRIES, using 1", e);
}
Name n = getAbsoluteName(name);
Object res = null;
boolean trace = log.isTraceEnabled();
for (int i = 0; i < maxTries; i++)
{
try
{
res = naming.lookup(n);
break;
}
catch (ConnectException ce)
{
int retries = maxTries - i - 1;
if( trace )
log.trace("Connect failed, retry count: "+retries, ce);
if (retries > 0)
{
try
{
Thread.sleep(1);
}
catch (InterruptedException ignored)
{
}
continue;
}
throw ce;
}
}
if (res instanceof MarshalledValuePair)
{
MarshalledValuePair mvp = (MarshalledValuePair) res;
Object storedObj = mvp.get();
return getObjectInstanceWrapFailure(storedObj, name, refEnv);
}
else if (res instanceof MarshalledObject)
{
MarshalledObject mo = (MarshalledObject) res;
return mo.get();
}
else if (res instanceof Context)
{
Enumeration keys = refEnv.keys();
while (keys.hasMoreElements())
{
String key = (String) keys.nextElement();
((Context) res).addToEnvironment(key, refEnv.get(key));
}
return res;
}
else if (res instanceof ResolveResult)
{
ResolveResult rr = (ResolveResult) res;
Object resolveRes = rr.getResolvedObj();
Object context;
Object instanceID;
if (resolveRes instanceof LinkRef)
{
context = resolveLink(resolveRes, null);
instanceID = ((LinkRef) resolveRes).getLinkName();
}
else
{
context = getObjectInstanceWrapFailure(resolveRes, name, refEnv);
instanceID = context;
}
if ((context instanceof Context) == false)
{
throw new NotContextException(instanceID + " is not a Context");
}
Context ncontext = (Context) context;
return ncontext.lookup(rr.getRemainingName());
}
else if (res instanceof LinkRef)
{
res = resolveLink(res, refEnv);
}
else if (res instanceof Reference)
{
res = getObjectInstanceWrapFailure(res, name, refEnv);
if (res instanceof LinkRef)
res = resolveLink(res, refEnv);
}
return res;
}
catch (CannotProceedException cpe)
{
cpe.setEnvironment(refEnv);
Context cctx = NamingManager.getContinuationContext(cpe);
return cctx.lookup(cpe.getRemainingName());
}
catch (IOException e)
{
naming = null;
removeServer(refEnv);
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
catch (ClassNotFoundException e)
{
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
}
public void unbind(String name)
throws NamingException
{
unbind(getNameParser(name).parse(name));
}
public void unbind(Name name)
throws NamingException
{
Hashtable refEnv = getEnv(name);
checkRef(refEnv);
Name parsedName = (Name) refEnv.get(JNP_PARSED_NAME);
if (parsedName != null)
name = parsedName;
try
{
naming.unbind(getAbsoluteName(name));
}
catch (CannotProceedException cpe)
{
cpe.setEnvironment(refEnv);
Context cctx = NamingManager.getContinuationContext(cpe);
cctx.unbind(cpe.getRemainingName());
}
catch (IOException e)
{
naming = null;
removeServer(refEnv);
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
}
public void rename(String oldname, String newname)
throws NamingException
{
rename(getNameParser(oldname).parse(oldname), getNameParser(newname).parse(newname));
}
public void rename(Name oldName, Name newName)
throws NamingException
{
bind(newName, lookup(oldName));
unbind(oldName);
}
public NamingEnumeration list(String name)
throws NamingException
{
return list(getNameParser(name).parse(name));
}
public NamingEnumeration list(Name name)
throws NamingException
{
Hashtable refEnv = getEnv(name);
checkRef(refEnv);
Name parsedName = (Name) refEnv.get(JNP_PARSED_NAME);
if (parsedName != null)
name = parsedName;
try
{
return new NamingEnumerationImpl(naming.list(getAbsoluteName(name)));
}
catch (CannotProceedException cpe)
{
cpe.setEnvironment(refEnv);
Context cctx = NamingManager.getContinuationContext(cpe);
return cctx.list(cpe.getRemainingName());
}
catch (IOException e)
{
naming = null;
removeServer(refEnv);
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
}
public NamingEnumeration listBindings(String name)
throws NamingException
{
return listBindings(getNameParser(name).parse(name));
}
public NamingEnumeration listBindings(Name name)
throws NamingException
{
Hashtable refEnv = getEnv(name);
checkRef(refEnv);
Name parsedName = (Name) refEnv.get(JNP_PARSED_NAME);
if (parsedName != null)
name = parsedName;
try
{
Collection bindings = naming.listBindings(getAbsoluteName(name));
Collection realBindings = new ArrayList(bindings.size());
Iterator enum = bindings.iterator();
while (enum.hasNext())
{
Binding binding = (Binding) enum.next();
Object obj = binding.getObject();
if (obj instanceof MarshalledValuePair)
{
try
{
obj = ((MarshalledValuePair) obj).get();
}
catch (ClassNotFoundException e)
{
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
}
else if (obj instanceof MarshalledObject)
{
try
{
obj = ((MarshalledObject) obj).get();
}
catch (ClassNotFoundException e)
{
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
}
realBindings.add(new Binding(binding.getName(), binding.getClassName(), obj));
}
return new NamingEnumerationImpl(realBindings);
}
catch (CannotProceedException cpe)
{
cpe.setEnvironment(refEnv);
Context cctx = NamingManager.getContinuationContext(cpe);
return cctx.listBindings(cpe.getRemainingName());
}
catch (IOException e)
{
naming = null;
removeServer(refEnv);
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
}
public String composeName(String name, String prefix)
throws NamingException
{
Name result = composeName(parser.parse(name),
parser.parse(prefix));
return result.toString();
}
public Name composeName(Name name, Name prefix)
throws NamingException
{
Name result = (Name) (prefix.clone());
result.addAll(name);
return result;
}
public NameParser getNameParser(String name)
throws NamingException
{
return parser;
}
public NameParser getNameParser(Name name)
throws NamingException
{
return getNameParser(name.toString());
}
public Context createSubcontext(String name)
throws NamingException
{
return createSubcontext(getNameParser(name).parse(name));
}
public Context createSubcontext(Name name)
throws NamingException
{
if (name.size() == 0)
throw new InvalidNameException("Cannot pass an empty name to createSubcontext");
Hashtable refEnv = getEnv(name);
checkRef(refEnv);
Name parsedName = (Name) refEnv.get(JNP_PARSED_NAME);
if (parsedName != null)
name = parsedName;
try
{
name = getAbsoluteName(name);
return naming.createSubcontext(name);
}
catch (CannotProceedException cpe)
{
cpe.setEnvironment(refEnv);
Context cctx = NamingManager.getContinuationContext(cpe);
return cctx.createSubcontext(cpe.getRemainingName());
}
catch (IOException e)
{
naming = null;
removeServer(refEnv);
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
}
public Object addToEnvironment(String propName, Object propVal)
throws NamingException
{
Object old = env.get(propName);
env.put(propName, propVal);
return old;
}
public Object removeFromEnvironment(String propName)
throws NamingException
{
return env.remove(propName);
}
public Hashtable getEnvironment()
throws NamingException
{
return env;
}
public void close()
throws NamingException
{
env = null;
naming = null;
}
public String getNameInNamespace()
throws NamingException
{
return prefix.toString();
}
public void destroySubcontext(String name)
throws NamingException
{
throw new OperationNotSupportedException();
}
public void destroySubcontext(Name name)
throws NamingException
{
throw new OperationNotSupportedException();
}
public Object lookupLink(String name)
throws NamingException
{
return lookupLink(getNameParser(name).parse(name));
}
public Object lookupLink(Name name)
throws NamingException
{
if (name.isEmpty())
return lookup(name);
Object link = null;
try
{
Name n = getAbsoluteName(name);
link = naming.lookup(n);
if (!(link instanceof LinkRef) && link instanceof Reference)
link = getObjectInstance(link, name, null);
;
}
catch (IOException e)
{
naming = null;
removeServer(env);
NamingException ex = new CommunicationException();
ex.setRootCause(e);
throw ex;
}
catch (Exception e)
{
NamingException ex = new NamingException("Could not lookup link");
ex.setRemainingName(name);
ex.setRootCause(e);
throw ex;
}
return link;
}
protected Object resolveLink(Object res, Hashtable refEnv)
throws NamingException
{
Object linkResult = null;
try
{
LinkRef link = (LinkRef) res;
String ref = link.getLinkName();
if (ref.startsWith("./"))
linkResult = lookup(ref.substring(2));
else if (refEnv != null)
linkResult = new InitialContext(refEnv).lookup(ref);
else
linkResult = new InitialContext().lookup(ref);
}
catch (Exception e)
{
NamingException ex = new NamingException("Could not dereference object");
ex.setRootCause(e);
throw ex;
}
return linkResult;
}
private boolean useAbsoluteName(Hashtable env)
{
if (env == null)
return true;
String useRelativeName = (String) env.get(JNP_USE_RELATIVE_NAME);
return Boolean.valueOf(useRelativeName) == Boolean.FALSE;
}
private Object getStateToBind(Object obj, Name name, Hashtable env)
throws NamingException
{
if (useAbsoluteName(env))
name = getAbsoluteName(name);
return NamingManager.getStateToBind(obj, name, this, env);
}
private Object getObjectInstance(Object obj, Name name, Hashtable env)
throws Exception
{
if (useAbsoluteName(env))
name = getAbsoluteName(name);
return NamingManager.getObjectInstance(obj, name, this, env);
}
private Object getObjectInstanceWrapFailure(Object obj, Name name, Hashtable env)
throws NamingException
{
try
{
return getObjectInstance(obj, name, env);
}
catch (NamingException e)
{
throw e;
}
catch (Exception e)
{
NamingException ex = new NamingException("Could not dereference object");
ex.setRootCause(e);
throw ex;
}
}
private Naming discoverServer(Hashtable serverEnv) throws NamingException
{
boolean trace = log.isTraceEnabled();
String disableDiscovery = (String) serverEnv.get(JNP_DISABLE_DISCOVERY);
if (Boolean.valueOf(disableDiscovery) == Boolean.TRUE)
{
if (trace)
log.trace("Skipping discovery due to disable flag");
return null;
}
String partitionName = (String) serverEnv.get(JNP_PARTITION_NAME);
Naming server = null;
if (partitionName != null)
{
server = getHANamingServerForPartition(partitionName);
if (server != null)
return server;
}
MulticastSocket s = null;
InetAddress iaGroup = null;
try
{
String group = DEFAULT_DISCOVERY_GROUP_ADDRESS;
int port = DEFAULT_DISCOVERY_GROUP_PORT;
int timeout = DEFAULT_DISCOVERY_TIMEOUT;
int ttl = 16;
String discoveryTTL = (String) serverEnv.get(JNP_DISCOVERY_TTL);
if(discoveryTTL != null)
ttl = Integer.parseInt(discoveryTTL);
String discoveryGroup = (String) serverEnv.get(JNP_DISCOVERY_GROUP);
if (discoveryGroup != null)
group = discoveryGroup;
String discoveryTimeout = (String) serverEnv.get(JNP_DISCOVERY_TIMEOUT);
if (discoveryTimeout == null)
{
discoveryTimeout = (String) serverEnv.get("DISCOVERY_TIMEOUT");
}
if (discoveryTimeout != null && !discoveryTimeout.equals(""))
timeout = Integer.parseInt(discoveryTimeout);
String discoveryGroupPort = (String) serverEnv.get(JNP_DISCOVERY_PORT);
if (discoveryGroupPort == null)
{
discoveryGroupPort = (String) serverEnv.get("DISCOVERY_GROUP");
}
if (discoveryGroupPort != null && !discoveryGroupPort.equals(""))
{
int colon = discoveryGroupPort.indexOf(':');
if (colon < 0)
{
try
{
port = Integer.parseInt(discoveryGroupPort);
}
catch (Exception ex)
{
log.warn("Failed to parse port: " + discoveryGroupPort, ex);
}
}
else
{
group = discoveryGroupPort.substring(0, colon);
String portStr = discoveryGroupPort.substring(colon + 1);
try
{
port = Integer.parseInt(portStr);
}
catch (Exception ex)
{
log.warn("Failed to parse port: " + portStr, ex);
}
}
}
iaGroup = InetAddress.getByName(group);
String localAddrStr = (String) serverEnv.get(JNP_LOCAL_ADDRESS);
String localPortStr = (String) serverEnv.get(JNP_LOCAL_PORT);
int localPort = 0;
if (localPortStr != null)
localPort = Integer.parseInt(localPortStr);
if (localAddrStr != null)
{
InetSocketAddress localAddr = new InetSocketAddress(localAddrStr, localPort);
s = new MulticastSocket(localAddr);
}
else
{
s = new MulticastSocket(localPort);
}
s.setSoTimeout(timeout);
s.setTimeToLive(ttl);
if(log.isTraceEnabled())
log.trace("TTL on multicast discovery socket is " + ttl);
s.joinGroup(iaGroup);
if (trace)
log.trace("MulticastSocket: " + s);
DatagramPacket packet;
StringBuffer data = new StringBuffer("GET_ADDRESS");
if (partitionName != null)
data.append(":" + partitionName);
byte[] buf = data.toString().getBytes();
packet = new DatagramPacket(buf, buf.length, iaGroup, port);
if (trace)
log.trace("Sending discovery packet(" + data + ") to: " + iaGroup + ":" + port);
s.send(packet);
buf = new byte[50];
packet = new DatagramPacket(buf, buf.length);
s.receive(packet);
String myServer = new String(packet.getData()).trim();
if (trace)
log.trace("Received answer packet: " + myServer);
while (myServer != null && myServer.startsWith("GET_ADDRESS"))
{
Arrays.fill(buf, (byte) 0);
packet.setLength(buf.length);
s.receive(packet);
byte[] reply = packet.getData();
myServer = new String(reply).trim();
if (trace)
log.trace("Received answer packet: " + myServer);
}
String serverHost;
int serverPort;
int colon = myServer.indexOf(':');
if (colon >= 0)
{
serverHost = myServer.substring(0, colon);
serverPort = Integer.valueOf(myServer.substring(colon + 1)).intValue();
server = getServer(serverHost, serverPort, serverEnv);
}
return server;
}
catch (IOException e)
{
if (trace)
log.trace("Discovery failed", e);
NamingException ex = new CommunicationException(e.getMessage());
ex.setRootCause(e);
throw ex;
}
finally
{
try
{
if (s != null)
s.leaveGroup(iaGroup);
}
catch (Exception ignore)
{
}
try
{
if (s != null)
s.close();
}
catch (Exception ignore)
{
}
}
}
private void checkRef(Hashtable refEnv)
throws NamingException
{
if (naming == null)
{
String host = "localhost";
int port = 1099;
Exception serverEx = null;
String urls = (String) refEnv.get(Context.PROVIDER_URL);
if (urls != null && urls.length() > 0)
{
StringTokenizer tokenizer = new StringTokenizer(urls, ",");
while (naming == null && tokenizer.hasMoreElements())
{
String url = tokenizer.nextToken();
Name urlAsName = getNameParser("").parse(url);
String server = parseNameForScheme(urlAsName, null);
if (server != null)
url = server;
int colon = url.indexOf(':');
if (colon < 0)
{
host = url;
}
else
{
host = url.substring(0, colon).trim();
try
{
port = Integer.parseInt(url.substring(colon + 1).trim());
}
catch (Exception ex)
{
}
}
try
{
naming = getServer(host, port, refEnv);
}
catch (Exception e)
{
serverEx = e;
log.debug("Failed to connect to " + host + ":" + port, e);
}
}
if (naming == null)
{
naming = discoverServer(refEnv);
if (naming == null)
{
CommunicationException ce = new CommunicationException("Could not obtain connection to any of these urls: " + urls);
ce.setRootCause(serverEx);
throw ce;
}
}
}
else
{
String jnpPartitionName = (String) refEnv.get(JNP_PARTITION_NAME);
if (jnpPartitionName != null)
{
naming = discoverServer(refEnv);
if (naming == null)
throw new ConfigurationException
("No valid context could be build for jnp.partitionName=" + jnpPartitionName);
}
else
{
naming = localServer;
if (naming == null)
{
naming = discoverServer(refEnv);
if (naming == null)
throw new ConfigurationException("No valid Context.PROVIDER_URL was found");
}
}
}
}
}
private Name getAbsoluteName(Name n)
throws NamingException
{
if (n.isEmpty())
return composeName(n, prefix);
else if (n.get(0).toString().equals("")) return n.getSuffix(1);
else return composeName(n, prefix);
}
private Hashtable getEnv(Name n)
throws InvalidNameException
{
Hashtable nameEnv = env;
env.remove(JNP_PARSED_NAME);
String serverInfo = parseNameForScheme(n, nameEnv);
if (serverInfo != null)
{
nameEnv = (Hashtable) env.clone();
nameEnv.put(Context.PROVIDER_URL, serverInfo);
}
return nameEnv;
}
}