View Javadoc
1 /* 2 * Copyright (C) The Apache Software Foundation. All rights reserved. 3 * 4 * This software is published under the terms of the Apache Software License 5 * version 1.1, a copy of which has been included with this distribution in 6 * the LICENSE file. 7 */ 8 package org.apache.avalon.excalibur.naming; 9 10 import java.util.Hashtable; 11 import javax.naming.Context; 12 import javax.naming.InvalidNameException; 13 import javax.naming.NamingEnumeration; 14 import javax.naming.Name; 15 import javax.naming.NameParser; 16 import javax.naming.ContextNotEmptyException; 17 import javax.naming.NameAlreadyBoundException; 18 import javax.naming.NamingException; 19 import javax.naming.NotContextException; 20 import javax.naming.Reference; 21 import javax.naming.Referenceable; 22 import javax.naming.OperationNotSupportedException; 23 24 /*** 25 * Abstract local JNDI Context that can be inherited from to 26 * provide a particular type of Context. These contexts are assumed to be 27 * on the same machine. 28 * 29 * @author <a href="mailto:donaldp@apache.org">Peter Donald</a> 30 * @version $Revision: 1.2 $ 31 */ 32 public abstract class AbstractLocalContext 33 extends AbstractContext 34 { 35 protected Context m_parent; 36 protected Namespace m_namespace; 37 38 public AbstractLocalContext( final Namespace namespace, 39 final Hashtable environment, 40 final Context parent ) 41 { 42 super( environment ); 43 m_namespace = namespace; 44 m_parent = parent; 45 } 46 47 protected boolean isDestroyableContext( final Object object ) 48 throws NamingException 49 { 50 return getClass().isInstance( object ); 51 } 52 53 protected abstract Context newContext() 54 throws NamingException; 55 56 protected abstract Context cloneContext() 57 throws NamingException; 58 59 /*** 60 * Helper method to bind 61 */ 62 protected void bind( final Name name, Object object, final boolean rebind ) 63 throws NamingException 64 { 65 if( isSelf( name ) ) 66 { 67 throw new InvalidNameException( "Failed to bind self" ); 68 } 69 70 if( 1 == name.size() ) 71 { 72 boolean alreadyBound = false; 73 try 74 { 75 localLookup( name ); 76 alreadyBound = true; 77 } 78 catch( final NamingException ne ) {} 79 80 if( !rebind && alreadyBound ) 81 { 82 throw new NameAlreadyBoundException( name.get( 0 ) ); 83 } 84 else 85 { 86 //Should this occur here or in the factories ??? 87 if( object instanceof Referenceable ) 88 { 89 object = ((Referenceable)object).getReference(); 90 } 91 92 // Call getStateToBind for using any state factories 93 final Name atom = name.getPrefix( 1 ); 94 object = m_namespace.getStateToBind( object, atom, this, m_environment ); 95 96 doLocalBind( name, object ); 97 } 98 } 99 else 100 { 101 final Context context = lookupSubContext( getPathName( name ) ); 102 if( rebind ) 103 { 104 context.rebind( getLeafName( name ), object ); 105 } 106 else 107 { 108 context.bind( getLeafName( name ), object ); 109 } 110 } 111 } 112 113 protected abstract void doLocalBind( Name name, Object object ) 114 throws NamingException; 115 116 public void close() 117 { 118 m_parent = null; 119 m_namespace = null; 120 } 121 122 /*** 123 * Create a Subcontext. 124 * 125 * @param name the name of subcontext 126 * @return the created context 127 * @exception NamingException if an error occurs (ie context exists, badly formated name etc) 128 */ 129 public Context createSubcontext( final Name name ) 130 throws NamingException 131 { 132 final Context context = newContext(); 133 bind( name, context ); 134 return context; 135 } 136 137 public void destroySubcontext( final Name name ) 138 throws NamingException 139 { 140 if( isSelf( name ) ) 141 { 142 throw new InvalidNameException( "Failed to destroy self" ); 143 } 144 145 if( 1 == name.size() ) 146 { 147 Object object = null; 148 try 149 { 150 object = localLookup( name ); 151 } 152 catch( final NamingException ne ) 153 { 154 return; 155 } 156 157 checkUnbindContext( name, object ); 158 159 doLocalUnbind( name ); 160 } 161 else 162 { 163 final Context context = lookupSubContext( getPathName( name ) ); 164 165 Object object = null; 166 167 final Name atom = getLeafName( name ); 168 try 169 { 170 object = context.lookup( atom ); 171 } 172 catch( final NamingException ne ) 173 { 174 return; 175 } 176 177 checkUnbindContext( atom, object ); 178 179 context.destroySubcontext( atom ); 180 } 181 } 182 183 protected void checkUnbindContext( final Name name, final Object entry ) 184 throws NamingException 185 { 186 if( !isDestroyableContext( entry ) ) 187 { 188 throw new NotContextException( name.toString() ); 189 } 190 191 final Context context = (Context)entry; 192 if( context.list( "" ).hasMoreElements() ) 193 { 194 throw new ContextNotEmptyException( name.toString() ); 195 } 196 } 197 198 public String getNameInNamespace() 199 throws NamingException 200 { 201 throw new OperationNotSupportedException( "Namespace has no notion of a 'full name'" ); 202 } 203 204 protected NameParser getNameParser() 205 throws NamingException 206 { 207 return m_namespace.getNameParser(); 208 } 209 210 /*** 211 * Enumerates the names bound in the named context. 212 * 213 * @param name the name of the context 214 * @return the enumeration 215 * @exception NamingException if an error occurs 216 */ 217 public NamingEnumeration list( final Name name ) 218 throws NamingException 219 { 220 if( isSelf( name ) ) 221 { 222 return doLocalList(); 223 } 224 else 225 { 226 // Perhaps 'name' names a context 227 final Context context = lookupSubContext( name ); 228 return context.list( "" ); 229 } 230 } 231 232 protected abstract NamingEnumeration doLocalList() 233 throws NamingException; 234 235 protected abstract NamingEnumeration doLocalListBindings() 236 throws NamingException; 237 238 /*** 239 * Enumerates the names bound in the named context, along with the objects bound to them. 240 * 241 * @param name the name of the context 242 * @return the enumeration 243 * @exception NamingException if an error occurs 244 */ 245 public NamingEnumeration listBindings( final Name name ) 246 throws NamingException 247 { 248 if( isSelf( name ) ) 249 { 250 return doLocalListBindings(); 251 } 252 else 253 { 254 // Perhaps 'name' names a context 255 final Context context = lookupSubContext( name ); 256 return context.listBindings( "" ); 257 } 258 } 259 260 /*** 261 * Get the object named. 262 * 263 * @param name the name 264 * @return the object 265 * @exception NamingException if an error occurs (ie object name is inavlid or unbound) 266 */ 267 public Object lookup( final Name name ) 268 throws NamingException 269 { 270 //if it refers to base context return a copy of it. 271 if( isSelf( name ) ) 272 { 273 return cloneContext(); 274 } 275 276 if( 1 == name.size() ) 277 { 278 return localLookup( name ); 279 } 280 else 281 { 282 final Context context = lookupSubContext( getPathName( name ) ); 283 return context.lookup( getLeafName( name ) ); 284 } 285 } 286 287 /*** 288 * Lookup entry in local context. 289 * 290 * @param name the name in local context (size() == 1) 291 * @return the bound object 292 * @exception NamingException if an error occurs 293 */ 294 protected Object localLookup( final Name name ) 295 throws NamingException 296 { 297 final Object value = doLocalLookup( name ); 298 299 // Call getObjectInstance for using any object factories 300 try 301 { 302 final Name atom = name.getPrefix( 1 ); 303 return m_namespace.getObjectInstance( value, atom, this, m_environment ); 304 } 305 catch( final Exception e ) 306 { 307 final NamingException ne = new NamingException( "getObjectInstance failed" ); 308 ne.setRootCause( e ); 309 throw ne; 310 } 311 } 312 313 /*** 314 * Actually lookup raw entry in local context. 315 * When overidding this it is not neccesary to resolve references etc. 316 * 317 * @param name the name in local context (size() == 1) 318 * @return the bound object 319 * @exception NamingException if an error occurs 320 */ 321 protected abstract Object doLocalLookup( Name name ) 322 throws NamingException; 323 324 /*** 325 * Lookup a sub-context of current context. 326 * Note that name must have 1 or more elements. 327 * 328 * @param name the name of subcontext 329 * @return the sub-Context 330 * @exception NamingException if an error occurs (like named entry is not a Context) 331 */ 332 protected Context lookupSubContext( final Name name ) 333 throws NamingException 334 { 335 final Name atom = name.getPrefix( 1 ); 336 Object object = localLookup( atom ); 337 338 if( 1 != name.size() ) 339 { 340 if( !(object instanceof Context) ) 341 { 342 throw new NotContextException( atom.toString() ); 343 } 344 345 object = ((Context)object).lookup( name.getSuffix( 1 ) ); 346 } 347 348 if( !(object instanceof Context) ) 349 { 350 throw new NotContextException( name.toString() ); 351 } 352 353 //((Context)object).close(); 354 return (Context)object; 355 } 356 357 /*** 358 * Unbind a object from a name. 359 * 360 * @param name the name 361 * @exception NamingException if an error occurs 362 */ 363 public void unbind( final Name name ) 364 throws NamingException 365 { 366 if( isSelf( name ) ) 367 { 368 throw new InvalidNameException( "Cannot unbind self" ); 369 } 370 else if( 1 == name.size() ) 371 { 372 doLocalUnbind( name ); 373 } 374 else 375 { 376 final Context context = lookupSubContext( getPathName ( name ) ); 377 context.unbind( getLeafName( name ) ); 378 } 379 } 380 381 /*** 382 * Actually unbind raw entry in local context. 383 * 384 * @param name the name in local context (size() == 1) 385 * @exception NamingException if an error occurs 386 */ 387 protected abstract void doLocalUnbind( Name name ) 388 throws NamingException; 389 }

This page was automatically generated by Maven