blob: 3de419a1fa9c8320c4b263c165587e1595e28dbf [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999-2005 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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.*;
35import org.omg.CosNaming.NamingContextPackage.*;
36import 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
47final 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}