// ex:sw=3 // ^-- shift-width 4 for vi package lava.net.common; import java.net.URL; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Hashtable; /** * UNA:
* Description of the logical Name of an Object.
* Format is similar to URL.
* Scheme-Name is psyc://
* Objects might be Servers, Groups, Users, Protocols.
* Servers: resource=null
* Groups: resource begins with '@'
* Users: resource begins with '~'
* Protocols: resource begins with '$'
* Every Object only can have only one UNA.
**/ public class UNA extends java.lang.Object { /** * **/ private static Hashtable cache = new Hashtable(); /** * **/ private static Hashtable revcache = new Hashtable(); /** * **/ private static boolean instantiated = false; /** * Flag to mark that we're an applet. **/ private static boolean applet = false; /** * **/ private static String defaultScheme = null; /** * **/ private static Hashtable defaultHost = new Hashtable(); /** * **/ private static Hashtable defaultPort = new Hashtable(); /** * **/ private static Hashtable defaultProtocol = new Hashtable(); /** * **/ private static Hashtable defaultResource = new Hashtable(); /** * **/ private String scheme = null; /** * **/ private String host = null; /** * **/ private InetAddress hostCache = null; /** * **/ private int port = -1; /** * **/ private String protocol = null; /** * **/ private String resource = null; /** * **/ private int hashCode = -1; /** * **/ private String string = null; /** * **/ public UNA() { instantiated = true; setScheme(null); setHost((String)null); setPort(-1); setProtocol(null); setResource(null); } /** * **/ public UNA(String spec) { this ((UNA)null,spec); } /** * **/ public UNA(UNA base, String spec) { this (); // pre-initialize it with our base if(base != null) { setScheme(base.getScheme()); setHost(base.getHostName()); setPort(base.getPort()); setProtocol(base.getProtocol()); setResource(base.getResource()); } if(spec == null) return; int i, c, limit = spec.length(); int start = 0; //System.err.println("[ "+spec+" ]"); while((limit > 0) && (spec.charAt(limit - 1) <= ' ')) { // eliminate trailing whitespace limit--; } while((start < limit) && (spec.charAt(start) <= ' ')) { // eliminate leading whitespace start++; } // rewritten here by LynX i = spec.indexOf("//"); if(i == start || (i > start && spec.charAt(i-1) == ':')) { if(i > start) setScheme(spec.substring(start,i-1).toLowerCase()); // jump over "//" start = i + 2; } else { // if we got here, there is no hostname:port info // instead, if it is a web url, there may be ../'s // which should be applied to the base resource path // since this is a psyc library, we don't to do that // if (spec.charAt(start) == '/') start++; setResource("/" + spec.substring(start,limit)); return; } i = spec.indexOf('/',start); if(i >= 0) { if(limit > i) setResource(spec.substring(i,limit)); limit = i; } i = spec.indexOf(':',start); if(i >= 0 && i < limit) { int j; for(j = i + 1;j < limit;++j) if(!Character.isDigit(spec.charAt(j))) break; if(j > i + 1) setPort(Integer.parseInt(spec.substring(i + 1,j))); if(j < limit) setProtocol(spec.substring(j,limit)); limit = i; } if(limit > start) setHost(spec.substring(start,limit)); /* if(host == null && resource == null) { // special case: no real host given // parse all the stuff as resource, prepend "/" setPort(-1); setProtocol(null); setResource("/" + spec.substring(start,limit)); } */ } /** * **/ public UNA(String scheme, String host, int port, String protocol, // String resource) { instantiated = true; setScheme(scheme); setHost(host); setPort(port); setProtocol(protocol); setResource(resource); } /** * **/ public UNA(String scheme, InetAddress host, int port, String protocol, // String resource) { instantiated = true; setScheme(scheme); setHost(host); setPort(port); setProtocol(protocol); setResource(resource); } /** * **/ public String getScheme() { return scheme != null ? scheme : getDefaultScheme(); } /** * **/ public InetAddress getHost() { if(hostCache == null) hostCache = lookup(getHostName()); return hostCache; } /** * **/ public String getHostName() { return host != null ? host : getDefaultHost(getScheme()); } /** * **/ public String getHostAddress() { InetAddress h = getHost(); return h == null ? null : h.getHostAddress(); } /** * **/ public int getPort() { return port > 0 ? port : getDefaultPort(getScheme()); } /** * **/ public String getProtocol() { return protocol != null ? protocol : getDefaultProtocol(getScheme()); } /** * **/ public String getResource() { return resource != null ? resource : getDefaultResource(getScheme()); } /** * **/ protected void setScheme(String newScheme) { scheme = newScheme; } /** * **/ protected void setHost(String newHost) { host = newHost; } /** * **/ protected void setHost(InetAddress newHost) { setHost(lookup(newHost)); } /** * **/ protected void setPort(int newPort) { port = newPort; } /** * **/ protected void setProtocol(String newProtocol) { protocol = newProtocol; } /** * **/ protected void setResource(String newResource) { if(newResource != null && newResource.length() > 1 && // newResource.charAt(newResource.length() - 1) != '/') newResource = newResource + "/"; resource = newResource; } /** * **/ public boolean equalsInScheme(UNA other) { if(other == null) return false; String s = getScheme(), os = other.getScheme(); return (s == null || os == null ? s == null && // os == null : s.toLowerCase().equals(os.toLowerCase())); } /** * **/ public boolean equalsInHost(UNA other) { if(other == null) return false; InetAddress h = getHost(); String n; return (h == null ? (n = getHostName()) == null ? // other.getHostName() == null : n.equals(other.getHostName()) : // h.equals(other.getHost())); } /** * **/ public boolean equalsInPort(UNA other) { return (other != null) && (getPort() == other.getPort()); } /** * **/ public boolean equalsInProtocol(UNA other) { if(other == null) return false; String p = getProtocol(), op = other.getProtocol(); return (p == null || op == null ? // p == null && op == null : p.equals(op)); } /** * **/ public boolean equalsInResource(UNA other) { if(other == null) return false; String r = getResource(), or = other.getResource(); return (r == null || or == null ? // r == null && or == null : r.equals(or)); } /** * **/ public boolean masterInResource(UNA other) { if(other == null) return false; try { String r = getResource(), or = other.getResource(); return (r == null || or == null ? r == null : // or.indexOf(r) == 0 && (or.charAt(r.length() - 1) == '/' || // or.charAt(r.length()) == '/')); } catch(StringIndexOutOfBoundsException e) { // resources are equal return true; } } /** * **/ public boolean master(UNA other) { return equalsInHost(other) && // equalsInPort(other) && // equalsInProtocol(other) && // masterInResource(other); } /** * **/ public boolean equals(Object obj) { return (obj instanceof UNA) && // equalsInScheme((UNA)obj) && // equalsInHost((UNA)obj) && // equalsInPort((UNA)obj) && // equalsInProtocol((UNA)obj) && // equalsInResource((UNA)obj); } /** * **/ public int hashCode() { if(hashCode == -1) { String s = getScheme(), p = getProtocol(), r = getResource(); InetAddress h = getHost(); String n; hashCode = (s == null ? 0 : s.hashCode()) ^ // (h == null ? (n = getHostName()) == null ? 0 : n.hashCode() : // h.hashCode()) ^ getPort() ^ // (p == null ? 0 : p.hashCode()) ^ // (r == null ? 0 : r.hashCode()); } return hashCode; } /** * **/ public String toString() { if(string != null) return string; StringBuffer me = new StringBuffer(); String s = getScheme(), p = getProtocol(), // dp = getDefaultProtocol(s), r = getResource(), h = getHostName(); int po = getPort(), dpo = getDefaultPort(s); if(s != null) me.append(s + "://"); if((h != null) && h != null) me.append(h); if((po >= 0 || p != null) && (po != dpo || p != dp)) me.append(":"); if(po >= 0 && po != dpo) me.append(po); if(p != null && p != dp) me.append(p); if(r != null) me.append(r); string = me.toString(); return string; } /** * **/ public static void setDefaults(String scheme, InetAddress host, // int port, String protocol, String resource) { String h = null; if(host != null) try { h = host.getHostAddress(); } catch(Exception e) { h = null; } setDefaults(scheme,h,port,protocol,resource); } /** * **/ public static void setDefaults(String scheme, String host, // int port, String protocol, String resource) { if(instantiated || scheme == null) return; if(defaultScheme == null) defaultScheme = scheme; scheme = scheme.toLowerCase(); if(host != null && defaultHost.get(scheme) == null) defaultHost.put(scheme,host); if(port > 0 && defaultPort.get(scheme) == null) defaultPort.put(scheme,new Integer(port)); if(protocol != null && defaultProtocol.get(scheme) == null) defaultProtocol.put(scheme,protocol); if(resource != null && defaultResource.get(scheme) == null) defaultResource.put(scheme,resource); } /** * **/ public static String getDefaultScheme() { return defaultScheme; } /** * **/ public static String getDefaultHost(String scheme) { if(scheme == null) return null; return (String)defaultHost.get(scheme.toLowerCase()); } /** * **/ public static int getDefaultPort(String scheme) { if(scheme == null) return -1; Integer port = (Integer)defaultPort.get(scheme.toLowerCase()); if(port == null) return -1; return port.intValue(); } /** * **/ public static int getDefaultPort() { return getDefaultPort(getDefaultScheme()); } /** * **/ public static String getDefaultProtocol(String scheme) { if(scheme == null) return null; return (String)defaultProtocol.get(scheme.toLowerCase()); } /** * **/ public static String getDefaultProtocol() { return getDefaultProtocol(getDefaultScheme()); } /** * **/ public static String getDefaultResource(String scheme) { if(scheme == null) return null; return (String)defaultResource.get(scheme.toLowerCase()); } /** * **/ public static String getDefaultResource() { return getDefaultResource(getDefaultScheme()); } /** * **/ public static void cache(String name, InetAddress addr) { if(name != null && addr != null) { cache.put(name,addr); revcache.put(addr,name); } } /** * **/ public static InetAddress lookup(String name) { if(name == null) return null; InetAddress addr = (InetAddress)cache.get(name); if(addr == null && !applet) { try { addr = InetAddress.getByName(name); cache(name,addr); } catch(Exception e) { addr = null; } } return addr; } /** * **/ public static String lookup(InetAddress addr) { if(addr == null) return null; String name = (String)revcache.get(addr); if(name == null) { if(!applet) { try { name = addr.getHostName(); if(name != null && name.indexOf('.') < 0) // refuse the name if it is not fully qualified name = null; else // only cache the name, if it seems to be a fully // qualified one cache(name,addr); } catch(Exception e) { name = null; } } if(name == null) { name = addr.getHostAddress(); cache(name,addr); } } return name; } /** * **/ public static void addAppletHost(String name) { applet = false; lookup(name); applet = true; } /** * **/ public static void addAppletHost(InetAddress addr) { applet = false; lookup(addr); applet = true; } /** * **/ public static boolean isApplet() { return applet; } }