431 lines · 13.5 KB · Java
RawDownload
/* * Copyright (c) 1999, 2004, 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.ldap; import javax.naming.*;import javax.naming.spi.*;import javax.naming.ldap.Control; import java.util.Hashtable;import java.util.Vector; /**  * This exception is raised when a referral to an alternative context  * is encountered.  * <p>  * An <tt>LdapReferralException</tt> object contains one or more referrals.  * Each referral is an alternative location for the same target entry.  * For example, a referral may be an LDAP URL.  * The referrals are attempted in sequence until one is successful or  * all have failed. In the case of the latter then the exception generated  * by the final referral is recorded and presented later.  * <p>  * A referral may be skipped or may be retried. For example, in the case  * of an authentication error, a referral may be retried with different  * environment properties.  * <p>  * An <tt>LdapReferralException</tt> object may also contain a reference  * to a chain of unprocessed <tt>LdapReferralException</tt> objects.  * Once the current set of referrals have been exhausted and unprocessed  * <tt>LdapReferralException</tt> objects remain, then the  * <tt>LdapReferralException</tt> object referenced by the current  * object is thrown and the cycle continues.  * <p>  * If new <tt>LdapReferralException</tt> objects are generated while  * following an existing referral then these new objects are appended  * to the end of the chain of unprocessed <tt>LdapReferralException</tt>  * objects.  * <p>  * If an exception was recorded while processing a chain of  * <tt>LdapReferralException</tt> objects then is is throw once  * processing has completed.  *  * @author Vincent Ryan  */final public class LdapReferralException extends    javax.naming.ldap.LdapReferralException {         // ----------- fields initialized in constructor ---------------    private int handleReferrals;    private Hashtable envprops;    private String nextName;    private Control[] reqCtls;         // ----------- fields that have defaults -----------------------    private Vector referrals = null;    // alternatives,set by setReferralInfo()    private int referralIndex = 0;      // index into referrals    private int referralCount = 0;      // count of referrals    private boolean foundEntry = false; // will stop when entry is found    private boolean skipThisReferral = false;    private int hopCount = 1;    private NamingException errorEx = null;    private String newRdn = null;    private boolean debug = false;            LdapReferralException nextReferralEx = null; // referral ex. chain     /**     * Constructs a new instance of LdapReferralException.     * @param   resolvedName    The part of the name that has been successfully     *                          resolved.     * @param   resolvedObj     The object to which resolution was successful.     * @param   remainingName   The remaining unresolved portion of the name.     * @param   explanation     Additional detail about this exception.     */    LdapReferralException(Name resolvedName,        Object resolvedObj,        Name remainingName,        String explanation,        Hashtable envprops,        String nextName,        int handleReferrals,        Control[] reqCtls) {         super(explanation);         if (debug)            System.out.println("LdapReferralException constructor");         setResolvedName(resolvedName);        setResolvedObj(resolvedObj);        setRemainingName(remainingName);        this.envprops = envprops;        this.nextName = nextName;        this.handleReferrals = handleReferrals;         // If following referral, request controls are passed to referral ctx        this.reqCtls =            (handleReferrals == LdapClient.LDAP_REF_FOLLOW ? reqCtls : null);    }     /**     * Gets a context at which to continue processing.     * The current environment properties are re-used.     */    public Context getReferralContext() throws NamingException {        return getReferralContext(envprops, null);    }     /**     * Gets a context at which to continue processing.     * The supplied environment properties are used.     */    public Context getReferralContext(Hashtable<?,?> newProps) throws        NamingException {        return getReferralContext(newProps, null);    }     /**     * Gets a context at which to continue processing.     * The supplied environment properties and connection controls are used.     */    public Context getReferralContext(Hashtable<?,?> newProps, Control[] connCtls)        throws NamingException {         if (debug)            System.out.println("LdapReferralException.getReferralContext");         LdapReferralContext refCtx = new LdapReferralContext(            this, newProps, connCtls, reqCtls,            nextName, skipThisReferral, handleReferrals);         refCtx.setHopCount(hopCount + 1);         if (skipThisReferral) {            skipThisReferral = false; // reset        }        return (Context)refCtx;    }     /**      * Gets referral information.      */    public Object getReferralInfo() {        if (debug) {            System.out.println("LdapReferralException.getReferralInfo");            System.out.println("  referralIndex=" + referralIndex);        }         if (hasMoreReferrals()) {            return referrals.elementAt(referralIndex);        } else {            return null;        }    }     /**     * Marks the current referral as one to be retried.     */    public void retryReferral() {        if (debug)            System.out.println("LdapReferralException.retryReferral");         if (referralIndex > 0)            referralIndex--; // decrement index    }     /**     * Marks the current referral as one to be ignored.     * Returns false when there are no referrals remaining to be processed.     */    public boolean skipReferral() {        if (debug)            System.out.println("LdapReferralException.skipReferral");         skipThisReferral = true;         // advance to next referral        try {            getNextReferral();        } catch (ReferralException e) {            // mask the referral exception        }         return (hasMoreReferrals() || hasMoreReferralExceptions());    }      /**     * Sets referral information.     */    void setReferralInfo(Vector referrals, boolean continuationRef) {        // %%% continuationRef is currently ignored         if (debug)            System.out.println("LdapReferralException.setReferralInfo");         this.referrals = referrals;        if (referrals != null) {            referralCount = referrals.size();        }         if (debug) {            for (int i = 0; i < referralCount; i++) {                System.out.println("  [" + i + "] " + referrals.elementAt(i));            }        }    }     /**     * Gets the next referral. When the current set of referrals have     * been exhausted then the next referral exception is thrown, if available.     */    String getNextReferral() throws ReferralException {         if (debug)            System.out.println("LdapReferralException.getNextReferral");         if (hasMoreReferrals()) {            return (String)referrals.elementAt(referralIndex++);        } else if (hasMoreReferralExceptions()) {            throw nextReferralEx;        } else {            return null;        }    }     /**     * Appends the supplied (chain of) referral exception onto the end of     * the current (chain of) referral exception. Spent referral exceptions     * are trimmed off.     */    LdapReferralException        appendUnprocessedReferrals(LdapReferralException back) {         if (debug) {            System.out.println(                "LdapReferralException.appendUnprocessedReferrals");            dump();            if (back != null) {                back.dump();            }        }         LdapReferralException front = this;         if (! front.hasMoreReferrals()) {            front = nextReferralEx; // trim             if ((errorEx != null) && (front != null)) {                front.setNamingException(errorEx); //advance the saved exception            }        }         // don't append onto itself        if (this == back) {            return front;        }         if ((back != null) && (! back.hasMoreReferrals())) {            back = back.nextReferralEx; // trim        }         if (back == null) {            return front;        }         // Locate the end of the current chain        LdapReferralException ptr = front;        while (ptr.nextReferralEx != null) {            ptr = ptr.nextReferralEx;        }        ptr.nextReferralEx = back; // append         return front;    }     /**     * Tests if there are any referrals remaining to be processed.     * If name resolution has already completed then any remaining     * referrals (in the current referral exception) will be ignored.     */    boolean hasMoreReferrals() {        if (debug)            System.out.println("LdapReferralException.hasMoreReferrals");         return (! foundEntry) && (referralIndex < referralCount);    }     /**     * Tests if there are any referral exceptions remaining to be processed.     */    boolean hasMoreReferralExceptions() {        if (debug)            System.out.println(                "LdapReferralException.hasMoreReferralExceptions");         return (nextReferralEx != null);    }     /**     * Sets the counter which records the number of hops that result     * from following a sequence of referrals.     */    void setHopCount(int hopCount) {        if (debug)            System.out.println("LdapReferralException.setHopCount");         this.hopCount = hopCount;    }     /**     * Sets the flag to indicate that the target name has been resolved.     */    void setNameResolved(boolean resolved) {        if (debug)            System.out.println("LdapReferralException.setNameResolved");         foundEntry = resolved;    }     /**     * Sets the exception generated while processing a referral.     * Only the first exception is recorded.     */    void setNamingException(NamingException e) {        if (debug)            System.out.println("LdapReferralException.setNamingException");         if (errorEx == null) {            e.setRootCause(this); //record the referral exception that caused it            errorEx = e;        }    }     /**     * Gets the new RDN name.     */    String getNewRdn() {        if (debug)            System.out.println("LdapReferralException.getNewRdn");         return newRdn;    }     /**     * Sets the new RDN name so that the rename operation can be completed     * (when a referral is being followed).     */    void setNewRdn(String newRdn) {        if (debug)            System.out.println("LdapReferralException.setNewRdn");         this.newRdn = newRdn;    }     /**     * Gets the exception generated while processing a referral.     */    NamingException getNamingException() {        if (debug)            System.out.println("LdapReferralException.getNamingException");         return errorEx;    }     /**     * Display the state of each element in a chain of LdapReferralException     * objects.     */    void dump() {         System.out.println();        System.out.println("LdapReferralException.dump");        LdapReferralException ptr = this;        while (ptr != null) {            ptr.dumpState();            ptr = ptr.nextReferralEx;        }    }     /**     * Display the state of this LdapReferralException object.     */    private void dumpState() {        System.out.println("LdapReferralException.dumpState");        System.out.println("  hashCode=" + hashCode());        System.out.println("  foundEntry=" + foundEntry);        System.out.println("  skipThisReferral=" + skipThisReferral);        System.out.println("  referralIndex=" + referralIndex);         if (referrals != null) {            System.out.println("  referrals:");            for (int i = 0; i < referralCount; i++) {                System.out.println("    [" + i + "] " + referrals.elementAt(i));            }        } else {            System.out.println("  referrals=null");        }         System.out.println("  errorEx=" + errorEx);         if (nextReferralEx == null) {            System.out.println("  nextRefEx=null");        } else {            System.out.println("  nextRefEx=" + nextReferralEx.hashCode());        }        System.out.println();    }}