JNDI DummyContext
Posted by admin on June 14, 2012
Como parte de un proyecto que estoy desarrollando con java, he decidido utilizar JNDI en un módulo como una interfaz estándar para obtener "repositorios" de objetos en tiempo de ejecución. Muchos servidores de aplicaciones (Glassfish, Tomcat, Jetty, entre otros) proveen una implementación disponible para las aplicaciones que se ejecuten en éste, sin embargo para hacer pruebas resulta conveniente contar con un SPI de JNDI independiente y sencillo.
La implementación puede ser extremadamente sencilla, tomando en cuenta sólo la funcionalidad que se necesita para cada aplicación:
TestDummyContext.java
- package org.devpower.test.jndi;
-
- public class TestDummyContext {
-
- "org.devpower.test.jndi.DummyContextFactory");
-
- }
- }
DummyContextFactory.java
- package org.devpower.test.jndi;
-
- import java.util.Map;
- import java.util.HashMap;
- import java.util.Hashtable;
- import javax.naming.NamingException;
- import javax.naming.Context;
-
- /**
- * Esta factory es la encargada de proveer la implementación
- * del contexto que se inicializará al crear un nuevo InitialContext
- */
- public class DummyContextFactory implements InitialContextFactory {
-
- /**
- * Este objeto sólo guarda referencias a objetos en un
- * HashMap<String, Object>, todos los métodos lanzan
- * una excepción de tipo UnsupportedOperationException
- * excepto bind(String name, Object object) y lookup(String name)
- * que son utilizados en el ejemplo.
- */
- private static class DummyContext implements Context {
-
- private Map<String, Object> bindings;
-
- public DummyContext() {
- this.bindings = new HashMap<String, Object>();
- }
-
- @Override
- public void bind(String name, Object obj) throws NamingException {
- bindings.put(name, obj);
- }
-
- @Override
- public Object lookup(String name) throws NamingException {
- return bindings.get(name);
- }
-
- /**
- * LOS DEMÁS MÉTODOS QUE SÓLO LANZAN UnsupportedOperationException
- * se excluyen...
- *
- */
- }
-
- private static final DummyContext context;
-
- static {
- context = new DummyContext();
-
- context.bind("test", new Object());
- }
-
- public Context getInitialContext(Hashtable<?, ?> env)
- throws NamingException {
-
- return context;
- }
- }
Firefox JSM: DevPower.Http.ResponseInterceptor
Posted by admin on June 14, 2012
Desde hace algunos días he estado programando una extensión de firefox, la cual debe interceptar las respuestas http basándose en las urls. Una vez interceptada la respuesta, el contenido de la misma debe almacenarse localmente.
Debido a que las extensiones de firefox utilizan javascript como lenguaje de programación, me dispuse a crear una "clase" reutilizable que se encargue de realizar dicha tarea. Esta clase es DevPower.Http.ResponseInterceptor, la cual se ha programado como un módulo JSM y su uso es muy sencillo:
- /** ..... importa el módulo y realiza inicializaciones
- ...
- */
-
- /**
- * Cada ResponseInterceptor debe implementar el método
- * ResponseInterceptor#createChannelListener(matcher),
- * el cual debe devolver un nsITraceableListener, que es el que se
- * encargará de realizar las acciones necesarias sobre la respuesta recibida.
- * En el script se incluye una implementación de esta interfaz que se
- * encarga de descargar a una carpeta seleccionada el contenido de la
- * respuesta, dicha implementación es
- * DevPower.Http.ResponseInterceptor.Downloader.
- */
- var MyInterceptor = new DevPower.Http.ResponseInterceptor();
- MyInterceptor.createChannelListener = function(matcher) {
- return new DevPower.Http.ResponseInterceptor.Downloader("/home/emerino/downloads", "mp3");
- };
-
- /**
- * Un interceptor necesita "matchers" para saber qué respuestas interceptar.
- * En el script se incluye una implementación básica de uno llamada UrlMatcher,
- * el cual verifica si la url de la respuesta actual coincide con alguna de las que
- * se tienen registradas en el matcher. Dichas urls deben ser expresiones
- * regulares.
- *
- * Independientemente de la implementación utilizada de los
- * nsITraceableListeners, cada uno de estos que se creen almacenarán el listener
- * original en la propiedad nsITraceableListenerImplementation.originalListener.
- */
- var matcher = new DevPower.Http.ResponseInterceptor.UrlMatcher();
- matcher.addUrl("^http://www.example.com$");
- matcher.addUrl("^http://devio.us/.*");
-
- MyInterceptor.addMatcher("mymatcher", matcher);
- MyInterceptor.start();
Con el código anterior, al llamar al método DevPower.Http.ResponseInterceptor#start(), se registra un observer para la notificación "http-on-examine-response", el cual verifica si algún DevPower.Http.Matcher causa un "match" sobre las urls dadas, de ser así se registra un nsITraceableListener con el nsIHttpChannel de la respuesta, el cual se encarga de descargar el contenido de la misma al disco duro.
El código fuente del módulo se encuentra disponible para su descarga aquí.
XLSWriter: Fácil manipulación de archivos XLS desde python
Posted by admin on June 14, 2012
Hace algunos días tuve que registrar algunos datos que se encontraban en un archivo de texto en una hoja de excel. Para agilizar el proceso y hacerlo automático, utilicé el lenguaje de programación python y las librerías xlwt, xlrd y xlutils.
A pesar de que cumplen con su función (xlwt: escritura, xlrd: lectura), crear un script para modificar un archivo existente con base en ciertos parámetros resulta un poco desorganizado. Es por eso que he creado la clase XLSWriter, la cual permite la modificación o creación de archivos XLS de manera sencilla:
- from devpower.xls import XLSWriter
-
- # crea un archivo XLS
- writer = XLSWriter()
- writer.append(["Col1", "Col2", "Col3"])
- writer.save("test.xls")
-
- #modifica un archivo XLS existente
- writer = XLSWriter("archivo.xls")
-
- # añade una fila al final del documento
- writer.append(["Col1", "Col2", "Col3"])
-
- # busca la cadena "VALOR" en la primera columna y reemplaza el renglón
- # con los datos proporcionados en la lista ["Col1", "Col2", "Col3"]
- writer.replace(0, "VALOR", ["Col1", "Col2", "Col3"])
-
- # escribe los datos en el renglón 5 (índice 4)
- writer.write(4, ["Col1", "Col2", "Col3"])
-
- # guarda los cambios en el archivo
- writer.save()
-
- # escribe los datos a un nuevo archivo
- writer.save("otro.xls")