| /* |
| * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code is distributed in the hope that it will be useful, but WITHOUT |
| * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package com.sun.jndi.cosnaming; |
| |
| import javax.naming.*; |
| import javax.naming.spi.NamingManager; |
| |
| import java.util.NoSuchElementException; |
| import java.util.Hashtable; |
| |
| import org.omg.CosNaming.*; |
| import org.omg.CosNaming.NamingContextPackage.*; |
| import org.omg.CORBA.*; |
| |
| /** |
| * Implements the JNDI NamingEnumeration interface for COS |
| * Naming. Gets hold of a list of bindings from the COS Naming Server |
| * and allows the client to iterate through them. |
| * |
| * @author Raj Krishnamurthy |
| * @author Rosanna Lee |
| */ |
| |
| final class CNBindingEnumeration implements NamingEnumeration { |
| |
| private static final int DEFAULT_BATCHSIZE = 100; |
| private BindingListHolder _bindingList; // list of bindings |
| private BindingIterator _bindingIter; // iterator for getting list of bindings |
| private int counter; // pointer in _bindingList |
| private int batchsize = DEFAULT_BATCHSIZE; // how many to ask for each time |
| private CNCtx _ctx; // ctx to list |
| private Hashtable _env; // environment for getObjectInstance |
| private boolean more = false; // iterator done? |
| private boolean isLookedUpCtx = false; // iterating on a context beneath this context ? |
| |
| /** |
| * Creates a CNBindingEnumeration object. |
| * @param ctx Context to enumerate |
| */ |
| CNBindingEnumeration(CNCtx ctx, boolean isLookedUpCtx, Hashtable env) { |
| // Get batch size to use |
| String batch = (env != null ? |
| (String)env.get(javax.naming.Context.BATCHSIZE) : null); |
| if (batch != null) { |
| try { |
| batchsize = Integer.parseInt(batch); |
| } catch (NumberFormatException e) { |
| throw new IllegalArgumentException("Batch size not numeric: " + batch); |
| } |
| } |
| _ctx = ctx; |
| _ctx.incEnumCount(); |
| this.isLookedUpCtx = isLookedUpCtx; |
| _env = env; |
| _bindingList = new BindingListHolder(); |
| BindingIteratorHolder _bindingIterH = new BindingIteratorHolder(); |
| |
| // Perform listing and request that bindings be returned in _bindingIter |
| // Upon return,_bindingList returns a zero length list |
| _ctx._nc.list(0, _bindingList, _bindingIterH); |
| |
| _bindingIter = _bindingIterH.value; |
| |
| // Get first batch using _bindingIter |
| if (_bindingIter != null) { |
| more = _bindingIter.next_n(batchsize, _bindingList); |
| } else { |
| more = false; |
| } |
| counter = 0; |
| } |
| |
| /** |
| * Returns the next binding in the list. |
| * @exception NamingException any naming exception. |
| */ |
| |
| public java.lang.Object next() throws NamingException { |
| if (more && counter >= _bindingList.value.length) { |
| getMore(); |
| } |
| if (more && counter < _bindingList.value.length) { |
| org.omg.CosNaming.Binding bndg = _bindingList.value[counter]; |
| counter++; |
| return mapBinding(bndg); |
| } else { |
| throw new NoSuchElementException(); |
| } |
| } |
| |
| |
| /** |
| * Returns true or false depending on whether there are more bindings. |
| * @return boolean value |
| */ |
| |
| public boolean hasMore() throws NamingException { |
| // If there's more, check whether current bindingList has been exhausted, |
| // and if so, try to get more. |
| // If no more, just say so. |
| return more ? (counter < _bindingList.value.length || getMore()) : false; |
| } |
| |
| /** |
| * Returns true or false depending on whether there are more bindings. |
| * Need to define this to satisfy the Enumeration api requirement. |
| * @return boolean value |
| */ |
| |
| public boolean hasMoreElements() { |
| try { |
| return hasMore(); |
| } catch (NamingException e) { |
| return false; |
| } |
| } |
| |
| /** |
| * Returns the next binding in the list. |
| * @exception NoSuchElementException Thrown when the end of the |
| * list is reached. |
| */ |
| |
| public java.lang.Object nextElement() { |
| try { |
| return next(); |
| } catch (NamingException ne) { |
| throw new NoSuchElementException(); |
| } |
| } |
| |
| public void close() throws NamingException { |
| more = false; |
| if (_bindingIter != null) { |
| _bindingIter.destroy(); |
| _bindingIter = null; |
| } |
| if (_ctx != null) { |
| _ctx.decEnumCount(); |
| |
| /** |
| * context was obtained by CNCtx, the user doesn't have a handle to |
| * it, close it as we are done enumerating through the context |
| */ |
| if (isLookedUpCtx) { |
| _ctx.close(); |
| } |
| _ctx = null; |
| } |
| } |
| |
| protected void finalize() { |
| try { |
| close(); |
| } catch (NamingException e) { |
| // ignore failures |
| } |
| } |
| |
| /** |
| * Get the next batch using _bindingIter. Update the 'more' field. |
| */ |
| private boolean getMore() throws NamingException { |
| try { |
| more = _bindingIter.next_n(batchsize, _bindingList); |
| counter = 0; // reset |
| } catch (Exception e) { |
| more = false; |
| NamingException ne = new NamingException( |
| "Problem getting binding list"); |
| ne.setRootCause(e); |
| throw ne; |
| } |
| return more; |
| } |
| |
| /** |
| * Constructs a JNDI Binding object from the COS Naming binding |
| * object. |
| * @exception NameNotFound No objects under the name. |
| * @exception CannotProceed Unable to obtain a continuation context |
| * @exception InvalidName Name not understood. |
| * @exception NamingException One of the above. |
| */ |
| |
| private javax.naming.Binding mapBinding(org.omg.CosNaming.Binding bndg) |
| throws NamingException { |
| java.lang.Object obj = _ctx.callResolve(bndg.binding_name); |
| |
| Name cname = CNNameParser.cosNameToName(bndg.binding_name); |
| |
| try { |
| obj = NamingManager.getObjectInstance(obj, cname, _ctx, _env); |
| } catch (NamingException e) { |
| throw e; |
| } catch (Exception e) { |
| NamingException ne = new NamingException( |
| "problem generating object using object factory"); |
| ne.setRootCause(e); |
| throw ne; |
| } |
| |
| // Use cname.toString() instead of bindingName because the name |
| // in the binding should be a composite name |
| String cnameStr = cname.toString(); |
| javax.naming.Binding jbndg = new javax.naming.Binding(cnameStr, obj); |
| |
| NameComponent[] comps = _ctx.makeFullName(bndg.binding_name); |
| String fullName = CNNameParser.cosNameToInsString(comps); |
| jbndg.setNameInNamespace(fullName); |
| return jbndg; |
| } |
| } |