1 /* 2 * Copyright (c) 1999, 2005, 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.jndi.cosnaming; 27 28 import javax.naming.*; 29 import javax.naming.spi.NamingManager; 30 31 import java.util.NoSuchElementException; 32 import java.util.Hashtable; 33 34 import org.omg.CosNaming.*; 35 import org.omg.CosNaming.NamingContextPackage.*; 36 import org.omg.CORBA.*; 37 38 /** 39 * Implements the JNDI NamingEnumeration interface for COS 40 * Naming. Gets hold of a list of bindings from the COS Naming Server 41 * and allows the client to iterate through them. 42 * 43 * @author Raj Krishnamurthy 44 * @author Rosanna Lee 45 */ 46 47 final class CNBindingEnumeration implements NamingEnumeration { 48 49 private static final int DEFAULT_BATCHSIZE = 100; 50 private BindingListHolder _bindingList; // list of bindings 51 private BindingIterator _bindingIter; // iterator for getting list of bindings 52 private int counter; // pointer in _bindingList 53 private int batchsize = DEFAULT_BATCHSIZE; // how many to ask for each time 54 private CNCtx _ctx; // ctx to list 55 private Hashtable _env; // environment for getObjectInstance 56 private boolean more = false; // iterator done? 57 private boolean isLookedUpCtx = false; // iterating on a context beneath this context ? 58 59 /** 60 * Creates a CNBindingEnumeration object. 61 * @param ctx Context to enumerate 62 */ 63 CNBindingEnumeration(CNCtx ctx, boolean isLookedUpCtx, Hashtable env) { 64 // Get batch size to use 65 String batch = (env != null ? 66 (String)env.get(javax.naming.Context.BATCHSIZE) : null); 67 if (batch != null) { 68 try { 69 batchsize = Integer.parseInt(batch); 70 } catch (NumberFormatException e) { 71 throw new IllegalArgumentException("Batch size not numeric: " + batch); 72 } 73 } 74 _ctx = ctx; 75 _ctx.incEnumCount(); 76 this.isLookedUpCtx = isLookedUpCtx; 77 _env = env; 78 _bindingList = new BindingListHolder(); 79 BindingIteratorHolder _bindingIterH = new BindingIteratorHolder(); 80 81 // Perform listing and request that bindings be returned in _bindingIter 82 // Upon return,_bindingList returns a zero length list 83 _ctx._nc.list(0, _bindingList, _bindingIterH); 84 85 _bindingIter = _bindingIterH.value; 86 87 // Get first batch using _bindingIter 88 if (_bindingIter != null) { 89 more = _bindingIter.next_n(batchsize, _bindingList); 90 } else { 91 more = false; 92 } 93 counter = 0; 94 } 95 96 /** 97 * Returns the next binding in the list. 98 * @exception NamingException any naming exception. 99 */ 100 101 public java.lang.Object next() throws NamingException { 102 if (more && counter >= _bindingList.value.length) { 103 getMore(); 104 } 105 if (more && counter < _bindingList.value.length) { 106 org.omg.CosNaming.Binding bndg = _bindingList.value[counter]; 107 counter++; 108 return mapBinding(bndg); 109 } else { 110 throw new NoSuchElementException(); 111 } 112 } 113 114 115 /** 116 * Returns true or false depending on whether there are more bindings. 117 * @return boolean value 118 */ 119 120 public boolean hasMore() throws NamingException { 121 // If there's more, check whether current bindingList has been exhausted, 122 // and if so, try to get more. 123 // If no more, just say so. 124 return more ? (counter < _bindingList.value.length || getMore()) : false; 125 } 126 127 /** 128 * Returns true or false depending on whether there are more bindings. 129 * Need to define this to satisfy the Enumeration api requirement. 130 * @return boolean value 131 */ 132 133 public boolean hasMoreElements() { 134 try { 135 return hasMore(); 136 } catch (NamingException e) { 137 return false; 138 } 139 } 140 141 /** 142 * Returns the next binding in the list. 143 * @exception NoSuchElementException Thrown when the end of the 144 * list is reached. 145 */ 146 147 public java.lang.Object nextElement() { 148 try { 149 return next(); 150 } catch (NamingException ne) { 151 throw new NoSuchElementException(); 152 } 153 } 154 155 public void close() throws NamingException { 156 more = false; 157 if (_bindingIter != null) { 158 _bindingIter.destroy(); 159 _bindingIter = null; 160 } 161 if (_ctx != null) { 162 _ctx.decEnumCount(); 163 164 /** 165 * context was obtained by CNCtx, the user doesn't have a handle to 166 * it, close it as we are done enumerating through the context 167 */ 168 if (isLookedUpCtx) { 169 _ctx.close(); 170 } 171 _ctx = null; 172 } 173 } 174 175 protected void finalize() { 176 try { 177 close(); 178 } catch (NamingException e) { 179 // ignore failures 180 } 181 } 182 183 /** 184 * Get the next batch using _bindingIter. Update the 'more' field. 185 */ 186 private boolean getMore() throws NamingException { 187 try { 188 more = _bindingIter.next_n(batchsize, _bindingList); 189 counter = 0; // reset 190 } catch (Exception e) { 191 more = false; 192 NamingException ne = new NamingException( 193 "Problem getting binding list"); 194 ne.setRootCause(e); 195 throw ne; 196 } 197 return more; 198 } 199 200 /** 201 * Constructs a JNDI Binding object from the COS Naming binding 202 * object. 203 * @exception NameNotFound No objects under the name. 204 * @exception CannotProceed Unable to obtain a continuation context 205 * @exception InvalidName Name not understood. 206 * @exception NamingException One of the above. 207 */ 208 209 private javax.naming.Binding mapBinding(org.omg.CosNaming.Binding bndg) 210 throws NamingException { 211 java.lang.Object obj = _ctx.callResolve(bndg.binding_name); 212 213 Name cname = CNNameParser.cosNameToName(bndg.binding_name); 214 215 try { 216 obj = NamingManager.getObjectInstance(obj, cname, _ctx, _env); 217 } catch (NamingException e) { 218 throw e; 219 } catch (Exception e) { 220 NamingException ne = new NamingException( 221 "problem generating object using object factory"); 222 ne.setRootCause(e); 223 throw ne; 224 } 225 226 // Use cname.toString() instead of bindingName because the name 227 // in the binding should be a composite name 228 String cnameStr = cname.toString(); 229 javax.naming.Binding jbndg = new javax.naming.Binding(cnameStr, obj); 230 231 NameComponent[] comps = _ctx.makeFullName(bndg.binding_name); 232 String fullName = CNNameParser.cosNameToInsString(comps); 233 jbndg.setNameInNamespace(fullName); 234 return jbndg; 235 } 236 }