Apache Abdera supports AtomPub-multipart creation 0

Posted by david

One of the most weird stuff in the AtomPub specification is the media creation flow. First, you need to send a request in order to post the new media resource and once the response is correct you can update the media link entry related with it.

In order to avoid the second step, the Picassa team added to their api a new way to add photos, and now, they allow to send a multipart file that wraps the photo and its metadata.

This atom extension is been covered by an IEFT draft that Joe Gregorio published, and this morning I've updated the Abdera trunk in order to implement this specification.

You can read more into the Abdera wiki. Enjoy it.

Using Hudson as Rails CI server 1

Posted by david

For some time, Hudson has become my favorite continuous integration server. It's easy to configure and provides a handful of really interesting plug-ins. The only thing that I missed was the possibility of use Rake as a project build tool and thus I'll be able to take my java, ruby or rails projects into the same CI server.

Well, past weekend I had too much spare time so I decided to develop my first Hudson plugin and this morning I've released the first version of the Hudson Rake plugin.

Once you have installed Hudson you just need to donwload the plug-in and upload it from the Manage Hudson section:

When the plugin is avalable it detects your ruby instances installed from your PATH but it allows you to add other ruby or jruby paths:

Finally you just need to select the Invoke Rake option into the project configuration and select the tasks that you want to Hudson executes:

That's it, you are ready to go with Rake, Hudson and the Continuous Integration Game.

Usa ruby para testear tu código java 2

Posted by david

Aunque navegando por la web se pueden encontrar artículos sobre cómo usar rspec para testear código java y ya existe algún framework de bdd para java, desde hace unas semanas existe una librería que nos da las mejores herramentas de test que ruby posee para aplicarlas con nuestro código java.

JtestR es una librería que integra jruby con rspec, dust, mocha y ActiveSuport, y permite ejecutar nuestros test escritos en ruby con herramentas de automatización como Ant o Maven.

Para ejecutarlos con Ant es tan facil como incluir una nueva tarea en nuestro fichero de configuración:

<target name="test" description="Runs all tests">
  <taskdef name="jtestr" classname="org.jtestr.ant.JtestRAntRunner" classpath="lib/jtestr.jar"/>

  <jtestr tests="test/ruby"/>
</target>

Pero lo que más me gusta de este framework es poder usar rspec para testear mis clases java, un sencillo ejemplo podría ser este:

import java.util.HashMap

describe HashMap, "is empty" do
  before :each do
    @map = mock(HashMap)
  end

  it "should be empty" do
    @map.stubs(:size).returns(0)

    @map.should be_empty
  end
end

Una herramienta a tener en cuenta si, como yo, pasas el día entre código java y código ruby :-).

Consumir microformatos con XQuery

Posted by david

XQuery es un lenguaje para hacer consultas bien formadas sobre documentos xml. Combinado con TagSoup, que permite parsear cualquier documento html como si fuera xml, y un procesador de documentos como Nux es muy facil consumir microformatos de cualquier web.

Como supuesto veamos como consumir el hcard de uno de mis sitios favoritos en 11870, el café Costello.

XQuery está basado en XPath pero además nos permite hacer consultas más cercanas al sql. La consulta para extraer del dom de un documento xml un elemento cuyo atributo contenga la palabra vcard podría ser así:

    String query = "declare namespace xhtml=\"http://www.w3.org/1999/xhtml\"; \n" +
        " for $data in //xhtml:* \n"+
        " where contains($data/@class, \"vcard\") \n" +
                " return  { data($data) } ";

Refinandola un poco más podríamos decir que solo queremos mostrar unos cuantos nodos, como los que contengan el nombre, dirección, localidad, provincia y país del sitio:

    String query = "declare namespace xhtml=\"http://www.w3.org/1999/xhtml\"; \n" +
        "for $data in //xhtml:* \n"+
    " where contains($data/@class, \"vcard\") \n"+
    " return <vcard> \n" + 
        " <fn> { data($data//xhtml:*[contains(@class, \"fn\")]) } </fn>" +
        " <street-address> { data($data//xhtml:*[contains(@class, \"street-address\")]) } </street-address>" +
        " <locality> { data($data//xhtml:*[contains(@class, \"locality\")]) } </locality>" +
        " <region> { data($data//xhtml:*[contains(@class, \"region\")]) } </region>" +
        " <country-name> { data($data//xhtml:*[contains(@class, \"country-name\")]) } </country-name>" +
    " </vcard> ";

Una vez tenemos la consulta, podemos obtener el html haciendo una llamada por get a la dirección de nuestra página:

    GetMethod get = new GetMethod("http://11870.com/pro/20770"); 
    get.setFollowRedirects(true); 

    HttpClient httpClient = new HttpClient();
    httpClient.executeMethod(get); 
    InputStream in = get.getResponseBodyAsStream(); 

Y transformar el html en xml para ejecutar nuestra consulta xquery:

    XMLReader parser = new org.ccil.cowan.tagsoup.Parser();
    Document doc = new Builder(parser).build(in);
    Nodes results = XQueryUtil.xquery(doc, query);

La variable results almacenaría el resultado de ejecutar la consulta, donde quedaría un xml parecido a este:

    <vcard>
        <fn>Costello Cafe</fn>
        <street-address>Calle del Caballero de Gracia 10</street-address>
        <locality>Madrid</locality>
        <region>Madrid</region>
        <country-name>España</country-name>
    </vcard>

