/*
 * Copyright (c) 1999, 2013, 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.toolkit.ctx;

import javax.naming.*;
import javax.naming.spi.ResolveResult;
import java.util.Hashtable;

This class contains information required to continue the method (place where it left off, and remaining name to continue).
Author:Rosanna Lee
/** * This class contains information required to continue * the method (place where it left off, and remaining name to * continue). * * @author Rosanna Lee */
public class Continuation extends ResolveResult {
The name that we started out with. It is initialized by the constructor and used to calculate to "resolved name" in NamingException in fillInException(). %%% Note that this approach does not always do the calculation correctly with respect to absence or presence of the trailing slash for resolved name.
/** * The name that we started out with. It is initialized by the constructor * and used to calculate to "resolved name" in NamingException in * fillInException(). * %%% Note that this approach does not always do the calculation * correctly with respect to absence or presence of the trailing slash * for resolved name. */
protected Name starter;
Whether links were encountered.
/** * Whether links were encountered. */
protected Object followingLink = null;
The environment used by the caller. Initialized by constructor and used when filling out a CannotProceedException.
/** * The environment used by the caller. Initialized by constructor and * used when filling out a CannotProceedException. */
protected Hashtable<?,?> environment = null;
Indicates whether the Continuation instance indicates that the operation should be continued using the data in the Continuation. Typically, this is only false if an error has been encountered or if the operation has succeeded.
/** * Indicates whether the Continuation instance indicates that the operation * should be continued using the data in the Continuation. * Typically, this is only false if an error has been encountered or if * the operation has succeeded. */
protected boolean continuing = false;
The last resolved context. Used to set the "AltNameCtx" in a CannotProceedException.
/** * The last resolved context. Used to set the "AltNameCtx" in a * CannotProceedException. */
protected Context resolvedContext = null;
The resolved name relative to resolvedContext. Used to set the "AltName" in a CannotProceedException.
/** * The resolved name relative to resolvedContext. Used to set the * "AltName" in a CannotProceedException. */
protected Name relativeResolvedName = null;
Constructs a new instance of Continuation. Used as dummy for contexts that do not do federation (e.g. for schema ops)
/** * Constructs a new instance of Continuation. * Used as dummy for contexts that do not do federation (e.g. for schema ops) */
public Continuation() { }
Constructs a new instance of Continuation.
Params:
  • top – The name of the object that is to be resolved/operated upon. This becomes the Continuation's 'starter' and is used to calculate the "resolved name" when filling in a NamingException.
  • environment – The environment used by the caller. It is used when setting the "environment" of a CannotProceedException.
/** * Constructs a new instance of Continuation. * @param top The name of the object that is to be resolved/operated upon. * This becomes the Continuation's 'starter' and is used to * calculate the "resolved name" when filling in a NamingException. * @param environment The environment used by the caller. It is used * when setting the "environment" of a CannotProceedException. */
@SuppressWarnings("unchecked") // For Hashtable clone: environment.clone() public Continuation(Name top, Hashtable<?,?> environment) { super(); starter = top; this.environment = (Hashtable<?,?>) ((environment == null) ? null : environment.clone()); }
Determines whether this Continuation contains data that should be used to continue the operation.
Returns:true if operation should continue; false if operation has completed (successfully or unsuccessfully).
/** * Determines whether this Continuation contains data that should be * used to continue the operation. * * @return true if operation should continue; false if operation has * completed (successfully or unsuccessfully). */
public boolean isContinue() { return continuing; }
Sets this Continuation to indicate successful completion. Subsequent calls to isContinue() will return false. This method is different from the setError() methods only from the standpoint that this method does not set any of the other fields such as resolved object or resolved context. This is because this method is typically called when the context recognizes that the operation has successfully completed and that the continuation already contains the appropriately set fields.
See Also:
  • setError
  • setErrorNNS
/** * Sets this Continuation to indicate successful completion. * Subsequent calls to isContinue() will return false. * This method is different from the setError() methods only from * the standpoint that this method does not set any of the other * fields such as resolved object or resolved context. This is because * this method is typically called when the context recognizes that * the operation has successfully completed and that the continuation * already contains the appropriately set fields. * @see setError * @see setErrorNNS */
public void setSuccess() { continuing = false; }
Fills in an exception's fields using data from this Continuation. The resolved name is set by subtracting remainingName from starter. %%% This might not not always produce the correct answer wrt trailing "/". If the exception is a CannotProceedException, its environment, altName, and altNameCtx fields are set using this continuation's environment, relativeResolvedName, and resolvedContext.
Params:
  • e – The non-null naming exception to fill.
Returns:The non-null naming exception with its fields set using data from this Continuation.
/** * Fills in an exception's fields using data from this Continuation. * The resolved name is set by subtracting remainingName from starter. * %%% This might not not always produce the correct answer wrt trailing "/". * If the exception is a CannotProceedException, its environment, * altName, and altNameCtx fields are set using this continuation's * environment, relativeResolvedName, and resolvedContext. * * @param e The non-null naming exception to fill. * @return The non-null naming exception with its fields set using * data from this Continuation. */
public NamingException fillInException(NamingException e) { e.setRemainingName(remainingName); e.setResolvedObj(resolvedObj); if (starter == null || starter.isEmpty()) e.setResolvedName(null); else if (remainingName == null) e.setResolvedName(starter); else e.setResolvedName( starter.getPrefix(starter.size() - remainingName.size())); if ((e instanceof CannotProceedException)) { CannotProceedException cpe = (CannotProceedException)e; Hashtable<?,?> env = (environment == null ? new Hashtable<>(11) : (Hashtable<?,?>)environment.clone()); cpe.setEnvironment(env); cpe.setAltNameCtx(resolvedContext); cpe.setAltName(relativeResolvedName); } return e; }
Sets this Continuation to indicated that an error has occurred, and that the remaining name is rename + "/". This method is typically called by _nns methods that have been given a name to process. It might process part of that name but encountered some error. Consequently, it would call setErrorNNS() with the remaining name. Since the _nns method was expected to operate upon the "nns" of the original name, the remaining name must include the "nns". That's why this method adds a trailing "/".

After this method is called, isContinuing() returns false.

Params:
  • resObj – The possibly null object that was resolved to.
  • remain – The non-null remaining name.
/** * Sets this Continuation to indicated that an error has occurred, * and that the remaining name is rename + "/". * * This method is typically called by _nns methods that have been * given a name to process. It might process part of that name but * encountered some error. Consequently, it would call setErrorNNS() * with the remaining name. Since the _nns method was expected to * operate upon the "nns" of the original name, the remaining name * must include the "nns". That's why this method adds a trailing "/". *<p> * After this method is called, isContinuing() returns false. * * @param resObj The possibly null object that was resolved to. * @param remain The non-null remaining name. */
public void setErrorNNS(Object resObj, Name remain) { Name nm = (Name)(remain.clone()); try { nm.add(""); } catch (InvalidNameException e) { // ignore; can't happen for composite name } setErrorAux(resObj, nm); }
Form that accepts a String name instead of a Name name.
Params:
  • resObj – The possibly null object that was resolved to.
  • remain – The possibly String remaining name.
See Also:
/** * Form that accepts a String name instead of a Name name. * @param resObj The possibly null object that was resolved to. * @param remain The possibly String remaining name. * * @see #setErrorNNS(java.lang.Object, javax.naming.Name) */
public void setErrorNNS(Object resObj, String remain) { CompositeName rname = new CompositeName(); try { if (remain != null && !remain.isEmpty()) rname.add(remain); rname.add(""); } catch (InvalidNameException e) { // ignore, can't happen for composite name } setErrorAux(resObj, rname); }
Sets this Continuation to indicated that an error has occurred and supply resolved information. This method is typically called by methods that have been given a name to process. It might process part of that name but encountered some error. Consequently, it would call setError() with the resolved object and the remaining name.

After this method is called, isContinuing() returns false.

Params:
  • resObj – The possibly null object that was resolved to.
  • remain – The possibly null remaining name.
/** * Sets this Continuation to indicated that an error has occurred * and supply resolved information. * * This method is typically called by methods that have been * given a name to process. It might process part of that name but * encountered some error. Consequently, it would call setError() * with the resolved object and the remaining name. *<p> * After this method is called, isContinuing() returns false. * * @param resObj The possibly null object that was resolved to. * @param remain The possibly null remaining name. */
public void setError(Object resObj, Name remain) { if (remain != null) remainingName = (Name)(remain.clone()); else remainingName = null; setErrorAux(resObj, remainingName); }
Form that accepts a String name instead of a Name name.
Params:
  • resObj – The possibly null object that was resolved to.
  • remain – The possibly String remaining name.
See Also:
/** * Form that accepts a String name instead of a Name name. * @param resObj The possibly null object that was resolved to. * @param remain The possibly String remaining name. * * @see #setError(java.lang.Object, javax.naming.Name) */
public void setError(Object resObj, String remain) { CompositeName rname = new CompositeName(); if (remain != null && !remain.isEmpty()) { try { rname.add(remain); } catch (InvalidNameException e) { // ignore; can't happen for composite name } } setErrorAux(resObj, rname); } private void setErrorAux(Object resObj, Name rname) { remainingName = rname; resolvedObj = resObj; continuing = false; } private void setContinueAux(Object resObj, Name relResName, Context currCtx, Name remain) { if (resObj instanceof LinkRef) { setContinueLink(resObj, relResName, currCtx, remain); } else { remainingName = remain; resolvedObj = resObj; relativeResolvedName = relResName; resolvedContext = currCtx; continuing = true; } }
Sets this Continuation with the supplied data, and set remaining name to be "/". This method is typically called by _nns methods that have been given a name to process. It might the name (without the nns) and continue process of the nns elsewhere. Consequently, it would call this form of the setContinueNNS(). This method supplies "/" as the remaining name.

After this method is called, isContinuing() returns true.

Params:
  • resObj – The possibly null resolved object.
  • relResName – The non-null resolved name relative to currCtx.
  • currCtx – The non-null context from which relResName is to be resolved.
/** * Sets this Continuation with the supplied data, and set remaining name * to be "/". * This method is typically called by _nns methods that have been * given a name to process. It might the name (without the nns) and * continue process of the nns elsewhere. * Consequently, it would call this form of the setContinueNNS(). * This method supplies "/" as the remaining name. *<p> * After this method is called, isContinuing() returns true. * * @param resObj The possibly null resolved object. * @param relResName The non-null resolved name relative to currCtx. * @param currCtx The non-null context from which relResName is to be resolved. */
public void setContinueNNS(Object resObj, Name relResName, Context currCtx) { CompositeName rname = new CompositeName(); setContinue(resObj, relResName, currCtx, PartialCompositeContext._NNS_NAME); }
Overloaded form that accesses String names.
Params:
  • resObj – The possibly null resolved object.
  • relResName – The non-null resolved name relative to currCtx.
  • currCtx – The non-null context from which relResName is to be resolved.
See Also:
/** * Overloaded form that accesses String names. * * @param resObj The possibly null resolved object. * @param relResName The non-null resolved name relative to currCtx. * @param currCtx The non-null context from which relResName is to be resolved. * @see #setContinueNNS(java.lang.Object, javax.naming.Name, javax.naming.Context) */
public void setContinueNNS(Object resObj, String relResName, Context currCtx) { CompositeName relname = new CompositeName(); try { relname.add(relResName); } catch (NamingException e) {} setContinue(resObj, relname, currCtx, PartialCompositeContext._NNS_NAME); }
Sets this Continuation with the supplied data, and set remaining name to be the empty name. This method is typically called by list-style methods in which the target context implementing list() expects an empty name. For example when c_list() is given a non-empty name to process, it would resolve that name, and then call setContinue() with the resolved object so that the target context to be listed would be called with the empty name (i.e. list the target context itself).

After this method is called, isContinuing() returns true.

Params:
  • obj – The possibly null resolved object.
  • relResName – The non-null resolved name relative to currCtx.
  • currCtx – The non-null context from which relResName is to be resolved.
/** * Sets this Continuation with the supplied data, and set remaining name * to be the empty name. * This method is typically called by list-style methods * in which the target context implementing list() expects an * empty name. For example when c_list() is given a non-empty name to * process, it would resolve that name, and then call setContinue() * with the resolved object so that the target context to be listed * would be called with the empty name (i.e. list the target context itself). *<p> * After this method is called, isContinuing() returns true. * * @param obj The possibly null resolved object. * @param relResName The non-null resolved name relative to currCtx. * @param currCtx The non-null context from which relResName is to be resolved. */
public void setContinue(Object obj, Name relResName, Context currCtx) { setContinueAux(obj, relResName, currCtx, (Name)PartialCompositeContext._EMPTY_NAME.clone()); }
Sets this Continuation with the supplied data. This method is typically called by a method that has been asked to operate on a name. The method resolves part of the name (relResName) to obj and sets the unprocessed part to rename. It calls setContinue() so that the operation can be continued using this data.

After this method is called, isContinuing() returns true.

Params:
  • obj – The possibly null resolved object.
  • relResName – The non-null resolved name relative to currCtx.
  • currCtx – The non-null context from which relResName is to be resolved.
  • remain – The non-null remaining name.
/** * Sets this Continuation with the supplied data. * This method is typically called by a method that has been asked * to operate on a name. The method resolves part of the name * (relResName) to obj and sets the unprocessed part to rename. * It calls setContinue() so that the operation can be continued * using this data. *<p> * After this method is called, isContinuing() returns true. * * @param obj The possibly null resolved object. * @param relResName The non-null resolved name relative to currCtx. * @param currCtx The non-null context from which relResName is to be resolved. * @param remain The non-null remaining name. */
public void setContinue(Object obj, Name relResName, Context currCtx, Name remain) { if (remain != null) this.remainingName = (Name)(remain.clone()); else this.remainingName = new CompositeName(); setContinueAux(obj, relResName, currCtx, remainingName); }
String overload.
Params:
  • obj – The possibly null resolved object.
  • relResName – The non-null resolved name relative to currCtx.
  • currCtx – The non-null context from which relResName is to be resolved.
  • remain – The non-null remaining name.
See Also:
/** * String overload. * * @param obj The possibly null resolved object. * @param relResName The non-null resolved name relative to currCtx. * @param currCtx The non-null context from which relResName is to be resolved. * @param remain The non-null remaining name. * @see #setContinue(java.lang.Object, java.lang.String, javax.naming.Context, java.lang.String) */
public void setContinue(Object obj, String relResName, Context currCtx, String remain) { CompositeName relname = new CompositeName(); if (!relResName.isEmpty()) { try { relname.add(relResName); } catch (NamingException e){} } CompositeName rname = new CompositeName(); if (!remain.isEmpty()) { try { rname.add(remain); } catch (NamingException e) { } } setContinueAux(obj, relname, currCtx, rname); }
%%% This method is kept only for backward compatibility. Delete when old implementations updated. Replaced by setContinue(obj, relResName, (Context)currCtx);
Deprecated:
/** * %%% This method is kept only for backward compatibility. Delete when * old implementations updated. * * Replaced by setContinue(obj, relResName, (Context)currCtx); * * @deprecated */
@Deprecated public void setContinue(Object obj, Object currCtx) { setContinue(obj, null, (Context)currCtx); }
Sets this Continuation to process a linkRef. %%% Not working yet.
/** * Sets this Continuation to process a linkRef. * %%% Not working yet. */
private void setContinueLink(Object linkRef, Name relResName, Context resolvedCtx, Name rname) { this.followingLink = linkRef; this.remainingName = rname; this.resolvedObj = resolvedCtx; this.relativeResolvedName = PartialCompositeContext._EMPTY_NAME; this.resolvedContext = resolvedCtx; this.continuing = true; } public String toString() { if (remainingName != null) return starter.toString() + "; remainingName: '" + remainingName + "'"; else return starter.toString(); } public String toString(boolean detail) { if (!detail || this.resolvedObj == null) return this.toString(); return this.toString() + "; resolvedObj: " + this.resolvedObj + "; relativeResolvedName: " + relativeResolvedName + "; resolvedContext: " + resolvedContext; } private static final long serialVersionUID = 8162530656132624308L; }