Programación en castellano Añadir una dirección | Buscador | Cursos | Artículos | Foros | Formación

Sistema de Nombrado en Java (JNDI) y II
Autor: Sun
Traductor: Juan Antonio Palos (Ozito)


En esta página:


Implementación del Contexto URL

Una implementación de contexto URL es un contexto que maneja strings URL arbitrarios del esquema URL soportado por el contexto. Es una clase que implementa el interface Context o uno de sus subinterfaces. Se diferencia de la implementación de contexto (plano) descrita en la lección Los Componentes Esenciales en la forma en que sus métodos aceptan y procesan el argumento nombre

Nombres Estructurados contra Nomres String

La lección Las Reglas de Fondo sugiere que implementemos los métodos de contexto que aceptan strings en términos de sus contrapartes Name porque los nombres string deberían ser tratados como nombres mixtos (JNDI). Esta regla no se aplica a las implementaciones de contexto URL, porque un string URL no es un nombre mixto JNDI. Un string URL debería procesarse de acuerdo a la síntaxis definida en su esquema de URL. De hecho, la dependencia también es a la inversa. es decir, las sobrecargas que aceptan Name también deberían ser implementadas en términos de sus contrapartes strings.

Si no queremos soportar federaciones, podemos sólo lanzar una InvalidNameException cuando se presente un Name multi-componente:

public void bind(Name name, Object obj) throws NamingException {
    if (name.size() == 1) {
        bind(name.get(0), obj);
    } else {
        throw new InvalidNameException(
	    "Cannot have composite names with URLs");
    }
}

Si soportamos federaciones, entonces cuando se presente con un CompositeName cuyo primer componente sea un string URL válido, deberíamos tratar el primer componente como una URL y luego el resto de los componentes de la federación (es decir, resolver la URL nos dirá qué sistema de nombres utilizar para resolver la parte restante). Si se presenta con un Name que no es un CompositeName, deberíamos tratar esto como un caso de error y lanzar una InvalidNameException. Esto es así porque una URL embebida dentro de un nombre compuesto no tiene sentido.

Este ejemplo no comprueba si la entrada es un CompositeName. Aquí está la definición de bind() del ejemplo:

public void bind(Name name, Object obj) throws NamingException {
    if (name.size() == 1) {
        bind(name.get(0), obj);
    } else {
	Context ctx = getContinuationContext(name);
	try {
	    ctx.bind(name.getSuffix(1), obj);
	} finally {
	    ctx.close();
        }
    }
}

Todas las sobrecargas que aceptan un Name usan un patrón similar. Si el nombre contiene un único componente, extrae el primer componente y lo pasa a la sobrecarga que acepta un nombre string. Esto se parece al llamador usando la sobrecarga que acepta nombres string en la primera posición. De otra forma, usa el método de utilidad getContinuationContext() para resolver el primer componente (es decir, el string URL) y continúa la operación en ese contexto. Aquí está la definición de getContinuationContext():

protected Context getContinuationContext(Name n) throws NamingException {
    Object obj = lookup(n.get(0));
    CannotProceedException cpe = new CannotProceedException();
    cpe.setResolvedObj(obj);
    cpe.setEnvironment(myEnv);
    return NamingManager.getContinuationContext(cpe);
}

Este método de utilidad resuelve el primer componente del nombre y usa el resultado como el "objeto resuelto" en una llamada a NamingManager.getContinuationContext() para obtener el contexto fuente en el que continuar la operación sobre el resto del nombre.

El Contexto Raíz URL

Observa que hemos tenido cuidado de las sobrecargas que aceptan Name, podemos cambiar nuestra atención a las sobrecargas que aceptan java.lang.String. Las implementaciones de estos métodos dependen en gran medida de su contraparte en la implementación de contexto "no-URL". Por ejemplo, una implementación de contexto URL para la URL LDAP es altamente dependiente de la implementación de contexto para el servicio LDAP. Una búsqueda de una URL LDAP en un contexto LDAP URL normalmente resulta en una búsqueda en un contexto LDAP (de la implementación de contexto LDAP) usando un DN LDAP. En este escenario, la implementación de contexto URL realmente sólo es una imagen de la implementación de contexto real del servicio. A causa de esta relación cerrada, este ejemplo podría no aplicarse tan bien en algunas implementaciones reales.

El ejemplo usa la noción de un contexto raiz que se deriva de la string URL de entrada. Define un método de utilidad, getRootURLContext(), que acepta un string URL. Este método devuelve un paquete que consta de un contexto que está derivado de la información de la URL y el resto del nombre de la URL para ser resuelto en relación al contexto raíz. Por ejemplo, en el ejemplo LDAP, supongamos que el string URL de entrada es "ldap://favserver:289/o=jnditutorial". El contexto raíz podría ser el contexto de la raíz del servidor LDAP en la máquina favserver y el puerto 289. En este caso, la porción "ldap://favserver:289/" del string URL será consumida en la producción del contexto raíz y el resto del nombre será "o=jnditutorial".

En nuestro ejemplo de URL foo, el contexto raíz apunta a la raíz del espacio de nombres estático HierCtx, y "foo:/" es consumido para producir el contexto raíz. El resto del nombre está representado como un sólo componente CompositeName:

