En este tutorial os vamos a enseñar a utilizar una API de Apache para gestionar las configuraciones de vuestras aplicaciones de manera avanzada.
Yo trabajo en Autentia, y en mi trayectoria profesional ligada a la informática he visto como los programadores invertían grandes cantidades de tiempo en reinventar la rueda por desconocimiento de determinadas APIs.
¿ Alguna vez has implementado clases que gestionaran directamente datos de configuración ? Si la respuesta es afirmativa, seguramente hayas reinventado la rueda.
Existen en varias formas estándar de gestionar los datos configuración de nuestros componentes y aplicaciones:
En este pequeño tutorial, voy a nombrar un API que a mi personalmente me parece de una enorme utilidad y potencia para la gestión de datos de configuración. Se trata de Apache Jakarta Commons Configuration.
Apache Jakarta Commons Configuration es un subproyecto de la serie de proyectos Apache Jakarta Commons.
Commons Configuration es un conjunto de proyectos que intentan estandarizar las tareas comunes que casi todas las aplicaciones y componentes realizan normalmente.
Una tarea muy común en cualquier aplicación es la gestión de datos de configuración. Es aquí en donde entra en juego Apache Jakarta Commons Configuration.
Podemos obtener todo lo necesario desde la siguiente dirección: http://jakarta.apache.org/commons/configuration/
Básicamente Apache Commons Configuration nos permite:
Algunos ejemplos
Antes de nada, deseo resaltar que este tutorial es sólo una introducción al API, y que debe documentarse en la Web oficial del API para ver todas las posibilidades que nos proporciona este API.
Ejemplo 1
Supongamos que tenemos el siguiente fichero de propiedades, en el que se definen datos de configuración relaccionada con el interfaz gráfico de la aplicación:
app.windows.properties:
mainmdi.title=Título de mi aplicación de prueba
mainmdi.width=800
mainmdi.height=600
mainmdi.state=maximized
userform.title=Gestión de usuarios
userform.width=320
userform.height=200
userform.state=normal
# También sería válido: language=Castellano,English,French
language=Castellano
language=English
language=French
Pues a través de Commons Configuration, podríamos acceder a las propiedades de la siguiente forma:
try {
// Leemos los datos de configuración. El fichero debe estar en el mismo directorio que la aplicación.
PropertiesConfiguration config = new PropertiesConfiguration("app.windows.properties");
// La siguiente sentencia imprimirá: 800
System.out.println(config.getInt("main.mdi.width"));
// La siguiente sentencia imprimirá: Mi aplicación de pruena
System.out.println(config.getString("main.mdi.title"));
// La siguiente sentencia imprimirá: Castellano
System.out.println(config.getStringArray("language")[0]);
// La siguiente sentencia configura el objeto para que salve las propiedades
// automáticamente en su origen (En este caso un fichero) cuando se actualizen
// o cuando se agregen nuevas propiedades
config.setAutoSave(true);
// Añadimos un par de propiedades
config.addProperty("version", "1.0");
config.addProperty("author", "Carlos García Pérez");
// No hace falta gracias a que está establecida la propiedad autoSave
// config.save();
} catch (ConfigurationException ex){
System.out.println(ex);
}
Ejemplo 2
Ahora vamos a ver las posibilidades de este API para tratar con propiedades Jerárquicas en formato xml.
app.windows.properties.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<gui>
<mainmdi>
<title>Mi aplicación de prueba</title>
<dimension>
<width>800</width>
<height>600</height>
</dimension>
<state>maximized</state>
</mainmdi>
<userform>
<title>Gestión de Usuarios</title>
<dimension>
<width>800</width>
<height>600</height>
</dimension>
<state>normal</state>
</userform>
<printer.form>
<dimension>
<width>320</width>
<height>200</height>
</dimension>
</printer.form>
<languages default="Castellano">
<language>Castellano</language>
<language>English</language>
<language>French</language>
</languages>
</gui>
Ahora podemos acceder a los datos de la siguiente forma. El ejemplo es autodescriptivo y está comentado.
try {
// Leemos los datos de configuración. El fichero debe estar en el mismo directorio que la aplicación.
XMLConfiguration config = new XMLConfiguration("app.windows.properties.xml");
// La siguiente sentencia imprimirá: 800
System.out.println(config.getInt("mainmdi.dimension.width"));
// La siguiente sentencia imprimirá: Mi aplicación de prueba
System.out.println(config.getString("mainmdi.title"));
// La siguiente sentencia imprimirá: Castellano
System.out.println(config.getString("languages[@default]"));
// La siguiente sentencia imprimirá: 3
System.out.println(((java.util.List) config.getProperty("languages.language")).size());
// La siguiente sentencia imprimirá: French
System.out.println(config.getString("languages.language(2)"));
// La siguiente sentencia imprimirá: 320
// Observe que debido a que el elemento contiene un punto en su nombre
// debemos acceder a el escapando el punto mediante ..
System.out.println(config.getInt("printer..form.dimension.width"));
// La siguiente sentencia configura el objeto para que salve las propiedades
// automáticamente en su origen (En este caso un fichero) cuando se actualizen
// o cuando se agregen nuevas propiedades
config.setAutoSave(true);
// Cambiamos el juego de caracteres, pues usaremos propiedades
// que precisan de tildes.
config.setEncoding("ISO-8859-1");
// Añadimos un par de propiedades
// Añadimos la propiedad 1.0 que desciende de la raiz
config.addProperty("version", "1.0");
// Añadimos la propiedad Carlos García Pérez que desciende de la raiz
config.addProperty("author", "Carlos García Pérez");
// No hace falta gracias a que está establecida la propiedad autoSave establecida
// config.save();
} catch (ConfigurationException ex){
System.out.println(ex);
}
Otras Características interesantes
Este API también nos da la posibilidad de que se recargen automáticamente los datos de configuración sobre el objeto Configuration en caso de que estos hayan sido modificados.
Para habilitar esta característica deberá indicarlo mediante la siguiente línea de código:
config.setReloadingStrategy(new FileChangedReloadingStrategy());
Conclusiones
A mi juició este API es más completo, potente y flexible que el resto de APIS o métodos para gestionar datos de configuración.
Aunque java.util.prefs proporciona una funcionalidad y potencia similar a Commons Configurations, los datos de configuración en java.util.prefs sólo pueden ser modificados desde aplicaciones y no manualmente, pues entre otras cosas no se sabe donde guarda realmente este API los datos de configuración.
Cuando utilizamos objetos Properties para gestionar las propiedades, debemos realizar conversiones de tipos de datos, con este API nos ahorramos ese trabajo.
Por comentar algo negativo, este API depende de otros subprojectos de Jakarta, por lo que debemos incluir sus JARs asociados si queremos usarlo. Por ejemplo, para usar las funciones básicas, el API depende de:
Puede encontrar más información acerca de las dependencias en la siguiente dirección http://jakarta.apache.org/commons/configuration/dependencies.html
¿ Alguna vez has implementado clases que gestionaran directamente datos de configuración ? Si la respuesta es afirmativa, seguramente hayas reinventado la rueda.
Existen en varias formas estándar de gestionar los datos configuración de nuestros componentes y aplicaciones:
- Mediante la clase java.util.Properties
- A través de las clases del paquete java.util.prefs. (API muy potente que permite gestionar datos de configuración de modo herárquico al estilo del "Registro de Windows" que recomiendo leerse si el lector la desconoce)
En este pequeño tutorial, voy a nombrar un API que a mi personalmente me parece de una enorme utilidad y potencia para la gestión de datos de configuración. Se trata de Apache Jakarta Commons Configuration.
Apache Jakarta Commons Configuration es un subproyecto de la serie de proyectos Apache Jakarta Commons.
Commons Configuration es un conjunto de proyectos que intentan estandarizar las tareas comunes que casi todas las aplicaciones y componentes realizan normalmente.
Una tarea muy común en cualquier aplicación es la gestión de datos de configuración. Es aquí en donde entra en juego Apache Jakarta Commons Configuration.
Podemos obtener todo lo necesario desde la siguiente dirección: http://jakarta.apache.org/commons/configuration/
Básicamente Apache Commons Configuration nos permite:
- Gestión de los datos de configuración independientemente del lugar en el que esten almacenados. (Ficheros de propiedades, documentos XML, JNDI, Base de datos, etc.).
- Un potente motor de consultas para realizar búsquedas del valor que tienen determinadas propiedades de configuración.
- Recarga automática de los datos de configuración en caso de que sean modificados en su lugar físico de origen (Fichero de texto plano, fichero xml, etc)
- Posibilidad de almacenar los datos de configuración automáticamente en su lugar físico (fichero de texto plano, fichero xml, etc).
Algunos ejemplos
Antes de nada, deseo resaltar que este tutorial es sólo una introducción al API, y que debe documentarse en la Web oficial del API para ver todas las posibilidades que nos proporciona este API.
Ejemplo 1
Supongamos que tenemos el siguiente fichero de propiedades, en el que se definen datos de configuración relaccionada con el interfaz gráfico de la aplicación:
app.windows.properties:
mainmdi.title=Título de mi aplicación de prueba
mainmdi.width=800
mainmdi.height=600
mainmdi.state=maximized
userform.title=Gestión de usuarios
userform.width=320
userform.height=200
userform.state=normal
# También sería válido: language=Castellano,English,French
language=Castellano
language=English
language=French
Pues a través de Commons Configuration, podríamos acceder a las propiedades de la siguiente forma:
try {
// Leemos los datos de configuración. El fichero debe estar en el mismo directorio que la aplicación.
PropertiesConfiguration config = new PropertiesConfiguration("app.windows.properties");
// La siguiente sentencia imprimirá: 800
System.out.println(config.getInt("main.mdi.width"));
// La siguiente sentencia imprimirá: Mi aplicación de pruena
System.out.println(config.getString("main.mdi.title"));
// La siguiente sentencia imprimirá: Castellano
System.out.println(config.getStringArray("language")[0]);
// La siguiente sentencia configura el objeto para que salve las propiedades
// automáticamente en su origen (En este caso un fichero) cuando se actualizen
// o cuando se agregen nuevas propiedades
config.setAutoSave(true);
// Añadimos un par de propiedades
config.addProperty("version", "1.0");
config.addProperty("author", "Carlos García Pérez");
// No hace falta gracias a que está establecida la propiedad autoSave
// config.save();
} catch (ConfigurationException ex){
System.out.println(ex);
}
Ejemplo 2
Ahora vamos a ver las posibilidades de este API para tratar con propiedades Jerárquicas en formato xml.
app.windows.properties.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<gui>
<mainmdi>
<title>Mi aplicación de prueba</title>
<dimension>
<width>800</width>
<height>600</height>
</dimension>
<state>maximized</state>
</mainmdi>
<userform>
<title>Gestión de Usuarios</title>
<dimension>
<width>800</width>
<height>600</height>
</dimension>
<state>normal</state>
</userform>
<printer.form>
<dimension>
<width>320</width>
<height>200</height>
</dimension>
</printer.form>
<languages default="Castellano">
<language>Castellano</language>
<language>English</language>
<language>French</language>
</languages>
</gui>
Ahora podemos acceder a los datos de la siguiente forma. El ejemplo es autodescriptivo y está comentado.
try {
// Leemos los datos de configuración. El fichero debe estar en el mismo directorio que la aplicación.
XMLConfiguration config = new XMLConfiguration("app.windows.properties.xml");
// La siguiente sentencia imprimirá: 800
System.out.println(config.getInt("mainmdi.dimension.width"));
// La siguiente sentencia imprimirá: Mi aplicación de prueba
System.out.println(config.getString("mainmdi.title"));
// La siguiente sentencia imprimirá: Castellano
System.out.println(config.getString("languages[@default]"));
// La siguiente sentencia imprimirá: 3
System.out.println(((java.util.List) config.getProperty("languages.language")).size());
// La siguiente sentencia imprimirá: French
System.out.println(config.getString("languages.language(2)"));
// La siguiente sentencia imprimirá: 320
// Observe que debido a que el elemento contiene un punto en su nombre
// debemos acceder a el escapando el punto mediante ..
System.out.println(config.getInt("printer..form.dimension.width"));
// La siguiente sentencia configura el objeto para que salve las propiedades
// automáticamente en su origen (En este caso un fichero) cuando se actualizen
// o cuando se agregen nuevas propiedades
config.setAutoSave(true);
// Cambiamos el juego de caracteres, pues usaremos propiedades
// que precisan de tildes.
config.setEncoding("ISO-8859-1");
// Añadimos un par de propiedades
// Añadimos la propiedad 1.0 que desciende de la raiz
config.addProperty("version", "1.0");
// Añadimos la propiedad Carlos García Pérez que desciende de la raiz
config.addProperty("author", "Carlos García Pérez");
// No hace falta gracias a que está establecida la propiedad autoSave establecida
// config.save();
} catch (ConfigurationException ex){
System.out.println(ex);
}
Otras Características interesantes
Este API también nos da la posibilidad de que se recargen automáticamente los datos de configuración sobre el objeto Configuration en caso de que estos hayan sido modificados.
Para habilitar esta característica deberá indicarlo mediante la siguiente línea de código:
config.setReloadingStrategy(new FileChangedReloadingStrategy());
Conclusiones
A mi juició este API es más completo, potente y flexible que el resto de APIS o métodos para gestionar datos de configuración.
Aunque java.util.prefs proporciona una funcionalidad y potencia similar a Commons Configurations, los datos de configuración en java.util.prefs sólo pueden ser modificados desde aplicaciones y no manualmente, pues entre otras cosas no se sabe donde guarda realmente este API los datos de configuración.
Cuando utilizamos objetos Properties para gestionar las propiedades, debemos realizar conversiones de tipos de datos, con este API nos ahorramos ese trabajo.
Por comentar algo negativo, este API depende de otros subprojectos de Jakarta, por lo que debemos incluir sus JARs asociados si queremos usarlo. Por ejemplo, para usar las funciones básicas, el API depende de:
- Apache Jakarta Commons Lang
- Apache Jakarta Commons Collections
- Apache Jakarta Commons Loggin
Puede encontrar más información acerca de las dependencias en la siguiente dirección http://jakarta.apache.org/commons/configuration/dependencies.html
Carlos García Pérez