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