/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*/
/**
* Provides implementation of p_* operations using
* c_* operations provided by subclasses.
*
* Clients: deal only with names for its own naming service. Must
* provide implementations for c_* methods, and for p_parseComponent()
* and the c_*_nns methods if the defaults are not appropriate.
*
* @author Rosanna Lee
* @author Scott Seligman
*/
protected ComponentContext() {
}
// ------ Abstract methods whose implementation are provided by subclass
/* Equivalent methods in Context interface */
throws NamingException;
throws NamingException;
throws NamingException;
throws NamingException;
throws NamingException;
throws NamingException;
throws NamingException;
// ------ Methods that may need to be overridden by subclass
/* Parsing method */
/**
* Determines which of the first components of 'name' belong
* to this naming system.
* If no components belong to this naming system, return
* the empty name (new CompositeName()) as the head,
* and the entire name as the tail.
*
* The default implementation supports strong separation.
* If the name is empty or if the first component is empty,
* head is the empty name and tail is the entire name.
* (This means that this context does not have any name to work with).
* Otherwise, it returns the first component as head, and the rest of
* the components as tail.
*
* Subclass should override this method according its own policies.
*
* For example, a weakly separated system with dynamic boundary
* determination would simply return as head 'name'.
* A weakly separated with static boundary
* determination would select the components in the front of 'name'
* that conform to some syntax rules. (e.g. in X.500 syntax, perhaps
* select front components that have a equal sign).
* If none conforms, return an empty name.
*/
throws NamingException {
int separator;
// if no name to parse, or if we're already at boundary
separator = 0;
} else {
separator = 1;
}
if (name instanceof CompositeName) {
} else {
// treat like compound name
}
if (debug > 2) {
}
}
/* Resolution method for supporting federation */
/**
* Resolves the nns for 'name' when the named context is acting
* as an intermediate context.
*
* For a system that supports only junctions, this would be
* equilvalent to
* c_lookup(name, cont);
* because for junctions, an intermediate slash simply signifies
* a syntactic separator.
*
* For a system that supports only implicit nns, this would be
* equivalent to
* c_lookup_nns(name, cont);
* because for implicit nns, a slash always signifies the implicit nns,
* regardless of whether it is intermediate or trailing.
*
* By default this method supports junctions, and also allows for an
* implicit nns to be dynamically determined through the use of the
* "nns" reference (see c_processJunction_nns()).
* Contexts that implement implicit nns directly should provide an
* appropriate override.
*
* A junction, by definition, is a binding of a name in one
* namespace to an object in another. The default implementation
* of this method detects the crossover into another namespace
* using the following heuristic: there is a junction when "name"
* resolves to a context that is not an instance of
* this.getClass(). Contexts supporting junctions for which this
* heuristic is inappropriate should override this method.
*/
throws NamingException {
try {
// Do not append "" to Continuation 'cont' even if set
// because the intention is to ignore the nns
// If "obj" is in the same type as this object, it must
// not be a junction. Continue the lookup with "/".
return null;
// obj is not even a context, so try to find its nns
// dynamically by constructing a Reference containing obj.
public Object getContent() {
return obj;
}
private static final long serialVersionUID =
-8831204798861786362L;
};
// Resolved name has trailing slash to indicate nns
// Set continuation leave it to
// PartialCompositeContext.getPCContext() to throw CPE.
// Do not use setContinueNNS() because we've already
// consumed "/" (i.e., moved it to resName).
return null;
} else {
// Consume "/" and continue
return obj;
}
} catch (NamingException e) {
throw e;
}
}
/* Equivalent of Context Methods for supporting nns */
// The following methods are called when the Context methods
// are invoked with a name that has a trailing slash.
// For naming systems that support implicit nns,
// the trailing slash signifies the implicit nns.
// For such naming systems, override these c_*_nns methods.
//
// For naming systems that do not support implicit nns, the
// default implementations here throw an exception. See
// c_processJunction_nns() for details.
throws NamingException {
return null;
}
throws NamingException {
return null;
}
return null;
}
return null;
}
throws NamingException {
}
throws NamingException {
}
throws NamingException {
}
return null;
}
throws NamingException {
}
throws NamingException {
}
throws NamingException {
return null;
}
// ------ internal method used by ComponentContext
/**
* Locates the nns using the default policy. This policy fully
* handles junctions, but otherwise throws an exception when an
* attempt is made to resolve an implicit nns.
*
* The default policy is as follows: If there is a junction in
* the namespace, then resolve to the junction and continue the
* operation there (thus deferring to that context to find its own
* nns). Otherwise, resolve as far as possible and then throw
* CannotProceedException with the resolved object being a reference:
* the address type is "nns", and the address contents is this
* context.
*
* For example, when c_bind_nns(name, obj, ...) is invoked, the
* caller is attempting to bind the object "obj" to the nns of
* "name". If "name" is a junction, it names an object in another
* naming system that (presumably) has an nns. c_bind_nns() will
* first resolve "name" to a context and then attempt to continue
* the bind operation there, (thus binding to the nns of the
* context named by "name"). If "name" is empty then throw an
* exception, since this context does not by default support an
* implicit nns.
*
* To implement a context that does support an implicit nns, it is
* necessary to override this default policy. This is done by
* overriding the c_*_nns() methods (which each call this method
* by default).
*/
throws NamingException
{
// Construct a new Reference that contains this context.
public Object getContent() {
return ComponentContext.this;
}
private static final long serialVersionUID =
-1389472957988053402L;
};
// Set continuation leave it to PartialCompositeContext.getPCContext()
// to throw the exception.
// Do not use setContinueNNS() because we've are
// setting relativeResolvedName to "/".
return;
}
try {
// lookup name to continue operation in nns
if (cont.isContinue())
else {
}
} catch (NamingException e) {
throw e;
}
}
/**
* Determine whether 'name' is a terminal component in
* this naming system.
* If so, return status indicating so, so that caller
* can perform context operation on this name.
*
* If not, then the first component(s) of 'name' names
* an intermediate context. In that case, resolve these components
* and set Continuation to be the object named.
*
* see test cases at bottom of file.
*/
throws NamingException {
int ret = USE_CONTINUATION;
//System.out.println("terminal : " + head);
// tail does not begin with "/"
/*
if (head.isEmpty()) {
// Context could not find name that it can use
// illegal syntax error or name not found
//System.out.println("nnf exception : " + head);
NamingException e = new NameNotFoundException();
cont.setError(this, name);
throw cont.fillInException(e);
} else {
*/
// head is being used as intermediate context,
// resolve head and set Continuation with tail
try {
//System.out.println("resInter : " + head + "=" + obj);
else if (cont.isContinue()) {
}
} catch (NamingException e) {
throw e;
}
/*
}
*/
} else {
// tail begins with "/"
//System.out.println("terminal_nns : " + head);
// resolve nns of head and continue with tail.getSuffix(1)
try {
//System.out.println("lookup_nns : " + head + "=" + obj);
else if (cont.isContinue()) {
// Name rname = cont.getRemainingName();
//System.out.println("cont.rname" + rname);
}
} catch (NamingException e) {
throw e;
}
} else {
// head is being used as intermediate context
// resolve and set continuation to tail
try {
//System.out.println("resInter2 : " + head + "=" + obj);
else if (cont.isContinue()) {
}
} catch (NamingException e) {
throw e;
}
}
}
return p;
}
// When c_resolveIntermediate_nns() or c_lookup_nns() sets up
// its continuation, to indicate "nns", it appends an empty
// component to the remaining name (e.g. "eng/"). If last
// component of remaining name is empty; delete empty component
// before appending tail so that composition of the names work
// correctly. For example, when merging "eng/" and "c.b.a", we want
// is extraneous. When merging "" and "c.b.a", we want the result
// to be "/c.b.a" and so must keep the trailing slash (empty name).
int count;
}
}
// Returns true if n contains only empty components
for (int i =0; i < count; i++ ) {
return false;
}
}
return true;
}
// ------ implementations of p_ Resolver and Context methods using
// ------ corresponding c_ and c_*_nns methods
/* implementation for Resolver method */
throws NamingException {
if (contextType.isInstance(this)) {
cont.setSuccess();
return (new ResolveResult(this, name));
}
case TERMINAL_NNS_COMPONENT:
}
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* pcont already set or exception thrown */
break;
}
return ret;
}
/* implementations of p_ Context methods */
case TERMINAL_NNS_COMPONENT:
}
break;
case TERMINAL_COMPONENT:
}
break;
default:
/* USE_CONTINUATION */
/* pcont already set or exception thrown */
break;
}
return ret;
}
throws NamingException {
case TERMINAL_NNS_COMPONENT:
if (debug > 0)
break;
case TERMINAL_COMPONENT:
if (debug > 0)
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
return ret;
}
case TERMINAL_NNS_COMPONENT:
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
return ret;
}
case TERMINAL_NNS_COMPONENT:
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
}
case TERMINAL_NNS_COMPONENT:
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
}
case TERMINAL_NNS_COMPONENT:
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
}
case TERMINAL_NNS_COMPONENT:
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
}
case TERMINAL_NNS_COMPONENT:
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
return ret;
}
case TERMINAL_NNS_COMPONENT:
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
}
case TERMINAL_NNS_COMPONENT:
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
return ret;
}
throws NamingException {
case TERMINAL_NNS_COMPONENT:
break;
case TERMINAL_COMPONENT:
break;
default:
/* USE_CONTINUATION */
/* cont already set or exception thrown */
break;
}
return ret;
}
}
/*
* How p_resolveIntermediate() should behave for various test cases
a.b/x {a.b, x}
c_resolveIntermediate_nns(a.b)
continue(x)
{x,}
terminal(x)
a.b/ {a.b, ""}
terminal_nns(a.b);
a.b//
{a.b, ("", "")}
c_lookup_nns(a.b)
continue({""})
{,""}
terminal_nns({})
/x {{}, {"", x}}
c_lookup_nns({})
continue(x)
{x,}
terminal(x)
//y {{}, {"", "", y}}
c_lookup_nns({})
continue({"", y})
{{}, {"", y}}
c_lookup_nns({})
continue(y)
{y,}
terminal(y)
a.b//y {a.b, {"", y}}
c_resolveIntermediate_nns(a.b)
continue({"", y})
{{}, {"",y}}
c_lookup_nns({});
continue(y)
{y,}
terminal(y);
*
*/