1 22 package org.jboss.ha.jndi; 23 24 import java.util.ArrayList ; 25 import java.util.Collection ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.List ; 29 import java.util.Map ; 30 import java.util.Set ; 31 import java.util.Vector ; 32 33 import javax.naming.Binding ; 34 import javax.naming.Context ; 35 import javax.naming.InitialContext ; 36 import javax.naming.InvalidNameException ; 37 import javax.naming.Name ; 38 import javax.naming.NameAlreadyBoundException ; 39 import javax.naming.NameClassPair ; 40 import javax.naming.NameNotFoundException ; 41 import javax.naming.NamingException ; 42 import javax.naming.NotContextException ; 43 44 import org.jboss.cache.Cache; 45 import org.jboss.cache.CacheException; 46 import org.jboss.cache.Fqn; 47 import org.jboss.cache.Node; 48 import org.jboss.ha.framework.interfaces.HAPartition; 49 import org.jboss.logging.Logger; 50 import org.jnp.interfaces.Naming; 51 import org.jnp.interfaces.NamingContext; 52 import org.jnp.interfaces.NamingParser; 53 54 61 public class TreeHead 62 implements org.jnp.interfaces.Naming 63 { 64 static final long serialVersionUID = 6342802270002172451L; 65 66 private static final NamingParser parser = new NamingParser(); 67 private final Fqn m_root; 68 69 private static Logger log = Logger.getLogger(TreeHead.class); 71 72 private Cache m_cache; 73 74 private transient HAPartition partition; 75 private transient HAJNDI father; 76 77 79 public TreeHead (Cache cache, Fqn root) 80 throws NamingException 81 { 82 super(); 83 m_cache = cache; 84 m_root = root; 85 } 86 87 89 public void init() throws Exception 90 { 91 log.debug("HAJNDI registering RPC Handler with HAPartition"); 92 partition.registerRPCHandler("HAJNDI", this); 93 log.debug("initializing HAJNDITreeCache root"); 94 putTreeRoot(); 95 } 96 97 public void stop() throws Exception 98 { 99 100 } 101 102 public void destroy() throws Exception 103 { 104 log.debug("HAJNDI unregistering RPCHandler with HAPartition"); 105 partition.unregisterRPCHandler("HAJNDI", this); 106 } 107 108 public void setPartition (HAPartition partition) 109 { 110 this.partition = partition; 111 } 112 113 public void setHARMIHead (HAJNDI father) 114 { 115 this.father = father; 116 } 117 118 120 public void bind(Name name, Object obj, String className) 121 throws NamingException 122 { 123 if( log.isTraceEnabled() ) 124 log.trace("bind, name="+name); 125 126 internalBind(name, obj, className, false); 127 } 128 129 public void rebind(Name name, Object obj, String className) 130 throws NamingException 131 { 132 if( log.isTraceEnabled() ) 133 log.trace("rebind, name="+name); 134 135 internalBind(name, obj, className, true); 136 } 137 138 public void unbind(Name name) 139 throws NamingException 140 { 141 if( log.isTraceEnabled() ) 142 log.trace("unbind, name="+name); 143 if (name.isEmpty()) 144 { 145 throw new InvalidNameException (); 147 } 148 149 try 151 { 152 Fqn temp = new Fqn(m_root, Fqn.fromString(name.toString())); 153 if (m_cache.hasChild(temp)) 155 { 156 m_cache.removeNode(temp); 157 return; 158 } 159 } catch (CacheException ce) 160 { 161 NamingException ne = new NamingException (); 162 ne.setRootCause(ce); 163 throw ne; 164 } 165 166 int size = name.size(); 167 168 Fqn ctx; 170 String key = name.get(size - 1); 171 if (size > 1) { 173 String prefix = name.getPrefix(size - 1).toString(); 174 Fqn fqn = Fqn.fromString(prefix); 175 ctx = new Fqn(m_root, fqn); 176 } 177 else 178 ctx = m_root; 179 180 try 181 { 182 Object removed = m_cache.remove(ctx, key); 183 if (removed == null) 184 { 185 if (!m_cache.hasChild(ctx)) 186 { 187 throw new NotContextException (name.getPrefix(size - 1).toString() + " not a context"); 188 } 189 else 190 { 191 throw new NameNotFoundException (key + " not bound"); 192 } 193 } 194 } catch (CacheException ce) 195 { 196 NamingException ne = new NamingException (); 197 ne.setRootCause(ce); 198 throw ne; 199 } 200 } 201 202 public Object lookup(Name name) 203 throws NamingException 204 { 205 boolean trace = log.isTraceEnabled(); 206 if( trace ) 207 log.trace("lookup, name="+name); 208 209 Object result = null; 210 if (name.isEmpty()) 211 { 212 return new NamingContext(null, (Name )(parser.parse("")), getRoot()); 214 } 215 216 try 218 { 219 Node n = m_cache.getChild(new Fqn(m_root, Fqn.fromString(name.toString()))); 220 if (n != null) 221 { 222 Name fullName = (Name )(name.clone()); 223 return new NamingContext(null, fullName, getRoot()); 224 } 225 } catch (CacheException ce) 226 { 227 NamingException ne = new NamingException (); 228 ne.setRootCause(ce); 229 throw ne; 230 } 231 232 int size = name.size(); 233 234 Fqn ctx; 236 String key = name.get(size - 1); 237 if (size > 1) { 239 String prefix = name.getPrefix(size - 1).toString(); 240 Fqn fqn = Fqn.fromString(prefix); 241 ctx = new Fqn(m_root, fqn); 242 } 243 else 244 ctx = m_root; 245 246 try 247 { 248 Binding b = (Binding )m_cache.get(ctx, key); 249 if (b != null) 250 { 251 result = b.getObject(); 252 } 253 else 254 { 255 result = internalLookupLocally(name); 257 } 258 } catch (CacheException ce) 259 { 260 NamingException ne = new NamingException (); 261 ne.setRootCause(ce); 262 throw ne; 263 } 264 return result; 265 } 266 267 public Object lookupLocally(Name name) throws NamingException 268 { 269 boolean trace = log.isTraceEnabled(); 270 if( trace ) 271 log.trace("lookupLocally, name="+name); 272 273 try 278 { 279 if (NamingContext.localServer != null) 280 { 281 return NamingContext.localServer.lookup(name); 282 } 283 else 284 { 285 InitialContext ctx = new InitialContext (); 286 return ctx.lookup(name); 287 } 288 } 289 catch (NamingException e) 290 { 291 if( trace ) 292 log.trace("lookupLocally failed, name=" + name, e); 293 throw e; 294 } 295 catch (java.rmi.RemoteException e) 296 { 297 NamingException ne = new NamingException ("unknown remote exception"); 298 ne.setRootCause(e); 299 if( trace ) 300 log.trace("lookupLocally failed, name=" + name, e); 301 throw ne; 302 } 303 catch (RuntimeException e) 304 { 305 if( trace ) 306 log.trace("lookupLocally failed, name=" + name, e); 307 throw e; 308 } 309 } 310 311 public Collection list(Name name) 312 throws NamingException 313 { 314 if( log.isTraceEnabled() ) 315 log.trace("list, name="+name); 316 Collection result = null; 317 318 Fqn ctx; 320 String ctxName = ""; 321 int size = name.size(); 322 if (size >= 1) 323 { 324 ctxName = name.toString(); 325 Fqn fqn = Fqn.fromString(ctxName); 326 ctx = new Fqn(m_root, fqn); 327 } 328 else 329 ctx = m_root; 330 331 boolean exists = m_cache.hasChild(ctx); 332 if (!exists) 333 { 334 try 335 { 336 return enum2list(new InitialContext ().list(name)); 337 } catch (NamingException e) 338 { 339 throw new NotContextException (ctxName+ " not a context"); 340 } 341 } 342 343 Vector list = null; 344 try 345 { 346 list = new Vector (); 347 348 Node base = m_cache.getChild(ctx); 349 if (base != null) 350 { 351 Map data = base.getData(); 352 for (Iterator it = data.values().iterator(); it.hasNext();) 353 { 354 Binding b = (Binding ) it.next(); 355 list.addElement(new NameClassPair (b.getName(),b.getClassName(),true)); 356 } 357 358 Set children = base.getChildrenNames(); 359 if (children != null && !children.isEmpty()) 360 { 361 Iterator iter2 = children.iterator(); 362 while (iter2.hasNext()) { 363 String node = (String )iter2.next(); 364 Name fullName = (Name )(name.clone()); 365 fullName.add(node); 366 list.addElement(new NameClassPair (node, NamingContext.class.getName(),true)); 367 } 368 } 369 } 370 } catch (CacheException ce) 371 { 372 NamingException ne = new NamingException (); 373 ne.setRootCause(ce); 374 throw ne; 375 } 376 return list; 377 } 378 379 public Collection listBindings(Name name) 380 throws NamingException 381 { 382 if( log.isTraceEnabled() ) 383 log.trace("listBindings, name="+name); 384 385 Fqn ctx; 387 String ctxName = ""; 388 int size = name.size(); 389 if (size >= 1) 390 { 391 ctxName = name.toString(); 392 Fqn fqn = Fqn.fromString(ctxName); 393 ctx = new Fqn(m_root, fqn); 394 } 395 else 396 ctx = m_root; 397 398 boolean exists = m_cache.hasChild(ctx); 399 if (!exists) 400 { 401 try 403 { 404 return enum2list(new InitialContext ().listBindings(name)); 405 } catch (NamingException e) 406 { 407 throw new NotContextException (ctxName+ " not a context"); 408 } 409 } 410 411 Vector list = null; 412 try 413 { 414 list = new Vector (); 415 416 Node node = m_cache.getChild(ctx); 417 if (node != null) 418 { 419 Map data = node.getData(); 420 if (data != null && data.size() > 0) 421 { 422 list.addAll(data.values()); 423 } 424 425 Set children = node.getChildrenNames(); 426 if (children != null && !children.isEmpty()) 427 { 428 Iterator iter2 = children.iterator(); 429 while (iter2.hasNext()) { 430 String child = (String )iter2.next(); 431 Name fullName = (Name )(name.clone()); 432 fullName.add(child); 433 NamingContext subCtx = new NamingContext(null, fullName, getRoot()); 434 Binding b = new Binding (child, NamingContext.class.getName(), subCtx, true); 435 list.addElement(b); 436 } 437 } 438 } 439 } catch (CacheException ce) 440 { 441 NamingException ne = new NamingException (); 442 ne.setRootCause(ce); 443 throw ne; 444 } 445 return list; 446 } 447 448 public javax.naming.Context createSubcontext(Name name) 449 throws NamingException 450 { 451 452 if( log.isTraceEnabled() ) 453 log.trace("createSubcontext, name="+name); 454 int size = name.size(); 455 if( size == 0 ) 456 throw new InvalidNameException ("Cannot pass an empty name to createSubcontext"); 457 458 Context subCtx = null; 459 460 String str = name.toString(); 462 Fqn fqn = Fqn.fromString(str); 463 Fqn ctx = new Fqn(m_root, fqn); 464 if (m_cache.hasChild(ctx)) 465 { 466 throw new NameAlreadyBoundException (); 467 } 468 469 Fqn pctx; 471 String newctx = name.get(size - 1); 472 if (size > 1) { 474 String prefix = name.getPrefix(size - 1).toString(); 475 Fqn fqn2 = Fqn.fromString(prefix); 476 pctx = new Fqn(m_root, fqn2); 477 } 478 else 479 pctx = m_root; 480 481 boolean exists = m_cache.hasChild(pctx); 482 if (!exists) 483 { 484 throw new NotContextException (name.getPrefix(size - 1).toString()); 485 } 486 487 Fqn newf = new Fqn(pctx, Fqn.fromString(newctx)); 488 try 489 { 490 m_cache.put(newf, new HashMap ()); 491 } catch (CacheException ce) 492 { 493 NamingException ne = new NamingException (); 494 ne.setRootCause(ce); 495 throw ne; 496 } 497 498 Name fullName = (Name ) parser.parse(""); 499 fullName.addAll(name); 500 subCtx = new NamingContext(null, fullName, getRoot()); 501 502 return subCtx; 503 } 504 505 public Naming getRoot () 506 { 507 return father.getHAStub(); 508 } 509 510 private void putTreeRoot() 511 throws CacheException 512 { 513 if (!m_cache.hasChild(m_root)) 514 { 515 m_cache.put(m_root, null); 516 } 517 } 518 519 private void internalBind(Name name, Object obj, String className, boolean rebind) 520 throws NamingException 521 { 522 if (name.isEmpty()) 523 { throw new InvalidNameException (); 525 } 526 527 int size = name.size(); 528 529 Fqn ctx; 531 String key = name.get(size - 1); 532 if (size > 1) { 534 String prefix = name.getPrefix(size - 1).toString(); 535 Fqn fqn = Fqn.fromString(prefix); 536 ctx = new Fqn(m_root, fqn); 537 } 538 else 539 ctx = m_root; 540 541 boolean exists = m_cache.hasChild(ctx); 542 if (!exists) 543 { 544 throw new NotContextException (name.getPrefix(size - 1).toString() + " not a context"); 545 } 549 if (!rebind) 550 { 551 Node node = m_cache.getChild(ctx); 552 if (node != null && (node.get(key) != null)) 553 { 554 throw new NameAlreadyBoundException (key); 555 } 556 } 557 try { 558 m_cache.put(ctx, key, new Binding (key, className, obj, true)); 559 } 560 catch (Exception e) 561 { 562 System.out.println(e.toString()); 563 } 564 } 565 566 private Object internalLookupLocally(Name name) 567 throws NamingException 568 { 569 boolean trace = log.isTraceEnabled(); 570 Object result = null; 571 try 572 { 573 result = lookupLocally(name); 575 } 576 catch (NameNotFoundException nnfe) 577 { 578 Object [] args = new Object [1]; 580 args[0] = name; 581 List rsp = null; 582 Exception cause = null; 583 try 584 { 585 if( trace ) 586 log.trace("calling lookupLocally(" + name + ") on HAJNDI cluster"); 587 rsp = partition.callMethodOnCluster("HAJNDI", "lookupLocally", args, new Class []{Name .class}, true); 588 } 589 catch (Exception ignored) 590 { 591 if( trace ) 592 log.trace("Clustered lookupLocally("+name+") failed", ignored); 593 cause = ignored; 594 } 595 596 if( trace ) 597 log.trace("Returned results size: "+ (rsp != null ? rsp.size() : 0)); 598 if (rsp == null || rsp.size() == 0) 599 { 600 NameNotFoundException nnfe2 = new NameNotFoundException (name.toString()); 601 nnfe2.setRootCause(cause); 602 throw nnfe2; 603 } 604 605 for (int i = 0; i < rsp.size(); i++) 606 { 607 result = rsp.get(i); 608 if( trace ) 609 { 610 String type = (result != null ? result.getClass().getName() : "null"); 611 log.trace("lookupLocally, i="+i+", value="+result+", type="+type); 612 } 613 if ( result != null && !(result instanceof Exception ) ) 615 return result; 616 } 617 throw nnfe; 618 } 619 return result; 620 } 621 622 private ArrayList enum2list (javax.naming.NamingEnumeration en) 623 { 624 ArrayList rtn = new ArrayList (); 625 try 626 { 627 while (en.hasMore()) 628 { 629 rtn.add(en.next()); 630 } 631 en.close(); 632 } 633 catch (NamingException ignored) {} 634 return rtn; 635 } 636 } 637 | Popular Tags |