001package org.biojava.naming; 002 003import java.util.Enumeration; 004import java.util.Hashtable; 005import java.util.NoSuchElementException; 006 007import javax.naming.Binding; 008import javax.naming.CompositeName; 009import javax.naming.Context; 010import javax.naming.InvalidNameException; 011import javax.naming.Name; 012import javax.naming.NameClassPair; 013import javax.naming.NameNotFoundException; 014import javax.naming.NameParser; 015import javax.naming.NamingEnumeration; 016import javax.naming.NamingException; 017import javax.naming.NotContextException; 018import javax.naming.OperationNotSupportedException; 019import javax.naming.directory.Attributes; 020import javax.naming.directory.BasicAttributes; 021import javax.naming.directory.DirContext; 022import javax.naming.directory.ModificationItem; 023import javax.naming.directory.SearchControls; 024 025/** 026 * 027 * 028 * @author Matthew Pocock 029 */ 030public class ObdaContext 031 implements DirContext 032{ 033 private ObdaContext parent; 034 private String myAtomicName; 035 private Hashtable bindings; 036 private Hashtable env; 037 private BasicAttributes attrs; 038 039 protected Name getMyComponents(Name name) throws NamingException 040 { 041 if(name instanceof CompositeName) { 042 if(name.size() > 1) { 043 throw new InvalidNameException( 044 name.toString() + 045 " has more components than namespace can handle"); 046 } 047 048 // Turn component that belongs to you into a compound name 049 return ObdaUriParser.getInstance().parse(name.get(0)); 050 } else { 051 // Already parsed 052 return name; 053 } 054 } 055 056 ObdaContext(ObdaContext parent, 057 String myAtomicName, 058 Hashtable bindings, 059 Hashtable env, 060 BasicAttributes attrs) 061 { 062 this.parent = parent; 063 this.myAtomicName = myAtomicName; 064 this.bindings = new Hashtable(bindings); 065 this.env = new Hashtable(env); 066 this.attrs = (BasicAttributes) attrs.clone(); 067 } 068 069 Hashtable getBindings() 070 { 071 return bindings; 072 } 073 074 BasicAttributes getAttrs() 075 { 076 return attrs; 077 } 078 079 public String getNameInNamespace() throws NamingException 080 { 081 ObdaContext ancestor = parent; 082 083 // No ancestor; at root of namespace 084 if(ancestor == null) { 085 return ""; 086 } 087 088 Name name = ObdaUriParser.getInstance().parse(""); 089 name.add(myAtomicName); 090 091 // Get the parent's names 092 while(ancestor != null && ancestor.myAtomicName != null) { 093 name.add(0, ancestor.myAtomicName); 094 ancestor = ancestor.parent; 095 } 096 097 return name.toString(); 098 } 099 100 public Name composeName(Name name, Name prefix) throws NamingException 101 { 102 Name result; 103 104 // Both are compound names; compose using compound name rules 105 if(!(name instanceof CompositeName) && 106 !(prefix instanceof CompositeName)) { 107 result = (Name) (prefix.clone()); 108 result.addAll(name); 109 return new CompositeName().add(result.toString()); 110 } 111 112 // Simplistic implementation; do not support federation 113 throw new OperationNotSupportedException( 114 "Do not support composing composite names"); 115 } 116 117 public Object lookup(Name name) throws NamingException 118 { 119 System.err.println("lookup: '" + name + "' for " + bindings); 120 if(name.isEmpty()) { 121 // Ask to look up this context itself; create and return 122 // a new instance that has its own independent environment. 123 System.err.println("Empty - return copy"); 124 return new ObdaContext(parent, myAtomicName, bindings, env, attrs); 125 } 126 127 // Extract the components that belong to this namespace 128 Name nm = getMyComponents(name); 129 System.err.println("My component is " + nm); 130 131 // Find the object in the internal hash table 132 String start = nm.get(0); 133 Object answer = bindings.get(start); 134 if(answer == null) { 135 throw new NameNotFoundException(name + " not found"); 136 } 137 138 if(nm.size() == 1) { 139 return answer; 140 } else { 141 return ((Context) answer).lookup(nm.getSuffix(1)); 142 } 143 } 144 145 public NamingEnumeration list(Name name) throws NamingException 146 { 147 if(name.isEmpty()) { 148 // Generate enumeration of context's contents 149 return new ListOfNames(bindings.keys()); 150 } 151 152 // Perhaps "name" names a context 153 Object target = lookup(name); 154 if(target instanceof Context) { 155 try { 156 return ((Context) target).list(""); 157 } finally { 158 ((Context) target).close(); 159 } 160 } 161 throw new NotContextException(name + " cannot be listed"); 162 } 163 164 public NamingEnumeration listBindings(Name name) throws NamingException 165 { 166 if(name.isEmpty()) { 167 // Generate enumeration of context's contents 168 return new ListOfBindings(bindings.keys()); 169 } 170 171 // Perhaps "name" names a context 172 Object target = lookup(name); 173 if(target instanceof Context) { 174 try { 175 return ((Context) target).list(""); 176 } finally { 177 ((Context) target).close(); 178 } 179 } 180 throw new NotContextException(name + " cannot be listed"); 181 } 182 183 public void bind(Name name, Object obj) throws NamingException 184 { 185 throw new OperationNotSupportedException(); 186 } 187 188 public void rebind(Name name, Object obj) throws NamingException 189 { 190 throw new OperationNotSupportedException(); 191 } 192 193 public void unbind(Name name) throws NamingException 194 { 195 throw new OperationNotSupportedException(); 196 } 197 198 public void rename(Name oldName, Name newName) throws NamingException 199 { 200 throw new OperationNotSupportedException(); 201 } 202 203 public Context createSubcontext(Name name) throws NamingException 204 { 205 throw new OperationNotSupportedException(); 206 } 207 208 public void destroySubcontext(Name name) throws NamingException 209 { 210 throw new OperationNotSupportedException(); 211 } 212 213 public NameParser getNameParser(Name name) throws NamingException 214 { 215 // Do lookup to verify that the name exists 216 Object obj = lookup(name); 217 if(obj instanceof Context) { 218 ((Context) obj).close(); 219 } 220 return ObdaUriParser.getInstance(); 221 } 222 223 public String composeName(String name, String prefix) 224 throws NamingException 225 { 226 throw new OperationNotSupportedException(); 227 } 228 229 public Object addToEnvironment(String propName, Object propVal) 230 throws NamingException 231 { 232 return env.put(propName, propVal); 233 } 234 235 public Object removeFromEnvironment(String propName) 236 throws NamingException 237 { 238 return env.remove(propName); 239 } 240 241 public Hashtable getEnvironment() throws NamingException 242 { 243 return new Hashtable(env); 244 } 245 246 public void close() throws NamingException 247 { 248 // nothing to do 249 } 250 251 252 253 public NamingEnumeration list(String name) throws NamingException 254 { 255 return list(new CompositeName(name)); 256 } 257 258 public NamingEnumeration listBindings(String name) throws NamingException 259 { 260 return listBindings(new CompositeName(name)); 261 } 262 263 public Object lookup(String name) throws NamingException 264 { 265 return lookup(new CompositeName(name)); 266 } 267 268 public Object lookupLink(Name name) throws NamingException 269 { 270 throw new OperationNotSupportedException(); 271 } 272 273 public Attributes getAttributes(Name name) throws NamingException 274 { 275 return getAttributes(name, null); // Same as attrIds == null 276 } 277 278 public Attributes getAttributes(Name name, String[] attrIds) 279 throws NamingException 280 { 281 if(name.isEmpty()) { 282 // Ask for the attributes of this context 283 return (Attributes) attrs.clone(); 284 } 285 286 // Extract the components that belong to this namespace 287 Name nm = getMyComponents(name); 288 String atom = nm.get(0); 289 Object inter = bindings.get(atom); 290 291 if(nm.size() == 1) { 292 // Atomic name; find object in the internal data structure 293 if(inter == null) { 294 throw new NameNotFoundException(name + " not found"); 295 } 296 297 if(inter instanceof DirContext) { 298 return ((DirContext) inter).getAttributes("", attrIds); 299 } else { 300 // Fetch the object's attributes from this context 301 return (Attributes) attrs.clone(); 302 } 303 } else { 304 // Intermediate name; consume the name in this context 305 // and then continue 306 if(!(inter instanceof DirContext)) { 307 throw new NotContextException(atom + " does not name a dircontext"); 308 } 309 return ((DirContext) inter).getAttributes(nm.getSuffix(1), attrIds); 310 } 311 } 312 313 public void modifyAttributes(Name name, int mod_op, Attributes attrs) 314 throws NamingException 315 { 316 throw new OperationNotSupportedException(); 317 } 318 319 public void modifyAttributes(Name name, ModificationItem[] mods) 320 throws NamingException 321 { 322 throw new OperationNotSupportedException(); 323 } 324 325 public void bind(Name name, Object obj, Attributes attrs) 326 throws NamingException 327 { 328 throw new OperationNotSupportedException(); 329 } 330 331 public void rebind(Name name, Object obj, Attributes attrs) 332 throws NamingException 333 { 334 throw new OperationNotSupportedException(); 335 } 336 337 public DirContext createSubcontext(Name name, Attributes attrs) 338 throws NamingException 339 { 340 throw new OperationNotSupportedException(); 341 } 342 343 public DirContext getSchema(Name name) throws NamingException 344 { 345 throw new OperationNotSupportedException(); 346 } 347 348 public DirContext getSchemaClassDefinition(Name name) 349 throws NamingException 350 { 351 throw new OperationNotSupportedException(); 352 } 353 354 public NamingEnumeration search(Name name, Attributes matchingAttrs) 355 throws NamingException 356 { 357 throw new OperationNotSupportedException(); 358 } 359 360 public NamingEnumeration search(Name name, 361 String filterExpr, 362 Object[] filterArgs, 363 SearchControls cons) 364 throws NamingException 365 { 366 throw new OperationNotSupportedException(); 367 } 368 369 public NamingEnumeration search(Name name, 370 Attributes matchingAttributes, 371 String[] attributesToReturn) 372 throws NamingException 373 { 374 throw new OperationNotSupportedException(); 375 } 376 377 public NamingEnumeration search(Name name, 378 String filter, 379 SearchControls cons) 380 throws NamingException 381 { 382 throw new OperationNotSupportedException(); 383 } 384 385 public void bind(String name, Object obj) throws NamingException 386 { 387 bind(new CompositeName(name), obj); 388 } 389 390 public void rebind(String name, Object obj) throws NamingException 391 { 392 rebind(new CompositeName(name), obj); 393 } 394 395 public void unbind(String name) throws NamingException 396 { 397 unbind(new CompositeName(name)); 398 } 399 400 public void rename(String oldName, String newName) throws NamingException 401 { 402 rename(new CompositeName(oldName), new CompositeName(newName)); 403 } 404 405 public Context createSubcontext(String name) throws NamingException 406 { 407 return createSubcontext(new CompositeName(name)); 408 } 409 410 public void destroySubcontext(String name) throws NamingException 411 { 412 destroySubcontext(new CompositeName(name)); 413 } 414 415 public NameParser getNameParser(String name) throws NamingException 416 { 417 return getNameParser(new CompositeName(name)); 418 } 419 420 public Object lookupLink(String name) throws NamingException 421 { 422 return lookupLink(new CompositeName(name)); 423 } 424 425 public Attributes getAttributes(String name) throws NamingException 426 { 427 return getAttributes(new CompositeName(name)); 428 } 429 430 public Attributes getAttributes(String name, String[] attrIds) 431 throws NamingException 432 { 433 return getAttributes(new CompositeName(name), attrIds); 434 } 435 436 public void modifyAttributes(String name, int mod_op, Attributes attrs) 437 throws NamingException 438 { 439 modifyAttributes(new CompositeName(name), mod_op, attrs); 440 } 441 442 public void modifyAttributes(String name, ModificationItem[] mods) 443 throws NamingException 444 { 445 modifyAttributes(new CompositeName(name), mods); 446 } 447 448 public void bind(String name, Object obj, Attributes attrs) 449 throws NamingException 450 { 451 bind(new CompositeName(name), attrs); 452 } 453 454 public void rebind(String name, Object obj, Attributes attrs) 455 throws NamingException 456 { 457 rebind(new CompositeName(name), obj, attrs); 458 } 459 460 public DirContext createSubcontext(String name, Attributes attrs) 461 throws NamingException 462 { 463 return createSubcontext(new CompositeName(name), attrs); 464 } 465 466 public DirContext getSchema(String name) throws NamingException 467 { 468 return getSchema(new CompositeName(name)); 469 } 470 471 public DirContext getSchemaClassDefinition(String name) 472 throws NamingException 473 { 474 return getSchemaClassDefinition(new CompositeName(name)); 475 } 476 477 public NamingEnumeration search(String name, 478 Attributes matchingAttributes, 479 String[] attributesToReturn) 480 throws NamingException 481 { 482 return search(new CompositeName(name), matchingAttributes, attributesToReturn); 483 } 484 485 public NamingEnumeration search(String name, 486 Attributes matchingAttributes) 487 throws NamingException 488 { 489 return search(new CompositeName(name), matchingAttributes); 490 } 491 492 public NamingEnumeration search(String name, 493 String filter, 494 SearchControls cons) 495 throws NamingException 496 { 497 return search(new CompositeName(name), filter, cons); 498 } 499 500 public NamingEnumeration search(String name, 501 String filterExpr, 502 Object[] filterArgs, 503 SearchControls cons) 504 throws NamingException 505 { 506 return search(new CompositeName(name), filterExpr, filterArgs, cons); 507 } 508 509 class ListOfNames implements NamingEnumeration { 510 protected Enumeration names; 511 512 ListOfNames(Enumeration names) 513 { 514 this.names = names; 515 } 516 517 public boolean hasMoreElements() 518 { 519 try { 520 return hasMore(); 521 } catch (NamingException e) { 522 return false; 523 } 524 } 525 526 public boolean hasMore() throws NamingException 527 { 528 return names.hasMoreElements(); 529 } 530 531 public Object next() throws NamingException 532 { 533 String name = (String) names.nextElement(); 534 String className = bindings.get(name).getClass().getName(); 535 return new NameClassPair(name, className); 536 } 537 538 public Object nextElement() 539 { 540 try { 541 return next(); 542 } catch (NamingException e) { 543 throw new NoSuchElementException(e.toString()); 544 } 545 } 546 547 public void close() 548 { 549 } 550 } 551 552 class ListOfBindings implements NamingEnumeration { 553 protected Enumeration names; 554 555 ListOfBindings(Enumeration names) 556 { 557 this.names = names; 558 } 559 560 public boolean hasMoreElements() 561 { 562 try { 563 return hasMore(); 564 } catch (NamingException e) { 565 return false; 566 } 567 } 568 569 public boolean hasMore() throws NamingException 570 { 571 return names.hasMoreElements(); 572 } 573 574 public Object next() throws NamingException 575 { 576 String name = (String) names.nextElement(); 577 Object bound = bindings.get(name); 578 return new Binding(name, bound); 579 } 580 581 public Object nextElement() 582 { 583 try { 584 return next(); 585 } catch (NamingException e) { 586 throw new NoSuchElementException(e.toString()); 587 } 588 } 589 590 public void close() 591 { 592 } 593 } 594 }