Métodos de Lista
list() y
listBindings() generan una
NamingEnumeration.
Una NamingEnumeration es como una
java.util.Enumeration, excepto en que contiene métodos que
permiten que se lance una
NamingException y contienen un
close() método para liberar los recursos asociados
con la enumeración. En el ejemplo de
espacio de nombres plano,
list() y listBindings()
simplemente realizaban una lookup() sobre el contexto fuente
(es decir, el contexto a listar) y luego hacían el listado usando el nombre vacío como
argumento. Si la fuente no nombra un Context, lanza una
NotContextException:
public NamingEnumeration list(Name name) throws NamingException {
if (name.isEmpty()) {
// Generate enumeration of context's contents
return new ListOfNames(bindings.keys());
}
// Perhaps "name" names a context
Object target = lookup(name);
if (target instanceof Context) {
try {
return ((Context)target).list("");
} finally {
((Context)target).close();
}
}
throw new NotContextException(name + " cannot be listed");
}
|
Nota de Implementación:
Observa que las implementaciones de list() y de
listBindings() tienen cuidado de cerrar el contexto en el que
han buscado. Esto es una buena práctica en el caso de que se necesite limpiar el contexto.
Esto también significa que la enumeración devuelta por ámbos métodos permanece disponible
despues de que se haya cerrado el Context desde el que se
obtuvieron. Cuando se cierre o se complete la enumeración del ejemplar
Context puede tener lugar la limpieza final del ejemplar de
Context.
|
El listado se genera usando dos clases internas
ListOfNames y ListOfBindings.
Aquí está la definición de ListOfNames:
// Class for enumerating name/class pairs
class ListOfNames implements NamingEnumeration {
protected Enumeration names;
ListOfNames (Enumeration names) {
this.names = names;
}
public boolean hasMoreElements() {
try {
return hasMore();
} catch (NamingException e) {
return false;
}
}
public boolean hasMore() throws NamingException {
return names.hasMoreElements();
}
public Object next() throws NamingException {
String name = (String)names.nextElement();
String className = bindings.get(name).getClass().getName();
return new NameClassPair(name, className);
}
public Object nextElement() {
try {
return next();
} catch (NamingException e) {
throw new NoSuchElementException(e.toString());
}
}
public void close() {
}
}
El trabajo real se hace en las definicines de
hasMore() y
next(). Para el ejemplo del hashtable,
ListOfNames simplemente es una envoltura alrededor de la
Enumeration. En una implementación real, el listado se generaría
acccediendo al servicio de nombres/directorio subyacente.
hasMoreElements() es una envoltura alderedor de
hasMore(), mientras que
nextElement() es una envoltura alrededor de
next(). hasMoreElements() y
nextElement() satisfacen el interface
java.util.Enumeration y las usan los clientes a los que no les
importa que les notifiquen excepciones que ocurren durante la enumeración. Estas son
definiciones genéricas que pueden usarse para cualquier implementación.
La clase interna ListOfBindings es una subclase de
ListOfNames. Sobreescribe la definición de
next() para devolver un ejemplar de
Binding en lugar de un
NameClassPair.
public Object next() throws NamingException {
String name = (String)names.nextElement();
return new Binding(name, bindings.get(name));
}
Obviamente esta es una implementación muy simplificada. Si el objeto de
Binding es un Context, debería
ser uno que pueda cerrarse (lo que probablemente significa que queremos clanarlo antes de
devolverlo).