TagSoup facilita bastante la tediosa tarea de parsear un html ya que transforma hasta los documentos peor formados, y con unos conocimientos de xquery las posiblidades son casi infinitas. Todo el código del ejemplo se puede descargar de aqui.

Java 6 y tu dni electrónico

Posted by david

Ahora que han pasado unos meses desde el lanzamiento de Java 6 y que en casi en cualquier provincia puedes expedir un dni electrónico ya podemos empezar a pensar como hacer uso de ambos.

Dentro de nuestro dnie se encuentran varios certificados digitales para firma electrónica o autenticación, para acceder a ellos necesitamos es un lector de tarjetas que acepte nuestro documento.

Una de las nuevas incorporaciones en java 6, y de las menos publicitadas, es el soporte nativo para acceder al almacen de claves de windows. Hasta ahora teníamos que usar complejas DLLs de windows para acceder a este almacen, pero con esta nueva release es tan fácil como esto:

KeyStore keyStore = KeyStore.getInstance("Windows-MY");
keyStore.load(null, null);

Como no todos en este mundo usamos ese sistema operativo, dentro de nuestro dnie también podremos encontrar los certificados dentro de una librería PKCS#11 llamada opensc-pkcs11.so que podremos usar en cualquier otro sistema. El proceso de acceder a una librería PKCS#11 es un poco más tedioso pero hay muy buenos artículos en la red que lo explican . Una aproximación rápida podría ser que tenemos que añadir esta librería como un proveedor de certificados a nuestro almacen de claves PKCS#11 y luego acceder a este para recuperar los certificados. Para añadir la librería a nuestro almacén necesitaríamos algo como esto:

String pkcs11config = "name = DNIE\nlibrary = opensc-pkcs11.so ";
InputStream confStream = new ByteArrayInputStream(pkcs11config.getBytes());

Class sunPkcs11Class = Class.forName("sun.security.pkcs11.SunPKCS11");
Constructor pkcs11Constr = sunPkcs11Class.getConstructor(InputStream.class);

Provider pkcs11Provider = (Provider) pkcs11Constr.newInstance( confStream );
Security.addProvider(pkcs11Provider);

para acceder a este almacén:

KeyStore keyStore = KeyStore.getInstance("PKCS11");
keyStore.load(null, password);

Una vez cargado nuestro almacén de claves correspondiente podríamos acceder a todos los certificados que contiene a través de sus alias:

Enumeration enumeration = keyStore.aliases();
while (enumeration.hasMoreElements()) {

String alias = enumeration.nextElement().toString();
Certificate[] certs = store.getCertificateChain( alias );

}

Y con esto ya tendríamos acceso a los certificados de nuestro dni electrónico y podríamos ir pensando en como darles uso.

Actualización: Si nuestros usuarios usan Mac OS X y queremos acceder al almacén de claves de este sistema tendríamos que usar el siguiente código:

KeyStore keyStore = KeyStore.getInstance("KeychainStore", "Apple");
keyStore.load(null, null);

Ahorrar tiempo con hibernate-tools 1

Posted by david

Una de las pegas que encuentro al trabajar con Hibernate es que me obliga a escribir el script de creación de tablas en base de datos, el fichero de mapeo de estas tablas en Hibernate y las clases Java que actuan como entidad.

Hibernate Tools, aporta un plugin de Eclipse y una serie de tareas para Ant que facilitan un poco la vida del desarrollador. En este artículo vamos a hacer una pequeña introducción a estas tareas para ver como podemos generar diréctamente el script de creación de las tablas y las clases Java a partir de nuestro fichero de mapeo hbm.

Para trabajar con la extensión de Ant no es necesario todo el paquete que nos descargamos. Podemos extraer únicamente el fichero hibernate-tools.jar que se ecuentra dentro del directorio /plugins/org.hibernate.eclipse_3.2.0.beta9a/lib/tools/.

Una vez tenemos la librería en nuestro directorio de trabajo lo primero que tenemos que hacer es definir la tarea hibernatetool dentro de nuestro fichero build.xml:

    <taskdef name="hibernatetool" 
         classname="org.hibernate.tool.ant.HibernateToolTask" 
     classpathref="buildpath" />

En el capítulo dedicado a las tareas de Ant nos indican varias formas para añadir la configuración de Hibernate. Para mí, la más cómoda es decirle donde se encuentra el fichero con la configuración básica y luego añadir los hbm que queremos que utilice:

    <configuration configurationfile="hibernate.cfg.xml">
        <fileset dir="${xml.dir}">
            <include name="**/${hbm.file}.hbm.xml"/>
        </fileset>
    </configuration>

Una vez que ya tenemos configurada nuestra tarea veamos los métodos que tenemos disponibles para exportar los ficheros hbm.

El primero de ellos es hbm2java, el encargado de generar nuestras clases Java. Su uso es muy sencillo:

    <hbm2java/>

El segundo que vamos a ver es hbm2ddl. Este exporter nos genera el sql de creación de las tablas en base de datos. Los atributos más comunes que se le añaden suelen ser el nombre del fichero que quieres que genere, si quieres que este fichero tenga un buen formateado o si deseas que además ejecute el sql directamente contra la base de datos:

    <hbm2ddl outputfilename="hbm2ddl.sql" 
        export="false" create="true" format="true"/>

Con todo esto ya tenemos nuestra nueva tarea creada. Para el que no le apetezca hacer mucho copy/paste puede ver todo el código en el fichero que yo suelo utilizar.