package org.mom4j.jndi;
import java.util.Hashtable;
import java.util.Map;
import java.util.Iterator;
import java.util.Properties;
import java.util.StringTokenizer;
import javax.naming.Context;
import javax.naming.CompositeName;
import javax.naming.CompoundName;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NameParser;
import org.mom4j.xcp.XcpResponse;
import org.mom4j.xcp.XcpSender;
public class ContextImpl implements Context {
private static final String MALFORMED_URL =
"Malformed PROVIDER_URL: use 'xcp://<hostname>:<port>'";
private String path;
private Hashtable environment;
private XcpSender sender;
private XcpBindingHandler handler;
/** Creates new ContextImpl */
public ContextImpl(String path, Hashtable env)
throws NamingException
{
if(path == null) {
throw new IllegalArgumentException("path is null!");
}
String s = (String)env.get(Context.PROVIDER_URL);
StringTokenizer st = new StringTokenizer(s, ":/");
if(st.countTokens() < 3) {
throw new NamingException(MALFORMED_URL);
}
if(!st.nextToken().equals("xcp")) {
throw new NamingException(MALFORMED_URL);
}
java.net.InetAddress host = null;
try {
host = java.net.InetAddress.getByName(st.nextToken());
} catch(Exception ex) {
throw new NamingException(MALFORMED_URL);
}
int port = 0;
try {
port = Integer.parseInt(st.nextToken());
} catch(Exception ex) {
throw new NamingException(MALFORMED_URL);
}
this.path = path;
this.sender = new XcpSender(host, port);
this.handler = new XcpBindingHandler();
this.environment = env;
}
public Object addToEnvironment(String name, Object value)
throws NamingException
{
this.assertNotNull("name", name);
this.assertNotNull("value", value);
return this.environment.put(name, value);
}
public void bind(String name, Object obj)
throws NamingException
{
this.assertNotNull("name", name);
this.assertNotNull("object", obj);
this.bind(new CompositeName(name), obj);
}
public void bind(Name name, Object obj)
throws NamingException
{
this.assertNotNull("name", name);
this.assertNotNull("object", obj);
XcpBinding b = new XcpBinding(this.path, name.toString(), XcpBinding.ACTION_BIND, obj);
try {
this.sender.send(b);
} catch(java.io.IOException ex) {
throw new NamingException(ex.getMessage());
}
}
public void close()
throws NamingException
{
}
public String composeName(String name, String prefix)
throws NamingException
{
this.assertNotNull("name", name);
this.assertNotNull("prefix", prefix);
Name result = composeName(new CompositeName(name),
new CompositeName(prefix));
return result.toString();
}
public Name composeName(Name name, Name prefix)
throws NamingException
{
this.assertNotNull("name", name);
this.assertNotNull("prefix", prefix);
Name result = (Name)(prefix.clone());
result.addAll(name);
return result;
}
public Context createSubcontext(String name)
throws NamingException
{
XcpBinding b = new XcpBinding(this.path, name, XcpBinding.ACTION_CREATE_CTX);
XcpResponse resp = null;
try {
resp = this.sender.send(b, this.handler);
} catch(java.io.IOException ex) {
NamingException nex = new NamingException(ex.getMessage());
nex.setRootCause(ex);
throw nex;
}
String newPath = (String) ((XcpBinding)resp.getRootElement()).getValue();
if(newPath == null) {
throw new javax.naming.NamingException(name + " already exists");
}
return new ContextImpl(newPath, this.environment);
}
public Context createSubcontext(Name name)
throws NamingException
{
if(name == null) {
throw new IllegalArgumentException("name is null!");
}
return this.createSubcontext(name.toString());
}
public void destroySubcontext(String name)
throws javax.naming.NamingException
{
throw new javax.naming.OperationNotSupportedException("destroySubcontext");
}
public void destroySubcontext(Name name)
throws NamingException
{
throw new javax.naming.OperationNotSupportedException("destroySubcontext");
}
public Hashtable getEnvironment()
throws NamingException
{
return (Hashtable)this.environment.clone();
}
public String getNameInNamespace()
throws NamingException
{
throw new javax.naming.OperationNotSupportedException("getNameInNamespace");
}
public NameParser getNameParser(String name)
throws NamingException
{
return new NameParserImpl();
}
public NameParser getNameParser(Name name)
throws NamingException
{
return new NameParserImpl();
}
public NamingEnumeration list(String name)
throws NamingException
{
return this.listBindings(name);
}
public NamingEnumeration list(Name name)
throws NamingException
{
return this.listBindings(name);
}
public NamingEnumeration listBindings(String name)
throws NamingException
{
this.assertNotNull("name", name);
return this.listBindings(new CompositeName(name));
}
public NamingEnumeration listBindings(Name name)
throws NamingException
{
this.assertNotNull("name", name);
XcpBinding b = new XcpBinding(this.path, name.toString(), XcpBinding.ACTION_LIST);
XcpResponse resp = null;
try {
resp = this.sender.send(b, this.handler);
} catch(java.io.IOException ex) {
NamingException nex = new NamingException(ex.getMessage());
nex.setRootCause(ex);
throw nex;
}
Map map = (Map)((XcpBinding)resp.getRootElement()).getValue();
return new NamingEnumerationImpl(map);
}
public Object lookup(String name)
throws NamingException
{
this.assertNotNull("name", name);
return this.lookup(new CompositeName(name));
}
public Object lookup(Name name)
throws NamingException
{
this.assertNotNull("name", name);
XcpBinding b = new XcpBinding(this.path, name.toString(), XcpBinding.ACTION_LOOKUP);
XcpResponse resp = null;
try {
resp = this.sender.send(b, this.handler);
} catch(java.io.IOException ex) {
NamingException nex = new NamingException(ex.getMessage());
nex.setRootCause(ex);
throw nex;
}
Object obj = ((XcpBinding)resp.getRootElement()).getValue();
if(obj == null) {
throw new javax.naming.NameNotFoundException(name.toString());
}
if(obj instanceof CreateCtx) {
return new ContextImpl(((CreateCtx)obj).getPath(), this.environment);
}
return obj;
}
public Object lookupLink(String name)
throws NamingException
{
this.assertNotNull("name", name);
return this.lookupLink(new CompositeName(name));
}
public Object lookupLink(Name name)
throws NamingException
{
return this.lookup(name);
}
public void rebind(String name, Object obj)
throws NamingException
{
this.rebind(new CompositeName(name), obj);
}
public void rebind(Name name, Object obj)
throws NamingException
{
this.assertNotNull("name", name);
this.assertNotNull("object", obj);
XcpBinding b = new XcpBinding(this.path, name.toString(), XcpBinding.ACTION_REBIND, obj);
try {
this.sender.send(b);
} catch(java.io.IOException ex) {
throw new NamingException(ex.getMessage());
}
}
public Object removeFromEnvironment(String key)
throws NamingException
{
this.assertNotNull("key", key);
return this.environment.remove(key);
}
public void rename(String oldName, String newName)
throws NamingException
{
throw new javax.naming.OperationNotSupportedException("rename");
}
public void rename(Name oldName, Name newName)
throws NamingException
{
throw new javax.naming.OperationNotSupportedException("rename");
}
public void unbind(String name)
throws NamingException
{
this.assertNotNull("name", name);
this.unbind(new CompositeName(name));
}
public void unbind(Name name)
throws NamingException
{
this.assertNotNull("name", name);
XcpBinding b = new XcpBinding(this.path, name.toString(), XcpBinding.ACTION_UNBIND);
try {
this.sender.send(b);
} catch(java.io.IOException ex) {
throw new NamingException(ex.getMessage());
}
}
private void assertNotNull(String name, Object obj)
throws NamingException
{
if(obj == null) {
throw new NamingException(name + " must not be null!");
}
}
public static class NameParserImpl implements NameParser {
private static Properties syntax = new Properties();
static {
syntax.put("jndi.syntax.direction", "flat");
syntax.put("jndi.syntax.ignorecase", "false");
}
public Name parse(String name) throws NamingException {
return new CompoundName(name, syntax);
}
}
class NamingEnumerationImpl implements NamingEnumeration {
private Map bindings;
private Iterator iter;
NamingEnumerationImpl (Map bindings) {
this.bindings = bindings;
this.iter = this.bindings.keySet().iterator();
}
public boolean hasMoreElements() {
return this.iter.hasNext();
}
public boolean hasMore() throws NamingException {
return this.iter.hasNext();
}
public Object nextElement() {
String name = (String)this.iter.next();
return new javax.naming.Binding(name, this.bindings.get(name));
}
public Object next() throws NamingException {
return nextElement();
}
public void close() {
}
}
}