Path: blob/master/src/java.naming/share/classes/com/sun/jndi/ldap/LdapReferralException.java
41161 views
/*1* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.jndi.ldap;2627import javax.naming.*;28import javax.naming.ldap.Control;2930import java.util.Hashtable;31import java.util.Vector;3233/**34* This exception is raised when a referral to an alternative context35* is encountered.36* <p>37* An {@code LdapReferralException} object contains one or more referrals.38* Each referral is an alternative location for the same target entry.39* For example, a referral may be an LDAP URL.40* The referrals are attempted in sequence until one is successful or41* all have failed. In the case of the latter then the exception generated42* by the final referral is recorded and presented later.43* <p>44* A referral may be skipped or may be retried. For example, in the case45* of an authentication error, a referral may be retried with different46* environment properties.47* <p>48* An {@code LdapReferralException} object may also contain a reference49* to a chain of unprocessed {@code LdapReferralException} objects.50* Once the current set of referrals have been exhausted and unprocessed51* {@code LdapReferralException} objects remain, then the52* {@code LdapReferralException} object referenced by the current53* object is thrown and the cycle continues.54* <p>55* If new {@code LdapReferralException} objects are generated while56* following an existing referral then these new objects are appended57* to the end of the chain of unprocessed {@code LdapReferralException}58* objects.59* <p>60* If an exception was recorded while processing a chain of61* {@code LdapReferralException} objects then it is throw once62* processing has completed.63*64* @author Vincent Ryan65*/66public final class LdapReferralException extends67javax.naming.ldap.LdapReferralException {68private static final long serialVersionUID = 627059076356906399L;6970// ----------- fields initialized in constructor ---------------71private int handleReferrals;72private Hashtable<?,?> envprops;73private String nextName;74private Control[] reqCtls;7576// ----------- fields that have defaults -----------------------77private Vector<?> referrals = null; // alternatives,set by setReferralInfo()78private int referralIndex = 0; // index into referrals79private int referralCount = 0; // count of referrals80private boolean foundEntry = false; // will stop when entry is found81private boolean skipThisReferral = false;82private int hopCount = 1;83private NamingException errorEx = null;84private String newRdn = null;85private boolean debug = false;86LdapReferralException nextReferralEx = null; // referral ex. chain8788/**89* Constructs a new instance of LdapReferralException.90* @param resolvedName The part of the name that has been successfully91* resolved.92* @param resolvedObj The object to which resolution was successful.93* @param remainingName The remaining unresolved portion of the name.94* @param explanation Additional detail about this exception.95*/96LdapReferralException(Name resolvedName,97Object resolvedObj,98Name remainingName,99String explanation,100Hashtable<?,?> envprops,101String nextName,102int handleReferrals,103Control[] reqCtls) {104105super(explanation);106107if (debug)108System.out.println("LdapReferralException constructor");109110setResolvedName(resolvedName);111setResolvedObj(resolvedObj);112setRemainingName(remainingName);113this.envprops = envprops;114this.nextName = nextName;115this.handleReferrals = handleReferrals;116117// If following referral, request controls are passed to referral ctx118this.reqCtls =119(handleReferrals == LdapClient.LDAP_REF_FOLLOW ||120handleReferrals == LdapClient.LDAP_REF_FOLLOW_SCHEME ? reqCtls : null);121}122123/**124* Gets a context at which to continue processing.125* The current environment properties are re-used.126*/127public Context getReferralContext() throws NamingException {128return getReferralContext(envprops, null);129}130131/**132* Gets a context at which to continue processing.133* The supplied environment properties are used.134*/135public Context getReferralContext(Hashtable<?,?> newProps) throws136NamingException {137return getReferralContext(newProps, null);138}139140/**141* Gets a context at which to continue processing.142* The supplied environment properties and connection controls are used.143*/144public Context getReferralContext(Hashtable<?,?> newProps, Control[] connCtls)145throws NamingException {146147if (debug)148System.out.println("LdapReferralException.getReferralContext");149150LdapReferralContext refCtx = new LdapReferralContext(151this, newProps, connCtls, reqCtls,152nextName, skipThisReferral, handleReferrals);153154refCtx.setHopCount(hopCount + 1);155156if (skipThisReferral) {157skipThisReferral = false; // reset158}159return (Context)refCtx;160}161162/**163* Gets referral information.164*/165public Object getReferralInfo() {166if (debug) {167System.out.println("LdapReferralException.getReferralInfo");168System.out.println(" referralIndex=" + referralIndex);169}170171if (hasMoreReferrals()) {172return referrals.elementAt(referralIndex);173} else {174return null;175}176}177178/**179* Marks the current referral as one to be retried.180*/181public void retryReferral() {182if (debug)183System.out.println("LdapReferralException.retryReferral");184185if (referralIndex > 0)186referralIndex--; // decrement index187}188189/**190* Marks the current referral as one to be ignored.191* Returns false when there are no referrals remaining to be processed.192*/193public boolean skipReferral() {194if (debug)195System.out.println("LdapReferralException.skipReferral");196197skipThisReferral = true;198199// advance to next referral200try {201getNextReferral();202} catch (ReferralException e) {203// mask the referral exception204}205206return (hasMoreReferrals() || hasMoreReferralExceptions());207}208209210/**211* Sets referral information.212*/213void setReferralInfo(Vector<?> referrals, boolean continuationRef) {214// %%% continuationRef is currently ignored215216if (debug)217System.out.println("LdapReferralException.setReferralInfo");218219this.referrals = referrals;220referralCount = (referrals == null) ? 0 : referrals.size();221222if (debug) {223if (referrals != null) {224for (int i = 0; i < referralCount; i++) {225System.out.println(" [" + i + "] " + referrals.elementAt(i));226}227} else {228System.out.println("setReferralInfo : referrals == null");229}230}231}232233/**234* Gets the next referral. When the current set of referrals have235* been exhausted then the next referral exception is thrown, if available.236*/237String getNextReferral() throws ReferralException {238239if (debug)240System.out.println("LdapReferralException.getNextReferral");241242if (hasMoreReferrals()) {243return (String)referrals.elementAt(referralIndex++);244} else if (hasMoreReferralExceptions()) {245throw nextReferralEx;246} else {247return null;248}249}250251/**252* Appends the supplied (chain of) referral exception onto the end of253* the current (chain of) referral exception. Spent referral exceptions254* are trimmed off.255*/256LdapReferralException257appendUnprocessedReferrals(LdapReferralException back) {258259if (debug) {260System.out.println(261"LdapReferralException.appendUnprocessedReferrals");262dump();263if (back != null) {264back.dump();265}266}267268LdapReferralException front = this;269270if (! front.hasMoreReferrals()) {271front = nextReferralEx; // trim272273if ((errorEx != null) && (front != null)) {274front.setNamingException(errorEx); //advance the saved exception275}276}277278// don't append onto itself279if (this == back) {280return front;281}282283if ((back != null) && (! back.hasMoreReferrals())) {284back = back.nextReferralEx; // trim285}286287if (back == null) {288return front;289}290291// Locate the end of the current chain292LdapReferralException ptr = front;293while (ptr.nextReferralEx != null) {294ptr = ptr.nextReferralEx;295}296ptr.nextReferralEx = back; // append297298return front;299}300301/**302* Tests if there are any referrals remaining to be processed.303* If name resolution has already completed then any remaining304* referrals (in the current referral exception) will be ignored.305*/306boolean hasMoreReferrals() {307if (debug)308System.out.println("LdapReferralException.hasMoreReferrals");309310return (! foundEntry) && (referralIndex < referralCount);311}312313/**314* Tests if there are any referral exceptions remaining to be processed.315*/316boolean hasMoreReferralExceptions() {317if (debug)318System.out.println(319"LdapReferralException.hasMoreReferralExceptions");320321return (nextReferralEx != null);322}323324/**325* Sets the counter which records the number of hops that result326* from following a sequence of referrals.327*/328void setHopCount(int hopCount) {329if (debug)330System.out.println("LdapReferralException.setHopCount");331332this.hopCount = hopCount;333}334335/**336* Sets the flag to indicate that the target name has been resolved.337*/338void setNameResolved(boolean resolved) {339if (debug)340System.out.println("LdapReferralException.setNameResolved");341342foundEntry = resolved;343}344345/**346* Sets the exception generated while processing a referral.347* Only the first exception is recorded.348*/349void setNamingException(NamingException e) {350if (debug)351System.out.println("LdapReferralException.setNamingException");352353if (errorEx == null) {354e.setRootCause(this); //record the referral exception that caused it355errorEx = e;356}357}358359/**360* Gets the new RDN name.361*/362String getNewRdn() {363if (debug)364System.out.println("LdapReferralException.getNewRdn");365366return newRdn;367}368369/**370* Sets the new RDN name so that the rename operation can be completed371* (when a referral is being followed).372*/373void setNewRdn(String newRdn) {374if (debug)375System.out.println("LdapReferralException.setNewRdn");376377this.newRdn = newRdn;378}379380/**381* Gets the exception generated while processing a referral.382*/383NamingException getNamingException() {384if (debug)385System.out.println("LdapReferralException.getNamingException");386387return errorEx;388}389390/**391* Display the state of each element in a chain of LdapReferralException392* objects.393*/394void dump() {395396System.out.println();397System.out.println("LdapReferralException.dump");398LdapReferralException ptr = this;399while (ptr != null) {400ptr.dumpState();401ptr = ptr.nextReferralEx;402}403}404405/**406* Display the state of this LdapReferralException object.407*/408private void dumpState() {409System.out.println("LdapReferralException.dumpState");410System.out.println(" hashCode=" + hashCode());411System.out.println(" foundEntry=" + foundEntry);412System.out.println(" skipThisReferral=" + skipThisReferral);413System.out.println(" referralIndex=" + referralIndex);414415if (referrals != null) {416System.out.println(" referrals:");417for (int i = 0; i < referralCount; i++) {418System.out.println(" [" + i + "] " + referrals.elementAt(i));419}420} else {421System.out.println(" referrals=null");422}423424System.out.println(" errorEx=" + errorEx);425426if (nextReferralEx == null) {427System.out.println(" nextRefEx=null");428} else {429System.out.println(" nextRefEx=" + nextReferralEx.hashCode());430}431System.out.println();432}433}434435436