Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.naming/share/classes/com/sun/jndi/ldap/AbstractLdapNamingEnumeration.java
41161 views
1
/*
2
* Copyright (c) 1999, 2018, 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.ldap;
27
28
import com.sun.jndi.toolkit.ctx.Continuation;
29
import java.util.NoSuchElementException;
30
import java.util.Vector;
31
32
import javax.naming.*;
33
import javax.naming.directory.Attributes;
34
import javax.naming.ldap.Control;
35
36
/**
37
* Basic enumeration for NameClassPair, Binding, and SearchResults.
38
*/
39
40
abstract class AbstractLdapNamingEnumeration<T extends NameClassPair>
41
implements NamingEnumeration<T>, ReferralEnumeration<T> {
42
43
protected Name listArg;
44
45
private boolean cleaned = false;
46
private LdapResult res;
47
private LdapClient enumClnt;
48
private Continuation cont; // used to fill in exceptions
49
private Vector<LdapEntry> entries = null;
50
private int limit = 0;
51
private int posn = 0;
52
protected LdapCtx homeCtx;
53
private LdapReferralException refEx = null;
54
private NamingException errEx = null;
55
56
/*
57
* Record the next set of entries and/or referrals.
58
*/
59
AbstractLdapNamingEnumeration(LdapCtx homeCtx, LdapResult answer, Name listArg,
60
Continuation cont) throws NamingException {
61
62
// These checks are to accommodate referrals and limit exceptions
63
// which will generate an enumeration and defer the exception
64
// to be thrown at the end of the enumeration.
65
// All other exceptions are thrown immediately.
66
// Exceptions shouldn't be thrown here anyhow because
67
// process_return_code() is called before the constructor
68
// is called, so these are just safety checks.
69
70
if ((answer.status != LdapClient.LDAP_SUCCESS) &&
71
(answer.status != LdapClient.LDAP_SIZE_LIMIT_EXCEEDED) &&
72
(answer.status != LdapClient.LDAP_TIME_LIMIT_EXCEEDED) &&
73
(answer.status != LdapClient.LDAP_ADMIN_LIMIT_EXCEEDED) &&
74
(answer.status != LdapClient.LDAP_REFERRAL) &&
75
(answer.status != LdapClient.LDAP_PARTIAL_RESULTS)) {
76
77
// %%% need to deal with referral
78
NamingException e = new NamingException(
79
LdapClient.getErrorMessage(
80
answer.status, answer.errorMessage));
81
82
throw cont.fillInException(e);
83
}
84
85
// otherwise continue
86
87
res = answer;
88
entries = answer.entries;
89
limit = (entries == null) ? 0 : entries.size(); // handle empty set
90
this.listArg = listArg;
91
this.cont = cont;
92
93
if (answer.refEx != null) {
94
refEx = answer.refEx;
95
}
96
97
// Ensures that context won't get closed from underneath us
98
this.homeCtx = homeCtx;
99
homeCtx.incEnumCount();
100
enumClnt = homeCtx.clnt; // remember
101
}
102
103
@Override
104
public final T nextElement() {
105
try {
106
return next();
107
} catch (NamingException e) {
108
// can't throw exception
109
cleanup();
110
return null;
111
}
112
}
113
114
@Override
115
public final boolean hasMoreElements() {
116
try {
117
return hasMore();
118
} catch (NamingException e) {
119
// can't throw exception
120
cleanup();
121
return false;
122
}
123
}
124
125
/*
126
* Retrieve the next set of entries and/or referrals.
127
*/
128
private void getNextBatch() throws NamingException {
129
130
res = homeCtx.getSearchReply(enumClnt, res);
131
if (res == null) {
132
limit = posn = 0;
133
return;
134
}
135
136
entries = res.entries;
137
limit = (entries == null) ? 0 : entries.size(); // handle empty set
138
posn = 0; // reset
139
140
// minimize the number of calls to processReturnCode()
141
// (expensive when batchSize is small and there are many results)
142
if ((res.status != LdapClient.LDAP_SUCCESS) ||
143
((res.status == LdapClient.LDAP_SUCCESS) &&
144
(res.referrals != null))) {
145
146
try {
147
// convert referrals into a chain of LdapReferralException
148
homeCtx.processReturnCode(res, listArg);
149
150
} catch (LimitExceededException | PartialResultException e) {
151
setNamingException(e);
152
153
}
154
}
155
156
// merge any newly received referrals with any current referrals
157
if (res.refEx != null) {
158
if (refEx == null) {
159
refEx = res.refEx;
160
} else {
161
refEx = refEx.appendUnprocessedReferrals(res.refEx);
162
}
163
res.refEx = null; // reset
164
}
165
166
if (res.resControls != null) {
167
homeCtx.respCtls = res.resControls;
168
}
169
}
170
171
private boolean more = true; // assume we have something to start with
172
private boolean hasMoreCalled = false;
173
174
/*
175
* Test if unprocessed entries or referrals exist.
176
*/
177
@Override
178
public final boolean hasMore() throws NamingException {
179
180
if (hasMoreCalled) {
181
return more;
182
}
183
184
hasMoreCalled = true;
185
186
if (!more) {
187
return false;
188
} else {
189
return (more = hasMoreImpl());
190
}
191
}
192
193
/*
194
* Retrieve the next entry.
195
*/
196
@Override
197
public final T next() throws NamingException {
198
199
if (!hasMoreCalled) {
200
hasMore();
201
}
202
hasMoreCalled = false;
203
return nextImpl();
204
}
205
206
/*
207
* Test if unprocessed entries or referrals exist.
208
*/
209
private boolean hasMoreImpl() throws NamingException {
210
// when page size is supported, this
211
// might generate an exception while attempting
212
// to fetch the next batch to determine
213
// whether there are any more elements
214
215
// test if the current set of entries has been processed
216
if (posn == limit) {
217
getNextBatch();
218
}
219
220
// test if any unprocessed entries exist
221
if (posn < limit) {
222
return true;
223
} else {
224
225
try {
226
// try to process another referral
227
return hasMoreReferrals();
228
229
} catch (LdapReferralException |
230
LimitExceededException |
231
PartialResultException e) {
232
cleanup();
233
throw e;
234
235
} catch (NamingException e) {
236
cleanup();
237
PartialResultException pre = new PartialResultException();
238
pre.setRootCause(e);
239
throw pre;
240
}
241
}
242
}
243
244
/*
245
* Retrieve the next entry.
246
*/
247
private T nextImpl() throws NamingException {
248
try {
249
return nextAux();
250
} catch (NamingException e) {
251
cleanup();
252
throw cont.fillInException(e);
253
}
254
}
255
256
private T nextAux() throws NamingException {
257
if (posn == limit) {
258
getNextBatch(); // updates posn and limit
259
}
260
261
if (posn >= limit) {
262
cleanup();
263
throw new NoSuchElementException("invalid enumeration handle");
264
}
265
266
LdapEntry result = entries.elementAt(posn++);
267
268
// gets and outputs DN from the entry
269
return createItem(result.DN, result.attributes, result.respCtls);
270
}
271
272
protected final String getAtom(String dn) {
273
// need to strip off all but lowest component of dn
274
// so that is relative to current context (currentDN)
275
try {
276
Name parsed = new LdapName(dn);
277
return parsed.get(parsed.size() - 1);
278
} catch (NamingException e) {
279
return dn;
280
}
281
}
282
283
protected abstract T createItem(String dn, Attributes attrs,
284
Vector<Control> respCtls) throws NamingException;
285
286
/*
287
* Append the supplied (chain of) referrals onto the
288
* end of the current (chain of) referrals.
289
*/
290
@Override
291
public void appendUnprocessedReferrals(LdapReferralException ex) {
292
if (refEx != null) {
293
refEx = refEx.appendUnprocessedReferrals(ex);
294
} else {
295
refEx = ex.appendUnprocessedReferrals(refEx);
296
}
297
}
298
299
final void setNamingException(NamingException e) {
300
errEx = e;
301
}
302
303
protected abstract AbstractLdapNamingEnumeration<? extends NameClassPair> getReferredResults(
304
LdapReferralContext refCtx) throws NamingException;
305
306
/*
307
* Iterate through the URLs of a referral. If successful then perform
308
* a search operation and merge the received results with the current
309
* results.
310
*/
311
protected final boolean hasMoreReferrals() throws NamingException {
312
313
if ((refEx != null) &&
314
(refEx.hasMoreReferrals() ||
315
refEx.hasMoreReferralExceptions()
316
&& !(errEx instanceof LimitExceededException))) {
317
318
if (homeCtx.handleReferrals == LdapClient.LDAP_REF_THROW) {
319
throw (NamingException)(refEx.fillInStackTrace());
320
}
321
322
// process the referrals sequentially
323
while (true) {
324
325
LdapReferralContext refCtx =
326
(LdapReferralContext)refEx.getReferralContext(
327
homeCtx.envprops, homeCtx.reqCtls);
328
329
try {
330
331
update(getReferredResults(refCtx));
332
break;
333
334
} catch (LdapReferralException re) {
335
336
// record a previous exception
337
if (errEx == null) {
338
errEx = re.getNamingException();
339
}
340
refEx = re;
341
continue;
342
343
} finally {
344
// Make sure we close referral context
345
refCtx.close();
346
}
347
}
348
return hasMoreImpl();
349
350
} else {
351
cleanup();
352
353
if (errEx != null) {
354
throw errEx;
355
}
356
return (false);
357
}
358
}
359
360
/*
361
* Merge the entries and/or referrals from the supplied enumeration
362
* with those of the current enumeration.
363
*/
364
protected void update(AbstractLdapNamingEnumeration<? extends NameClassPair> ne) {
365
// Cleanup previous context first
366
homeCtx.decEnumCount();
367
368
// New enum will have already incremented enum count and recorded clnt
369
homeCtx = ne.homeCtx;
370
enumClnt = ne.enumClnt;
371
372
// Do this to prevent referral enumeration (ne) from decrementing
373
// enum count because we'll be doing that here from this
374
// enumeration.
375
ne.homeCtx = null;
376
377
// Record rest of information from new enum
378
posn = ne.posn;
379
limit = ne.limit;
380
res = ne.res;
381
entries = ne.entries;
382
refEx = ne.refEx;
383
listArg = ne.listArg;
384
}
385
386
@SuppressWarnings("deprecation")
387
protected final void finalize() {
388
cleanup();
389
}
390
391
protected final void cleanup() {
392
if (cleaned) return; // been there; done that
393
394
if(enumClnt != null) {
395
enumClnt.clearSearchReply(res, homeCtx.reqCtls);
396
}
397
398
enumClnt = null;
399
cleaned = true;
400
if (homeCtx != null) {
401
homeCtx.decEnumCount();
402
homeCtx = null;
403
}
404
}
405
406
@Override
407
public final void close() {
408
cleanup();
409
}
410
}
411
412