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}).

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):

<components xmlns="http://jboss.com/products/seam/components"
	...
	xsi:schemaLocation="
                 ...
                 http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.2.xsd">
 
    ...
 
    <component name="prototipoProperties" scope="application" class="es.um.atica.seam.components.PropertiesContainer" startup="true">
 
        <property name="declaredProperties">
        	<key>propiedad1</key><value>@valor_propieada_1@</value>
        	<key>propiedad2</key><value>valor_propieada_2</value>
        </property>
 
        <property name="classpathFileProperties">
        	<value>META-INF/fichero2.properties</value>
        	<value>fichero1.properties</value>
        	<value>seam.properties</value>
        </property>
 
        <property name="propertiesProviders">pruebaPropiedades</property>
 
        <property name="webappFileProperties">
               	<value>WEB-INF/webapp_webinf.properties</value>
        	<value>webapp.properties</value>
        </property>
 
    </component>
 
</components>

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 <key><value>.
  • 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 <resources> (hija de la etiqueta <build> principal) y:

  • Añadimos como <exclude> en el <resource> donde esta desactivado el filtrado (indicado con <filtering>false</filtering> o no tiene etiqueta <filtering>).
  • Añadimos como <include> en el <resource> donde esta desactivado el filtrado (indicado con <filtering>true</filtering>).

Ejemplo con el fichero META-INF/fichero2.properties:

<build>
	...
 
	<filters>
		<filter>src/main/filters/filtro-${entorno}.properties</filter>
	</filters>
 
	<resources>
		<resource>
			<directory>src/main/resources</directory>
			<excludes>
				<exclude>META-INF/fichero2.properties</exclude>
				...
			</excludes>
		</resource>
		<resource>
			<directory>src/main/resources</directory>
			<includes>
				<include>META-INF/fichero2.properties</include>
				...
			</includes>
			<filtering>true</filtering>
		</resource>
	</resources>
</build>

Sobre ese fichero, se sustituirán todas las propiedades cuya clave este comprendida entre ${} definidas en <properties> o en los ficheros de <filters> 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 <exclude> en el <resource> donde esta desactivado el filtrado (indicado con <filtering>false</filtering> o no tiene etiqueta <filtering>).
  • Añadimos como <include> en el <resource> donde esta desactivado el filtrado (indicado con <filtering>true</filtering>).

Ejemplo con el fichero WEB-INF/webapp_webinf.properties:

<build>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-war-plugin</artifactId>
			<configuration>
				<webResources>
					<resource>
						<directory>src/main/webapp</directory>
						<excludes>
							<exclude>WEB-INF/webapp_webinf.properties</exclude>
							...
						</excludes>
						<filtering>false</filtering>
					</resource>
					<resource>
						<directory>src/main/webapp</directory>
						<includes>
							<include>WEB-INF/webapp_webinf.properties</include>
							...
						</includes>
						<filtering>true</filtering>
					</resource>
 
					...
 
				</webResources>
				<attachClasses>true</attachClasses>
			</configuration>
		</plugin>
 
		...
 
	</plugins>
 
	...
 
</build>

Sobre ese fichero, se sustituirán todas las propiedades cuya clave este comprendida entre ${} definidas en <properties> o en los ficheros de <filters> 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 <resources> (hija de la etiqueta <build> principal) y:

  • Añadimos como <exclude> en el <resource> donde esta desactivado el filtrado (indicado con <filtering>false</filtering> o no tiene etiqueta <filtering>).
  • Añadimos como <include> en el <resource> donde esta desactivado el filtrado (indicado con <filtering>true</filtering>).

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:

  1. Los ficheros de propiedades cargados indicados en classpathFileProperties.
  2. Los ficheros de propiedades cargados indicados en webappFileProperties.
  3. Las propiedades de los componentes declarados en propertiesProviders.
  4. 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<String, String> 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<String, String> prototipoProperties = (Map<String, String>) 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 <h:outputStylesheet>
  • Ficheros Javascript cargados con <h:outputScript>.
  • En la anotación @In.

Veamos un ejemplo en una página XHTML:

<span>#{prototipoProperties['propiedad2']}</span>
 
 
<span>#{prototipoProperties.propiedad2}</span>

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)
 
        ...
    }
 
}

JUAN MIGUEL BERNAL GONZALEZ 2016/11/25 12:38

  • fdw2.0/fundeweb2.0/gt/gt-cargador-propiedades.txt
  • Última modificación: 09/04/2024 13:53
  • por JUAN MIGUEL BERNAL GONZALEZ