protected ResolveResult getRootURLContext(String url, Hashtable env) 
    throws NamingException {
    if (!url.startsWith("foo:/")) {
	throw new IllegalArgumentException(url + " is not a foo URL");
    }

    String objName = url.length() > 5 ? url.substring(5) : null;

    // Represent the object name as empty or a single-component composite name.
    CompositeName remaining = new CompositeName();
    if (objName != null) {
	remaining.add(objName);
    }

    // Get the handle to the static namespace to use for testing
    // In an actual implementation, this might be the root
    // namespace on a particular server
    Context ctx = tut.HierCtx.getStaticNamespace(env);

    return (new ResolveResult(ctx, remaining));
}

Las sobrecargas que aceptan nombres string usan este método de utilidad para procesar el string URL y completar la operación. Aquí tenemos la definición de bind() para el ejemplo:

public void bind(String name, Object obj) throws NamingException {
    ResolveResult res = getRootURLContext(name, myEnv);
    Context ctx = (Context)res.getResolvedObj();
    try {
        ctx.bind(res.getRemainingName(), obj);
    } finally {
        ctx.close();
    }
}

Observa que antes de que el método retorne, cierra el contexto raíz. En este ejemplo, este paso no es realmente necesario porque fooURLContext no mantiene ninguna conexión ni recurso. Sin embargo, es una buena práctica para asegurarse de que las implementaciones que mantienen conexiones o recursos las liberan apropiadamente. Esto también significa que los métodos con estado como list() deben asegurarse de que la enumeración resultante que devuelven permanezca utilizable después de que se haya cerrado el contexto.

Consideraciones Espaciales para rename()

rename() es diferente de otros métodos de contexto en que acepta dos nombres en lugar de uno. Con un nombre, podemos usar getRootURLContext() para obtener un contexto trabajable para terminar la operación. Con dos nombres, no podemos llamar a getRootURLContext() dos veces, una por cada nombre, porque cada llamada podría devolver un contexto diferente. rename() sólo puede tener un contexto en el que hacer el resto.

Para resolver esto en nuestro ejemplo, primero extraemos de ambos nombres un prefijo común (usando la utilidad interna getURLPrefix()). Luego usamos getRootURLContext() para obtener el contexto raíz y el resto del nombre del nombre original. Para obtener el resto del nombre del nuevo nombre, usamos otra utilidad interna getURLSuffix(). Observa que es muy importante que los tres metodos --getRootURLContext(), getURLPrefix(), y getURLSuffix()-- estén completamente de acuerdo en cómo se analiza un string URL y que partes se designan como prefijo y sufijo.

En particular, getRootURLContext() debería consumir la porción devuelta por getURLPrefix() para crear el contexto raíz y devolver el como el resto del nombre la porción que devolverá getURLSuffix(). También deberíamos tener en cuenta las restricciones sobre la habilidad de una implementación de contexto para realizar renombrados a través de diferentes servidores o espacios de nombre.

Aquí tenemos un ejemplo de rename():

public void rename(String oldName, String newName) 
    throws NamingException {
    String oldPrefix = getURLPrefix(oldName);
    String newPrefix = getURLPrefix(newName);
    if (!urlEquals(oldPrefix, newPrefix)) {
	throw new OperationNotSupportedException(
	    "Renaming using different URL prefixes not supported : " +
		oldName + " " + newName);
    }

    ResolveResult res = getRootURLContext(oldName, myEnv);
    Context ctx = (Context)res.getResolvedObj();
    try {
        ctx.rename(res.getRemainingName(), 
	    getURLSuffix(newPrefix, newName));
    } finally {
	ctx.close();
    }
}

Aquí están las implementaciones de getURLPrefix() y getURLSuffix():

protected String getURLPrefix(String url) throws NamingException {
    int start = url.indexOf(":");

    if (start < 0) {
        throw new OperationNotSupportedException("Invalid URL: " + url);
    }
    ++start; // Skip ":"

    if (url.startsWith("//", start)) {
	start += 2;  // Skip the double forward slash
	    
	// Find the last forward slash
	int posn = url.indexOf("/", start);
	if (posn >= 0) {
	    start = posn;
	} else {
	    start = url.length();  // Rest of the URL
	}
    }

    // Else 0 or 1 initial slashes; the start is unchanged
    return url.substring(0, start);
}

protected Name getURLSuffix(String prefix, String url) 
    throws NamingException {
    String suffix = url.substring(prefix.length());
    if (suffix.length() == 0) {
        return new CompositeName();
    }

    if (suffix.charAt(0) == '/') {
	suffix = suffix.substring(1); // Skip the leading forward slash
    }

    // Note: This is a simplified implementation;
    // a real implementation should
    // transform any URL-encoded characters into their Unicode char
    // representations
    return new CompositeName().add(suffix);
}

Principio Página
© 1999-2002, Programación en castellano, s.l.
Contacto - Datos legales

ReD Internet: Hospedaje Web | envio sms gratis | Salvapantallas | Fondos de Escritorio, famosas | melodias moviles gratis| Gratis