Tabla de Contenidos

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

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

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:

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:

Estas referencias relacionadas en el código fuente del proyecto Maven, se traducen en:

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:

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:

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:

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:

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:

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:

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:

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