miércoles, 8 de diciembre de 2010

Personalizar proyecto según el cliente con Maven

Es un caso bastante habitual que se desarrolle un proyecto web que después vaya a ser vendido a varios clientes. En el producto final que se le venderá al cliente se tendrán que realizar una serie de personalizaciones, por ejemplo la imagén del logo, alguna css para cambiar los estilos generales de la aplicación, los valores de algunos ficheros properties (mensajes internacionalizados), etc...

Lo que considero que nunca habría que hacer es hacer una copia del proyecto y modificar los ficheros necesarios, ya que cada vez que haya que hacer un cambio en la base, también habría que hacerlo en todos los clientes.

Con maven he encontrado una manera sencilla y rápida de hacer esto, que consiste en configurarlo con profiles para que justo antes de que se genere el war final, se sobreescriban o añadan una serie de ficheros.

A continuación voy a explicar qué tipos de cosas son las que yo he necesitado personalizar y cómo hacerlo en el pom.xml de Maven.

Ficheros properties que se encuentran en el classpath de la aplicación. Generalmente esos ficheros deberían encontrarse en 'src/main/resources'. Podría interesarnos modificar algun valor concreto: Por ejemplo, imaginaros que tenemos el fichero bundle con las textos traducidos que se van a mostrar en la web, y que un texto es:

footer.text = Copyright 2010, Compañia bla bla bla bla Compañia bla bla bla.

En nuestro caso querríamos sustituir el literal "Compañia" por el nombre del cliente. Para hacer esto, lo más sencillo me parece lo siguiente: Primero sustituimos el texto footer.text con el siguiente valor:

footer.text = Copyright 2010, ${company.name} bla bla bla bla ${company.name} bla bla bla.

Nos vamos a crear un directorio nuevo 'src/main/profiles' donde vamos a crear una carpeta por cada cliente nuevo. En nuestro caso vamos a crear una carpeta 'cliente1' y ponemos en un fichero de propiedades 'filters.properties' el valor de la propiedad company.name.

company.name=Cliente1

Ahora tenemos que configurar en el pom.xml para que en los ficheros properties se filtren las propiedades y se sustituyan por los valores concretos y también habrá que crear un profile nuevo para que cuando lo utilicemos tenga en cuenta que los valores de las propiedades se encuentran en el fichero 'src/main/profiles/cliente1/filters.properties'



.....


src/main/resources

**/*.properties

true


.....

......


cliente1


src/main/profiles/cliente1/filter.properties






Ejecutando 'mvn clean package -P cliente1' ya tendremos en nuestro fichero de propiedades el valor correcto para el footer.text.

Supongamos que este modo de trabajar no nos vale porque lo que queremos hacer es sobreescribir el fichero de propiedades entero. En este caso yo dejaría los ficheros finales en el directorio 'src/main/profiles/cliente1/resources' y configurar dentro del profile para que se sobreescriban.


......


org.apache.maven.plugins
maven-resources-plugin
2.4.3

ISO-8859-1
true



......


cliente1


src/main/profiles/cliente1/filter.properties



src/main/profiles/cliente1/resources

**/*.properties

true







La primera parte donde se define el plugin 'maven-resources-plugin' es muy importante, ya que hay que definir la configuración '<overwrite>true</overwrite>' porque sino los ficheros no se sobreescribirán.

Otra cosa que podemos querer sobreescribir son las imagenes, css y contenido estático que se encuentre en el directorio 'src/main/webapp'.

Para ello colgamos los ficheros que queramos sobreescribir en el directorio 'src/main/profiles/cliente1/webapp' manteniendo dentro la misma estructura de directorios que se sigue en 'src/main/webapp'. Y después lo único que nos falta sería configurar maven para que nos copie esos ficheros. Esto último es un poco más complicado que como lo hemos hecho hasta ahora porque no se puede utilizar el tag <resources> ya que siempre nos lo copiará dentro del directorio WEB-INF/classes. Si queremos definir un nuevo directorio lo tenemos que hacer de la siguiente manera:



cliente1


src/main/profiles/cliente1/filter.properties



maven-resources-plugin
2.4.3

ISO-8859-1
true



copy-personalization
process-resources

copy-resources


${basedir}/target/${project.artifactId}-${project.version}


src/main/profiles/cliente1/webapp











Si ejecutamos 'mvn clean package -P cliente1' deberían estar todos los ficheros sobreescritos, pero no es así. ¿Por qué? La razón es que en la fase 'process-resources' en la que se está ejecutando la tarea 'copy-personalization' no se ha creado todavía el directorio 'target/${project.artifactId}-${project.version}'. La única forma posible que he encontrado de solucionar este problema es indicarle a maven que adelante la creación de este directorio mediante el goal 'war:exploded'. Por lo que la ejecución de Maven final que funciona es:

mvn clean war:exploded package -P cliente1

No hay comentarios:

Publicar un comentario