com.gemstone.gemfire.internal.jndi.ContextImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gemfire-core Show documentation
Show all versions of gemfire-core Show documentation
SnappyData store based off Pivotal GemFireXD
/*
* Copyright 2004 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License. See accompanying
* LICENSE file.
*/
/*
* Adapted from MockEJB's MockContext for GemFire.
*
* Portions Copyright (c) 2010-2015 Pivotal Software, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you
* may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License. See accompanying
* LICENSE file.
*/
package com.gemstone.gemfire.internal.jndi;
import com.gemstone.gemfire.i18n.LogWriterI18n;
import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
import java.util.Hashtable;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.util.NoSuchElementException;
import java.util.Vector;
import java.util.Iterator;
import javax.naming.Binding;
import javax.naming.CompositeName;
import javax.naming.Context;
import javax.naming.ContextNotEmptyException;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NoPermissionException;
import javax.naming.NotContextException;
import javax.naming.NameAlreadyBoundException;
import javax.transaction.SystemException;
import com.gemstone.gemfire.internal.jta.TransactionUtils;
import com.gemstone.gemfire.internal.jta.UserTransactionImpl;
/**
* Provides implementation of javax.naming.Context interface. A name in the
* ContextImpl namespace is a sequence of one or more atomic names, relative to
* a root initial context. When a name consist of more than one atomic names it
* is a CompoundName where atomic names are separated with separator character -
* '/' or '.'. It is possible to use both separator characters in the same name.
* In such cases any occurrences of '.' are replaced with '/' before parsing.
* This rule can be altered/modified by making changes in NameParserImpl class.
*/
public class ContextImpl implements Context {
private static final String ROOT_CONTEXT_NAME = "ROOT";
// Naming scheme for the ContextImpl.
private static final NameParser nameParser = new NameParserImpl();
/*
* Map of objects registered for this context representing the local context
*/
private final Map ctxMaps = Collections.synchronizedMap(new HashMap());
// Name of this Context
private String ctxName;
// Parent Context of this Context
private ContextImpl parentCtx;
// Shows if this context has been destroyed
private boolean isDestroyed;
/*
* Creates new instance of ContextImpl. @param parentCtx parent context of
* this context. null if this is the root context. @param name atomic name for
* this context
*/
private ContextImpl(ContextImpl parentCtx, String name) {
this.parentCtx = parentCtx;
this.ctxName = name;
this.isDestroyed = false;
}
/**
* Default constructor
*/
public ContextImpl() {
// call the constructor with default setting
this(null, ROOT_CONTEXT_NAME);
}
/**
* Not implemented
*
*/
public Object addToEnvironment(String key, Object value)
throws NamingException {
throw new NamingException(LocalizedStrings.ContextImpl_ADDTOENVIRONMENTSTRING_KEY_OBJECT_VALUE_IS_NOT_IMPLEMENTED.toLocalizedString());
}
/**
* Binds object to a name in this context. Intermediate contexts that do not
* exist will be created.
*
* @param name Name of the object to bind
* @param obj Object to bind. Can be null.
* @throws NoPermissionException if this context has been destroyed.
* @throws InvalidNameException if name is empty or is CompositeName that
* spans more than one naming system.
* @throws NotContextException if name has more than one atomic name and
* intermediate atomic name is bound to object that is not context.
*/
public void bind(Name name, Object obj) throws NamingException {
checkIsDestroyed();
// Do not check for already bound name.
// Simply replace the existing value.
rebind(name, obj);
}
/**
* Binds object to name in this context.
*
* @param name * name of the object to add
* @param obj object to bind
* @throws NamingException if naming error occurs
*
*/
public void bind(String name, Object obj) throws NamingException {
bind(nameParser.parse(name), obj);
}
/**
* Does nothing.
*/
public void close() throws NamingException {
}
/**
* Returns composition of prefix and name .
*
* @param name name relative to this context
* @param prefix name of this context Example: composeName("a","b") : b/a
* composeName("a","") : a
*
*/
public Name composeName(Name name, Name prefix) throws NamingException {
checkIsDestroyed();
// We do not want to modify any of the parameters (JNDI requirement).
// Clone prefix
to satisfy the requirement.
Name parsedPrefix = getParsedName((Name) prefix.clone());
Name parsedName = getParsedName(name);
return parsedPrefix.addAll(parsedName);
}
/**
* Returns composition of prefix and name .
*
* @param name name relative to this context
* @param prefix name of this context Example: composeName("a","b") : b/a
* composeName("a","") : a
*
*/
public String composeName(String name, String prefix) throws NamingException {
checkIsDestroyed();
return composeName(nameParser.parse(name), nameParser.parse(prefix))
.toString();
}
/**
* Creates subcontext with name, relative to this Context.
*
* @param name subcontext name.
* @return new subcontext named name relative to this context.
* @throws NoPermissionException if this context has been destroyed.
* @throws InvalidNameException if name is empty or is CompositeName that
* spans more than one naming system.
* @throws NameAlreadyBoundException if name is already bound in this Context
* @throws NotContextException if any intermediate name from name is not bound
* to instance of javax.naming.Context.
*
*/
public Context createSubcontext(Name name) throws NamingException {
checkIsDestroyed();
Name parsedName = getParsedName(name);
if (parsedName.size() == 0 || parsedName.get(0).length() == 0) { throw new InvalidNameException(LocalizedStrings.ContextImpl_NAME_CAN_NOT_BE_EMPTY.toLocalizedString()); }
String subContextName = parsedName.get(0);
Object boundObject = ctxMaps.get(parsedName.get(0));
if (parsedName.size() == 1) {
// Check if name is already in use
if (boundObject == null) {
Context subContext = new ContextImpl(this, subContextName);
ctxMaps.put(subContextName, subContext);
return subContext;
}
else {
throw new NameAlreadyBoundException(LocalizedStrings.ContextImpl_NAME_0_IS_ALREADY_BOUND.toLocalizedString(subContextName));
}
}
else {
if (boundObject instanceof Context) {
// Let the subcontext create new subcontext
// lets consider a scenerio a/b/c
// case a/b exists : c will be created
// case a exists : b/c will not be created
// an exception will be thrown in that case.
return ((Context) boundObject)
.createSubcontext(parsedName.getSuffix(1));
}
else {
throw new NotContextException(LocalizedStrings.ContextImpl_EXPECTED_CONTEXT_BUT_FOUND_0.toLocalizedString(boundObject));
}
}
}
/**
* Creates subcontext with name, relative to this Context.
*
* @param name subcontext name
* @return new subcontext named name relative to this context.
* @throws NamingException if naming error occurs.
*
*/
public Context createSubcontext(String name) throws NamingException {
return createSubcontext(nameParser.parse(name));
}
/**
* Destroys subcontext with name name. The subcontext must be empty otherwise
* ContextNotEmptyException is thrown. Once a context is destroyed, the
* instance should not be used.
*
* @param name subcontext to destroy
* @throws NoPermissionException if this context has been destroyed.
* @throws InvalidNameException if name is empty or is CompositeName that
* spans more than one naming system.
* @throws ContextNotEmptyException if Context name is not empty.
* @throws NameNotFoundException if subcontext with name name can not be
* found.
* @throws NotContextException if name is not bound to instance of
* ContextImpl.
*
*/
public void destroySubcontext(Name name) throws NamingException {
checkIsDestroyed();
Name parsedName = getParsedName(name);
if (parsedName.size() == 0 || parsedName.get(0).length() == 0) { throw new InvalidNameException(LocalizedStrings.ContextImpl_NAME_CAN_NOT_BE_EMPTY.toLocalizedString()); }
String subContextName = parsedName.get(0);
Object boundObject = ctxMaps.get(subContextName);
if (boundObject == null) { throw new NameNotFoundException(LocalizedStrings.ContextImpl_NAME_0_NOT_FOUND_IN_THE_CONTEXT.toLocalizedString(subContextName)); }
if (!(boundObject instanceof ContextImpl)) { throw new NotContextException(); }
ContextImpl contextToDestroy = (ContextImpl) boundObject;
if (parsedName.size() == 1) {
// Check if the Context to be destroyed is empty. Can not destroy
// non-empty Context.
if (contextToDestroy.ctxMaps.size() == 0) {
ctxMaps.remove(subContextName);
contextToDestroy.destroyInternal();
}
else {
throw new ContextNotEmptyException(LocalizedStrings.ContextImpl_CAN_NOT_DESTROY_NONEMPTY_CONTEXT.toLocalizedString());
}
}
else {
// Let the subcontext destroy the context
((ContextImpl) boundObject).destroySubcontext(parsedName.getSuffix(1));
}
}
/**
* Destroys subcontext with name name.
*
* @param name name of subcontext to destroy.
* @throws NamingException if naming error occurs
*/
public void destroySubcontext(String name) throws NamingException {
destroySubcontext(nameParser.parse(name));
}
/**
* Not implemented
*
*/
public Hashtable getEnvironment() throws NamingException {
throw new NamingException(LocalizedStrings.ContextImpl_GETENVIRONMENT_IS_NOT_IMPLEMENTED.toLocalizedString());
}
/**
* Not implemented
*
*/
public String getNameInNamespace() throws NamingException {
throw new NamingException(LocalizedStrings.ContextImpl_GETNAMEINNAMESPACE_IS_NOT_IMPLEMENTED.toLocalizedString());
}
/**
* Retrieves NameParser used to parse context with name name.
*
* @param name context name.
* @return NameParser.
* @throws NoPermissionException if this context has been destroyed.
* @throws NamingException if any other naming error occurs.
*
*/
public NameParser getNameParser(Name name) throws NamingException {
checkIsDestroyed();
return nameParser;
}
/**
* Retrieves NameParser used to parse context with name name.
*
* @param name context name.
* @return NameParser.
* @throws NoPermissionException if this context has been destroyed.
* @throws NamingException if any other naming error occurs.
*
*/
public NameParser getNameParser(String name) throws NamingException {
checkIsDestroyed();
return nameParser;
}
/**
* The same as listBindings(String).
*
* @param name name of Context, relative to this Context
* @return NamingEnumeration of all name-class pairs. Each element from the
* enumeration is instance of NameClassPair
* @throws NamingException if naming error occurs
*
*/
public NamingEnumeration list(Name name) throws NamingException {
return listBindings(name);
}
/**
* The same as listBindings(String).
*
* @param name name of Context, relative to this Context
* @return NamingEnumeration of all name-class pairs. Each element from the
* enumeration is instance of NameClassPair
* @throws NamingException if naming error occurs
*
*/
public NamingEnumeration list(String name) throws NamingException {
return list(nameParser.parse(name));
}
/**
* Lists all bindings for Context with name name. If name is empty then this
* Context is assumed.
*
* @param name name of Context, relative to this Context
* @return NamingEnumeration of all name-object pairs. Each element from the
* enumeration is instance of Binding.
* @throws NoPermissionException if this context has been destroyed
* @throws InvalidNameException if name is CompositeName that spans more than
* one naming system
* @throws NameNotFoundException if name can not be found
* @throws NotContextException component of name is not bound to instance of
* ContextImpl, when name is not an atomic name
* @throws NamingException if any other naming error occurs
*
*/
public NamingEnumeration listBindings(Name name) throws NamingException {
checkIsDestroyed();
Name parsedName = getParsedName(name);
if (parsedName.size() == 0) {
Vector bindings = new Vector();
Iterator iterat = ctxMaps.keySet().iterator();
while (iterat.hasNext()) {
String bindingName = (String) iterat.next();
bindings.addElement(new Binding(bindingName, ctxMaps.get(bindingName)));
}
return new NamingEnumerationImpl(bindings);
}
else {
Object subContext = ctxMaps.get(parsedName.get(0));
if (subContext instanceof Context) {
Name nextLayer = nameParser.parse("");
// getSuffix(1) only apply to name with size() > 1
if (parsedName.size() > 1) {
nextLayer = parsedName.getSuffix(1);
}
return ((Context) subContext).list(nextLayer);
}
if (subContext == null && !ctxMaps.containsKey(parsedName.get(0))) {
throw new NameNotFoundException(LocalizedStrings.ContextImpl_NAME_0_NOT_FOUND.toLocalizedString(name));
}
else {
throw new NotContextException(LocalizedStrings.ContextImpl_EXPECTED_CONTEXT_BUT_FOUND_0.toLocalizedString(subContext));
}
}
}
/**
* Lists all bindings for Context with name name. If name is empty then this
* Context is assumed.
*
* @param name name of Context, relative to this Context
* @return NamingEnumeration of all name-object pairs. Each element from the
* enumeration is instance of Binding.
* @throws NoPermissionException if this context has been destroyed
* @throws InvalidNameException if name is CompositeName that spans more than
* one naming system
* @throws NameNotFoundException if name can not be found
* @throws NotContextException component of name is not bound to instance of
* ContextImpl, when name is not an atomic name
* @throws NamingException if any other naming error occurs
*
*/
public NamingEnumeration listBindings(String name) throws NamingException {
return listBindings(nameParser.parse(name));
}
/**
* Looks up object with binding name name in this context.
*
* @param name name to look up
* @return object reference bound to name name.
* @throws NoPermissionException if this context has been destroyed.
* @throws InvalidNameException if name is CompositeName that spans more than
* one naming system
* @throws NameNotFoundException if name can not be found.
* @throws NotContextException component of name is not bound to instance of
* ContextImpl, when name is not atomic name.
* @throws NamingException if any other naming error occurs
*
*/
public Object lookup(Name name) throws NamingException {
checkIsDestroyed();
try {
Name parsedName = getParsedName(name);
String nameComponent = parsedName.get(0);
Object res = ctxMaps.get(nameComponent);
if (res instanceof UserTransactionImpl) {
res = new UserTransactionImpl();
}
// if not found
if (!ctxMaps.containsKey(nameComponent)) {
throw new NameNotFoundException(LocalizedStrings.ContextImpl_NAME_0_NOT_FOUND.toLocalizedString(name));
}
// if this is a compound name
else if (parsedName.size() > 1) {
if (res instanceof ContextImpl) {
res = ((ContextImpl) res).lookup(parsedName.getSuffix(1));
}
else {
throw new NotContextException(LocalizedStrings.ContextImpl_EXPECTED_CONTEXTIMPL_BUT_FOUND_0.toLocalizedString(res));
}
}
return res;
}
catch (NameNotFoundException e) {
LogWriterI18n writer = TransactionUtils.getLogWriterI18n();
if (writer.infoEnabled()) writer.info(LocalizedStrings.ContextImpl_CONTEXTIMPL_LOOKUP_ERROR_WHILE_LOOKING_UP_0, name, e);
throw new NameNotFoundException(LocalizedStrings.ContextImpl_NAME_0_NOT_FOUND.toLocalizedString(new Object[] {name}));
}
catch (SystemException se) {
LogWriterI18n writer = TransactionUtils.getLogWriterI18n();
if (writer.severeEnabled()) writer.info(LocalizedStrings.ContextImpl_CONTEXTIMPL_LOOKUP_ERROR_WHILE_CREATING_USERTRANSACTION_OBJECT, se);
throw new NameNotFoundException(LocalizedStrings.ContextImpl_CONTEXTIMPL_LOOKUP_ERROR_WHILE_CREATING_USERTRANSACTION_OBJECT.toLocalizedString());
}
}
/**
* Looks up the object in this context. If the object is not found and the
* remote context was provided, calls the remote context to lookup the object.
*
* @param name object to search
* @return object reference bound to name name.
* @throws NamingException if naming error occurs.
*
*/
public Object lookup(String name) throws NamingException {
checkIsDestroyed();
try {
return lookup(nameParser.parse(name));
}
catch (NameNotFoundException e) {
LogWriterI18n writer = TransactionUtils.getLogWriterI18n();
if (writer.infoEnabled()) writer.info(LocalizedStrings.ContextImpl_CONTEXTIMPL_LOOKUP_ERROR_WHILE_LOOKING_UP_0, name, e);
throw new NameNotFoundException(LocalizedStrings.ContextImpl_NAME_0_NOT_FOUND.toLocalizedString(new Object[] {name}));
}
}
/**
* Not implemented
*
*/
public Object lookupLink(Name name) throws NamingException {
throw new NamingException(LocalizedStrings.ContextImpl_LOOKUPLINKNAME_NAME_IS_NOT_IMPLEMENTED.toLocalizedString());
}
/**
* Not implemented
*
*/
public Object lookupLink(String name) throws NamingException {
throw new NamingException(LocalizedStrings.ContextImpl_LOOKUPLINKSTRING_NAME_IS_NOT_IMPLEMENTED.toLocalizedString());
}
/**
* Rebinds object obj to name name . If there is existing binding it will be
* overwritten.
*
* @param name name of the object to rebind.
* @param obj object to add. Can be null.
* @throws NoPermissionException if this context has been destroyed
* @throws InvalidNameException if name is empty or is CompositeName that
* spans more than one naming system
* @throws NotContextException if name has more than one atomic name and
* intermediate context is not found
* @throws NamingException if any other naming error occurs
*
*/
public void rebind(Name name, Object obj) throws NamingException {
checkIsDestroyed();
Name parsedName = getParsedName(name);
if (parsedName.size() == 0 || parsedName.get(0).length() == 0) { throw new InvalidNameException(LocalizedStrings.ContextImpl_NAME_CAN_NOT_BE_EMPTY.toLocalizedString()); }
String nameToBind = parsedName.get(0);
if (parsedName.size() == 1) {
ctxMaps.put(nameToBind, obj);
}
else {
Object boundObject = ctxMaps.get(nameToBind);
if (boundObject instanceof Context) {
/*
* Let the subcontext bind the object.
*/
((Context) boundObject).bind(parsedName.getSuffix(1), obj);
}
else {
if (boundObject == null) {
// Create new subcontext and let it do the binding
Context sub = createSubcontext(nameToBind);
sub.bind(parsedName.getSuffix(1), obj);
}
else {
throw new NotContextException(LocalizedStrings.ContextImpl_EXPECTED_CONTEXT_BUT_FOUND_0.toLocalizedString(boundObject));
}
}
}
}
/**
* Rebinds object obj to String name. If there is existing binding it will be
* overwritten.
*
* @param name name of the object to rebind.
* @param obj object to add. Can be null.
* @throws NoPermissionException if this context has been destroyed
* @throws InvalidNameException if name is empty or is CompositeName that
* spans more than one naming system
* @throws NotContextException if name has more than one atomic name and
* intermediate context is not found
* @throws NamingException if any other naming error occurs
*
*/
public void rebind(String name, Object obj) throws NamingException {
rebind(nameParser.parse(name), obj);
}
/**
* Not implemented
*
*/
public Object removeFromEnvironment(String key) throws NamingException {
throw new NamingException(LocalizedStrings.ContextImpl_REMOVEFROMENVIRONMENTSTRING_KEY_IS_NOT_IMPLEMENTED.toLocalizedString());
}
/**
* Not implemented
*
*/
public void rename(Name name1, Name name2) throws NamingException {
throw new NamingException(LocalizedStrings.ContextImpl_RENAMENAME_NAME1_NAME_NAME2_IS_NOT_IMPLEMENTED.toLocalizedString());
}
/**
* Not implemented
*
*/
public void rename(String name1, String name2) throws NamingException {
throw new NamingException(LocalizedStrings.ContextImpl_RENAMESTRING_NAME1_STRING_NAME2_IS_NOT_IMPLEMENTED.toLocalizedString());
}
/**
* Removes name and its associated object from the context.
*
* @param name name to remove
* @throws NoPermissionException if this context has been destroyed.
* @throws InvalidNameException if name is empty or is CompositeName that
* spans more than one naming system
* @throws NameNotFoundException if intermediate context can not be found
* @throws NotContextException if name has more than one atomic name and
* intermediate context is not found.
* @throws NamingException if any other naming exception occurs
*
*/
public void unbind(Name name) throws NamingException {
checkIsDestroyed();
Name parsedName = getParsedName(name);
if (parsedName.size() == 0 || parsedName.get(0).length() == 0) { throw new InvalidNameException(LocalizedStrings.ContextImpl_NAME_CAN_NOT_BE_EMPTY.toLocalizedString()); }
String nameToRemove = parsedName.get(0);
// scenerio unbind a
// remove a and its associated object
if (parsedName.size() == 1) {
ctxMaps.remove(nameToRemove);
}
else {
// scenerio unbind a/b or a/b/c
// remove b and its associated object
Object boundObject = ctxMaps.get(nameToRemove);
if (boundObject instanceof Context) {
// remove b and its associated object
((Context) boundObject).unbind(parsedName.getSuffix(1));
}
else {
// if the name is not found then throw exception
if (!ctxMaps.containsKey(nameToRemove)) { throw new NameNotFoundException(LocalizedStrings.ContextImpl_CAN_NOT_FIND_0.toLocalizedString(name)); }
throw new NotContextException(LocalizedStrings.ContextImpl_EXPECTED_CONTEXT_BUT_FOUND_0.toLocalizedString(boundObject));
}
}
}
/**
*
* Removes name and its associated object from the context.
*
* @param name name to remove
* @throws NoPermissionException if this context has been destroyed.
* @throws InvalidNameException if name is empty or is CompositeName that
* spans more than one naming system
* @throws NameNotFoundException if intermediate context can not be found
* @throws NotContextException if name has more than one atomic name and
* intermediate context is not found.
* @throws NamingException if any other naming exception occurs
*
*/
public void unbind(String name) throws NamingException {
unbind(nameParser.parse(name));
}
/**
* Checks if this context has been destroyed. isDestroyed is set to true when
* a context is destroyed by calling destroySubcontext method.
*
* @throws NoPermissionException if this context has been destroyed
*/
private void checkIsDestroyed() throws NamingException {
if (isDestroyed) { throw new NoPermissionException(LocalizedStrings.ContextImpl_CAN_NOT_INVOKE_OPERATIONS_ON_DESTROYED_CONTEXT.toLocalizedString()); }
}
/**
* Marks this context as destroyed. Method called only by destroySubcontext.
*/
private void destroyInternal() {
isDestroyed = true;
}
/**
* Parses name which is CompositeName or CompoundName . If name is not
* CompositeName then it is assumed to be CompoundName. If the name contains
* leading and/or terminal empty components, they will not be included in the
* result.
*
* @param name Name to parse.
* @return parsed name as instance of CompoundName.
* @throws InvalidNameException if name is CompositeName and spans more than
* one name space.
* @throws NamingException if any other naming exception occurs
*/
private Name getParsedName(Name name) throws NamingException {
Name result = null;
if (name instanceof CompositeName) {
if (name.size() == 0) {
// Return empty CompositeName
result = nameParser.parse("");
}
else if (name.size() > 1) { throw new InvalidNameException(LocalizedStrings.ContextImpl_MULTIPLE_NAME_SYSTEMS_ARE_NOT_SUPPORTED.toLocalizedString()); }
result = nameParser.parse(name.get(0));
}
else {
result = (Name) name.clone();
}
while (!result.isEmpty()) {
if (result.get(0).length() == 0) {
result.remove(0);
continue;
}
if (result.get(result.size() - 1).length() == 0) {
result.remove(result.size() - 1);
continue;
}
break;
}
// Validate that there are not intermediate empty components.
// Skip first and last element, they are valid
for (int i = 1; i < result.size() - 1; i++) {
if (result.get(i).length() == 0) { throw new InvalidNameException(LocalizedStrings.ContextImpl_EMPTY_INTERMEDIATE_COMPONENTS_ARE_NOT_SUPPORTED.toLocalizedString()); }
}
return result;
}
/**
* Returns the compound string name of this context. Suppose a/b/c/d is the
* full name and this context is "c". It's compound string name is a/b/c
*
* @return compound string name of the context
*/
String getCompoundStringName() throws NamingException {
//StringBuffer compositeName = new StringBuffer();
String compositeName = "";
ContextImpl curCtx = this;
while (!curCtx.isRootContext()) {
compositeName = composeName(compositeName, curCtx.getAtomicName());
curCtx = curCtx.getParentContext();
}
return compositeName;
}
/*
* Returns parent context of this context
*/
ContextImpl getParentContext() {
return parentCtx;
}
/*
* Returns the "atomic" (as opposed to "composite") name of the context.
* @return name of the context
*/
String getAtomicName() {
return ctxName;
}
/*
* Returns true if this context is the root context @return true if the
* context is the root context
*/
boolean isRootContext() {
return getParentContext() == null;
}
static private class NamingEnumerationImpl implements NamingEnumeration {
private Vector elements;
private int currentElement;
NamingEnumerationImpl(Vector elements) {
this.elements = elements;
this.currentElement = 0;
}
public void close() {
currentElement = 0;
elements.clear();
}
public boolean hasMore() {
return hasMoreElements();
}
public boolean hasMoreElements() {
if (currentElement < elements.size()) { return true; }
close();
return false;
}
public Object next() {
return nextElement();
}
public Object nextElement() {
if (hasMoreElements()) { return elements.get(currentElement++); }
throw new NoSuchElementException();
}
}
}