1 4 package gnu.mapping; 5 import java.util.Hashtable ; 6 import java.io.*; 7 8 18 19 public class Namespace 20 implements Externalizable, HasNamedParts 21 { 22 23 protected static final Hashtable nsTable = new Hashtable (50); 24 25 26 public static final Namespace EmptyNamespace = getInstance(""); 27 28 29 String name; 30 31 protected String prefix = ""; 32 33 34 public final String getName () { return name; } 35 36 public final void setName (String name) { this.name = name; } 37 38 public Namespace () 39 { 40 this(64); 41 } 42 43 public Namespace (int capacity) 44 { 45 log2Size = 4; 46 while (capacity > (1 << log2Size)) 47 log2Size++; 48 capacity = 1 << log2Size; 49 table = new SymbolRef[capacity]; 50 mask = capacity - 1; 51 } 52 53 public static Namespace getDefault () 54 { 55 return EmptyNamespace; 56 } 57 58 public static Symbol getDefaultSymbol (String name) 59 { 60 return EmptyNamespace.getSymbol(name); 61 } 62 63 public static Namespace make(String name) { 65 return getInstance(name); 66 } 67 68 public static Namespace getInstance(String name) 69 { 70 if (name == null) 71 name = ""; 72 synchronized (nsTable) 73 { 74 Namespace ns = (Namespace) nsTable.get(name); 75 if (ns != null) 76 return ns; 77 ns = new Namespace (); 78 ns.setName(name.intern()); 79 nsTable.put(name, ns); 80 return ns; 81 } 82 } 83 84 public static Namespace make (String uri, String prefix) 85 { 86 if (prefix == null || prefix.length() == 0) 87 return getInstance(uri); 88 String xname = prefix + " -> "+ uri; 89 synchronized (nsTable) 90 { 91 Object old = nsTable.get(xname); 92 if (old instanceof Namespace) 93 return (Namespace) old; 94 Namespace ns = new Namespace(); 95 ns.setName(uri); 96 ns.prefix = prefix; 97 nsTable.put(xname, ns); 98 return ns; 99 } 100 } 101 102 106 public static Namespace makeUnknownNamespace (String prefix) 107 { 108 String uri; 109 if (prefix == null || prefix == "") 110 uri = ""; 111 else 112 uri = "http://kawa.gnu.org/unknown-namespace/"+prefix; 113 return Namespace.make(uri, prefix); 114 } 115 116 public Object get (String name) 117 { 118 return Environment.getCurrent().get(getSymbol(getName())); 119 } 120 121 public boolean isConstant (String key) 122 { 123 return false; 124 } 125 126 130 public Symbol getSymbol (String key) 131 { 132 return lookup(key, key.hashCode(), true); 133 } 134 135 138 public Symbol lookup(String key) 139 { 140 return lookup(key, key.hashCode(), false); 141 } 142 143 protected final Symbol lookupInternal(String key, int hash) 144 { 145 int index = hash & mask; 146 SymbolRef prev = null; 147 for (SymbolRef ref = table[index]; ref != null; ) 148 { 149 SymbolRef next = ref.next; 150 Symbol sym = ref.getSymbol(); 151 if (sym == null) 152 { 153 if (prev == null) 155 table[index] = next; 156 else 157 prev.next = next; 158 num_bindings--; 159 } 160 else 161 { 162 if (sym.getLocalPart().equals(key)) 163 return sym; 164 prev = ref; 165 } 166 ref = next; 167 } 168 return null; 169 } 170 171 public Symbol add(Symbol sym, int hash) 172 { 173 int index = hash & mask; 174 SymbolRef ref = new SymbolRef(sym, this); 175 sym.namespace = this; 176 ref.next = table[index]; 177 table[index] = ref; 178 num_bindings++; 179 if (num_bindings >= table.length) 180 rehash(); 181 return sym; 182 } 183 184 public Symbol lookup(String key, int hash, boolean create) 185 { 186 synchronized (this) 187 { 188 Symbol sym = lookupInternal(key, hash); 189 if (sym != null) 190 return sym; 191 192 202 if (create) 203 return add(new Symbol(this, key), hash); 204 else 205 return null; 206 } 207 } 208 209 public boolean remove (Symbol symbol) 210 { 211 synchronized (this) 212 { 213 String name = symbol.getLocalPart(); 214 int hash = name.hashCode(); 215 int index = hash & mask; 216 SymbolRef prev = null; 217 SymbolRef ref = table[index]; 218 while (ref != null) 219 { 220 SymbolRef next = ref.next; 221 Symbol refsym = ref.getSymbol(); 222 if (refsym == null || refsym == symbol) 223 { 224 if (prev == null) 225 table[index] = next; 226 else 227 prev.next = next; 228 num_bindings--; 229 if (refsym != null) 230 return true; 231 } 232 else 233 prev = ref; 234 ref = next; 235 } 236 return false; 237 } 238 } 239 240 protected SymbolRef[] table; 241 int log2Size; 242 private int mask; 243 int num_bindings; 244 245 protected void rehash () 246 { 247 int oldCapacity = table.length; 248 int newCapacity = 2 * oldCapacity; 249 int newMask = newCapacity - 1; 250 int countInserted = 0; 251 SymbolRef[] oldTable = table; 252 SymbolRef[] newTable = new SymbolRef[newCapacity]; 253 254 for (int i = oldCapacity; --i >= 0;) 255 { 256 for (SymbolRef ref = oldTable[i]; ref != null; ) 257 { 258 SymbolRef next = ref.next; 259 Symbol sym = ref.getSymbol(); 260 if (sym != null) 261 { 262 String key = sym.getName(); 263 int hash = key.hashCode(); 264 int index = hash & newMask; 265 countInserted++; 266 ref.next = newTable[index]; 267 newTable[index] = ref; 268 } 269 ref = next; 270 } 271 } 272 273 table = newTable; 274 log2Size++; 275 mask = newMask; 276 num_bindings = countInserted; 277 } 278 279 public void writeExternal(ObjectOutput out) throws IOException 280 { 281 out.writeObject(getName()); 282 out.writeObject(prefix); 283 } 284 285 public void readExternal(ObjectInput in) 286 throws IOException, ClassNotFoundException 287 { 288 name = ((String ) in.readObject()).intern(); 289 prefix = (String ) in.readObject(); 290 } 291 292 public Object readResolve() throws ObjectStreamException 293 { 294 String name = getName(); 295 if (name != null) 296 { 297 String xname = (prefix == null || prefix.length() == 0 ? name 298 : (prefix + " -> "+ name)); 299 Namespace ns = (Namespace) nsTable.get(xname); 300 if (ns != null) 301 return ns; 302 nsTable.put(xname, this); 303 } 304 return this; 305 306 } 307 308 public String toString() 309 { return "#,(namespace \""+name+"\")"; } 310 } 311 312 315 316 class SymbolRef 317 318 extends java.lang.ref.WeakReference 319 320 { 321 SymbolRef next; 322 323 324 326 327 334 335 SymbolRef (Symbol sym, Namespace ns) 336 { 337 338 super(sym); 339 340 342 } 343 344 Symbol getSymbol() 345 { 346 347 return (Symbol) get(); 348 349 350 352 } 353 354 public String toString() 355 { 356 return "SymbolRef["+getSymbol()+"]"; 357 } 358 } 359 | Popular Tags |