1 /* 2 * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.corba.se.impl.naming.cosnaming; 27 28 // Import general CORBA classes 29 import org.omg.CORBA.SystemException; 30 import org.omg.CORBA.Object; 31 import org.omg.CORBA.INTERNAL; 32 import org.omg.CORBA.CompletionStatus; 33 import org.omg.CORBA.ORB; 34 import org.omg.PortableServer.POA; 35 36 // Import org.omg.CosNaming types 37 import org.omg.CosNaming.Binding; 38 import org.omg.CosNaming.BindingType; 39 import org.omg.CosNaming.BindingTypeHolder; 40 import org.omg.CosNaming.BindingListHolder; 41 import org.omg.CosNaming.BindingIteratorHolder; 42 import org.omg.CosNaming.NameComponent; 43 import org.omg.CosNaming.NamingContext; 44 45 import java.util.logging.Logger; 46 import java.util.logging.Level; 47 48 import java.util.Hashtable; 49 import com.sun.corba.se.impl.orbutil.LogKeywords; 50 import com.sun.corba.se.impl.logging.NamingSystemException; 51 import com.sun.corba.se.spi.logging.CORBALogDomains; 52 53 /** 54 * Class TransientNamingContext implements the methods defined 55 * by NamingContextDataStore, and extends the NamingContextImpl class to 56 * provide a servant implementation of CosNaming::NamingContext. 57 * The TransientNamingContext uses a hash table 58 * to store the mappings between bindings and object references and the 59 * hash table is not persistent; thereby the name "transient". 60 * This class should not be used directly; instead, the class 61 * TransientNameService should be instantiated. 62 * <p> 63 * The keys in the hash table are InternalBindingKey objects, containing 64 * a single NameComponent and implementing the proper functions, i.e., 65 * equals() and hashCode() in an efficient manner. The values in the hash 66 * table are InternalBindingValues and store a org.omg.CosNaming::Binding and 67 * the object reference associated with the binding. For iteration, 68 * TransientBindingIterator objects are created, which are passed a cloned 69 * copy of the hashtable. Since elements are inserted and deleted and 70 * never modified, this provides stable iterators at the cost of cloning 71 * the hash table. 72 * <p> 73 * To create and destroy object references, the TransientNamingContext 74 * uses the orb.connect() and orb.disconnect() methods. 75 * 76 * @see NamingContextImpl 77 * @see NamingContextDataStore 78 * @see TransientBindingIterator 79 * @see TransientNameService 80 */ 81 public class TransientNamingContext extends NamingContextImpl implements NamingContextDataStore 82 { 83 private Logger readLogger, updateLogger, lifecycleLogger; 84 85 // XXX: the wrapper calls are all preceded by logger updates. 86 // These can be combined, and then we simply use 3 NamingSystemException wrappers, 87 // for read, update, and lifecycl. 88 private NamingSystemException wrapper ; 89 90 /** 91 * Constructs a new TransientNamingContext object. 92 * @param orb an orb object. 93 * @param initial the initial naming context. 94 * @exception Exception a Java exception thrown of the base class cannot 95 * initialize. 96 */ 97 public TransientNamingContext(com.sun.corba.se.spi.orb.ORB orb, 98 org.omg.CORBA.Object initial, 99 POA nsPOA ) 100 throws java.lang.Exception 101 { 102 super(orb, nsPOA ); 103 wrapper = NamingSystemException.get( orb, CORBALogDomains.NAMING ) ; 104 105 this.localRoot = initial; 106 readLogger = orb.getLogger( CORBALogDomains.NAMING_READ); 107 updateLogger = orb.getLogger( CORBALogDomains.NAMING_UPDATE); 108 lifecycleLogger = orb.getLogger( 109 CORBALogDomains.NAMING_LIFECYCLE); 110 lifecycleLogger.fine( "Root TransientNamingContext LIFECYCLE.CREATED" ); 111 } 112 113 /** 114 * Binds the object to the name component as the specified binding type. 115 * It creates a InternalBindingKey object and a InternalBindingValue 116 * object and inserts them in the hash table. 117 * @param n A single org.omg.CosNaming::NameComponent under which the 118 * object will be bound. 119 * @param obj An object reference to be bound under the supplied name. 120 * @param bt The type of the binding (i.e., as object or as context). 121 * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA 122 * system exceptions. 123 */ 124 public final void Bind(NameComponent n, org.omg.CORBA.Object obj, 125 BindingType bt) 126 throws org.omg.CORBA.SystemException 127 { 128 // Create a key and a value 129 InternalBindingKey key = new InternalBindingKey(n); 130 NameComponent[] name = new NameComponent[1]; 131 name[0] = n; 132 Binding b = new Binding(name,bt); 133 InternalBindingValue value = new InternalBindingValue(b,null); 134 value.theObjectRef = obj; 135 // insert it 136 InternalBindingValue oldValue = 137 (InternalBindingValue)this.theHashtable.put(key,value); 138 139 if (oldValue != null) { 140 updateLogger.warning( LogKeywords.NAMING_BIND + "Name " + 141 getName( n ) + " Was Already Bound" ); 142 throw wrapper.transNcBindAlreadyBound() ; 143 } 144 if( updateLogger.isLoggable( Level.FINE ) ) { 145 updateLogger.fine( LogKeywords.NAMING_BIND_SUCCESS + 146 "Name Component: " + n.id + "." + n.kind ); 147 } 148 } 149 150 /** 151 * Resolves the supplied name to an object reference and returns 152 * the type of the resolved binding. It creates a InternalBindingKey 153 * and uses the key for looking up in the hash table. If nothing 154 * is found an exception is thrown, otherwise the object reference 155 * is returned and the binding type set. 156 * @param n a NameComponent which is the name to be resolved. 157 * @param bth the BindingType as an out parameter. 158 * @return the object reference bound under the supplied name, null if not 159 * found. 160 * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA 161 * system exceptions. 162 */ 163 public final org.omg.CORBA.Object Resolve(NameComponent n, 164 BindingTypeHolder bth) 165 throws org.omg.CORBA.SystemException 166 { 167 // Is the initial naming context requested? 168 if ( (n.id.length() == 0) 169 &&(n.kind.length() == 0 ) ) 170 { 171 bth.value = BindingType.ncontext; 172 return localRoot; 173 } 174 175 // Create a key and lookup the value 176 InternalBindingKey key = new InternalBindingKey(n); 177 178 InternalBindingValue value = 179 (InternalBindingValue) this.theHashtable.get(key); 180 if (value == null) return null; 181 if( readLogger.isLoggable( Level.FINE ) ) { 182 readLogger.fine( LogKeywords.NAMING_RESOLVE_SUCCESS 183 + "Namecomponent :" + getName( n ) ); 184 } 185 186 // Copy out binding type and object reference 187 bth.value = value.theBinding.binding_type; 188 return value.theObjectRef; 189 } 190 191 /** 192 * Deletes the binding with the supplied name. It creates a 193 * InternalBindingKey and uses it to remove the value associated 194 * with the key. If nothing is found an exception is thrown, otherwise 195 * the element is removed from the hash table. 196 * @param n a NameComponent which is the name to unbind 197 * @return the object reference bound to the name, or null if not found. 198 * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA 199 * system exceptions. 200 */ 201 public final org.omg.CORBA.Object Unbind(NameComponent n) 202 throws org.omg.CORBA.SystemException 203 { 204 // Create a key and remove it from the hashtable 205 InternalBindingKey key = new InternalBindingKey(n); 206 InternalBindingValue value = 207 (InternalBindingValue)this.theHashtable.remove(key); 208 209 // Return what was found 210 if (value == null) { 211 if( updateLogger.isLoggable( Level.FINE ) ) { 212 updateLogger.fine( LogKeywords.NAMING_UNBIND_FAILURE + 213 " There was no binding with the name " + getName( n ) + 214 " to Unbind " ); 215 } 216 return null; 217 } else { 218 if( updateLogger.isLoggable( Level.FINE ) ) { 219 updateLogger.fine( LogKeywords.NAMING_UNBIND_SUCCESS + 220 " NameComponent: " + getName( n ) ); 221 } 222 return value.theObjectRef; 223 } 224 } 225 226 /** 227 * List the contents of this NamingContext. It creates a new 228 * TransientBindingIterator object and passes it a clone of the 229 * hash table and an orb object. It then uses the 230 * newly created object to return the required number of bindings. 231 * @param how_many The number of requested bindings in the BindingList. 232 * @param bl The BindingList as an out parameter. 233 * @param bi The BindingIterator as an out parameter. 234 * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA 235 * system exceptions. 236 */ 237 public final void List(int how_many, BindingListHolder bl, 238 BindingIteratorHolder bi) 239 throws org.omg.CORBA.SystemException 240 { 241 try { 242 // Create a new binding iterator servant with a copy of this 243 // hashtable. nsPOA is passed to the object so that it can 244 // de-activate itself from the Active Object Map when 245 // Binding Iterator.destroy is called. 246 TransientBindingIterator bindingIterator = 247 new TransientBindingIterator(this.orb, 248 (Hashtable)this.theHashtable.clone(), nsPOA); 249 // Have it set the binding list 250 bindingIterator.list(how_many,bl); 251 252 byte[] objectId = nsPOA.activate_object( bindingIterator ); 253 org.omg.CORBA.Object obj = nsPOA.id_to_reference( objectId ); 254 255 // Get the object reference for the binding iterator servant 256 org.omg.CosNaming.BindingIterator bindingRef = 257 org.omg.CosNaming.BindingIteratorHelper.narrow( obj ); 258 259 bi.value = bindingRef; 260 } catch (org.omg.CORBA.SystemException e) { 261 readLogger.warning( LogKeywords.NAMING_LIST_FAILURE + e ); 262 throw e; 263 } catch (Exception e) { 264 // Convert to a CORBA system exception 265 readLogger.severe( LogKeywords.NAMING_LIST_FAILURE + e ); 266 throw wrapper.transNcListGotExc( e ) ; 267 } 268 } 269 270 /** 271 * Create a new NamingContext. It creates a new TransientNamingContext 272 * object, passing it the orb object. 273 * @return an object reference for a new NamingContext object implemented 274 * by this Name Server. 275 * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA 276 * system exceptions. 277 */ 278 public final org.omg.CosNaming.NamingContext NewContext() 279 throws org.omg.CORBA.SystemException 280 { 281 try { 282 // Create a new servant 283 TransientNamingContext transContext = 284 new TransientNamingContext( 285 (com.sun.corba.se.spi.orb.ORB) orb,localRoot, nsPOA); 286 287 byte[] objectId = nsPOA.activate_object( transContext ); 288 org.omg.CORBA.Object obj = nsPOA.id_to_reference( objectId ); 289 lifecycleLogger.fine( "TransientNamingContext " + 290 "LIFECYCLE.CREATE SUCCESSFUL" ); 291 return org.omg.CosNaming.NamingContextHelper.narrow( obj ); 292 293 } catch (org.omg.CORBA.SystemException e) { 294 lifecycleLogger.log( 295 Level.WARNING, LogKeywords.LIFECYCLE_CREATE_FAILURE, e ); 296 throw e; 297 } catch (Exception e) { 298 lifecycleLogger.log( 299 Level.WARNING, LogKeywords.LIFECYCLE_CREATE_FAILURE, e ); 300 throw wrapper.transNcNewctxGotExc( e ) ; 301 } 302 } 303 304 /** 305 * Destroys this NamingContext by disconnecting from the ORB. 306 * @exception org.omg.CORBA.SystemException One of a fixed set of CORBA 307 * system exceptions. 308 */ 309 public final void Destroy() 310 throws org.omg.CORBA.SystemException 311 { 312 // Destroy the object reference by disconnecting from the ORB 313 try { 314 byte[] objectId = nsPOA.servant_to_id( this ); 315 if( objectId != null ) { 316 nsPOA.deactivate_object( objectId ); 317 } 318 if( lifecycleLogger.isLoggable( Level.FINE ) ) { 319 lifecycleLogger.fine( 320 LogKeywords.LIFECYCLE_DESTROY_SUCCESS ); 321 } 322 } catch (org.omg.CORBA.SystemException e) { 323 lifecycleLogger.log( Level.WARNING, 324 LogKeywords.LIFECYCLE_DESTROY_FAILURE, e ); 325 throw e; 326 } catch (Exception e) { 327 lifecycleLogger.log( Level.WARNING, 328 LogKeywords.LIFECYCLE_DESTROY_FAILURE, e ); 329 throw wrapper.transNcDestroyGotExc( e ) ; 330 } 331 } 332 333 /** 334 * A Utility Method For Logging.. 335 */ 336 private String getName( NameComponent n ) { 337 return n.id + "." + n.kind; 338 } 339 340 /** 341 * Return whether this NamingContext contains any bindings. It forwards 342 * this request to the hash table. 343 * @return true if this NamingContext contains no bindings. 344 */ 345 public final boolean IsEmpty() 346 { 347 return this.theHashtable.isEmpty(); 348 } 349 350 // A hashtable to store the bindings 351 private final Hashtable theHashtable = new Hashtable(); 352 353 /** 354 * The local root naming context. 355 */ 356 public org.omg.CORBA.Object localRoot; 357 }