| 1 7 package winstone.jndi; 8 9 import java.util.ArrayList ; 10 import java.util.Hashtable ; 11 import java.util.Iterator ; 12 import java.util.List ; 13 import java.util.Map ; 14 15 import javax.naming.CompositeName ; 16 import javax.naming.Context ; 17 import javax.naming.Name ; 18 import javax.naming.NameNotFoundException ; 19 import javax.naming.NameParser ; 20 import javax.naming.NamingEnumeration ; 21 import javax.naming.NamingException ; 22 import javax.naming.NotContextException ; 23 import javax.naming.OperationNotSupportedException ; 24 import javax.naming.spi.NamingManager ; 25 26 import winstone.Logger; 27 28 34 public class WinstoneContext implements Context { 35 static final String PREFIX = "java:"; 36 static final String FIRST_CHILD = "comp"; 37 static final String BODGED_PREFIX = "java:comp"; 38 39 private Hashtable environment; 40 private Hashtable bindings; 41 private final static NameParser nameParser = new WinstoneNameParser(); 42 private WinstoneContext parent; 43 private String myAbsoluteName; 44 private Object contextLock; 45 46 49 public WinstoneContext(Map sourceEnvironment, WinstoneContext parent, 50 String absoluteName, Object contextLock) throws NamingException { 51 this.environment = new Hashtable (); 52 List sourceKeys = new ArrayList (sourceEnvironment.keySet()); 53 for (Iterator i = sourceKeys.iterator(); i.hasNext();) { 54 String key = (String ) i.next(); 55 addToEnvironment(key, sourceEnvironment.get(key)); 56 } 57 this.parent = parent; 58 this.myAbsoluteName = absoluteName; 59 this.contextLock = contextLock; 60 this.bindings = new Hashtable (); 61 Logger.log(Logger.FULL_DEBUG, ContainerJNDIManager.JNDI_RESOURCES, 62 "WinstoneContext.Initialised", this.myAbsoluteName); 63 } 64 65 68 protected WinstoneContext(Map sourceEnvironment, WinstoneContext parent, 69 String absoluteName, Object contextLock, Hashtable bindings) throws NamingException { 70 this.environment = new Hashtable (); 71 List sourceKeys = new ArrayList (sourceEnvironment.keySet()); 72 for (Iterator i = sourceKeys.iterator(); i.hasNext();) { 73 String key = (String ) i.next(); 74 addToEnvironment(key, sourceEnvironment.get(key)); 75 } 76 this.parent = parent; 77 this.myAbsoluteName = absoluteName; 78 this.contextLock = contextLock; 79 this.bindings = bindings; 80 Logger.log(Logger.FULL_DEBUG, ContainerJNDIManager.JNDI_RESOURCES, 81 "WinstoneContext.Copied", this.myAbsoluteName); 82 } 83 84 public void close() throws NamingException { 85 } 86 87 public Hashtable getEnvironment() throws NamingException { 88 return new Hashtable (this.environment); 89 } 90 91 public Object removeFromEnvironment(String property) throws NamingException { 92 return this.environment.remove(property); 93 } 94 95 public Object addToEnvironment(String property, Object value) 96 throws NamingException { 97 return this.environment.put(property, value); 98 } 99 100 108 protected Name validateName(Name name) throws NamingException { 109 if (name.isEmpty()) 111 return name; 112 else if (name.get(0).equals(BODGED_PREFIX)) { 113 Name newName = name.getSuffix(1).add(0, FIRST_CHILD).add(0, PREFIX); 114 return validateName(newName); 115 } else if (name.get(0).equals(PREFIX)) { 116 String stringName = name.toString(); 117 if (stringName.equals(this.myAbsoluteName)) 118 return nameParser.parse(""); 119 else if (stringName.startsWith(this.myAbsoluteName)) 120 return nameParser.parse(stringName 121 .substring(this.myAbsoluteName.length() + 1)); 122 else if (this.parent != null) 123 return null; 124 else 125 throw new NameNotFoundException (ContainerJNDIManager.JNDI_RESOURCES.getString( 126 "WinstoneContext.NameNotFound", name.toString())); 127 } else if (name instanceof CompositeName ) 128 return nameParser.parse(name.toString()); 129 else 130 return name; 131 } 132 133 138 public Object lookup(Name name) throws NamingException { 139 Name searchName = validateName(name); 140 141 if (searchName == null) 144 return this.parent.lookup(name); 145 else if (searchName.isEmpty()) 147 return new WinstoneContext(this.environment, this.parent, 148 this.myAbsoluteName, this.contextLock, this.bindings); 149 150 String thisName = searchName.get(0); 151 synchronized (this.contextLock) { 152 Object thisValue = bindings.get(thisName); 153 154 if (searchName.size() == 1) { 158 if (thisValue == null) 159 throw new NameNotFoundException (ContainerJNDIManager.JNDI_RESOURCES.getString( 160 "WinstoneContext.NameNotFound", name.toString())); 161 162 try { 163 return NamingManager.getObjectInstance(thisValue, 164 new CompositeName ().add(thisName), this, 165 this.environment); 166 } catch (Exception e) { 167 NamingException ne = new NamingException (ContainerJNDIManager.JNDI_RESOURCES 168 .getString("WinstoneContext.FailedToGetInstance")); 169 ne.setRootCause(e); 170 throw ne; 171 } 172 } 173 174 else if (thisValue == null) 175 throw new NameNotFoundException (ContainerJNDIManager.JNDI_RESOURCES.getString( 176 "WinstoneContext.NameNotFound", thisName.toString())); 177 178 else if (!(thisValue instanceof Context )) 181 throw new NotContextException (ContainerJNDIManager.JNDI_RESOURCES.getString( 182 "WinstoneContext.NotContext", new String [] { 183 thisName.toString(), 184 thisValue.getClass().getName() })); 185 186 else 189 try { 190 return ((Context ) thisValue) 191 .lookup(searchName.getSuffix(1)); 192 } finally { 193 ((Context ) thisValue).close(); 194 } 195 } 196 } 197 198 public Object lookup(String name) throws NamingException { 199 return lookup(new CompositeName (name)); 200 } 201 202 public Object lookupLink(Name name) throws NamingException { 203 Logger.log(Logger.WARNING, ContainerJNDIManager.JNDI_RESOURCES, 204 "WinstoneContext.LinkRefUnsupported"); 205 return lookup(name); 206 } 207 208 public Object lookupLink(String name) throws NamingException { 209 return lookupLink(new CompositeName (name)); 210 } 211 212 215 public NamingEnumeration list(Name name) throws NamingException { 216 Name searchName = validateName(name); 217 218 if (searchName == null) 221 return this.parent.list(name); 222 else if (searchName.isEmpty()) { 224 NamingEnumeration e = null; 225 synchronized (this.contextLock) { 226 e = new WinstoneNameEnumeration(this.bindings); 227 } 228 return e; 229 } 230 231 else { 233 Object ctx = this.lookup(searchName); 234 if (ctx instanceof Context ) 235 try { 236 return ((Context ) ctx).list(new CompositeName ("")); 237 } finally { 238 ((Context ) ctx).close(); 239 } 240 else if (ctx == null) 241 throw new NameNotFoundException (ContainerJNDIManager.JNDI_RESOURCES.getString( 242 "WinstoneContext.NameNotFound", searchName.toString())); 243 else 244 throw new NotContextException (ContainerJNDIManager.JNDI_RESOURCES.getString( 245 "WinstoneContext.NotContext", 246 new String [] { searchName.toString(), 247 ctx.getClass().getName() })); 248 } 249 } 250 251 public NamingEnumeration list(String name) throws NamingException { 252 return list(new CompositeName (name)); 253 } 254 255 public NamingEnumeration listBindings(Name name) throws NamingException { 256 Name searchName = validateName(name); 257 258 if (searchName == null) 261 return this.parent.list(name); 262 else if (searchName.isEmpty()) { 264 NamingEnumeration e = null; 265 synchronized (this.contextLock) { 266 e = new WinstoneBindingEnumeration(this.bindings, 267 this.environment, this); 268 } 269 return e; 270 } 271 272 else { 274 Object ctx = this.lookup(searchName); 275 if (ctx instanceof Context ) 276 try { 277 return ((Context ) ctx).listBindings(new CompositeName ("")); 278 } finally { 279 ((Context ) ctx).close(); 280 } 281 else if (ctx == null) 282 throw new NameNotFoundException (ContainerJNDIManager.JNDI_RESOURCES.getString( 283 "WinstoneContext.NameNotFound", searchName.toString())); 284 else 285 throw new NotContextException (ContainerJNDIManager.JNDI_RESOURCES.getString( 286 "WinstoneContext.NotContext", 287 new String [] { searchName.toString(), 288 ctx.getClass().getName() })); 289 } 290 } 291 292 public NamingEnumeration listBindings(String name) throws NamingException { 293 return listBindings(new CompositeName (name)); 294 } 295 296 public NameParser getNameParser(Name name) throws NamingException { 297 Object obj = lookup(name); 298 if (obj instanceof Context ) { 299 ((Context ) obj).close(); 300 } 301 return nameParser; 302 } 303 304 public NameParser getNameParser(String name) throws NamingException { 305 return getNameParser(new CompositeName (name)); 306 } 307 308 public String getNameInNamespace() throws NamingException { 309 return this.myAbsoluteName; 310 } 311 312 315 316 public void bind(String name, Object value) throws NamingException { 317 bind(new CompositeName (name), value); 318 } 319 320 public void bind(Name name, Object value) throws NamingException { 321 bind(name, value, false); 322 } 323 324 protected void bind(Name name, Object value, boolean allowOverwrites) 325 throws NamingException { 326 Name bindName = validateName(name); 327 328 if (bindName == null) 331 this.parent.bind(name, value, allowOverwrites); 332 else if (bindName.isEmpty()) 334 throw new NamingException (ContainerJNDIManager.JNDI_RESOURCES.getString( 335 "WinstoneContext.AlreadyExists", name.toString())); 336 else if (bindName.size() > 1) { 337 Object ctx = lookup(bindName.get(0)); 338 if (!(ctx instanceof Context )) 339 throw new NotContextException (ContainerJNDIManager.JNDI_RESOURCES.getString( 340 "WinstoneContext.NotContext", new String [] { 341 bindName.get(0), ctx.getClass().getName() })); 342 else if (ctx == null) 343 throw new NameNotFoundException (ContainerJNDIManager.JNDI_RESOURCES.getString( 344 "WinstoneContext.NameNotFound", bindName.get(0))); 345 else 346 try { 347 if (allowOverwrites) 348 ((Context ) ctx).rebind(bindName.getSuffix(1), value); 349 else 350 ((Context ) ctx).bind(bindName.getSuffix(1), value); 351 } finally { 352 ((Context ) ctx).close(); 353 } 354 } else if ((!allowOverwrites) && this.bindings.get(name.get(0)) != null) 355 throw new NamingException (ContainerJNDIManager.JNDI_RESOURCES.getString( 356 "WinstoneContext.AlreadyExists", name.toString())); 357 else { 358 value = NamingManager.getStateToBind(value, new CompositeName () 359 .add(bindName.get(0)), this, this.environment); 360 synchronized (this.contextLock) { 361 this.bindings.put(bindName.get(0), value); 362 } 363 } 364 } 365 366 public void rebind(String name, Object value) throws NamingException { 367 rebind(new CompositeName (name), value); 368 } 369 370 public void rebind(Name name, Object value) throws NamingException { 371 bind(name, value, true); 372 } 373 374 public void unbind(String name) throws NamingException { 375 unbind(new CompositeName (name)); 376 } 377 378 public void unbind(Name name) throws NamingException { 379 Name unbindName = validateName(name); 380 381 if (unbindName == null) 384 this.parent.unbind(name); 385 else if (unbindName.isEmpty()) 387 throw new NamingException (ContainerJNDIManager.JNDI_RESOURCES 388 .getString("WinstoneContext.CantUnbindEmptyName")); 389 else if (unbindName.size() > 1) { 390 Object ctx = lookup(unbindName.get(0)); 391 if (!(ctx instanceof Context )) 392 throw new NotContextException (ContainerJNDIManager.JNDI_RESOURCES.getString( 393 "WinstoneContext.NotContext", new String [] { 394 unbindName.get(0), ctx.getClass().getName() })); 395 else if (ctx == null) 396 throw new NameNotFoundException (ContainerJNDIManager.JNDI_RESOURCES.getString( 397 "WinstoneContext.NameNotFound", unbindName.get(0))); 398 else 399 try { 400 ((Context ) ctx).unbind(unbindName.getSuffix(1)); 401 } finally { 402 ((Context ) ctx).close(); 403 } 404 } else if (this.bindings.get(name.get(0)) == null) 405 throw new NamingException (ContainerJNDIManager.JNDI_RESOURCES.getString( 406 "WinstoneContext.NameNotFound", name.toString())); 407 else { 408 synchronized (this.contextLock) { 409 this.bindings.remove(unbindName.get(0)); 411 } 412 } 413 } 414 415 public void rename(Name oldName, Name newName) throws NamingException { 416 throw new OperationNotSupportedException ( 417 "rename not supported in Winstone java:/ context"); 418 } 419 420 public void rename(String oldName, String newName) throws NamingException { 421 rename(new CompositeName (oldName), new CompositeName (newName)); 422 } 423 424 public Context createSubcontext(String name) throws NamingException { 425 return createSubcontext(new CompositeName (name)); 426 } 427 428 public Context createSubcontext(Name name) throws NamingException { 429 Name childName = validateName(name); 430 431 if (childName == null) 434 return this.parent.createSubcontext(name); 435 else if (childName.isEmpty()) 437 throw new NamingException (ContainerJNDIManager.JNDI_RESOURCES.getString( 438 "WinstoneContext.AlreadyExists", name.toString())); 439 else if (childName.size() > 1) { 440 Object ctx = lookup(childName.get(0)); 441 if (!(ctx instanceof Context )) 442 throw new NotContextException (ContainerJNDIManager.JNDI_RESOURCES.getString( 443 "WinstoneContext.NotContext", new String [] { 444 childName.get(0), ctx.getClass().getName() })); 445 else if (ctx == null) 446 throw new NameNotFoundException (ContainerJNDIManager.JNDI_RESOURCES.getString( 447 "WinstoneContext.NameNotFound", childName.get(0))); 448 else 449 try { 450 ((Context ) ctx).createSubcontext(childName.getSuffix(1)); 451 } finally { 452 ((Context ) ctx).close(); 453 } 454 } 455 456 Context childContext = null; 457 synchronized (this.contextLock) { 458 if (this.bindings.get(childName.get(0)) != null) 459 throw new NamingException (ContainerJNDIManager.JNDI_RESOURCES.getString( 460 "WinstoneContext.AlreadyExists", childName.get(0))); 461 else { 462 childContext = new WinstoneContext(this.environment, this, 463 this.myAbsoluteName + "/" + childName.get(0), 464 new Boolean (true)); 465 this.bindings.put(childName.get(0), childContext); 466 } 467 } 468 return childContext; 469 } 470 471 public void destroySubcontext(String name) throws NamingException { 472 destroySubcontext(new CompositeName (name)); 473 } 474 475 public void destroySubcontext(Name name) throws NamingException { 476 Name childName = validateName(name); 477 478 if (childName == null) 480 this.parent.destroySubcontext(name); 481 else if (childName.isEmpty()) { 483 if (!name.isEmpty()) 484 this.parent.destroySubcontext(name.getSuffix(name.size() - 2)); 485 else 486 throw new NamingException (ContainerJNDIManager.JNDI_RESOURCES 487 .getString("WinstoneContext.CantDestroyEmptyName")); 488 } else if (childName.size() > 1) { 489 Object ctx = lookup(childName.get(0)); 490 if (!(ctx instanceof Context )) 491 throw new NotContextException (ContainerJNDIManager.JNDI_RESOURCES.getString( 492 "WinstoneContext.NotContext", new String [] { 493 childName.get(0), ctx.getClass().getName() })); 494 else if (ctx == null) 495 throw new NameNotFoundException (ContainerJNDIManager.JNDI_RESOURCES.getString( 496 "WinstoneContext.NameNotFound", childName.get(0))); 497 else 498 try { 499 ((Context ) ctx).destroySubcontext(childName.getSuffix(1)); 500 } finally { 501 ((Context ) ctx).close(); 502 } 503 } else 504 synchronized (this.contextLock) { 505 Context childContext = (Context ) lookup(childName.get(0)); 506 childContext.close(); 507 this.bindings.remove(childName.get(0)); 508 } 509 } 510 511 public String composeName(String name1, String name2) 512 throws NamingException { 513 Name name = composeName(new CompositeName (name1), new CompositeName ( 514 name2)); 515 return name == null ? null : name.toString(); 516 } 517 518 public Name composeName(Name name1, Name name2) throws NamingException { 519 throw new OperationNotSupportedException ( 520 "composeName not supported in Winstone java:/ namespace"); 521 } 522 } 523 | Popular Tags |