====== Componente para Cargar Propiedades y Ficheros de Propiedades ======
Este componente permite cargar propiedades o ficheros de propiedades para la aplicación y tenerlos disponibles desde código //JAVA// o desde cualquier ámbito que admita expresiones //EL// (recordatorio: aquellas que tienen el formato //#{_mi_expresion}//).
===== Declaración del Componente =====
Lo primero que hay que indicar es que podemos declarar todos los componentes de carga de propiedades que necesitemos en la aplicación. Estos se declaran en el fichero //components.xml//. Veamos un ejemplo:
=== Declaración Mediante el fichero components.xml ===
Veamos un ejemplo (no tenéis porque cargar los mismos ficheros en vuestras aplicaciones):
...
propiedad1@valor_propieada_1@
propiedad2valor_propieada_2
META-INF/fichero2.properties
fichero1.properties
seam.properties
pruebaPropiedades
WEB-INF/webapp_webinf.properties
webapp.properties
En este ejemplo, hemos creado el componente con la siguiente configuración:
* Nombre //prototipoProperties//, aunque podemos poner el que queramos.
* Ambito aplicación, pero puede ser cualquier ambito, todo depende del alcance que queramos que tengan las propiedades.
* Tiene que implementar la clase //es.um.atica.seam.components.PropertiesContainer//, que es la clase base que contiene toda la funcionalidad.
* Se carga al arrancar la aplicación, pero también podemos indicar que no, y se carga cuando se inyecte el componente (//@In//) o se haga referencia en una expresión //EL//.
Para aplicaciones FundeWeb 1.5.x la clase a implementar es //org.umu.atica.seam.components.PropertiesContainer//.
Las propiedades que tiene el componente son las siguientes:
* //declaredProperties//: propiedades declaradas directamente en el fichero //components.xml//, son pares ////.
* //classpathFileProperties//: rutas a ficheros de propiedades que se encuentran en el //classpath//.
* //propertiesProviders//: una lista separada por comas de nombres de otros componentes Seam que implementan la interface //PropertiesProvider//.
* //webappFileProperties//: rutas a ficheros de propiedades que se encuentran dentro del módulo //WEB//.
==== Aclaraciones y Conceptos ====
En el ejemplo, dentro de las propiedades declaradas en //declaredProperties//, tenemos la //propiedad1// con valor //@valor_propieada_1@//. Recordaros que todas las propiedades o valores que se encuentran comprendidos entre //@'s// en el fichero //components.xml//, su valor real es el contenido en la propiedad del mismo nombre que lo contenido entre //@'s// (en este caso //valor_propieada_1//) que se encuentra en el fichero //components.properties//.
Las propiedades definidas en el fichero //components.properties// están accesibles directamente mediante el componente //seamComponentsProperties//.
Cuando en la propiedad //classpathFileProperties//, indicamos que son rutas a ficheros de propiedades que se encuentran en el //classpath//. Queremos decir que, //classpath//: son las rutas a lugares donde se encuentran ficheros //.class//, es decir, los compilados //JAVA//. En una aplicación Web, tenemos varios lugares como pueden ser:
* Los ficheros //JAR// contenidos en la carpeta //lib// de la raíz del fichero //EAR//.
* Los ficheros //JAR// contenidos en la carpeta //WEB-INF/lib// del módulo //WEB//.
* Los ficheros //JAR// que son módulos //EJBs//.
* En la carpeta //WEB-INF/classes// del módulo //WEB//.
Estas referencias relacionadas en el código fuente del proyecto Maven, se traducen en:
* Los ficheros de propiedades que se encuentran dentro de una carpeta //src/main/resources// del módulo //EJB// o del módulo //WEB//.
* Los ficheros de propiedades que se encuentren dentro de dependencias del proyecto.
En el ejemplo, vemos que en la propiedad //classpathFileProperties//, tenemos el fichero //seam.properties//. Ese fichero lo solemos encontrar dentro de la carpeta //src/main/resources// del módulo //EJB// y/o del módulo //WEB//, y dentro de algunas dependencias de JBoss Seam. Pues bien, el componente, nos recupera todos los ficheros //seam.properties// que hay en el //classpath// y carga las propiedades que tenga.
Cuando en la propiedad //webappFileProperties//, indicamos que son rutas a ficheros de propiedades que se encuentran dentro del módulo //WEB//. Queremos decir, en relación al código fuente del proyecto Maven, que son ficheros que se encuentran dentro de las siguientes carpetas del módulo //WEB//:
* //src/main/webapp//
* //src/main/web_resources//.
* Se ignoran los ficheros que se encuentran dentro de //src/main/webapp/WEB-INF/classes// y //src/main/web_resources/WEB-INF/classes//, esos ficheros deberían ir en la propiedad //classpathFileProperties//.
Para los ficheros declarados en la propiedad //webappFileProperties//, solo se carga la única referencia existente del fichero.
Por razones de seguridad, es conveniente que:
* Los ficheros de propiedades declarados en //webappFileProperties//, estén creados dentro de la carpeta //WEB-INF// que esta protegida del acceso exterior.
* Los ficheros de propiedades declarados en //classpathFileProperties//, estén creados dentro de la carpeta //META-INF// que esta protegida del acceso exterior.
La propiedad //propertiesProviders//, nos permiten integrar los actuales métodos de carga de propiedades que tengáis creados en la aplicación (propiedades obtenidas en la BBDD, otros ficheros, etc.) con este nuevo componente. Solo tenéis que hacer que se puede acceder mediante un componente (es decir, que tenga la anotación //@Name// o declarado en el fichero //componentx.xml//) e implementar la interfaz //PropertiesProvider//.
==== Filtrado de Ficheros con Propiedades ====
Si estamos usando propiedades cuyo valor depende del entorno de ejecución, del cliente, etc.; entonces tenemos que añadir el fichero de propiedades al sistema de filtrado de ficheros de Maven.
En aplicaciones **FundeWeb 2.0**, la configuración de filtrado se hace en el archivo POM del módulo WEB.
Si el fichero esta dentro de **//src/main/resources//**, buscamos la etiqueta **////** (hija de la etiqueta **////** principal) y:
* Añadimos como **////** en el **////** donde esta desactivado el filtrado (indicado con **//false//** o no tiene etiqueta **////**).
* Añadimos como **////** en el **////** donde esta desactivado el filtrado (indicado con **//true//**).
Ejemplo con el fichero //META-INF/fichero2.properties//:
...
src/main/filters/filtro-${entorno}.properties
src/main/resources
META-INF/fichero2.properties
...
src/main/resources
META-INF/fichero2.properties
...
true
Sobre ese fichero, se sustituirán todas las propiedades cuya clave este comprendida entre //${}// definidas en //// o en los ficheros de //// que estén definidas en Maven.
Si el fichero esta dentro de **//src/main/webapp//**, buscamos el plugin **//maven-war-plugin//** y:
* Añadimos como **////** en el **////** donde esta desactivado el filtrado (indicado con **//false//** o no tiene etiqueta **////**).
* Añadimos como **////** en el **////** donde esta desactivado el filtrado (indicado con **//true//**).
Ejemplo con el fichero //WEB-INF/webapp_webinf.properties//:
org.apache.maven.plugins
maven-war-plugin
src/main/webapp
WEB-INF/webapp_webinf.properties
...
false
src/main/webapp
WEB-INF/webapp_webinf.properties
...
true
...
true
...
...
Sobre ese fichero, se sustituirán todas las propiedades cuya clave este comprendida entre //${}// definidas en //// o en los ficheros de //// que estén definidas en Maven.
\\
\\
En aplicaciones **FundeWeb 1.5**, si el fichero a filtrar, esta en el módulo WEB, se aplican las mismas acciones de antes (para aplicaciones FundeWeb 2.0).
Si el fichero a filtrar esta en el módulo EJB, buscamos la etiqueta **////** (hija de la etiqueta **////** principal) y:
* Añadimos como **////** en el **////** donde esta desactivado el filtrado (indicado con **//false//** o no tiene etiqueta **////**).
* Añadimos como **////** en el **////** donde esta desactivado el filtrado (indicado con **//true//**).
El fichero **//components.properties//** ya esta incluido en el sistema de filtrado de Maven.
Esta configuración puede cambiar, si el fichero a filtrar depende de la configuración especifica para un cliente. En ese caso, suele configurarse en el perfil asociado.
==== Orden de Carga de Propiedades ====
El orden en la carga de las propiedades y ficheros de propiedades es el siguiente:
- Los ficheros de propiedades cargados indicados en //classpathFileProperties//.
- Los ficheros de propiedades cargados indicados en //webappFileProperties//.
- Las propiedades de los componentes declarados en //propertiesProviders//.
- Las propiedades indicadas en //declaredProperties//.
El orden de carga es inversamente proporcional a la prioridad de las propieades. Que quiere decir esto, que si hay una colisión de una propiedad (es decir, que aparece en más de un sitio) el valor que contendrá será el de la última aparición en el orden de carga. El orden de prioridad es el siguiente:
* Las propiedades declaradas en //declaredProperties// son las más prioritarias, y si alguna propiedad esta declarada en otro sitio, se mantiene el valor de //declaredProperties//.
* Las propiedades obtenidas de los //propertiesProviders//, tiene prioridad sobre las propiedades de //webappFileProperties// y //classpathFileProperties//.
* Las propiedades declaradas en //webappFileProperties//, tiene prioridad sobre las propiedades de //classpathFileProperties//.
==== Ejemplos de Utilización del Componente ====
Como ya hemos indicado el componente lo podemos utilizar en cualquier parte del código //JAVA// o en expresiones //EL//. Veamos algunos ejemplos:
=== Ejemplos en Código Java ===
Podemos inyectar directamente el componente en cualquier componente JBoss Seam mediante la anotación //@In//.
package mi.package.pruebas;
import java.util.Hashtable;
@Name("clasePrueba")
public class ClasePrueba {
@In("prototipoProperties")
private Hashtable prototipoProperties;
public void miMetodo() {
String variable = prototipoProperties.get("propiedad1");
...
}
}
Podemos obtener una instancia del componente en cualquier componente clase //JAVA//.
package mi.package.pruebas;
import java.util.Map;
public class ClasePrueba {
public void miMetodo() {
Map prototipoProperties = (Map) Component.getInstance("prototipoProperties");
String variable = (String) prototipoProperties.get("propiedad1");
...
}
}
=== Ejemplos en Expresiones EL ===
Podemos utilizar sus valores en cualquiera lugar que acepte una expresión //EL// como los siguientes elementos:
* Páginas //XHTML//
* Ficheros de estilo //CSS// cargados con ////
* Ficheros //Javascript// cargados con ////.
* En la anotación //@In//.
Veamos un ejemplo en una página //XHTML//:
#{prototipoProperties['propiedad2']}
#{prototipoProperties.propiedad2}
En expresiones //EL// tenemos dos formas validas para acceder a las propiedades:
* Mediante //['']//.
* Mediante el separador //'.'// (punto), aunque esta es mas restrictiva, ya que el nombre de la propiedad no puede contener //'.'// en el nombre.
Veamos como inyectar el valor de una propiedad mediante la anotación //@In//.
package mi.package.pruebas;
@Name("clasePrueba")
public class ClasePrueba {
@In("#{prototipoProperties['propiedad1']}")
private String valorPropiedad1;
...
}
Veamos como obtener el valor de una propiedad directamente en una variable mediante la clase //Expressions//.
package mi.package.pruebas;
public class ClasePrueba {
private String valorPropiedad1 = Expressions.instance().createValueExpression("#{prototipoProperties['propiedad1']}", String.class);
...
}
Veamos como obtener el valor de una propiedad directamente en un método mediante la clase //Expressions//.
package mi.package.pruebas;
public class ClasePrueba {
public void miMetodo() {
String variable = Expressions.instance().createValueExpression("#{prototipoProperties['propiedad1']}", String.class)
...
}
}
----
--- //[[juanmiguel.bernal@ticarum.es|JUAN MIGUEL BERNAL GONZALEZ]] 2016/11/25 12:38//