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