Commons Configurations

Tabla de contenidos

Uso de Configuración

Commons Configuration allows you to access configuration properties from a variety of different sources. Comunes de configuración le permite acceder a las propiedades de configuración de una variedad de fuentes diferentes. No matter if they are stored in a properties file, a XML document, or a JNDI tree, they can all be accessed in the same way through the generic Configuration interface. No importa si se almacenan en un archivo de propiedades, un documento XML, o un árbol JNDI, todos ellos se puede acceder de la misma forma genérica a través de la Configuration de la interfaz.

Another strength of Commons Configuration is its ability to mix configurations from heterogeneous sources and treat them like a single logic configuration. This section will introduce you to the different configurations available and will show you how to combine them. Otro punto fuerte de los Comunes de configuración es su capacidad para mezclar configuraciones de fuentes heterogéneas y tratarlos como una configuración única lógica. En esta sección se le dará a conocer la disposición diferentes configuraciones y le mostrará la forma de combinarlos.

Configuration Sources Configuración de Fuentes

Currently there are quite a number of different sources of Configuration objects. En la actualidad hay un buen número de fuentes distintas de los objetos de configuración. But, by just using a Configuration object versus a specific type like XMLConfiguration or JNDIConfiguration, you are sheltered from the mechanics of actually retrieving the configuration values. Pero, sólo por el uso de un objeto de configuración en comparación con un tipo específico como XMLConfiguration o JNDIConfiguration, que están al abrigo de la mecánica de la realidad, recuperar los valores de configuración. These various sources include: Estas diversas fuentes incluyen:

  • PropertiesConfiguration Loads configuration values from a properties file. PropertiesConfiguration valores de configuración de Carga un archivo de propiedades.
  • XMLConfiguration Takes values from an XML document. XMLConfiguration Toma valores de un documento XML.
  • INIConfiguration Loads the values from a .ini file as used by Windows. INIConfiguration Carga los valores de un archivo. Ini como el usado por Windows.
  • PropertyListConfiguration Loads values from an OpenStep .plist file. PropertyListConfiguration Carga valores de un OpenStep. Plist. XMLPropertyListConfiguration is also available to read the XML variant used by Mac OS X. XMLPropertyListConfiguration también está disponible para leer la variante de XML utilizado por Mac OS X.
  • JNDIConfiguration Using a key in the JNDI tree, can retrieve values as configuration properties. JNDIConfiguration uso de una clave en el árbol JNDI, puede recuperar los valores como las propiedades de configuración.
  • BaseConfiguration An in-memory method of populating a Configuration object. BaseConfiguration Un método en memoria de poblar un objeto Configuration.
  • HierarchicalConfiguration An in-memory Configuration object that is able to deal with complex structured data. HierarchicalConfiguration Una memoria de configuración de objetos en que es capaz de hacer frente a los complejos datos estructurados.
  • SystemConfiguration A configuration using the system properties SystemConfiguration una configuración que utiliza las propiedades del sistema
  • ConfigurationConverter Takes a java.util.Properties or an org.apache.commons.collections.ExtendedProperties and converts it to a Configuration object. Toma un ConfigurationConverter java.util.Properties o org.apache.commons.collections.ExtendedProperties una y lo convierte en un objeto de configuración.

Mixing Configuration Sources Fuentes de configuración de mezcla

Often you want to provide a base set of configuration values, but allow the user to easily override them for their specific environment. A menudo se desea para proporcionar un conjunto básico de valores de configuración, pero que el usuario pueda reemplazar fácilmente a su entorno específico. Well one way is to hard code the default values into your code, and have then provide a property file that overrides this. Bueno una forma de hacerlo es duro código los valores predeterminados en su código, y luego han proporcionar un archivo de propiedad que reemplaza esta. However, this is a very rigid way of doing things. Sin embargo, esta es una forma muy rígida de hacer las cosas. Instead, with the CompositeConfiguration you can provide many different ways of setting up a configuration. En cambio, con la CompositeConfiguration que se puede brindar muchas maneras diferentes de crear una configuración. You can either do it manually: Puede hacerlo manualmente:

CompositeConfiguration config = new CompositeConfiguration(); CompositeConfiguration config = new CompositeConfiguration();

config.addConfiguration(new SystemConfiguration());

config.addConfiguration(new PropertiesConfiguration(“application.properties”));

or via the ConfigurationFactory class: oa través de la ConfigurationFactory clase:

ConfigurationFactory factory = new ConfigurationFactory(“config.xml”);

Configuration config = factory.getConfiguration();

The config.xml file used in the example above is a configuration descriptor, it specifies the Configuration objects to load. El config.xml de archivos utilizado en el ejemplo anterior es un descriptor de configuración, que especifica los objetos de configuración para cargar. Here is an example of descriptor: He aquí un ejemplo de descriptor:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<configuration>

<system/>

<properties fileName=”application.properties”/>

</configuration>

What this says is that we are loading up all system properties, as well as the properties file application.properties . Lo que esto dice es que estamos cargando todas las propiedades del sistema, así como las propiedades del archivo application.properties . The order of precedence is first to last. El orden de precedencia es el primero al último. So in the above example, if a property is not found in the system properties, it’ll be searched in the properties file. Así en el ejemplo anterior, si una propiedad no se encuentra en las propiedades del sistema, será buscado en el archivo de propiedades. This allows you to set up default values in a properties file, and override them with the system properties. Esto le permite configurar los valores por defecto en un archivo de propiedades, y por encima de ellas con las propiedades del sistema.

The Configuration interface La interfaz de configuración

All the classes in this package that represent different kinds of configuration sources share a single interface: Configuration . This interface allows you to access and manipulate configuration properties in a generic way. Todas las clases de este paquete que representan diferentes tipos de configuración de las fuentes de compartir una única interfaz: Configuration . Esta interfaz le permite tener acceso y manipular las propiedades de configuración de una manera genérica.

A major part of the methods defined in the Configuration interface deals with retrieving properties of different data types. Una parte importante de los métodos definidos en la Configuration ofertas de interfaz con la recuperación de las propiedades de diferentes tipos de datos. All these methods take a key as an argument that points to the desired property. Todos estos métodos tienen una clave como argumento que señala a la propiedad deseada. This is a string value whose exact meaning depends on the concrete Configuration implementation used. Se trata de un valor de cadena cuyo exacto significado depende de la concreta Configuration la aplicación utilizada. They try to find the property specified by the passed in key and convert it to their target type; this converted value will be returned. Tratan de encontrar la propiedad especificada por el pasado en los principales y convertirlo a su tipo de destino, lo que convierte el valor serán devueltas. There are also overloaded variants of all methods that allow to specify a default value, which will be returned if the property cannot be found. También hay variantes sobrecargadas de todos los métodos que permiten especificar un valor predeterminado, el cual será devuelto si la propiedad no se puede encontrar. The following data types are supported: Los tipos de datos siguientes son compatibles:

  • BigDecimal BigDecimal
  • BigInteger BigInteger
  • boolean booleano
  • byte byte
  • double doble
  • float flotador
  • int int
  • long largo
  • short corto
  • String Cadena

The names of these methods start with get followed by their data type. Los nombres de estos métodos de empezar con get seguido de su tipo de datos. The getString() method for instance will return String values, getInt() will operate on integers. El getString() método, por ejemplo, se devuelven valores String, getInt() funcionará en números enteros.

Properties can have multiple values, so it is also possible to query a list containing all of the available values. Las propiedades pueden tener varios valores, por lo que también es posible consultar una lista que contiene todos los valores disponibles. This is done using the getList() method. Esto se hace utilizando el getList() método.

For manipulating properties or their values the following methods can be used: Para las propiedades de manipulación o de sus valores los siguientes métodos pueden ser utilizados:

addProperty()

Adds a new property to the configuration. Agrega una nueva propiedad a la configuración. If this property already exists, another value is added to it (so it becomes a multi-valued property). Si esta propiedad ya existe, otro valor se añade a la misma (por lo que se convierte en una propiedad de valor múltiple).

clearProperty()

Removes the specified property from the configuration. Elimina la propiedad especificada de la configuración.

setProperty()

Overwrites the value of the specified property. Sobrescribe el valor de la propiedad especificada. This is the same as removing the property and then calling addProperty() with the new property value. Esta es la misma que la eliminación de la propiedad y luego llamar addProperty() con el nuevo valor de propiedad.

clear()

Wipes out the whole configuration Borra toda la configuración

Threading issues cuestiones Threading

The most concrete implementations of the Configuration interface that are shipped with this library are not thread-safe. They can be accessed concurrently in a read-only manner. El concreto la mayoría de las implementaciones Configuration interfaz que se comercializan con esta biblioteca no son thread-safe. Se puede acceder al mismo tiempo en una forma de sólo lectura. However if one thread modifies a configuration object, manual synchronization has to be performed to ensure correctness of data. Sin embargo, si un hilo modifica un objeto de configuración, la sincronización manual se tiene que realizar para garantizar la exactitud de los datos. Notes about the thread safety of conrete implementation classes can be found in the Javadocs for these classes. Notas acerca de la seguridad hilo de las clases de implementación conrete se puede encontrar en el Javadocs para estas clases.

Características básicas y AbstractConfiguration

The Configuration interface defines a whole bunch of methods. Implementing these methods all from scratch can be quite hard. La Configuration interfaz define un montón de métodos. La implementación de estos métodos todo desde el principio puede ser bastante duro. Because of that the AbstractConfiguration class exists. Debido a que el AbstractConfiguration clase existe. This class serves as a common base class for most of the Configuration implementations in Commons Configuration and provides a great deal of the functionality required by the interface. Esta clase sirve como una clase base común para la mayoría de la Configuration en las implementaciones de los Comunes de configuración y proporciona una gran parte de la funcionalidad requerida por la interfaz. So for creating a custom Configuration implementation this class will be a good starting point. Así que para crear una costumbre Configuration la implementación de esta clase será un buen punto de partida.

In addition to base implementations for lots of the methods declared in the Configuration interface the AbstractConfiguration class provides some other handy and convenient features. Además de las implementaciones de referencia para muchos de los métodos declarados en la Configuration la interfaz de la AbstractConfiguration clase proporciona un útil y conveniente otras características. Because this class is at the very root of the class hierarchy in Commons Configuration these features are available in most of the specific implementations of the Configuration interface provided by this library. Debido a que esta clase está en la raíz misma de la jerarquía de clases en los Comunes de configuración de estas características están disponibles en la mayoría de las implementaciones específicas de la Configuration la interfaz proporcionada por esta biblioteca. We will cover some of these basic features in this section. Vamos a cubrir algunas de estas características en esta sección.

Handling of missing properties Manejo de las propiedades que faltan

What is a configuration object supposed to do if you pass in a key to one of its get methods that does not map to an existing property? ¿Qué es un objeto de configuración que hacer si se pasa de una clave a uno de sus métodos get que no se asigna a una propiedad ya existente? Well, the default behavior as implemented in AbstractConfiguration is to return null if the return value is an object type. Bueno, el comportamiento por defecto como se aplica en AbstractConfiguration es devolver null si el valor devuelto es un tipo de objeto. For primitive types as return values returning null (or any other special value) is not possible, so in this case a NoSuchElementException is thrown: Para los tipos primitivos como valores de retorno devuelve null (o cualquier otro valor especial) no es posible, por lo que en este caso un NoSuchElementException se produce:

// This will probably return null / / Esto probablemente devolverá null

String strValue = config.getString(“NonExistingProperty”); String = strValue config.getString (“NonExistingProperty”);

// This might throw an exception / / Esto podría lanzar una excepción

long longValue = config.getLong(“NonExistingProperty”); longValue largo = config.getLong (“NonExistingProperty”);

For object types like String , BigDecimal , or BigInteger this default behavior can be changed: If the setThrowExceptionOnMissing() method is called with an argument of true , these methods will behave like their primitive counter parts and also throw an exception if the passed in property key cannot be resolved. Por tipos de objetos como String , BigDecimal , o BigInteger este comportamiento por defecto puede ser cambiado: si el setThrowExceptionOnMissing() se llama al método con un argumento de verdad, estos métodos se comportan igual que sus homólogos primitivo y también una excepción si el pasado en materia de propiedad clave no se puede resolver.

Note: Unfortunately support for the throwExceptionOnMissing property is not always consistent: The methods getList() and getStringArray() do not evaluate this flag, but return an empty list or array if the requested property cannot be found. Nota: Lamentablemente el apoyo a la throwExceptionOnMissing propiedad no siempre es coherente: los métodos getList() y getStringArray() no evaluar este indicador, pero devolver una lista vacía o una matriz si el inmueble solicitado no se encuentra. Maybe this behavior will be changed in a future major release. Tal vez este comportamiento se cambió en un lanzamiento importante en el futuro.

List handling Lista de manipulación

With getList() and getStringArray() the Configuration interface defines methods for dealing with properties that have multiple values. Con getList() y getStringArray() la Configuration interfaz define métodos para tratar las propiedades que tienen varios valores. When a configuration source (eg a properties file, an XML document, or a JNDI context) is processed the corresponding Configuration implementation detects such properties with multiple values and ensures that the data is correctly stored. Cuando una fuente de configuración (por ejemplo, un archivo de propiedades, un documento XML, o de un contexto JNDI) es tramitada la correspondiente Configuration la aplicación detecta dichas propiedades con varios valores y asegura que los datos están correctamente almacenados.

When modifying properties the addProperty() and setProperty() methods of AbstractConfiguration also implement special list handling. Al modificar las propiedades de la addProperty() y setProperty() los métodos de AbstractConfiguration también poner en práctica el manejo lista especial. The property value that is passed to these methods can be a list or an array resulting in a property with multiple values. El valor de la propiedad que se pasa a estos métodos puede ser una lista o una matriz que resulta en una propiedad con varios valores. If the property value is a string, it is checked whether it contains the list delimiter character . Si el valor de la propiedad es una cadena, se comprueba si contiene el carácter delimitador de lista. If this is the case, the string is splitted, and its single parts are added one by one. Si este es el caso, la cadena se separa, y de sus partes individuales se añaden uno por uno. The list delimiter character is the comma by default. El carácter delimitador de lista es la coma de forma predeterminada. It is also taken into account when the configuration source is loaded (ie string values of properties will be checked whether they contain this delimiter). También se toma en cuenta cuando la fuente de configuración se carga (es decir, cadena de valores de las propiedades se comprobará si contienen este delimitador). By using the setListDelimiter() method you can set it to a different character. Al utilizar el setListDelimiter() método que puede establecer en un personaje diferente. Here are some examples: He aquí algunos ejemplos:

// Change the list delimiter character to a slash / / Cambiar la lista de caracteres delimitador de una barra

    config.setListDelimiter(‘/’);

// Now add some properties / / Ahora añada algunas propiedades

config.addProperty(“greeting”, “Hello, how are you?”);    config.addProperty(“greeting”, “Hello, how are you?”);

    config.addProperty(“colors.pie”,

    new String[] { “#FF0000”, “#00FF00”, “#0000FF” });

    config.addProperty(“colors.graph”, “#808080/#00FFCC/#6422FF”);

// Access data / / Acceso a los datos

String salut = config.getString(“greeting”);

List colPie = config.getList(“colors.pie”);

String[] colGraph = config.getStringArray(“colors.graph”);

String firstPieColor = config.getString(“colors.pie”);In this example the list delimiter character is changed from a comma to a slash. En este ejemplo el carácter delimitador de la lista se cambia de una coma a una barra. Because of this the greeting property won’t be splitted, but remains a single string. Por ello, el greeting propiedad no podrá ser dividido, pero sigue siendo una sola cadena. The string passed as value for the colors.graph property in opposite contains the new delimiter character and thus will result in a property with three values. La cadena que se pasa como valor para la colors.graph propiedad en contrario contiene el carácter delimitador de nuevo y por lo tanto dará lugar a una propiedad con tres valores.

Of interest is also the last line of the example fragment. De interés es también la última línea del fragmento de ejemplo. Here the getString() method is called for a property that has multiple values. Aquí el getString() se llama al método de una propiedad que tiene varios valores. This call will return the first value of the list. La presente convocatoria se devolverá el valor primero de la lista.

If you want to change the list delimiter character for all configuration objects, you can use the static setDefaultListDelimiter() method of AbstractConfiguration . Si desea cambiar el carácter delimitador de la lista de todos los objetos de configuración, puede usar la estática setDefaultListDelimiter() método de AbstractConfiguration . It is also possible to disable splitting of string properties at all for a Configuration instance by calling its setDelimiterParsingDisabled() method with a value of true . También es posible desactivar a la división de propiedades de cadena en todo para una instancia de configuración llamando a su setDelimiterParsingDisabled() método con un valor de verdad.

Variable Interpolation Variable Interpolación

If you are familiar with Ant or Maven, you have most certainly already encountered the variables (like ${token} ) that are automatically expanded when the configuration file is loaded. Si está familiarizado con Ant o Maven, tiene sin duda ya se encuentran las variables (como ${token} ) que se expanden automáticamente cuando el archivo de configuración se carga. Commons Configuration supports this feature as well, here is an example (we use a properties file in this example, but other configuration sources work the same way; you can learn more about properties files in the chapter Properties files ): Commons configuración admite esta función, así, aquí hay un ejemplo (se utiliza un archivo de propiedades en este ejemplo, pero la configuración de otras fuentes de trabajo de la misma manera, usted puede aprender más sobre las propiedades de archivos en el capítulo de archivos de propiedades ):

application.name = Killer App

application.version = 1.6.2

application.title = ${application.name} ${application.version}

If you now retrieve the value for the application.title property, the result will be Killer App 1.6.2 . Si ahora recuperar el valor de la application.title propiedad, el resultado será Killer App 1.6.2 . So per default variables are interpreted as the keys of other properties. Así que por defecto las variables se interpretan como las llaves de otras propiedades. This is only a special case, the general syntax of a variable name is ${prefix:name} . Esto es sólo un caso especial, la sintaxis general de un nombre de variable es ${prefix:name} . The prefix tells Commons Configuration that the variable is to evaluated in a certain context. El prefijo indica Commons configuración que la variable es evaluada en un contexto determinado. We have already seen that the context is the current configuration instance if the prefix is missing. Ya hemos visto que el contexto es la instancia de configuración actual, si el prefijo no se encuentra. The following other prefix names are supported by default: Los siguientes nombres de otros prefijos tienen soporte por defecto:

Prefix Prefijo Description Descripción
sys sistemas This prefix marks a variable to be a system property. Este prefijo marca una variable a una propiedad del sistema. Commons Configuration will search for a system property with the given name and replace the variable by its value. Commons configuración buscará una propiedad del sistema con el nombre de pila y sustituir la variable por su valor. This is a very easy means for accessing the values of system properties in every configuration implementation. Este es un medio muy fácil para acceder a los valores de las propiedades del sistema en cada ejecución de configuración.
const const The const prefix indicates that a variable is to be interpreted as a constant member field of a class (ie a field with the static final modifiers). El const prefijo indica que una variable debe ser interpretado como un campo continuo de miembros de una clase (es decir, un campo con el final modificadores static). The name of the variable must be of the form <full qualified class name>.<field name> . El nombre de la variable debe ser de la forma <full qualified class name>.<field name> . The specified class will be loaded and the value of this field will be obtained. La clase especificada estará cargado y el valor de este campo se obtendrá.

Here are some examples (again using properties syntax): Éstos son algunos ejemplos (de nuevo usando la sintaxis de las propiedades):

user.file = ${sys:user.home}/settings.xml

action.key = ${const:java.awt.event.KeyEvent.VK_CANCEL}

If a variable cannot be resolved, eg because the name is invalid or an unknown prefix is used, it won’t be replaced, but is returned as is including the dollar sign and the curly braces. Si una variable no puede resolverse, por ejemplo, porque el nombre no es válida o un prefijo de desconocidos se utiliza, no será reemplazado, pero se devuelve como está incluyendo el signo de dólar y las llaves.

Customizing interpolation Personalización de la interpolación

This sub section goes a bit behind the scenes of interpolation and explains some approaches how you can add your own interpolation facilities. Under the hood interpolation is implemented using the StrSubstitutor class of the text package of Commons Lang . En esta sección se sub va un poco detrás de las escenas de la interpolación y explica algunos enfoques cómo puede añadir sus propias instalaciones de la interpolación. Bajo la interpolación campana se realizará mediante los StrSubstitutor clase del text conjunto de los Comunes Lang . This class uses objects derived from the StrLookup class for resolving variables. StrLookup defines a simple lookup() method that must be implemented by custom implementations; it expects the name of a variable as argument and returns the corresponding value (further details can be found in the documentation of Commons Lang). Esta clase utiliza los objetos derivados de la StrLookup clase para resolver variables. StrLookup define una simple lookup() método que debe realizarse antes de implementaciones personalizadas, sino que espera que el nombre de una variable como argumento y devuelve el valor correspondiente (más detalles se pueden encontrar en la documentación de los Comunes Lang). The standard prefixes for variables we have covered so far are indeed realized by special classes derived from StrLookup . Los prefijos estándar para las variables que hemos cubierto hasta ahora son verdaderamente realizado por clases especiales derivados de StrLookup .

It is now possible to create your own implementation of StrLookup and make it available for all configuration objects under a custom prefix. Ahora es posible crear su propia implementación de StrLookup y ponerla a disposición de todos los objetos de configuración en un prefijo personalizado. We will show how this can be achieved. Vamos a mostrar cómo esto se puede lograr. The first step is to create a new class derived from StrLookup , which must implement the lookup() method. El primer paso es crear una nueva clase derivada de StrLookup , que debe implementar el lookup() método. As an example we implement a rather dull lookup object that simply returns a kind of “echo” for the variable passed in: Como ejemplo vamos a aplicar una búsqueda de objetos sin brillar, que simplemente devuelve una especie de “eco” de la variable pasada en:

import org.apache.commons.lang.text.StrLookup; import org.apache.commons.lang.text.StrLookup;

public class EchoLookup extends StrLookup

{

public String lookup(String varName)

{

return “Value of variable ” + varName;

}

}

Now we want this class to be called for variables with the prefix echo .

Ahora queremos esta clase que se llama para las variables con el prefijo echo . For this purpose the EchoLookup class has to be registered at the ConfigurationInterpolator class with the desired prefix. ConfigurationInterpolator implements a thin wrapper over the StrLookup API defined by Commons Lang. Para ello, el EchoLookup clase tiene que estar inscrito en el ConfigurationInterpolator clase con el prefijo deseado. ConfigurationInterpolator aplica una envoltura delgada sobre la StrLookup API definida por Commons Lang. It has a static registerGlobalLookup() method, which we have to call as follows: Tiene una estática registerGlobalLookup() método, que tenemos que llamar de la siguiente manera:

// Place this code somewhere in an initialization section of your application / / Coloque este código en algún lugar de una sección de inicialización de la aplicación

ConfigurationInterpolator.registerGlobalLookup(“echo”, new EchoLookup()); ConfigurationInterpolator.registerGlobalLookup(“echo”, new EchoLookup());

Each AbstractConfiguration object that is created after this line is executed will contain the new lookup class and can thus resolve variables of the form ${echo:my_variable} . Cada AbstractConfiguration objeto que se crea después de esta línea se ejecuta contendrá la clase de búsqueda nueva y por lo tanto puede resolver variables de la forma ${echo:my_variable} .

Each instance of AbstractConfiguration is associated with a ConfigurationInterpolator object. Cada instancia de AbstractConfiguration se asocia con un ConfigurationInterpolator objeto. This object is created by the createInterpolator() method on first access of one of the interpolation features. Este objeto es creado por el createInterpolator() método en el primer acceso de una de las características de interpolación. By overriding this method even deeper intervention in the interpolation mechanism is possible. Por imperiosas este método de intervención más profunda, incluso en el mecanismo de la interpolación es posible. For instance a custom implementation can add further lookup objects to the interpolator, which are then only used by this configuration instance. Por ejemplo, una aplicación personalizada puede añadir otros objetos de búsqueda para el interpolador, que sólo será utilizado por esta instancia de configuración.

Propiedades de los archivos

Properties files are a popular mean of configuring applications. Las propiedades son archivos de un medio popular de configuración de aplicaciones. Of course Commons Configuration supports this format and enhances significantly the basic java.util.Properties class. This section introduces the features of the PropertiesConfiguration class. Note that PropertiesConfiguration is a very typical example for an implementation of the Configuration interface and many of the features described in this section (eg list handling or interpolation) are supported by other configuration classes as well. This is because most configuration implementations that ship with Commons Configuration are derived from the common base class AbstractConfiguration , which implementes this features. Por supuesto Commons configuración compatible con este formato y mejora significativamente la base java.util.Properties clase. Esta sección presenta las características de la PropertiesConfiguration clase. Tenga en cuenta que PropertiesConfiguration es un típico ejemplo muy para una implementación de la Configuration la interfaz y muchas de las características que se describen en esta sección (por ejemplo, lista manipulación o interpolación) son compatibles con otras clases de configuración también. Esto es porque la mayoría de las implementaciones de configuración que se incluyen en los Comunes de configuración se derivan de la clase base común AbstractConfiguration , que implementes esta características.

Using PropertiesConfiguration Usando PropertiesConfiguration

Let’s start with a simple properties file named usergui.properties with the following content: Vamos a empezar de un archivo denominado propiedades simples usergui.properties con el siguiente contenido:

# Properties definining the GUI # Properties definining the GUI

colors.background = #FFFFFF

colors.foreground = #000080

window.width = 500

window.height = 300

To load this file, you’ll write: Para cargar este archivo, voy a escribir:

Configuration config = new PropertiesConfiguration(“usergui.properties”); Configuration config = new PropertiesConfiguration(“usergui.properties”);

If you do not specify an absolute path, the file will be searched automatically in the following locations:Si no se especifica una ruta absoluta, el archivo se buscará automáticamente en las siguientes ubicaciones:

  • in the current directory en el directorio actual
  • in the user home directory en el directorio home del usuario
  • in the classpath en la ruta de clases

Instead of using a constructor that takes a file name you can also invoke one of the load() methods. En lugar de utilizar un constructor que toma un nombre de archivo también puede invocar uno de los load() métodos. There are several overloaded variants that allow you to load properties from various sources. Hay varias variantes sobrecargado que permiten cargar las propiedades de diversas fuentes. More information about loading properties files (and file-based configurations in general) can be found in the section about File-based Configurations . Más información sobre la carga archivos de propiedades (y basados en configuraciones de archivos en general) se puede encontrar en la sección de configuraciones basadas en archivos .

After the properties file was loaded you can access its content through the methods of the Configuration interface, eg Después de que el archivo de propiedades se cargó puede acceder a su contenido a través de los métodos de la Configuration de la interfaz, por ejemplo,

String backColor = config.getString(“colors.background”); String backColor = config.getString(“colors.background”);

Dimension size = new Dimension(config.getInt(“window.width”),

config.getInt(“window.height”));

Includes Incluye

If a property is named ” include ” and the value of that property is the name of a file on the disk, that file will be included into the configuration. Si una propiedad se denomina ” include “y el valor de esa propiedad es el nombre de un archivo en el disco, ese archivo se incluirá en la configuración. Here is an example: Aquí está un ejemplo:

# usergui.properties # usergui.properties

include = colors.properties

include = sizes.properties

# colors.properties

colors.background = #FFFFFF

Lists and arrays Las listas y matrices

As was already pointed out in the section List handling of Basic features , Commons Configuration has the ability to return easily a list of values. Como ya se señaló en la sección de manejo de la lista de características básicas, comunes de configuración tiene la capacidad para volver fácilmente una lista de valores. For example a properties file can contain a list of comma separated values: Por ejemplo un archivo de propiedades puede contener una lista de valores separados por comas:

# chart colors # Colores de la carta

colors.pie = #FF0000, #00FF00, #0000FF colors.pie = # FF0000, # 00FF00, # 0000FF

You don’t have to split the value manually, you can retrieve an array or a java.util.List directly with:

Usted no tiene que dividir el valor manualmente, puede recuperar una matriz o un java.util.List directamente con:

String[] colors = config.getStringArray(“colors.pie”); String [] = config.getStringArray colores (“colors.pie”);

List colorList = config.getList(“colors.pie”); Lista colorlist = config.getList (“colors.pie”);

Alternatively, you can specify a list of values in your properties file by using the same key on several lines: Como alternativa, puede especificar una lista de valores en sus propiedades de archivo utilizando la misma clave en varias líneas:

# chart colors # Colores de la carta

colors.pie = #FF0000; colors.pie = # FF0000;

colors.pie = #00FF00; colors.pie = # 00FF00;

colors.pie = #0000FF; colors.pie = # 0000FF;

All of the features related to list handling described for AbstractConfiguration also apply to properties files, including changing the list delimiter or disabling list handling at all. Todas las características relacionadas con la manipulación a la lista descrita para AbstractConfiguration también se aplican a los archivos de propiedades, incluyendo el cambio de la lista delimitador o desactivar la manipulación lista en absoluto.

Saving Ahorro

To save your configuration, just call the save() method: Para guardar la configuración, sólo llame al save() método:

PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”); config PropertiesConfiguration = PropertiesConfiguration nueva (“usergui.properties”);

config.setProperty(“colors.background”, “#000000); config.setProperty (“colors.background”, “# 000000);

config.save(); config.save ();

You can also save a copy of the configuration to another file: También puede guardar una copia de la configuración a otro archivo:

PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”); PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”);

config.setProperty(“colors.background”, “#000000);

config.save(“usergui.backup.properties);

More information about saving properties files (and file-based configurations in general) can be found in the section about File-based Configurations .

Más información sobre cómo guardar archivos de propiedades (y basados en configuraciones de archivos en general) se puede encontrar en la sección de configuraciones basadas en archivos .

Special Characters Caracteres especiales

If you need a special character in a property like a line feed, a tabulation or an unicode character, you can specify it with the same escaped notation used for Java Strings. Si usted necesita un carácter especial en una casa que tenga un avance de línea, tabulación o un carácter Unicode, puede especificarlo con la misma notación utilizada escapó para Java Cadenas. The list separator (“,” by default), can also be escaped: El separador de listas (“,” por defecto), también se puede escapar:

key = This \n string \t contains \, escaped \\ characters \u0020 key = Esta cadena \ n \ t contiene \, escapó caracteres \ \ \ u0020

Layout Objects Diseño de Objetos

Each PropertiesConfiguration object is associated with a Layout object , an instance of the class PropertiesConfigurationLayout . Cada PropertiesConfiguration objeto está asociado con un objeto de diseño, una instancia de la clase PropertiesConfigurationLayout . This layout object is responsible for preserving most of the structure of loaded configuration files. Este objeto de diseño es responsable de preservar la mayor parte de la estructura de archivos de configuración cargadas. This means that things like comments or blanc lines in a saved properties file will closely resemble the original properties file (the algorithm is not 100 percent perfect, but for most use cases it should be sufficient). Esto significa que cosas como comentarios o líneas de blanc en el inmueble archivo guardado se parecerán mucho a las propiedades del archivo original (el algoritmo no es 100 por ciento perfecto, pero para el uso mayoría de los casos debería ser suficiente).

Normally a developer does not have to deal with these layout objects. However there are some methods that might be of interest in certain use cases. Normalmente, un desarrollador no tiene que hacer frente a estos objetos de la presentación. Sin embargo, hay algunos métodos que podrían ser de interés en los casos de uso determinadas. For instance PropertiesConfigurationLayout defines methods for obtaining and setting the comment for a property key. Por ejemplo PropertiesConfigurationLayout define métodos para obtener y establecer el comentario a una clave de propiedad. A header comment for the whole properties file is also supported. Un comentario de cabecera para todo el archivo de las propiedades también se apoya. If the values of multi-valued properties should always be written on a single line rather than adding a new property definition for each value (which would be incompatible with java.util.Properties ) the setForceSingleLine() method can be used. Si los valores de múltiples propiedades valoradas deben hacerse siempre en una sola línea en vez de añadir una nueva definición de la propiedad para cada valor (lo que sería incompatible con java.util.Properties ) la setForceSingleLine() método puede ser utilizado.

Configuraciones basadas en archivos

Often configuration properties are stored in files on the user’s hard disk, eg in .properties files or as XML documents. A menudo, las propiedades de configuración se almacenan en archivos en el disco duro de usuario, por ejemplo, en los archivos. Propiedades o como documentos XML. Configuration classes that deal with such properties need to provide typical operations like loading or saving files. clases de configuración que se ocupan de tales propiedades necesidad de proporcionar a las operaciones habituales como cargar o guardar archivos. The files to be processed can be specified in several different flavors like java.io.File objects, relative or absolute path names, or URLs. Los archivos a procesar se pueden especificar en varios sabores diferentes como java.io.File objetos, relativa o absoluta nombres de ruta o URL.

To provide a consistent way of dealing with configuration files in Commons Configuration the FileConfiguration interface exists. FileConfiguration defines a standard API for accessing files and is implemented by many configuration implementations, including PropertiesConfiguration and XMLConfiguration . Para proporcionar una forma consistente de tratar con ficheros de configuración en la configuración de los Comunes FileConfiguration interfaz existe. FileConfiguration define una API estándar para acceder a los archivos y se ejecuta por las implementaciones de configuración, incluyendo PropertiesConfiguration y XMLConfiguration .

In the following sections we take a closer look at the methods of the FileConfiguration interface and how they are used. En las siguientes secciones echamos un vistazo más de cerca los métodos de la FileConfiguration interfaz y cómo se utilizan.

Specifying the file Especificar el archivo de

The FileConfiguration interface contains several methods for specifying the file to be loaded. El FileConfiguration interfaz contiene varios métodos para especificar el archivo a cargar. The following variants are supported: Las variantes se admiten los siguientes:

  • With the setFile() method the data file can be specified as a java.io.File object. Con la setFile() el método de archivo de datos puede ser especificado como un java.io.File objeto.
  • The setURL() takes a java.net.URL as argument; the file will be loaded from this URL. El setURL() toma un java.net.URL como argumento, el archivo será cargada desde esta URL.
  • The methods setFileName() and setBasePath() allows to specify the path of the data file. Los métodos setFileName() y setBasePath() permite especificar la ruta del archivo de datos. The base path is important if relative paths are to be resolved based on this file. La ruta de acceso base es importante si las rutas relativas se resolverán sobre la base de este archivo.

While a File or a URL uniquely identify a file, the situation is a bit ambigous when only a base path and a file name are set. Mientras que un File o un URL único identificar un archivo, la situación es un poco ambigua en que sólo una ruta de acceso base y un nombre de archivo se establecen. These can be arbitrary strings (even full URLs) whose exact meaning must be detected when the file is loaded. Estos pueden ser cadenas arbitrarias (incluso una URL completa), cuyo exacto significado debe ser detectado cuando se carga el archivo. For this purpose file-based configurations perform the following checks (in this order): Para ello basado en las configuraciones de archivo realizan los siguientes controles (en este orden):

  • If the combination from base path and file name is a full URL that points to an existing file, this URL will be used to load the file. Si la combinación de la ruta de acceso base y el nombre del archivo es una URL completa que apunta a un archivo existente, esta dirección URL se utiliza para cargar el archivo.
  • If the combination from base path and file name is an absolute file name and this file exists, it will be loaded. Si la combinación de la ruta de acceso base y el nombre del archivo es un nombre de archivo archivo existe absoluta y esto, se cargará.
  • If the combination from base path and file name is a relative file path that points to an existing file, this file will be loaded. Si la combinación de la ruta de acceso base y el nombre del archivo es una ruta de acceso relativa que apunta a un archivo existente, este archivo se cargará.
  • If a file with the specified name exists in the user’s home directory, this file will be loaded. Si un archivo con el nombre especificado en el directorio principal del usuario, este archivo se cargará.
  • Otherwise the file name is interpreted as a resource name, and it is checked whether the data file can be loaded from the classpath. De lo contrario el nombre de archivo se interpreta como un nombre de recurso, y se comprueba si el archivo de datos se pueden cargar desde la ruta de clases.

If all these checks fail, a ConfigurationException will be thrown. Si todas estas comprobaciones no se, un ConfigurationException será lanzada.

Loading Cargando

After the file name has been defined using one of the methods mentioned above, the load() method can be called. Después de que el nombre del archivo se ha definido usando uno de los métodos mencionados anteriormente, la load() pueden ser invocadas. This method tries to locate the file and open it. Este método intenta localizar el archivo y abrirlo. If this fails, a ConfigurationException is thrown. Si esto falla, un ConfigurationException es lanzada.

The FileConfiguration interface defines multiple overloaded load() methods. El FileConfiguration interfaz define múltiples sobrecarga load() métodos. The one that takes no argument will always operate on the file name that has been set earlier. El que no tiene argumentos siempre funcionará en el nombre del archivo que se ha definido en su momento. All other methods allow to specify the source to be loaded. Todos los otros métodos permiten especificar la fuente que desea cargar. This can be done as java.io.File , java.net.URL , string (containing either an absolute or relative path), input stream, or reader. Esto se puede hacer como java.io.File , java.net.URL , la cadena (que contiene ya sea una ruta de acceso relativa), flujo de entrada o absoluta, o el lector. When using these variants of the load() method be aware of two things: Al utilizar estas variantes de la load() método ha de ser consciente de dos cosas:

  1. They do not change the configuration’s file name. No cambian el nombre de la configuración de archivos. To do this you have to explicitely call one of the setter methods. Para hacer esto usted tiene que llamar explícitamente a uno de los métodos setter.
  2. The load() methods do not empty the configuration before new data is loaded. El load() métodos no vaciar la configuración antes de los nuevos datos se ha cargado. This makes it easy to construct union configurations by simply calling load() multiple times. Esto hace que sea fácil de construir configuraciones de unión simplemente llamando load() varias veces. But if you want to reuse a Configuration object and load a different file, remember to call the clear() method first to ensure that old properties are wiped out. Pero si desea volver a utilizar una Configuration objeto y cargar un archivo diferente, recuerde llamar al clear() primer método para garantizar que las viviendas antiguas son eliminadas.

File-based configurations typically define a set of constructors that correspond to the various setter methods for defining the data file. These constructors will set the file and then invoke the load() method. Basados en configuraciones de archivo normalmente definen un conjunto de constructores que se corresponden con los métodos setter diferentes para definir el archivo de datos. Estos constructores creará el archivo y luego llamará a la load() método. So creating a file-based configuration object and loading its content can be done in a single step. Así que la creación de una configuración basada en objetos de archivo y cargar su contenido se puede hacer en un solo paso.

Saving Ahorro

Saving is implemented analogously to loading: There is a no argument save() method that will use the internal file name. El ahorro es aplicado de forma análoga a la carga: No hay ningún argumento un save() método que utiliza el nombre de archivo interno. Then for each load() method a corresponding save() method exists that will write the data contained in the configuration to different targets. Entonces, por cada load() un método correspondiente save() existe un método que escribirá los datos contenidos en la configuración para diferentes objetivos.

An example for loading, manipulating, and saving a configuration (based on a PropertiesConfiguration ) could look as follows: Un ejemplo para cargar, manipular y guardar una configuración (basado en un PropertiesConfiguration ) podría ser el siguiente:

PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”); PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”);

config.setProperty(“colors.background”, “#000000);

config.save();You can also save a copy of the configuration to another file:

También puede guardar una copia de la configuración a otro archivo:

PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”); PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”);

config.setProperty(“colors.background”, “#000000);

config.save(“usergui.backup.properties);

Automatic Saving Salvado automático

If you want to ensure that every modification of a configuration object is immideately written to disk, you can enable the automatic saving mode. Si desea asegurarse de que cada modificación de un objeto de configuración es immideately escriben en el disco, puede habilitar el modo de guardado automático. This is done through the setAutoSave() method as shown in the following example: Esto se hace a través de la setAutoSave() método como se muestra en el ejemplo siguiente:

PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”); PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”);

config.setAutoSave(true);

config.setProperty(“colors.background”, “#000000); //configuración se guarda tras la convocatoria

Be careful with this mode when you have many updates on your configuration. Tenga cuidado con este modo cuando usted tiene muchas actualizaciones de su configuración. This will lead to many I/O operations, too. Esto llevará a que muchas operaciones de E /, también.

Automatic Reloading Recarga automática

A common issue with file-based configurations is to handle the reloading of the data file when it changes. Un problema común con configuraciones basadas fichero es la de manejar la carga del archivo de datos cuando cambia. This is especially important if you have long running applications and do not want to restart them when a configuration file was updated. Esto es especialmente importante si usted hace mucho tiempo las aplicaciones en ejecución y no quieren que les volverá a funcionar cuando un archivo de configuración se ha actualizado. Commons Configuration has the concept of so called reloading strategies that can be associated with a file-based configuration. Configuración de los Comunes tiene el concepto de las denominadas estrategias de recarga que pueden estar asociados con un archivo de configuración basadas en. Such a strategy monitors a configuration file and is able to detect changes. Esa estrategia supervisa un archivo de configuración y es capaz de detectar los cambios. A default reloading strategy is FileChangedReloadingStrategy . It can be set on a file-based configuration as follows: Un valor por defecto es la estrategia de recarga FileChangedReloadingStrategy . Se puede establecer en un fichero de configuración basado en lo siguiente:

PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”); PropertiesConfiguration config = new PropertiesConfiguration(“usergui.properties”);

config.setReloadingStrategy(new FileChangedReloadingStrategy());

FileChangedReloadingStrategy works as follows: On every property access the configuration checks its associated reloading strategy. FileChangedReloadingStrategy will then obtain the last modification date of the configuration file and check whether it has changed since the last access. FileChangedReloadingStrategy funciona de la siguiente: En cada acceso a la propiedad de la configuración comprueba su estrategia de recarga asociada. FileChangedReloadingStrategy entonces obtener la última fecha de modificación del archivo de configuración y comprobar si ha cambiado desde el último acceso. If this is the case, a reload is triggered. Si este es el caso, la recarga se ha disparado. To avoid often disk access when multiple properties are queried from the configuration, a refresh delay can be set on the reloading strategy. Para evitar a menudo el acceso a disco cuando se consultan varias propiedades de la configuración, cargar un retraso se puede establecer en la estrategia de recarga. This is a time in milli seconds with the meaning that the reloading strategy will only once check the file’s last modification time in the period specified here. Este es un tiempo en segundos mili con el significado que la estrategia de una sola vez se recarga de verificación de archivos de última hora de modificación en el período que se especifica aquí.

Managed Reloading Gestionado Recarga

ManagedReloadingStrategy is an alternative to automatic reloading. ManagedReloadingStrategy es una alternativa a la carga automática. It allows to hot-reload properties on a running application but only when requested by admin. Permite cargar propiedades-caliente en una aplicación que se ejecuta, pero sólo cuando se le solicite por el administrador. The refresh() method will force a reload of the configuration source. El refresh() método fuerza una recarga de la fuente de configuración.

A typical use of this feature is to setup ManagedReloadingStrategy as a JMX MBean. Un uso típico de esta característica es ManagedReloadingStrategy configuración como un MBean JMX. The following code sample uses Springframework MBeanExporter to expose the ManagedReloadingStrategy to the JMX console : El ejemplo de código siguiente se utiliza Springframework MBeanExporter para exponer el ManagedReloadingStrategy a la consola JMX:

<!– Un archivo de configuración basado en bean –>

<bean id=”configuration” class=”(…).PropertiesConfiguration”>

<constructor-arg type=”java.net.URL” value=”file:${user.home}/custom.properties”/>

<property name=”reloadingStrategy” ref=”reloadingStrategy”/>

</bean>

<!– The La estrategia de gestión para la recarga de bean de configuración –>

<bean id=”reloadingStrategy” class=”…ManagedReloadingStrategy”/>

<!– El MBeanExporter que expone reloadingStrategy a la consola JMX –>

<bean id=”mbeanMetadataExporter” class=”org.springframework.jmx.export.MBeanExporter”>

<property name=”server” ref=”mbeanServer”/>

<property name=”beans”>

<map>

<entry key=”myApp:bean=configuration” value-ref=”reloadingStrategy”/>

</map>

</property>

</bean>

With this configuration, the JMX console will expose the “myApp:bean=configuration” MBean and it’s refresh operation. Con esta configuración, la consola JMX expondrá el myApp “: bean de configuración =” MBean y es operación de actualización.

Jerárquica propiedades

Because of its tree-like nature XML documents can represent data that is structured in many ways. Debido a su naturaleza-en forma de árbol de documentos XML puede representar datos que se estructura en muchos aspectos. This section explains how to deal with such structured documents and demonstrates the enhanced query facilities supported by the XMLConfiguration class. En esta sección se explica cómo hacer frente a tales documentos estructurados y demuestra las instalaciones de mayor consulta con el apoyo de la XMLConfiguration clase.

Accessing properties defined in XML documents Obtener acceso a propiedades definidas en los documentos XML

We will start with a simple XML document to show some basics about accessing properties. Vamos a empezar con un simple documento XML para mostrar algunos conceptos básicos de acceso a las propiedades. The following file named gui.xml is used as example document: El siguiente archivo llamado gui.xml se utiliza como documento de ejemplo:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<gui-definition>

<colors>

<background>#808080</background>

<text>#000000</text>

<header>#008000</header>

<link normal=”#000080″ visited=”#800080″/>

<default>${colors.header}</default>

</colors>

<rowsPerPage>15</rowsPerPage>

<buttons>

<name>OK,Cancel,Help</name>

</buttons>

<numberFormat pattern=”###\,###.##”/>

</gui-definition>

(As becomes obvious, this tutorial does not bother with good design of XML documents, the example file should rather demonstrate the different ways of accessing properties.) To access the data stored in this document it must be loaded by XMLConfiguration . (Como resulta obvio, este tutorial no se preocupa por el buen diseño de documentos XML, el archivo de ejemplo y no debe demostrar las diferentes formas de acceso a las propiedades.) Para acceder a los datos almacenados en este documento debe ser cargado por XMLConfiguration . Like other file based configuration classes XMLConfiguration supports many ways of specifying the file to process. Al igual que otros archivos basados en clases de configuración XMLConfiguration soporta muchas formas de especificar el archivo en proceso. One way is to pass the file name to the constructor as shown in the following code fragment: Una manera es pasar el nombre de archivo al constructor como se muestra en el siguiente fragmento de código:

try

{

XMLConfiguration config = new XMLConfiguration(“tables.xml”);

// / Hacer algo con config

}

catch(ConfigurationException cex)

{

// Algo salió mal, por ejemplo, el archivo no fue encontrado

}

If no exception was thrown, the properties defined in the XML document are now available in the configuration object. The following fragment shows how the properties can be accessed: Si no es la excepción fue lanzada, las propiedades definidas en el documento XML ya están disponibles en el objeto de configuración. El fragmento siguiente se muestra cómo las propiedades se puede acceder a:

String backColor = config.getString(“colors.background”); String backColor = config.getString(“colors.background”);

String textColor = config.getString(“colors.text”);

String linkNormal = config.getString(“colors.link[@normal]”);

String defColor = config.getString(“colors.default”);

int rowsPerPage = config.getInt(“rowsPerPage”);

List buttons = config.getList(“buttons.name”);

This listing demonstrates some important points about constructing keys for accessing properties load from XML documents and about features of XMLConfiguration in general: Este listado muestra algunos puntos importantes sobre la construcción de claves de acceso a las propiedades de la carga de documentos XML y sobre las características de XMLConfiguration en general:

  • Nested elements are accessed using a dot notation. elementos anidados se accede mediante una notación de puntos. In the example document there is an element <text> in the body of the <color> element. En el documento de ejemplo que hay un elemento <text> en el cuerpo de la <color> elemento. The corresponding key is color.text . La clave correspondiente color.text .
  • The root element is ignored when constructing keys. El elemento raíz se ignora cuando la construcción de claves. In the example you do not write gui-definition.color.text , but only color.text . En el ejemplo que usted no escribe gui-definition.color.text , pero sólo color.text .
  • Attributes of XML elements are accessed in a XPath like notation. Atributos de los elementos XML se tiene acceso en un XPath como notación.
  • Interpolation can be used as in PropertiesConfiguration . Here the <default> element in the colors section refers to another color. La interpolación se pueden utilizar como en PropertiesConfiguration . Aquí el <default> elemento en el colors sección se refiere a otro color.
  • Lists of properties can be defined in a short form using the delimiter character (which is the comma by default). In this example the buttons.name property has the three values OK , Cancel , and Help , so it is queried using the getList() method. Listas de propiedades se pueden definir en un breve formulario con el carácter delimitador (que es la coma por defecto). En este ejemplo el buttons.name propiedad tiene los tres valores en Aceptar, Cancelar y Ayuda, por lo que se consulta con el getList() método. This works in attributes, too. Esto funciona en los atributos, también. Using the static setDefaultDelimiter() method of AbstractConfiguration you can globally define a different delimiter character or – by setting the delimiter to 0 – disabling this mechanism completely. Uso de la estática setDefaultDelimiter() método de AbstractConfiguration que el mundo puede definir un carácter delimitador diferente o – al establecer el delimitador a 0 – desactivar este mecanismo completo. Placing a backslash before a delimiter character will escape it. Colocación de una barra invertida antes de un carácter delimitador se le escapan. This is demonstrated in the pattern attribute of the numberFormat element. Esto se demuestra en el pattern atributo de la numberFormat elemento.

In the next section will show how data in a more complex XML document can be processed. En la siguiente sección se mostrará cómo los datos en un documento XML más complejos pueden ser procesados.

Structured XML Estructurado XML

Consider the following scenario: An application operates on database tables and wants to load a definition of the database schema from its configuration. Considere el siguiente escenario: Una aplicación funciona en tablas de bases de datos y quiere cargar una definición del esquema de la base de su configuración. A XML document provides this information. Un documento XML proporciona esta información. It could look as follows: Podría ser el siguiente:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<database>

<tables>

<table tableType=”system”>

<name>users</name>

<fields>

<field>

<name>uid</name>

<type>long</type>

</field>

<field>

<name>uname</name>

<type>java.lang.String</type>

</field>

<field>

<name>firstName</name>

<type>java.lang.String</type>

</field>

<field>

<name>lastName</name>

<type>java.lang.String</type>

</field>

<field>

<name>email</name>

<type>java.lang.String</type>

</field>

</fields>

</table>

<table tableType=”application”>

<name>documents</name>

<fields>

<field>

<name>docid</name>

<type>long</type>

</field>

<field>

<name>name</name>

<type>java.lang.String</type>

</field>

<field>

<name>creationDate</name>

<type>java.util.Date</type>

</field>

<field>

<name>authorID</name>

<type>long</type>

</field>

<field>

<name>version</name>

<type>int</type>

</field>

</fields>

</table>

</tables>

</database>

This XML is quite self explanatory; there is an arbitrary number of table elements, each of it has a name and a list of fields. A field in turn consists of a name and a data type. Este XML es muy explica por sí mismo, hay un número arbitrario de elementos de la tabla, cada una de ella tiene un nombre y una lista de campos. Un campo, a su vez consta de un nombre y un tipo de datos. This XML document (let’s call it tables.xml ) can be loaded in exactly the same way as the simple document in the section before. Este documento XML (llamémosla tables.xml ) puede ser cargado exactamente de la misma manera que el documento simple en la sección anterior.

When we now want to access some of the properties we face a problem: the syntax for constructing configuration keys we learned so far is not powerful enough to access all of the data stored in the tables document. Si ahora se quiere acceder a algunas de las propiedades que se enfrentan a un problema: la sintaxis para la construcción de claves de configuración que hemos aprendido hasta ahora es suficientemente potentes como para acceder a todos los datos almacenados en el documento de tablas.

Because the document contains a list of tables some properties are defined more than once. Debido a que el documento contiene una lista de tablas algunas propiedades se definen más de una vez. Eg the configuration key tables.table.name refers to a name element inside a table element inside a tables element. Por ejemplo, la configuración de teclas tables.table.name se refiere a un name elemento dentro de una table un elemento dentro de tables elemento. This constellation happens to occur twice in the tables document. Esta constelación le sucede a ocurrir dos veces en el documento de tablas.

Multiple definitions of a property do not cause problems and are supported by all classes of Configuration. Las definiciones múltiples de una propiedad no causan problemas y son apoyados por todas las clases de configuración. If such a property is queried using getProperty() , the method recognizes that there are multiple values for that property and returns a collection with all these values. Si este tipo de propiedad se consulta con getProperty() , el método se reconoce que hay varios valores para que la propiedad y devuelve una colección con todos estos valores. So we could write Así que podemos escribir

Object prop = config.getProperty(“tables.table.name”); Object prop = config.getProperty(“tables.table.name”);

if(prop instanceof Collection)

{

    System.out.println(“Number of tables: ” + ((Collection) prop).size());

}

An alternative to this code would be the getList() method of Configuration . Una alternativa a este código podría ser el getList() método de Configuration . If a property is known to have multiple values (as is the table name property in this example), getList() allows to retrieve all values at once. Note: it is legal to call getString() or one of the other getter methods on a property with multiple values; it returns the first element of the list. Si una propiedad se sabe que tiene varios valores (como es la propiedad nombre de la tabla en este ejemplo), getList() permite recuperar todos los valores de una vez. Nota: es legal para llamar a getString() o uno de los métodos getter otros una propiedad con varios valores, sino que devuelve el primer elemento de la lista.

Accessing structured properties Obtener acceso a propiedades estructuradas

Okay, we can obtain a list with the names of all defined tables. Bueno, podemos obtener una lista con los nombres de todas las tablas definidas. In the same way we can retrieve a list with the names of all table fields: just pass the key tables.table.fields.field.name to the getList() method. De la misma manera podemos obtener una lista con los nombres de todos los campos de la tabla: sólo tiene que pasar la clave tables.table.fields.field.name a la getList() método. In our example this list would contain 10 elements, the names of all fields of all tables. This is fine, but how do we know, which field belongs to which table? En nuestro ejemplo de esta lista que contiene 10 elementos, los nombres de todos los campos de todas las tablas. Esto está bien, pero ¿cómo sabemos que el terreno pertenece a cada mesa?

When working with such hierarchical structures the configuration keys used to query properties can have an extended syntax. Cuando se trabaja con este tipo de estructura jerárquica las teclas de configuración utilizada para propiedades de una consulta puede tener una sintaxis extendida. All components of a key can be appended by a numerical value in parentheses that determines the index of the affected property. Todos los componentes de una clave puede ser añadido por un valor numérico entre paréntesis que determina el índice de la propiedad afectada. So if we have two table elements we can exactly specify, which one we want to address by appending the corresponding index. Así que si tenemos dos table elementos que se pueden especificar exactamente, ¿cuál queremos abordar si se añade el índice correspondiente. This is explained best by some examples: Esto se explica mejor con algunos ejemplos:

We will now provide some configuration keys and show the results of a getProperty() call with these keys as arguments. A continuación se ofrecen algunas claves de configuración y mostrar los resultados de una getProperty() llamada con estas claves como argumentos.

tables.table(0).name

Returns the name of the first table (all indices are 0 based), in this example the string users . Devuelve el nombre de la primera tabla (todos los índices se basa 0), en este ejemplo los usuarios de cadena.

tables.table(0)[@tableType]

Returns the value of the tableType attribute of the first table ( system ). Devuelve el valor del atributo TableType de la primera tabla (del sistema).

tables.table(1).name

Analogous to the first example returns the name of the second table ( documents ). Análoga a la primer ejemplo devuelve el nombre de la segunda tabla (documentos).

tables.table(2).name

Here the name of a third table is queried, but because there are only two tables result is null . Aquí el nombre de una tercera tabla se consulta, sino porque sólo hay dos tablas de resultados es nulo. The fact that a null value is returned for invalid indices can be used to find out how many values are defined for a certain property: just increment the index in a loop as long as valid objects are returned. El hecho de que un valor nulo se devuelve para los índices no válidos puede ser utilizado para determinar cuántos valores están definidos para una determinada propiedad: sólo incrementar el índice en un bucle, siempre y cuando se devuelven objetos válidos.

tables.table(1).fields.field.name

Returns a collection with the names of all fields that belong to the second table. Devuelve una colección con los nombres de todos los campos que pertenecen a la segunda tabla. With such kind of keys it is now possible to find out, which fields belong to which table. Con este tipo de teclas, es posible ahora saber, que los campos pertenecen a cada mesa.

tables.table(1).fields.field(2).name

The additional index after field selects a certain field. This expression represents the name of the third field in the second table ( creationDate ). adicionales después de índice del campo El selecciona un campo determinado. Esta expresión representa el nombre del tercer campo en el segundo cuadro (CreationDate).

tables.table.fields.field(0).type

This key may be a bit unusual but nevertheless completely valid. Esta clave puede ser un poco inusual, pero no obstante, válida por completo. It selects the data types of the first fields in all tables. Selecciona los tipos de datos de los campos de primera en todos los cuadros. So here a collection would be returned with the values [ long, long ]. Así que aquí una colección sería devuelto con los valores [tiempo] de largo.

These examples should make the usage of indices quite clear. Because each configuration key can contain an arbitrary number of indices it is possible to navigate through complex structures of XML documents; each XML element can be uniquely identified. Estos ejemplos deberían hacer que el uso de índices muy claro. Dado que cada clave de configuración puede contener un número arbitrario de índices, es posible navegar a través de estructuras complejas de documentos XML, y cada elemento XML puede ser identificada.

Sometimes dealing with long property keys may become inconvenient, especially if always the same properties are accessed. A veces se ocupan de las claves de propiedad a largo puede llegar a ser incómodo, especialmente si siempre las mismas propiedades que se accede. For this case HierarchicalConfiguration provides a short cut with the configurationAt() method. Para este caso HierarchicalConfiguration proporciona un atajo con el configurationAt() método. This method can be passed a key that selects exactly one node of the hierarchy of nodes contained in a hierarchical configuration. Este método se puede pasar una clave que selecciona exactamente un nodo de la jerarquía de nodos que figuran en una configuración jerárquica. Then a new hierarchical configuration will be returned whose root node is the selected node. A continuación, una nueva configuración jerárquica será devuelto cuyo nodo raíz es el nodo seleccionado. So all property keys passed into that configuration should be relative to the new root node. Así que todas las claves de la propiedad pasó a que la configuración debe ser relativo al nodo raíz nueva. For instance, if we are only interested in information about the first database table, we could do something like that: Por ejemplo, si sólo estamos interesados en información sobre la tabla primera base de datos, podríamos hacer algo así:

HierarchicalConfiguration sub = config.configurationAt(“tables.table(0)”); HierarchicalConfiguration sub = config.configurationAt(“tables.table(0)”);

String tableName = sub.getString(“name”); // sólo tiene que proporcionar ruta relativa

List fieldNames = sub.getList(“fields.field.name”);

List fieldNames = sub.getList(“fields.field.name”);

For dealing with complex list-like structures there is another short cut. Para hacer frente a estructuras complejas, como la lista hay otro atajo. Often it will be necessary to iterate over all items in the list and access their (sub) properties. A menudo será necesario para iterar sobre todos los elementos de la lista y acceder a sus (sub) propiedades. A good example are the fields of the tables in our demo configuration. Un buen ejemplo son los campos de las tablas en nuestra configuración de demostración. When you want to process all fields of a table (eg for constructing a CREATE TABLE statement), you will need all information stored for them in the configuration. Cuando usted desea procesar todos los campos de una tabla (por ejemplo, para la construcción de un CREATE TABLE declaración), tendrá toda la información almacenada por ellos en la configuración. An option would be to use the getList() method to fetch the required data one by one: Una opción sería utilizar el getList() método para obtener los datos requeridos, uno por uno:

List fieldNames = config.getList(“tables.table(0).fields.field.name”); List fieldNames = config.getList(“tables.table(0).fields.field.name”);

List fieldTypes = config.getList(“tables.table(0).fields.field.type”);

List … // Pide además otros datos que pueden ser almacenados en la configuraciónBut this is not very readable and will fail if not all field elements contain the same set of data (for instance the type property may be optional, then the list for the types can contain less elements than the other lists).

Pero esto no es muy legible y se producirá un error si no todos los elementos de campo contienen el mismo conjunto de datos (por ejemplo, el type de propiedad puede ser opcional, a continuación, la lista de los tipos puede contener menos elementos de las otras listas). A solution to these problems is the configurationsAt() method, a close relative to the configurationAt() method covered above. Una solución a estos problemas es el configurationsAt() método, un pariente cercano a la configurationAt() método especificado anteriormente. This method evaluates the passed in key and collects all configuration nodes that match this criterion. Este método evalúa el pasado en clave y recoge todos los nodos de configuración que coinciden con este criterio. Then for each node a HierarchicalConfiguration object is created with this node as root node. A continuación, para cada nodo un HierarchicalConfiguration objeto se crea con este nodo como nodo raíz. A list with these configuration objects is returned. Una lista de todos estos objetos de configuración se devuelve. As the following example shows this comes in very handy when processing list-like structures: Como muestra el ejemplo siguiente se muestra esto viene en muy útil en el tratamiento de estructuras, como la lista:

List fields = config.configurationsAt(“tables.table(0).fields.field”); List fields = config.configurationsAt(“tables.table(0).fields.field”);

for(Iterator it = fields.iterator(); it.hasNext();)

{

HierarchicalConfiguration sub = (HierarchicalConfiguration) it.next();

// sub contains now all data about a single field

String fieldName = sub.getString(“name”);

String fieldType = sub.getString(“type”);

The configurations returned by the configurationAt() and configurationsAt() method are in fact instances of the SubnodeConfiguration class. Las configuraciones devuelto por el configurationAt() y configurationsAt() método se encuentran en instancias hecho de la SubnodeConfiguration clase. The API documentation of this class contains more information about its features and limitations. La documentación de la API de esta clase contiene más información acerca de sus características y limitaciones.

Adding new properties Adición de nuevas propiedades

So far we have learned how to use indices to avoid ambiguities when querying properties. Hasta ahora hemos aprendido a utilizar índices para evitar ambigüedades cuando las propiedades de consulta. The same problem occurs when adding new properties to a structured configuration. El mismo problema se produce cuando se agregan nuevas propiedades a una configuración estructurada. As an example let’s assume we want to add a new field to the second table. Como ejemplo supongamos que queremos añadir un nuevo campo a la segunda tabla. New properties can be added to a configuration using the addProperty() method. Las nuevas propiedades se puede añadir a una configuración determinada usando el addProperty() método. Of course, we have to exactly specify where in the tree like structure new data is to be inserted. Por supuesto, tenemos que especificar exactamente en qué parte del árbol como la nueva estructura de datos se va a insertar. A statement like Una declaración como

// Warning: This might cause trouble! / / Advertencia: Esto podría causar problemas!

config.addProperty(“tables.table.fields.field.name”, “size”); config.addProperty(“tables.table.fields.field.name”, “size”);

would not be sufficient because it does not contain all needed information. no sería suficiente, ya que no contiene toda la información necesaria. How is such a statement processed by the addProperty() method? ¿Cómo es una manifestación procesados por el addProperty() método?

addProperty() splits the provided key into its single parts and navigates through the properties tree along the corresponding element names. addProperty() divide la clave proporcionada en sus partes individuales y navega a través de las propiedades a lo largo del árbol de nombres de los elementos correspondientes. In this example it will start at the root element and then find the tables element. En este ejemplo se iniciará en el elemento raíz y, a continuación encontrarás las tables elemento. The next key part to be processed is table , but here a problem occurs: the configuration contains two table properties below the tables element. La parte siguiente tecla que debe transformarse es table , pero aquí surge un problema: la configuración contiene dos table propiedades por debajo de los tables elemento. To get rid off this ambiguity an index can be specified at this position in the key that makes clear, which of the two properties should be followed. tables.table(1).fields.field.name eg would select the second table property. Para deshacerse de esta ambigüedad puede ser un índice especificado en esta posición en la llave que deja claro, ¿cuál de las dos propiedades deben ser seguidas. tables.table(1).fields.field.name por ejemplo, se selecciona la segunda table propiedad. If an index is missing, addProperty() always follows the last available element. Si un índice de falta, addProperty() sigue siempre el elemento a disposición. In our example this would be the second table , too. En nuestro ejemplo, esta sería la segunda table , también.

The following parts of the key are processed in exactly the same manner. Las partes siguientes de la clave son procesadas exactamente de la misma manera. Under the selected table property there is exactly one fields property, so this step is not problematic at all. En el marco del seleccionado table de propiedad no es exactamente un fields de propiedad, por lo que este paso no es problemático en absoluto. In the next step the field part has to be processed. En el siguiente paso del field parte tiene que ser procesado. At the actual position in the properties tree there are multiple field (sub) properties. En la posición real en el árbol de propiedades, hay múltiples field (sub) propiedades. So we here have the same situation as for the table part. Because no explicit index is defined the last field property is selected. Así que aquí tienen la misma situación en cuanto a la table partes. Dado que ningún índice explícito se define el último field la propiedad está activada. The last part of the key passed to addProperty() ( name in this example) will always be added as new property at the position that has been reached in the former processing steps. La última parte de la clave pasa a addProperty() ( name en este ejemplo) siempre se añadirá como nueva propiedad en la posición que se ha alcanzado en las etapas de producción anterior. So in our example the last field property of the second table would be given a new name sub property and the resulting structure would look like the following listing: Así que en nuestro ejemplo, la última field propiedad de la segunda tabla se le daría un nuevo name la propiedad sub y la estructura resultante se vería como el siguiente listado:

    … <table tableType=”application”>

<name>documents</name>

<fields>

<field>

<name>docid</name>

<type>long</type>

</field>

<field>

<name>name</name>

<type>java.lang.String</type>

</field>

<field>

<name>creationDate</name>

<type>java.util.Date</type>

</field>

<field>

<name>authorID</name>

<type>long</type>

</field>

<field>

<name>version</name>

         <name>size</name> <== Newly added property

<type>int</type>

</field>

</fields>

</table>

</tables>

</database>

This result is obviously not what was desired, but it demonstrates how addProperty() works: the method follows an existing branch in the properties tree and adds new leaves to it. (If the passed in key does not match a branch in the existing tree, a new branch will be added. Eg if we pass the key tables.table.data.first.test , the existing tree can be navigated until the data part of the key. From here a new branch is started with the remaining parts data , first and test .)

Este resultado obviamente no es lo deseado, pero se muestra cómo addProperty() funciona: el método sigue una rama existente en el árbol de propiedades y añade nuevas hojas a ella. (Si el pasado en clave no se corresponde con una rama en el árbol existente , una nueva rama será añadido. Por ejemplo, si pasamos la clave tables.table.data.first.test , el árbol existente se puede navegar hasta la data parte de la clave. A partir de aquí una nueva rama se inicia con el resto de piezas data , first y test .)

If we want a different behavior, we must explicitely tell addProperty() what to do. Si queremos un comportamiento diferente, que debe informar explícitamente addProperty() qué hacer. In our example with the new field our intension was to create a new branch for the field part in the key, so that a new field property is added to the structure rather than adding sub properties to the last existing field property. En nuestro ejemplo con el nuevo campo de nuestra intención era crear una nueva rama para el field parte de la clave, para que un nuevo field la propiedad se agrega a la estructura, más que la adición de propiedades a los actuales sub último field de propiedad. This can be achieved by specifying the special index (-1) at the corresponding position in the key as shown below: Esto puede lograrse mediante la especificación del índice especial (-1) en la posición correspondiente en la clave como se muestra a continuación:

config.addProperty(“tables.table(1).fields.field(-1).name”, “size”); config.addProperty(“tables.table(1).fields.field(-1).name”, “size”);

config.addProperty(“tables.table(1).fields.field.type”, “int”);The first line in this fragment specifies that a new branch is to be created for the field property (index -1). In the second line no index is specified for the field, so the last one is used – which happens to be the field that has just been created.

La primera línea en este fragmento se especifica que una nueva sucursal se va a crear para el field la propiedad (índice de -1). En la segunda línea se especifica ningún índice para el campo, por lo que el último se utiliza – que pasa a ser el campo que se acaba de crear. So these two statements add a fully defined field to the second table. Así pues, estas dos declaraciones agregar un campo definido plenamente a la segunda tabla. This is the default pattern for adding new properties or whole hierarchies of properties: first create a new branch in the properties tree and then populate its sub properties. As an additional example let’s add a complete new table definition to our example configuration: Este es el patrón por defecto para añadir nuevas propiedades o jerarquías conjunto de propiedades: crear primero una nueva rama en el árbol de propiedades, y luego rellenar sus propiedades sub. Como un ejemplo adicional vamos a añadir una nueva definición de la tabla completa a nuestra configuración de ejemplo:

// Add a new table element and define the name

// Añadir un elemento de la tabla nueva y definir el nombre

config.addProperty(“tables.table(-1).name”, “versions”);

// Añadir un nuevo campo a la nueva tabla

// (Un índice de la tabla no es necesario porque el último se utiliza)

config.addProperty(“tables.table.fields.field(-1).name”, “id”);

config.addProperty(“tables.table.fields.field.type”, “int”);

// Añadir otro campo a la nueva tabla

config.addProperty(“tables.table.fields.field(-1).name”, “date”);

config.addProperty(“tables.table.fields.field.type”, “java.sql.Date”);

For more information about adding properties to a hierarchical configuration also have a look at the javadocs for HierarchicalConfiguration . Para obtener más información sobre cómo agregar propiedades a una configuración jerárquica también echar un vistazo a los javadocs para HierarchicalConfiguration .

Escaping dot characters in XML tags Escapar caracteres de punto en las etiquetas XML

In XML the dot character used as delimiter by most configuration classes is a legal character that can occur in any tag. En XML el carácter de punto utilizado como delimitador por la configuración de la mayoría de las clases es un carácter jurídico que puede ocurrir en cualquier etiqueta. So the following XML document is completely valid: Así que el siguiente documento XML es completamente válido:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<configuration>

<test.value>42</test.value>

<test.complex>

<test.sub.element>many dots</test.sub.element>

</test.complex>

</configuration>

This XML document can be loaded by XMLConfiguration without trouble, but when we want to access certain properties we face a problem: The configuration claims that it does not store any values for the properties with the keys test.value or test.complex.test.sub.element !

Este documento XML se pueden cargar por XMLConfiguration sin problemas, pero cuando queremos acceder a ciertas propiedades nos enfrentamos a un problema: La configuración alega que no almacena los valores para las propiedades con las teclas de test.value o test.complex.test.sub.element !

Of course, it is the dot character contained in the property names, which causes this problem. Por supuesto, es el carácter de punto que figura en los nombres de propiedad, lo que causa este problema. A dot is always interpreted as a delimiter between elements. Un punto siempre se interpreta como un delimitador entre los elementos. So given the property key test.value the configuration would look for an element named test and then for a sub element with the name value . Entonces, dada la característica clave test.value la configuración buscaría un elemento llamado test y luego de un elemento secundario con el nombre de value . To change this behavior it is possible to escape a dot character, thus telling the configuration that it is really part of an element name. Para cambiar este comportamiento se puede escapar de un carácter de punto, con lo que dice la configuración que es en realidad parte de un nombre de elemento. This is simply done by duplicating the dot. Esto se hace simplemente por duplicar el punto. So the following statements will return the desired property values: Así que las siguientes afirmaciones le devolverá el valor de la propiedad deseada:

int testVal = config.getInt(“test..value”); int testVal = config.getInt(“test..value”);

String complex = config.getString(“test..complex.test..sub..element”); Note the duplicated dots whereever the dot does not act as delimiter.

Tenga en cuenta que los puntos duplicados siempre que sea el punto no actúa como delimitador. This way it is possible to access properties containing dots in arbitrary combination. De esta manera es posible acceder a las propiedades que contiene puntos en combinación arbitraria. However, as you can see, the escaping can be confusing sometimes. Sin embargo, como se puede ver, el escape puede ser confuso a veces. So if you have a choice, you should avoid dots in the tag names of your XML configuration files. Así que si usted tiene una opción, se debe evitar puntos en los nombres de las etiquetas de sus archivos de configuración XML.

Expression engines motores de Expresión

In the previous chapters we saw many examples about how properties in a XMLConfiguration object (or more general in a HierarchicalConfiguration object, because this is the base class, which implements this functionality) can be queried or modified using a special syntax for the property keys. En los capítulos anteriores hemos visto muchos ejemplos de cómo las propiedades en un XMLConfiguration objeto (o más general en un HierarchicalConfiguration objeto, porque esta es la clase base, que implementa esta funcionalidad) se puede consultar o modificar mediante una sintaxis especial para las teclas de la propiedad. Well, this was not the full truth. Bueno, esta no era la verdad completa. Actually, property keys are not processed by the configuration object itself, but are delegated to a helper object, a so called Expression engine . En realidad, las claves de la propiedad no son procesados por la configuración del objeto mismo, sino que son nombrados para un objeto de ayuda, una expresión de motor, llamado así.

The separation of the task of interpreting property keys into a helper object is a typical application of the Strategy design pattern. La separación de la tarea de interpretar las claves de propiedad en un objeto de ayuda es una aplicación típica del patrón de diseño Estrategia. In this case it also has the advantage that it becomes possible to plug in different expression engines into a HierarchicalConfiguration object. En este caso también tiene la ventaja de que es posible conectar los motores de expresión diferente en un HierarchicalConfiguration objeto. So by providing different implementations of the ExpressionEngine interface hierarchical configurations can support alternative expression languages for accessing their data. Así que al proporcionar implementaciones diferentes de la ExpressionEngine interfaz de configuración jerárquica puede soportar lenguajes de expresión alternativa para acceder a sus datos.

Before we discuss the available expression engines that ship with Commons Configuration, it should be explained how an expression engine can be associated with a configuration object. HierarchicalConfiguration and all derived classes provide a setExpressionEngine() method, which expects an implementation of the ExpressionEngine interface as argument. Antes de discutir los motores de expresión disponibles que se incluyen en los Comunes de configuración, se debe explicar cómo funciona un motor expresión puede estar asociada con un objeto de configuración. HierarchicalConfiguration y todas las clases derivadas proporcionar un setExpressionEngine() método, que espera una implementación de la ExpressionEngine interfaz como argumento. After this method was called, the configuration object will use the passed expression engine, which means that all property keys passed to methods like getProperty() , getString() , or addProperty() must conform to the syntax supported by this engine. Después de este método fue llamado, el objeto de configuración se utiliza el motor de expresiones pasado, lo que significa que todas las claves propiedad pasó a métodos como getProperty() , getString() , o addProperty() debe ajustarse a la sintaxis con el apoyo de este motor. Property keys returned by the getKeys() method will follow this syntax, too. claves de la Propiedad que devuelve la getKeys() método seguirá esta sintaxis, también.

In addition to instance specific expression engines that change the behavior of single configuration objects it is also possible to set a global expression engine. Además de la instancia de motores expresión específica que cambian el comportamiento de los objetos de configuración única, también es posible crear un motor de expresión global. This engine is shared between all hierarchical configuration objects, for which no specific expression engine was set. Este motor es compartido entre todos los objetos de configuración jerárquica, para lo cual la expresión set fue el motor no específicos. The global expression engine can be set using the static setDefaultExpressionEngine() method of HierarchicalConfiguration . El motor de expresiones mundial se pueden establecer mediante la estática setDefaultExpressionEngine() método de HierarchicalConfiguration . By invoking this method with a custom expression engine the syntax of all hierarchical configuration objects can be altered at once. Al invocar este método con un motor de expresiones personalizado de la sintaxis de todos los objetos de configuración jerárquica puede ser alterado a la vez.

The default expression engine El motor de expresiones por defecto

The syntax described so far for property keys of hierarchical configurations is implemented by a specific implementation of the ExpressionEngine interface called DefaultExpressionEngine . La sintaxis descrita hasta ahora para las llaves de propiedad de las configuraciones jerárquicas se lleva a cabo mediante una aplicación específica de la ExpressionEngine interfaz llamada DefaultExpressionEngine . An instance of this class is installed as the global expression engine in HierarchicalConfiguration . Una instancia de esta clase se instala como el motor de la expresión global en HierarchicalConfiguration . So all newly created instances of this class will make use of this engine (which is the reason that our examples above worked). Así que todos los casos de nueva creación de esta clase, se recurrirá a este motor (que es la razón por la que nuestros ejemplos anteriores trabajadas).

After reading the examples of property keys provided so far in this document you should have a sound understanding regarding the features and the syntax supported by the DefaultExpressionEngine class. Después de leer los ejemplos de las claves de propiedad facilitada hasta ahora en este documento debe tener una buena comprensión sobre las características y la sintaxis con el apoyo de la DefaultExpressionEngine clase. But it can do a little bit more for you: it defines a bunch of properties, which can be used to customize most tokens that can appear in a valid property key. Pero se puede hacer un poco más por ti, ya que define un conjunto de propiedades, que se puede utilizar para personalizar la mayoría de los tokens que pueden aparecer en una clave de propiedad válidos. You prefer curly brackets over paranthesis as index markers? Usted prefiere llaves en paréntesis como marcadores de índice? You find the duplicated dot as escaped property delimiter counter-intuitive? Encuentra el punto dupliquen como delimitador de la propiedad escapó contra de la intuición? Well, simply go ahead and change it! Bueno, simplemente seguir adelante y cambiar él! The following example shows how the syntax of a DefaultExpressionEngine object is modified. El siguiente ejemplo muestra cómo la sintaxis de una DefaultExpressionEngine objeto se modifica. Then this object is set as the global expression engine, so that from now on all hierarchical configuration objects will take up this new syntax: A continuación, este objeto está establecido como el motor de expresiones mundial, para que de ahora en adelante todos los objetos de configuración jerárquica se ocupará de esta nueva sintaxis:

DefaultExpressionEngine engine = new DefaultExpressionEngine();

// Se utiliza una barra como delimitador de la propiedad

engine.setPropertyDelimiter(“/”);

// Índices deberá indicarse entre llaves

engine.setIndexStart(“{“);

engine.setIndexEnd(“}”);

// Para los atributos utilizar simplemente un @

engine.setAttributeStart(“@”);

engine.setAttributeEnd(null);

// Una barra invertida se utiliza para escapar delimitadores de propiedad

engine.setEscapedDelimiter(“\\/”);

// Ahora instale este motor como el motor mundial

HierarchicalConfiguration.setDefaultExpressionEngine(engine);

// Acceso inmueble con la nueva sintaxis

HierarchicalConfiguration config = …

String tableName = config.getString(“tables/table{0}/name”);

String tableType = config.getString(“tables/table{0}@type”);

DefaultExpressionEngine engine = new DefaultExpressionEngine();

Tip: Sometimes when processing an XML document you don’t want to distinguish between attributes and “normal” child nodes. Consejo: en ocasiones la hora de procesar un documento XML que no desea distinguir entre los atributos y “normal” nodos secundarios. You can achieve this by setting the AttributeEnd property to null and the AttributeStart property to the same value as the PropertyDelimiter property. Todo esto es posible mediante el establecimiento de la AttributeEnd propiedad como null y el AttributeStart propiedad al mismo valor que la PropertyDelimiter propiedad. Then the syntax for accessing attributes is the same as the syntax for other properties: A continuación, la sintaxis para acceder a los atributos es la misma que la sintaxis de las otras propiedades:

DefaultExpressionEngine engine = new DefaultExpressionEngine();

DefaultExpressionEngine engine = new DefaultExpressionEngine();

engine.setAttributeEnd(null);

engine.setAttributeStart(engine.getPropertyDelimiter());

Object value = config.getProperty(“tables.table(0).name”);

// name can either be a child node of table or an attribute / / El nombre puede ser un nodo secundario de la tabla o un atributo

The XPATH expression engine La expresión XPath motor

The expression language provided by the DefaultExpressionEngine class is powerful enough to address all properties in a hierarchical configuration, but it is not always convenient to use. El lenguaje de expresión proporcionado por el DefaultExpressionEngine clase es lo suficientemente potente como para hacer frente a todas las propiedades en una configuración jerárquica, pero no siempre es cómodo de usar. Especially if list structures are involved, it is often necessary to iterate through the whole list to find a certain element. Especialmente si las estructuras de la lista están implicados, a menudo es necesario para recorrer toda la lista para encontrar un elemento determinado.

Think about our example configuration that stores information about database tables. Piense en nuestra configuración de ejemplo que almacena información acerca de las tablas de bases de datos. A use case could be to load all fields that belong to the “users” table. Un caso de uso podría ser la de cargar todos los campos que pertenecen a los “usuarios” de mesa. If you knew the index of this table, you could simply build a property key like tables.table(<index>).fields.field.name , but how do you find out the correct index? Si conocieras el índice de esta tabla, usted puede simplemente crear una clave de propiedad como tables.table(<index>).fields.field.name , pero ¿cómo saber el índice correcto? When using the default expression engine, the only solution to this problem is to iterate over all tables until you find the “users” table. Cuando se utiliza el motor de expresiones por defecto, la única solución a este problema es para iterar sobre todas las tablas hasta que encuentre los “usuarios” de mesa.

Life would be much easier if an expression language could be used, which would directly support queries of such kind. La vida sería mucho más fácil si un lenguaje de expresión puede ser utilizada, que se apoyarían directamente las consultas de este tipo. In the XML world, the XPATH syntax has grown popular as a powerful means of querying structured data. En el mundo de XML, la sintaxis XPath ha crecido popular como un poderoso medio de consulta de datos estructurada. In XPATH a query that selects all field names of the “users” table would look something like tables/table[@name=’users’]/fields/name (here we assume that the table’s name is modelled as an attribute). This is not only much simpler than an iteration over all tables, but also much more readable: it is quite obvious, which fields are selected by this query. En XPATH una consulta que selecciona todos los nombres de campo de los “usuarios” tabla sería algo como tables/table[@name=’users’]/fields/name (en este caso suponemos que la tabla es el nombre del se modela como un atributo). Este no sólo es mucho más simple que una iteración sobre todos los cuadros, pero también mucho más legible: es bastante obvio, que los campos son seleccionados por esta consulta.

Given the power of XPATH it is no wonder that we got many user requests to add XPATH support to Commons Configuration. Well, here is it! Dado el poder de XPATH no es de extrañar que tenemos muchas peticiones de usuarios para agregar XPATH apoyo a los Comunes de configuración. Bueno, aquí está!

For enabling XPATH syntax for property keys you need the XPathExpressionEngine class. Para habilitar la sintaxis XPath para las llaves de propiedad se necesita el XPathExpressionEngine clase. This class implements the ExpressionEngine interface and can be plugged into a HierarchicalConfiguration object using the setExpressionEngine() method. Esta clase implementa la ExpressionEngine interfaz y puede ser conectado a un HierarchicalConfiguration objeto utilizando el setExpressionEngine() método. It is also possible to set an instance of this class as the global expression engine, so that all hierarchical configuration objects make use of XPATH syntax. También es posible establecer una instancia de esta clase como el motor de la expresión global, de modo que todos los objetos de configuración jerárquica hacer uso de la sintaxis XPath. The following code fragment shows how XPATH support can be enabled for a configuration object: El fragmento de código siguiente se muestra cómo XPATH apoyo se puede habilitar para un objeto de configuración:

HierarchicalConfiguration config = … HierarchicalConfiguration config = …

config.setExpressionEngine(new XPathExpressionEngine());

// Now we can use XPATH queries: / / Ahora podemos usar XPATH consultas:

List fields = config.getList(“tables/table[1]/fields/name”); List fields = config.getList(“tables/table[1]/fields/name”);

XPATH expressions are not only used for selecting properties (ie for the several getter methods), but also for adding new properties. XPATH expresiones no sólo se utilizan para la selección de propiedades (es decir, para los métodos getter), sino también para añadir nuevas propiedades. For this purpose the keys passed into the addProperty() method must conform to a special syntax. Para ello las claves pasaron a addProperty() método debe ajustarse a una sintaxis especial. They consist of two parts: the first part is an arbitrary XPATH expression that selects the node where the new property is to be added to, the second part defines the new element to be added. Se componen de dos partes: la primera parte es una expresión XPath que selecciona arbitrariamente el nodo en la nueva propiedad es que se añade a la segunda parte se define el nuevo elemento que se añade. Both parts are separated by whitespace. Ambas partes están separadas por espacios en blanco.

Okay, let’s make an example. Bueno, vamos a dar un ejemplo. Say, we want to add a type property under the first table (as a sibling to the name element). Oye, vamos a agregar un type de propiedad en virtud de la primera tabla (como un hermano al name del elemento). Then the first part of our key will have to select the first table element, the second part will simply be type , ie the name of the new property: A continuación la primera parte de nuestra llave tendrá que seleccionar el elemento de la tabla primera, la segunda parte será simplemente type , es decir, el nombre de la nueva propiedad:

config.addProperty(“tables/table[1] type”, “system”); config.addProperty(“tables/table[1] type”, “system”);

(Note that indices in XPATH are 1-based, while in the default expression language they are 0-based.) In this example the part tables/table[1] selects the target element of the add operation. (Tenga en cuenta que los índices en XPATH son 1-base, mientras que en el lenguaje de expresiones por defecto son 0-base.) En este ejemplo la parte tables/table[1] selecciona el elemento objetivo de la operación de adición. This element must exist and must be unique, otherwise an exception will be thrown. type is the name of the new element that will be added. Este elemento debe existir y debe ser único, de lo contrario una excepción será lanzada. type es el nombre del nuevo elemento que se añadirá. If instead of a normal element an attribute should be added, the example becomes Si en lugar de un elemento normal debería ser un atributo añadido, se convierte en el ejemplo

config.addProperty(“tables/table[1] @type”, “system”);

It is possible to add complete paths at once. Es posible añadir rutas completas a la vez. Then the single elements in the new path are separated by “/” characters. Entonces, los elementos individuales en el nuevo camino están separadas por caracteres “/”. The following example shows how data about a new table can be added to the configuration. El siguiente ejemplo muestra cómo los datos acerca de una nueva tabla se puede añadir a la configuración. Here we use full paths: Aquí se utiliza rutas completas:

// Add new table “tasks” with name element and type attribute

// Agregar nueva tabla “tareas” con elemento de nombre y tipo de atributo

config.addProperty(“tables table/name”, “tasks”);

// last()selecciona el último elemento de este nombre,

// Que es la nueva tabla del elemento

config.addProperty(“tables/table[last()] @type”, “system”);

// Ahora agregar campos

config.addProperty(“tables/table[last()] fields/field/name”, “taskid”);

config.addProperty(“tables/table[last()]/fields/field[last()] type”, “int”);

config.addProperty(“tables/table[last()]/fields field/name”, “name”);

config.addProperty(“tables/table[last()]/fields field/name”, “startDate”);

The first line of this example adds the path table/name to the tables element, ie a new table element will be created and added as last child to the tables element. La primera línea de este ejemplo se agrega la ruta de table/name de la tables elemento, es decir, una nueva table elemento se creará y añadirá como último hijo a los tables elemento. Then a new name element is added as child to the new table element. A continuación, un nuevo name se añade como elemento de niño a la nueva table elemento. To this element the value “tasks” is assigned. Para este elemento el valor “tareas” se le asigna. The next line adds a type attribute to the new table element. La siguiente línea añade un type atributo para el elemento de la nueva tabla. To obtain the correct table element, to which the attribute must be added, the XPATH function last() is used; this function selects the last element with a given name, which in this case is the new table element. The following lines all use the same approach to construct a new element hierarchy: At first complete new branches are added ( fields/field/name ), then to the newly created elements further children are added. Para obtener la correcta table elemento, para que el atributo debe añadir, el XPATH función last() se utiliza, esta función se selecciona el último elemento con un nombre determinado, que en este caso es la nueva table de elementos. Las siguientes líneas todo uso el mismo enfoque para construir una jerarquía nuevo elemento: Al principio, las nuevas oficinas se suman completa ( fields/field/name ), luego a los elementos recién creados niños mayores de esa incorporación.

Note: XPATH support is implemented through Commons JXPath . So when making use of this feature, be sure you include the commons-jxpath jar in your classpath. Nota: el soporte XPath se implementa a través JXPath Commons . Así que al hacer uso de esta función, asegúrese de incluir el jar-jxpath comunes en su ruta de clases.

In this tutorial we don’t want to describe XPATH syntax and expressions in detail. En este tutorial no queremos para describir la sintaxis de XPath y expresiones en detalle. Please refer to corresponding documentation. It is important to mention that by embedding Commons JXPath the full extent of the XPATH 1.0 standard can be used for constructing property keys. Por favor, consulte la documentación correspondiente. Es importante mencionar que mediante la incorporación de los Comunes JXPath toda la extensión de la XPATH puede ser 1,0 estándar utilizado para la construcción de las claves de propiedad.

Validation of XML configuration files Validación de la configuración de archivos XML

XML parsers provide support for validation of XML documents to ensure that they conform to a certain DTD. analizadores XML proporcionar apoyo para la validación de documentos XML para asegurar que se ajusten a una DTD determinada. This feature can be useful for configuration files, too. XMLConfiguration allows to enable validation for the files to load. Esta característica puede ser útil para los archivos de configuración, también. XMLConfiguration permite habilitar la validación de los archivos a cargar.

The easiest way to turn on validation is to simply set the validating property to true as shown in the following example: La forma más fácil de convertir en la validación es establecer simplemente la validating la propiedad en true como se muestra en el ejemplo siguiente:

XMLConfiguration config = new XMLConfiguration();

config.setFileName(“myconfig.xml”);

config.setValidating(true);

/ / Esto lanzará un ConfigurationException si el documento XML no

// conform to its DTD. / / Se ajustan a su DTD.

config.load();

XMLConfiguration config = new XMLConfiguration();

Setting the validating flag to true will cause XMLConfiguration to use a validating XML parser. Ajuste de la validating bandera en true hará que XMLConfiguration utilizar un analizador de validación XML. At this parser a custom ErrorHandler will be registered, which throws exceptions on simple and fatal parsing errors. En este analizador una costumbre ErrorHandler serán registrados, lo que arroja excepciones en fatales errores de análisis y simple.

There is also some support for dealing with DTD files. También hay algo de apoyo para tratar con los archivos DTD. Often the DTD of an XML document is stored locally so that it can be quickly accessed. A menudo, el DTD de un documento XML se almacena localmente para que pueda acceder rápidamente. However the DOCTYPE declaration of the document points to a location on the web as in the following example: Sin embargo, el DOCTYPE declaración de los puntos de documento en una ubicación en la web como en el ejemplo siguiente:

<?xml version=”1.0″ encoding=”ISO-8859-1″?> <?xml version=”1.0″ encoding=”ISO-8859-1″?>

<!DOCTYPE web-app

PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN”

http://java.sun.com/j2ee/dtds/web-app_2.2.dtd”&gt;

When working with XML documents directly you would use an EntityResolver in such a case.

Al trabajar con documentos XML directamente debería utilizar un EntityResolver en tal caso. The task of such an entity resolver is to point the XML parser to the location of the file referred to by the declaration. La tarea de dicha resolución de la entidad es de señalar con el analizador de XML en la ubicación del archivo a que se refiere la declaración. So in our example the entity resolver would load the DTD file from a local cache instead of retrieving it from the internet. Así que en nuestro ejemplo, la resolución de la entidad que cargar el archivo DTD de una caché local en lugar de recuperarla del Internet.

XMLConfiguration provides a simple default implementation of an EntityResolver . XMLConfiguration proporciona una implementación simple de un defecto EntityResolver . This implementation is initialized by calling the registerEntityId() method with the public IDs of the entities to be retrieved and their corresponding local URLs. Esta aplicación se inicializa llamando a la registerEntityId() método con los identificadores de las entidades públicas para ser recuperados y sus URLs locales correspondientes. This method has to be called before the configuration is loaded. Este método tiene que ser llamada antes de la configuración se ha cargado. To continue our example, consider that the DTD file for our example document is stored on the class path. Para continuar con nuestro ejemplo, considere la posibilidad de que el archivo DTD para nuestro documento de ejemplo se almacena en la ruta de clase. We can register it at XMLConfiguration using the following code: Podemos registrar en XMLConfiguration usando el siguiente código:

XMLConfiguration config = new XMLConfiguration();

// Carga la dirección URL del archivo DTD de ruta de clases

URL dtdURL = getClass().getResource(“web-app_2.2.dtd”);

// Que registrarse en la configuración

config.registerEntityId(“-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN”,

dtdURL);

config.setValidating(true); // habilitar la validación

config.setFileName(“web.xml”);

config.load();

This basically tells the XML configuration to use the specified URL when it encounters the given public ID. Esto básicamente le dice a la configuración de XML para utilizar la dirección URL especificada cuando encuentra el id público. Note that the call to registerEntityId() has to be performed before the configuration is loaded. Tenga en cuenta que la llamada a registerEntityId() tiene que ser realizado antes de la configuración se ha cargado. So you cannot use one of the constructors that directly load the configuration. Así que no puedes utilizar uno de los constructores que cargar directamente la configuración.

While using the validating flag is a simple means of enabling validation it cannot fullfil more complex requirements, eg schema validation. Si bien la utilización de la validating bandera es un procedimiento sencillo que permite la validación de que no pueden llenar los requisitos más complejos, por ejemplo, la validación del esquema. To be able to deal with such requirements XMLConfiguration provides a generic way of setting up the XML parser to use: A preconfigured DocumentBuilder object can be passed to the setDocumentBuilder() method. Para poder hacer frente a estas exigencias XMLConfiguration proporciona una manera genérica de crear el analizador XML de uso: Una preconfigurado DocumentBuilder objeto puede ser pasado a la setDocumentBuilder() método.

So an application can create a DocumentBuilder object and initialize it according to its special needs. Así que una aplicación puede crear un DocumentBuilder objeto y lo inicializa de acuerdo con sus necesidades especiales. Then this object must be passed to the XMLConfiguration instance before invocation of the load() method. A continuación, este objeto se debe pasar a la XMLConfiguration instancia antes de la invocación de la load() método. When loading a configuration file, the passed in DocumentBuilder will be used instead of the default one. Note: If a custom DocumentBuilder is used, the default implementation of the EntityResolver interface is disabled. Al cargar un archivo de configuración, la aprobada en DocumentBuilder se utilizará en lugar del default. Nota: Si una costumbre DocumentBuilder se utiliza la implementación predeterminada de la EntityResolver interfaz está desactivado. This means that the registerEntityId() method has no effect in this mode. Esto significa que el registerEntityId() método no tiene efecto en este modo.

motores de Expresión

In the previous chapters we saw many examples about how properties in a XMLConfiguration object (or more general in a HierarchicalConfiguration object, because this is the base class, which implements this functionality) can be queried or modified using a special syntax for the property keys. En los capítulos anteriores hemos visto muchos ejemplos de cómo las propiedades en un XMLConfiguration objeto (o más general en un HierarchicalConfiguration objeto, porque esta es la clase base, que implementa esta funcionalidad) se puede consultar o modificar mediante una sintaxis especial para las teclas de la propiedad. Well, this was not the full truth. Bueno, esta no era la verdad completa. Actually, property keys are not processed by the configuration object itself, but are delegated to a helper object, a so called Expression engine . En realidad, las claves de la propiedad no son procesados por la configuración del objeto mismo, sino que son nombrados para un objeto de ayuda, una expresión de motor, llamado así.

The separation of the task of interpreting property keys into a helper object is a typical application of the Strategy design pattern. La separación de la tarea de interpretar las claves de propiedad en un objeto de ayuda es una aplicación típica del patrón de diseño Estrategia. In this case it also has the advantage that it becomes possible to plug in different expression engines into a HierarchicalConfiguration object. En este caso también tiene la ventaja de que es posible conectar los motores de expresión diferente en un HierarchicalConfiguration objeto. So by providing different implementations of the ExpressionEngine interface hierarchical configurations can support alternative expression languages for accessing their data. Así que al proporcionar implementaciones diferentes de la ExpressionEngine interfaz de configuración jerárquica puede soportar lenguajes de expresión alternativa para acceder a sus datos.

Before we discuss the available expression engines that ship with Commons Configuration, it should be explained how an expression engine can be associated with a configuration object. HierarchicalConfiguration and all derived classes provide a setExpressionEngine() method, which expects an implementation of the ExpressionEngine interface as argument. Antes de discutir los motores de expresión disponibles que se incluyen en los Comunes de configuración, se debe explicar cómo funciona un motor expresión puede estar asociada con un objeto de configuración. HierarchicalConfiguration y todas las clases derivadas proporcionar un setExpressionEngine() método, que espera una implementación de la ExpressionEngine interfaz como argumento. After this method was called, the configuration object will use the passed expression engine, which means that all property keys passed to methods like getProperty() , getString() , or addProperty() must conform to the syntax supported by this engine. Después de este método fue llamado, el objeto de configuración se utiliza el motor de expresiones pasado, lo que significa que todas las claves propiedad pasó a métodos como getProperty() , getString() , o addProperty() debe ajustarse a la sintaxis con el apoyo de este motor. Property keys returned by the getKeys() method will follow this syntax, too. claves de la Propiedad que devuelve la getKeys() método seguirá esta sintaxis, también.

In addition to instance specific expression engines that change the behavior of single configuration objects it is also possible to set a global expression engine. Además de la instancia de motores expresión específica que cambian el comportamiento de los objetos de configuración única, también es posible crear un motor de expresión global. This engine is shared between all hierarchical configuration objects, for which no specific expression engine was set. Este motor es compartido entre todos los objetos de configuración jerárquica, para lo cual la expresión set fue el motor no específicos. The global expression engine can be set using the static setDefaultExpressionEngine() method of HierarchicalConfiguration . El motor de expresiones mundial se pueden establecer mediante la estática setDefaultExpressionEngine() método de HierarchicalConfiguration . By invoking this method with a custom expression engine the syntax of all hierarchical configuration objects can be altered at once. Al invocar este método con un motor de expresiones personalizado de la sintaxis de todos los objetos de configuración jerárquica puede ser alterado a la vez.

The default expression engine El motor de expresiones por defecto

The syntax described so far for property keys of hierarchical configurations is implemented by a specific implementation of the ExpressionEngine interface called DefaultExpressionEngine . La sintaxis descrita hasta ahora para las llaves de propiedad de las configuraciones jerárquicas se lleva a cabo mediante una aplicación específica de la ExpressionEngine interfaz llamada DefaultExpressionEngine . An instance of this class is installed as the global expression engine in HierarchicalConfiguration . Una instancia de esta clase se instala como el motor de la expresión global en HierarchicalConfiguration . So all newly created instances of this class will make use of this engine (which is the reason that our examples above worked). Así que todos los casos de nueva creación de esta clase, se recurrirá a este motor (que es la razón por la que nuestros ejemplos anteriores trabajadas).

After reading the examples of property keys provided so far in this document you should have a sound understanding regarding the features and the syntax supported by the DefaultExpressionEngine class. Después de leer los ejemplos de las claves de propiedad facilitada hasta ahora en este documento debe tener una buena comprensión sobre las características y la sintaxis con el apoyo de la DefaultExpressionEngine clase. But it can do a little bit more for you: it defines a bunch of properties, which can be used to customize most tokens that can appear in a valid property key. Pero se puede hacer un poco más por ti, ya que define un conjunto de propiedades, que se puede utilizar para personalizar la mayoría de los tokens que pueden aparecer en una clave de propiedad válidos. You prefer curly brackets over paranthesis as index markers? Usted prefiere llaves en paréntesis como marcadores de índice? You find the duplicated dot as escaped property delimiter counter-intuitive? Encuentra el punto dupliquen como delimitador de la propiedad escapó contra de la intuición? Well, simply go ahead and change it! Bueno, simplemente seguir adelante y cambiar él! The following example shows how the syntax of a DefaultExpressionEngine object is modified. El siguiente ejemplo muestra cómo la sintaxis de una DefaultExpressionEngine objeto se modifica. Then this object is set as the global expression engine, so that from now on all hierarchical configuration objects will take up this new syntax: A continuación, este objeto está establecido como el motor de expresiones mundial, para que de ahora en adelante todos los objetos de configuración jerárquica se ocupará de esta nueva sintaxis:

DefaultExpressionEngine engine = new DefaultExpressionEngine(); DefaultExpressionEngine engine = new DefaultExpressionEngine();

// Se utiliza una barra como delimitador de la propieda

engine.setPropertyDelimiter(“/”);

// Índices deberá indicarse entre llaves

engine.setIndexStart(“{“);

engine.setIndexEnd(“}”);

// Para los atributos utilizar simplemente un @

engine.setAttributeStart(“@”);

engine.setAttributeEnd(null);

// Una barra invertida se utiliza para escapar delimitadores de propiedad

engine.setEscapedDelimiter(“\\/”);

// Ahora instale este motor como el motor mundial

HierarchicalConfiguration.setDefaultExpressionEngine(engine);

// Acceso inmueble con la nueva sintaxis

HierarchicalConfiguration config = …

String tableName = config.getString(“tables/table{0}/name”);

String tableType = config.getString(“tables/table{0}@type”);

Tip: Sometimes when processing an XML document you don’t want to distinguish between attributes and “normal” child nodes. Consejo: en ocasiones la hora de procesar un documento XML que no desea distinguir entre los atributos y “normal” nodos secundarios. You can achieve this by setting the AttributeEnd property to null and the AttributeStart property to the same value as the PropertyDelimiter property. Todo esto es posible mediante el establecimiento de la AttributeEnd propiedad como null y el AttributeStart propiedad al mismo valor que la PropertyDelimiter propiedad. Then the syntax for accessing attributes is the same as the syntax for other properties: A continuación, la sintaxis para acceder a los atributos es la misma que la sintaxis de las otras propiedades:

DefaultExpressionEngine engine = new DefaultExpressionEngine();

engine.setAttributeEnd(null);

engine.setAttributeStart(engine.getPropertyDelimiter());


Object value = config.getProperty(“tables.table(0).name”);

// name can either be a child node of table or an attribute // El nombre puede ser un nodo secundario de la tabla o un atributo

The XPATH expression engine La expresión XPath motor

The expression language provided by the DefaultExpressionEngine class is powerful enough to address all properties in a hierarchical configuration, but it is not always convenient to use. El lenguaje de expresión proporcionado por el DefaultExpressionEngine clase es lo suficientemente potente como para hacer frente a todas las propiedades en una configuración jerárquica, pero no siempre es cómodo de usar. Especially if list structures are involved, it is often necessary to iterate through the whole list to find a certain element. Especialmente si las estructuras de la lista están implicados, a menudo es necesario para recorrer toda la lista para encontrar un elemento determinado.

Think about our example configuration that stores information about database tables. Piense en nuestra configuración de ejemplo que almacena información acerca de las tablas de bases de datos. A use case could be to load all fields that belong to the “users” table. Un caso de uso podría ser la de cargar todos los campos que pertenecen a los “usuarios” de mesa. If you knew the index of this table, you could simply build a property key like tables.table(<index>).fields.field.name , but how do you find out the correct index? Si conocieras el índice de esta tabla, usted puede simplemente crear una clave de propiedad como tables.table(<index>).fields.field.name , pero ¿cómo saber el índice correcto? When using the default expression engine, the only solution to this problem is to iterate over all tables until you find the “users” table. Cuando se utiliza el motor de expresiones por defecto, la única solución a este problema es para iterar sobre todas las tablas hasta que encuentre los “usuarios” de mesa.

Life would be much easier if an expression language could be used, which would directly support queries of such kind. La vida sería mucho más fácil si un lenguaje de expresión puede ser utilizada, que se apoyarían directamente las consultas de este tipo. In the XML world, the XPATH syntax has grown popular as a powerful means of querying structured data. En el mundo de XML, la sintaxis XPath ha crecido popular como un poderoso medio de consulta de datos estructurada. In XPATH a query that selects all field names of the “users” table would look something like tables/table[@name=’users’]/fields/name (here we assume that the table’s name is modelled as an attribute). This is not only much simpler than an iteration over all tables, but also much more readable: it is quite obvious, which fields are selected by this query. En XPATH una consulta que selecciona todos los nombres de campo de los “usuarios” tabla sería algo como tables/table[@name=’users’]/fields/name (en este caso suponemos que la tabla es el nombre del se modela como un atributo). Este no sólo es mucho más simple que una iteración sobre todos los cuadros, pero también mucho más legible: es bastante obvio, que los campos son seleccionados por esta consulta.

Given the power of XPATH it is no wonder that we got many user requests to add XPATH support to Commons Configuration. Well, here is it! Dado el poder de XPATH no es de extrañar que tenemos muchas peticiones de usuarios para agregar XPATH apoyo a los Comunes de configuración. Bueno, aquí está!

For enabling XPATH syntax for property keys you need the XPathExpressionEngine class. Para habilitar la sintaxis XPath para las llaves de propiedad se necesita el XPathExpressionEngine clase. This class implements the ExpressionEngine interface and can be plugged into a HierarchicalConfiguration object using the setExpressionEngine() method. Esta clase implementa la ExpressionEngine interfaz y puede ser conectado a un HierarchicalConfiguration objeto utilizando el setExpressionEngine() método. It is also possible to set an instance of this class as the global expression engine, so that all hierarchical configuration objects make use of XPATH syntax. También es posible establecer una instancia de esta clase como el motor de la expresión global, de modo que todos los objetos de configuración jerárquica hacer uso de la sintaxis XPath. The following code fragment shows how XPATH support can be enabled for a configuration object: El fragmento de código siguiente se muestra cómo XPATH apoyo se puede habilitar para un objeto de configuración:

HierarchicalConfiguration config = … HierarchicalConfiguration config = …

config.setExpressionEngine(new XPathExpressionEngine());

// Now Ahora podemos usar XPATH consultas:

List fields = config.getList(“tables/table[1]/fields/name”);

XPATH expressions are not only used for selecting properties (ie for the several getter methods), but also for adding new properties. XPATH expresiones no sólo se utilizan para la selección de propiedades (es decir, para los métodos getter), sino también para añadir nuevas propiedades. For this purpose the keys passed into the addProperty() method must conform to a special syntax. Para ello las claves pasaron a addProperty() método debe ajustarse a una sintaxis especial. They consist of two parts: the first part is an arbitrary XPATH expression that selects the node where the new property is to be added to, the second part defines the new element to be added. Se componen de dos partes: la primera parte es una expresión XPath que selecciona arbitrariamente el nodo en la nueva propiedad es que se añade a la segunda parte se define el nuevo elemento que se añade. Both parts are separated by whitespace. Ambas partes están separadas por espacios en blanco.

Okay, let’s make an example. Bueno, vamos a dar un ejemplo. Say, we want to add a type property under the first table (as a sibling to the name element). Oye, vamos a agregar un type de propiedad en virtud de la primera tabla (como un hermano al name del elemento). Then the first part of our key will have to select the first table element, the second part will simply be type , ie the name of the new property: A continuación la primera parte de nuestra llave tendrá que seleccionar el elemento de la tabla primera, la segunda parte será simplemente type , es decir, el nombre de la nueva propiedad:

config.addProperty(“tables/table[1] type”, “system”); config.addProperty(“tables/table[1] type”, “system”);

(Note that indices in XPATH are 1-based, while in the default expression language they are 0-based.) In this example the part tables/table[1] selects the target element of the add operation. (Tenga en cuenta que los índices en XPATH son 1-base, mientras que en el lenguaje de expresiones por defecto son 0-base.) En este ejemplo la parte tables/table[1] selecciona el elemento objetivo de la operación de adición. This element must exist and must be unique, otherwise an exception will be thrown. type is the name of the new element that will be added. Este elemento debe existir y debe ser único, de lo contrario una excepción será lanzada. type es el nombre del nuevo elemento que se añadirá. If instead of a normal element an attribute should be added, the example becomes Si en lugar de un elemento normal debería ser un atributo añadido, se convierte en el ejemplo

config.addProperty(“tables/table[1] @type”, “system”); config.addProperty(“tables/table[1] @type”, “system”);

It is possible to add complete paths at once. Es posible añadir rutas completas a la vez. Then the single elements in the new path are separated by “/” characters. Entonces, los elementos individuales en el nuevo camino están separadas por caracteres “/”. The following example shows how data about a new table can be added to the configuration. El siguiente ejemplo muestra cómo los datos acerca de una nueva tabla se puede añadir a la configuración. Here we use full paths: Aquí se utiliza rutas completas:

// Agregar nueva tabla “tareas” con elemento de nombre y tipo de atributo config.addProperty(“tables table/name”, “tasks”);

// last()selecciona el último elemento de este nombre,

// Que es la nueva tabla del elemento

config.addProperty(“tables/table[last()] @type”, “system”);

// Ahora agregar campos

config.addProperty(“tables/table[last()] fields/field/name”, “taskid”);

config.addProperty(“tables/table[last()]/fields/field[last()] type”, “int”);

config.addProperty(“tables/table[last()]/fields field/name”, “name”);

config.addProperty(“tables/table[last()]/fields field/name”, “startDate”);

// Add new table “tasks” with name element and type attribute

The first line of this example adds the path table/name to the tables element, ie a new table element will be created and added as last child to the tables element. La primera línea de este ejemplo se agrega la ruta de table/name de la tables elemento, es decir, una nueva table elemento se creará y añadirá como último hijo a los tables elemento. Then a new name element is added as child to the new table element. A continuación, un nuevo name se añade como elemento de niño a la nueva table elemento. To this element the value “tasks” is assigned. Para este elemento el valor “tareas” se le asigna. The next line adds a type attribute to the new table element. La siguiente línea añade un type atributo para el elemento de la nueva tabla. To obtain the correct table element, to which the attribute must be added, the XPATH function last() is used; this function selects the last element with a given name, which in this case is the new table element. The following lines all use the same approach to construct a new element hierarchy: At first complete new branches are added ( fields/field/name ), then to the newly created elements further children are added. Para obtener la correcta table elemento, para que el atributo debe añadir, el XPATH función last() se utiliza, esta función se selecciona el último elemento con un nombre determinado, que en este caso es la nueva table de elementos. Las siguientes líneas todo uso el mismo enfoque para construir una jerarquía nuevo elemento: Al principio, las nuevas oficinas se suman completa ( fields/field/name ), luego a los elementos recién creados niños mayores de esa incorporación.

Note: XPATH support is implemented through Commons JXPath . So when making use of this feature, be sure you include the commons-jxpath jar in your classpath. Nota: el soporte XPath se implementa a través JXPath Commons . Así que al hacer uso de esta función, asegúrese de incluir el jar-jxpath comunes en su ruta de clases.

In this tutorial we don’t want to describe XPATH syntax and expressions in detail. En este tutorial no queremos para describir la sintaxis de XPath y expresiones en detalle. Please refer to corresponding documentation. It is important to mention that by embedding Commons JXPath the full extent of the XPATH 1.0 standard can be used for constructing property keys. Por favor, consulte la documentación correspondiente. Es importante mencionar que mediante la incorporación de los Comunes JXPath toda la extensión de la XPATH puede ser 1,0 estándar utilizado para la construcción de las claves de propiedad.

Validation of XML configuration files Validación de la configuración de archivos XML

XML parsers provide support for validation of XML documents to ensure that they conform to a certain DTD. analizadores XML proporcionar apoyo para la validación de documentos XML para asegurar que se ajusten a una DTD determinada. This feature can be useful for configuration files, too. XMLConfiguration allows to enable validation for the files to load. Esta característica puede ser útil para los archivos de configuración, también. XMLConfiguration permite habilitar la validación de los archivos a cargar.

The easiest way to turn on validation is to simply set the validating property to true as shown in the following example: La forma más fácil de convertir en la validación es establecer simplemente la validating la propiedad en true como se muestra en el ejemplo siguiente:

XMLConfiguration config = new XMLConfiguration(); XMLConfiguration config = new XMLConfiguration();

config.setFileName(“myconfig.xml”);

config.setValidating(true);

// Esto lanzará un ConfigurationException si el documento XML no

// conform to its DTD. // Se ajustan a su DTD.

config.load();

Setting the validating flag to true will cause XMLConfiguration to use a validating XML parser. Ajuste de la validating bandera en true hará que XMLConfiguration utilizar un analizador de validación XML. At this parser a custom ErrorHandler will be registered, which throws exceptions on simple and fatal parsing errors. En este analizador una costumbre ErrorHandler serán registrados, lo que arroja excepciones en fatales errores de análisis y simple.

There is also some support for dealing with DTD files. También hay algo de apoyo para tratar con los archivos DTD. Often the DTD of an XML document is stored locally so that it can be quickly accessed. A menudo, el DTD de un documento XML se almacena localmente para que pueda acceder rápidamente. However the DOCTYPE declaration of the document points to a location on the web as in the following example: Sin embargo, el DOCTYPE declaración de los puntos de documento en una ubicación en la web como en el ejemplo siguiente:

<?xml version=”1.0″ encoding=”ISO-8859-1″?> <?xml version=”1.0″ encoding=”ISO-8859-1″?>

<!DOCTYPE web-app

PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN”

http://java.sun.com/j2ee/dtds/web-app_2.2.dtd”&gt;

When working with XML documents directly you would use an EntityResolver in such a case. Al trabajar con documentos XML directamente debería utilizar un EntityResolver en tal caso. The task of such an entity resolver is to point the XML parser to the location of the file referred to by the declaration. La tarea de dicha resolución de la entidad es de señalar con el analizador de XML en la ubicación del archivo a que se refiere la declaración. So in our example the entity resolver would load the DTD file from a local cache instead of retrieving it from the internet. Así que en nuestro ejemplo, la resolución de la entidad que cargar el archivo DTD de una caché local en lugar de recuperarla del Internet.

XMLConfiguration provides a simple default implementation of an EntityResolver . XMLConfiguration proporciona una implementación simple de un defecto EntityResolver . This implementation is initialized by calling the registerEntityId() method with the public IDs of the entities to be retrieved and their corresponding local URLs. Esta aplicación se inicializa llamando a la registerEntityId() método con los identificadores de las entidades públicas para ser recuperados y sus URLs locales correspondientes. This method has to be called before the configuration is loaded. Este método tiene que ser llamada antes de la configuración se ha cargado. To continue our example, consider that the DTD file for our example document is stored on the class path. Para continuar con nuestro ejemplo, considere la posibilidad de que el archivo DTD para nuestro documento de ejemplo se almacena en la ruta de clase. We can register it at XMLConfiguration using the following code: Podemos registrar en XMLConfiguration usando el siguiente código:

XMLConfiguration config = new XMLConfiguration(); XMLConfiguration config = new XMLConfiguration();

// Carga la dirección URL del archivo DTD de ruta de clases

URL dtdURL = getClass().getResource(“web-app_2.2.dtd”);

// Que registrarse en la configuración

config.registerEntityId(“-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN”,

dtdURL);

config.setValidating(true); // enable validation

config.setFileName(“web.xml”);

config.load();

This basically tells the XML configuration to use the specified URL when it encounters the given public ID.

Esto básicamente le dice a la configuración de XML para utilizar la dirección URL especificada cuando encuentra el id público. Note that the call to registerEntityId() has to be performed before the configuration is loaded. Tenga en cuenta que la llamada a registerEntityId() tiene que ser realizado antes de la configuración se ha cargado. So you cannot use one of the constructors that directly load the configuration. Así que no puedes utilizar uno de los constructores que cargar directamente la configuración.

While using the validating flag is a simple means of enabling validation it cannot fullfil more complex requirements, eg schema validation. Si bien la utilización de la validating bandera es un procedimiento sencillo que permite la validación de que no pueden llenar los requisitos más complejos, por ejemplo, la validación del esquema. To be able to deal with such requirements XMLConfiguration provides a generic way of setting up the XML parser to use: A preconfigured DocumentBuilder object can be passed to the setDocumentBuilder() method. Para poder hacer frente a estas exigencias XMLConfiguration proporciona una manera genérica de crear el analizador XML de uso: Una preconfigurado DocumentBuilder objeto puede ser pasado a la setDocumentBuilder() método.

So an application can create a DocumentBuilder object and initialize it according to its special needs. Así que una aplicación puede crear un DocumentBuilder objeto y lo inicializa de acuerdo con sus necesidades especiales. Then this object must be passed to the XMLConfiguration instance before invocation of the load() method. A continuación, este objeto se debe pasar a la XMLConfiguration instancia antes de la invocación de la load() método. When loading a configuration file, the passed in DocumentBuilder will be used instead of the default one. Note: If a custom DocumentBuilder is used, the default implementation of the EntityResolver interface is disabled. Al cargar un archivo de configuración, la aprobada en DocumentBuilder se utilizará en lugar del default. Nota: Si una costumbre DocumentBuilder se utiliza la implementación predeterminada de la EntityResolver interfaz está desactivado. This means that the registerEntityId() method has no effect in this mode. Esto significa que el registerEntityId() método no tiene efecto en este modo.

Compuesto Detalles de la configuración

There are many use cases when you want to collect the properties of several configuration sources and access them like a single configuration object. Hay muchos casos el uso cuando se desea recopilar las propiedades de configuración de fuentes diversas y acceder a ellos como un objeto de configuración. One way to do that is using the CompositeConfiguration class. Una forma de hacerlo es utilizando el CompositeConfiguration clase.

A CompositeConfiguration object contains a list of other configuration objects. Un CompositeConfiguration objeto contiene una lista de objetos de configuración. When properties are accessed from a composite configuration the object takes the passed in property key and iterates over the list of the contained configurations. Cuando se accede a las propiedades de una configuración compuesta, el objeto toma el pasado en los principales bienes y itera sobre la lista de las configuraciones de contenido. As soon as a value is found for the key it is returned. Tan pronto como un valor se encuentra la clave para su restitución. This means that a CompositeConfiguration implements a kind of override semantics, ie the properties of configurations that were added first hide the property values of configurations added later. Esto significa que un CompositeConfiguration implementa un tipo de semántica aumento al presupuesto, es decir, las propiedades de las configuraciones que se agregaron primera ocultar el valor de las propiedades de configuraciones añadió más tarde.

We will discuss how you can establish a “default” choice for your Composite Configuration as well as save changes made to your Composite Configuration. Vamos a discutir cómo se puede establecer un “incumplimiento” por la elección de su compuesto de configuración, así como guardar los cambios realizados en su compuesto de configuración.

Setting Up Defaults Configuración de valores predeterminados

Defaults are very simple. Los valores predeterminados son muy simples. You can just add them as your last configuration object, either through the ConfigurationFactory or manually: Sólo puede añadirlos como su objeto de configuración anterior, ya sea a través de la ConfigurationFactory o de forma manual:

Configuration defaults = new PropertiesConfiguration(fileToDefaults); Configuration defaults = new PropertiesConfiguration(fileToDefaults);

Configuration otherProperties = new PropertiesConfiguration(fileToOtherProperties);

CompositeConfiguration cc = new CompositeConfiguration();

cc.addConfiguration(otherProperties);

cc.addDefaults(fileToDefaults);

Saving Changes Guardar los cambios

If you have a non static Configuration where you want to save changes made to a configuration, and you are using a CompositeConfiguration, then you will need to pass into the constructor of the CompositeConfiguration what Configuration to save the changes via. Si usted tiene una configuración estática donde no desea guardar los cambios realizados en una configuración, y si está utilizando un CompositeConfiguration, entonces usted tendrá que pasar al constructor de la CompositeConfiguration lo Configuración para guardar los cambios a través de.

PropertiesConfiguration saveConfiguration = new PropertiesConfiguration(fileToSaveChangesIn); PropertiesConfiguration saveConfiguration = new PropertiesConfiguration(fileToSaveChangesIn);

Configuration cc = new CompositeConfiguration(saveConfiguration);

cc.setProperty(“newProperty”,”new value”);

saveConfiguration.save();

Alternatively, you can just request the inMemoryConfiguration that stores the changes: Alternativamente, usted puede solicitar la inMemoryConfiguration que almacena los cambios:

Configuration changes = myCompositeConfiguration.getInMemoryConfiguration(); Configuration changes = myCompositeConfiguration.getInMemoryConfiguration();

DatabaseConfiguration config = new DatabaseConfiguration(datasource, “configuration”, “key”, “value”);

for (Iterator i = changes.getKeys().iterator();i.hasNext()){

    String key = (key)i.next();

    Object value = changes.get(key);

    config.setProperty(key,value);

}

Combinada de configuración

The CombinedConfiguration class provides an alternative for handling multiple configuration sources. El CombinedConfiguration clase proporciona una alternativa para el manejo de configuración de múltiples fuentes. Its API is very similar to the CompositeConfiguration class, which was discussed in the last section . Su API es muy similar a la CompositeConfiguration clase, que se debatió en la última sección . There are the following differences however: Existen las siguientes diferencias sin embargo:

  • A CombinedConfiguration is a truely hierarchical configuration . Un CombinedConfiguration es una verdadera configuración jerárquica . This means that all the enhanced facilities provided by HierarchicalConfiguration (eg expression engines) can be used. Esto significa que todas las instalaciones reforzadas previstas por HierarchicalConfiguration (expresión de los motores, por ejemplo) pueden ser utilizados.
  • A CombinedConfiguration is not limited to implementing an override semantics for the properties of the contained configurations. Instead it has the concept of so-called node combiners , which know how properties of multiple configuration sources can be combined. Node combiners are discussed later in detail. Un CombinedConfiguration no se limita a la aplicación de una semántica de aumento al presupuesto para las propiedades de las configuraciones de contenido. En su lugar, tiene el concepto de nodo llamado combinadores, de modo que sabemos cómo las propiedades de configuración de fuentes múltiples se pueden combinar. combinadores Nodo se discuten más adelante en detalle. For instance, there is a node combiner implementation available that constructs a union of the contained configurations. Por ejemplo, hay una aplicación combinador nodo disponible que construye una unión de las configuraciones de contenido.
  • Contained configurations can be assigned a name. Incluida configuraciones se pueden asignar un nombre. They can later be accessed by their name. Más tarde se puede acceder por su nombre.
  • Each contained configuration can have an optional prefix. La configuración de cada figura puede tener un prefijo opcional. Its properties are then added under this prefix to the combined configuration. Sus propiedades se han añadido posteriormente en virtud de este prefijo en la configuración combinada.
  • There is no concept of an in memory configuration . No existe el concepto de una configuración en la memoria. Changes to a combined configuration are handled in a different way. Los cambios en una configuración combinada se manejan de una manera diferente.

How it works ¿Cómo funciona?

A CombinedConfiguration provides a logic view on the properties of the configurations it contains. Un CombinedConfiguration proporciona una vista lógica de las propiedades de las configuraciones que contiene. This view is determined by the associated node combiner object. Esta visión está determinada por el objeto de nodo combinador asociados. Because of that it must be re-constructed whenever one of these contained configurations is changed. Debido a que debe ser reconstruido cuando una de estas configuraciones figura cambia.

To achieve this, a CombinedConfiguration object registers itself as an event listener at the configurations that are added to it. It will then be notified for every modification that occurs. Para lograr esto, una CombinedConfiguration objeto se registra como un detector de eventos en las configuraciones que se agregan a él. A continuación, se le notificará por cada modificación que se produce. If such a notification is received, the internally managed view is invalidated. When a property of the combined configuration is to be accessed, the view is checked whether it is valid. Si tal notificación haya sido recibida, la vista gestionado internamente se invalida. Cuando una característica de la configuración combinada es que se acceda, la vista se comprueba si es válido. If this is the case, the property’s value can be directly fetched. Si este es el caso, el valor de la propiedad puede ser directamente a buscar. Otherwise the associated node combiner is asked to re-construct the view. De lo contrario el combinador nodo asociado se le pide que vuelva a construir la vista.

Node combiners Nodo combinadores

A node combiner is an object of a class that inherits from the abstract NodeCombiner class. Un combinador de nodo es un objeto de una clase que hereda de lo abstracto NodeCombiner clase. This class defines an abstract combine() method, which takes the root nodes of two hierarchical configurations and returns the root node of the combined node structure. Esta clase define un resumen combine() método, que toma los nodos raíz de dos configuraciones jerárquicas y devuelve el nodo raíz de la estructura nodo combinado. It is up to a concrete implementation how this combined structure will look like. Corresponde a una aplicación concreta cómo esta estructura combinada se verá así. Commons Configuration ships with the two concrete implementations OverrideCombiner and UnionCombiner , which implement an override and a union semantics respective. Commons buques de configuración con las dos implementaciones concretas OverrideCombiner y UnionCombiner , que implementan un reemplazo y una semántica respectivo sindicato.

Constructing a combination of multiple node hierarchies is not a trivial task. La construcción de una combinación de varios nodos de las jerarquías no es una tarea trivial. The available implementations descend the passed in node hierarchies in a recursive manner to decide, which nodes have to be copied into the resulting structure. Las implementaciones disponibles descender el pasado en las jerarquías de nodos de forma recursiva para decidir, que los nodos tienen que copiar en la estructura resultante. Under certain circumstances two nodes of the source structures can be combined into a single result node, but unfortunately this process cannot be fully automated, but sometimes needs some hints from the developer. En determinadas circunstancias, dos nodos de la fuente de las estructuras se pueden combinar en un nodo único resultado, pero lamentablemente este proceso no puede ser totalmente automatizado, pero a veces necesita un poco de sugerencias del programador. As an example consider the following XML configuration sources: Como ejemplo, consideremos el siguiente código fuente XML de configuración:

<configuration> <configuration>

<database>

<tables>

<table>

<name>users</name>

<fields>

<field>

<name>user_id</name>

</field>


</fields>

</table>

</tables>

</database>

</configuration>

and y

<configuration> <configuration>

<database>

<tables>

<table>

<name>documents</name>

<fields>

<field>

<name>document_id</name>

</field>


</fields>

</table>

</tables>

</database>

</configuration>

These two configuration sources define database tables. Estas dos fuentes de configuración de definir tablas de bases de datos. Each source defines one table. Cada fuente se define una tabla. When constructing a union for these sources the result should look as follows: Al construir una unión de estas fuentes, el resultado debería parecerse a lo siguiente:

<configuration>

<database>

<tables>

<table>

<name>users</name>

<fields>

<field>

<name>user_id</name>

</field>

</fields>

</table>

<table>

<name>documents</name>

<fields>

<field>

<name>document_id</name>

</field>


</fields>

</table>

</tables>

</database>

</configuration>

As you can see, the resulting structure contains two table nodes while the nodes database and tables appear only once. Como puede ver, la estructura resultante contiene dos table , mientras que los nodos de los nodos de database y tables aparecen sólo una vez. For a human being this is quite logic because database and tables define the overall structure of the configuration data, and there can be multiple tables. Para un ser humano que es bastante lógica, porque database y tables definir la estructura general de los datos de configuración, y no puede haber varias tablas. A node combiner however does not know anything about structure nodes, list nodes, or whatever. Un combinador de nodo sin embargo, no sabe nada de nudos de la estructura, los nodos de la lista, o lo que sea. From its point of view there is no detectable difference between the tables nodes and the table nodes in the source structures: both appear once in each source file and have no values. Desde su punto de vista no hay diferencia perceptible entre las tables nodos y la table nodos en las estructuras de la fuente: ambos aparecen una vez en cada archivo de origen y no tienen valores. So without any assistance the result constructed by the UnionCombiner when applied on the two example sources would be a bit different: Así que sin ninguna ayuda el resultado construido por el UnionCombiner cuando se aplica sobre las dos fuentes de ejemplo podría ser un poco diferente:

<configuration> <configuration>

<database>

<tables>

<table>

<name>users</name>

<fields>

<field>

<name>user_id</name>

</field>


</fields>

<name>documents</name>

<fields>

<field>

<name>document_id</name>

</field>


</fields>

</table>

</tables>

</database>

</configuration>

Note that the table node would be considered a structure node, too, and would not be duplicated. Tenga en cuenta que la table nodos sería considerado un nodo de la estructura, también, y no ser duplicada. This is probably not what was desired. Esto probablemente no es lo deseado. To deal with such situations it is possible to tell the node combiner that certain nodes are list nodes and thus should not be combined. Para hacer frente a tales situaciones, es posible saber el combinador nodo que ciertos nodos son nodos de lista y por lo tanto no debe combinarse. So in this concrete example the table node should be declared as a list node, then we would get the expected result. Así que en este ejemplo concreto de la table nodo debe ser declarado como un nodo de la lista, entonces obtendríamos el resultado esperado. We will see below how this is done. Más adelante veremos cómo se hace esto. Note that this explicit declaration of a list node is necessary only in situations where there is ambiguity. Tenga en cuenta que esta declaración explícita de un nodo de la lista es necesaria sólo en situaciones donde hay ambigüedad. If in one of our example configuration sources multiple tables had been defined, the node combiner would have concluded itself that table is a list node and would have acted correspondigly. Si en una de varias fuentes de ejemplo de configuración de nuestras mesas se había definido, el combinador de nodo se habría concluido que table es un nodo de la lista y que han actuado correspondigly.

Constructing a CombinedConfiguration La construcción de un CombinedConfiguration

To create a CombinedConfiguration object you specify the node combiner to use and then add an arbitrary number of configurations. Para crear un CombinedConfiguration objeto de especificar el combinador de nodo a utilizar ya continuación, agregue un número arbitrario de configuraciones. We will show how to construct a union configuration from the two example sources introduced earlier: Vamos a mostrar cómo construir una configuración de la unión de las dos fuentes ejemplo presentado anteriormente:

// Carga la fuente de configuraciones

XMLConfiguration conf1 = new XMLConfiguration(“table1.xml”);

XMLConfiguration conf2 = new XMLConfiguration(“table2.xml”);

// Crear e inicializar el nodo combinador

NodeCombiner combiner = new UnionCombiner();

combiner.addListNode(“table”); // table marca como lista de nodos

// Esto es necesario sólo si hay ambigüedades

// Construir la configuración combinada

CombinedConfiguration cc = new CombinedConfiguration(combiner);

cc.addConfiguration(conf1, “tab1”);

cc.addConfiguration(conf2);

// Load the source configurations// Create and initialize the node combinerHere we also specified a name for one of the configurations, so it can later be accessed by cc.getConfiguration(“tab1”); .

Aquí también se especifica un nombre para una de las configuraciones, por lo que más tarde se puede acceder por cc.getConfiguration(“tab1”); . Access by index is also supported. El acceso por el índice también se apoya. After that the properties in the combined configuration can be accessed as if it were a normal hierarchical configuration Después de que las propiedades en la configuración combinada se puede acceder como si se tratara de una configuración jerárquica normal

Dealing with changes Lidiando con los cambios

There is nothing that prevents you from updating a combined configuration, eg by calling methods like addProperty() or removeProperty() . No hay nada que no le permite actualizar una configuración combinada, por ejemplo, llamando a métodos como addProperty() o removeProperty() . The problem is that depending on the used node combiner it might no be clear, which of the contained configurations will be modified or whether one is modified at all. El problema es que, dependiendo del combinador de nodo no lo utilizó bastante claro, ¿cuál de las configuraciones de contenido será modificado o si se está modificado en absoluto.

Typical node combiners work by copying parts of the node structures of the source configurations into the target structure and linking them togehter using special link nodes. combinadores nodo típico trabajo de copiar partes de las estructuras nodo de la fuente de configuraciones en la estructura de la meta juntos, y vincularlos con enlace nodos especiales. So updates of the combined node structure will either effect nodes from one of the contained configuration (then the changes are directly visible in this configuration) or one of the link nodes (then they cannot really be saved). Así que las actualizaciones de la estructura de nodos ya sea combinado afectará nodos de una figura de la configuración (en ese entonces los cambios son visibles directamente en esta configuración) o uno de los nodos de enlace (en ese entonces que en realidad no puede ser salvado).

It is also possible that a change is done at the combined node structure, which is not compatible with the current node combiner. También es posible que un cambio se realiza en el nodo de la estructura combinada, que no es compatible con el combinador de nodo actual. Imagine that an OverrideCombiner is used and that a property should be removed. Imagine que un OverrideCombiner se utiliza y que una propiedad debe ser eliminado. This property will then be removed from one of the contained configurations. Esta propiedad se extraerá después de una de las configuraciones de contenido. Now it may happen that this removed property had hidden property values of other contained configurations. Their values won’t become visible automatically, but only after the combined view was re-constructed. Ahora bien, puede ocurrir que este había escondido los bienes incautados valores de propiedad de otras formaciones del contenido. Sus valores no serán visibles de forma automática, pero sólo después de la vista combinada fue re-construida.

Because of that it is recommended that changes are not done at the combined configuration, but only at contained configurations. Por eso se recomienda que los cambios no se hacen en la configuración del combinado, pero sólo a configuraciones de contenido. This way the correct configuration to be updated can unambigously be identified. Obtaining the configuration to be updated from the combined configuration is easy when it was given a name. De esta manera la configuración correcta para ser actualizado sin ambigüedad, puede ser identificado. La obtención de la configuración que se actualizará de la configuración del combinado es fácil cuando se le dio un nombre.

Declarar y Creación de Beanes

Often it is good practice to make heavy use of Java interfaces and program an application or components against these interfaces rather than concrete implementation classes. A menudo es una buena práctica para hacer un uso intensivo de las interfaces de programa de Java y una aplicación o de componentes contra estas interfaces en lugar de clases concretas de aplicación. This makes it possible to switch to different implementations without having to modify calling code. Esto hace que sea posible cambiar a las distintas aplicaciones sin tener que modificar código de llamadas. However the problem remains how a concrete implementation of an interface is obtained. Sin embargo el problema sigue siendo cómo una aplicación concreta de una interfaz se obtiene. Simply using the new operator on a specific implementation class would somehow break the interface concept because then the code would have an explicit reference to a concrete implementation. Simplemente utilizando el nuevo operador en una clase de implementación específica de alguna manera se rompería el concepto de interfaz porque entonces el código tendría una referencia explícita a una aplicación concreta.

A solution to this problem is to define the concrete implementation class that should be used in a configuration file. Una solución a este problema es definir la clase de implementación concreta que se debe utilizar en un archivo de configuración. Client code would obtain an object (or a bean) from the configuration and cast it to the service interface. El código cliente obtendría un objeto (o un grano) de la configuración y lo echó a la interfaz de servicio. This way the caller would have no knowledge about which concrete implementation is used; it would only interact with the service through the interface. De esta manera la persona que llama no tendría ningún conocimiento sobre lo que utiliza es la aplicación concreta, sino que sólo interactúan con el servicio a través de la interfaz. By changing the configuration file and entering a different class name for the implementation class the behavior of the application can be altered, eg to inject a test stub for the used service. Al cambiar el archivo de configuración e introduzca un nombre de clase diferente para la clase de implementación del comportamiento de la demanda puede ser alterado, por ejemplo, para inyectar un trozo de prueba para el servicio utilizado.

Note: The concept of defining service objects in configuration files and let them be created by a special container has grown popular these days.
Nota: El concepto de la definición de los objetos de servicio en los archivos de configuración y dejar que sean creadas por un recipiente especial ha crecido muy popular en estos días.
Especially IoC containers like
HiveMind or Spring offer wide functionality related to this topic.
Especialmente contenedores IoC como
HiveMind o primavera ofrecen una funcionalidad amplia acerca de este tema.
Commons Configuration is not and has no ambitions to become an IoC container.
Configuración de los Comunes no está y no tiene ambiciones de convertirse en un contenedor de IoC.
The provided functionality for declaring and creating beans is very basic and limited compared to the specialists.
La funcionalidad proporcionada por la que se declara la creación y el bean es muy básico y limitado en comparación con los especialistas.
So if you are in need of enhanced features like the creation of complete networks of service objects, life cycle handling and such things, you should in any case use a real IoC container.
Así que si usted está en necesidad de características mejoradas, como la creación de redes completas de objetos de servicio, manejo de ciclo de vida y esas cosas, debería en cualquier caso de uso real de un contenedor de IoC.
For simple use cases however the functionality of Commons Configuration might be sufficient, and we have tried to provide hooks for extending the predefined mechanisms.
Para los casos de uso simple sin embargo la funcionalidad de los Comunes de configuración puede ser suficiente, y hemos tratado de proveer los ganchos para ampliar los mecanismos predefinidos.

Basic Concepts Conceptos básicos

Beans (we use the term bean here to name any plain old Java object that is defined in a configuration file and can be instantiated by Commons Configuration) are defined in configuration files in a specific format, a so called Bean declaration . Beanes (usamos el término aquí bean a nombre de cualquier edad Java objeto plano que se define en un archivo de configuración y se pueden crear instancias de los Comunes de configuración) se definen en los archivos de configuración en un formato específico, la denominada declaración de Bean. Such a declaration contains all information needed to create an instance of this bean class, eg the full qualified name of the class and initialization parameters. Dicha declaración contiene toda la información necesaria para crear una instancia de esta clase de bean, por ejemplo, el nombre completo calificado de la clase y los parámetros de inicialización. We will explain how a bean declaration looks like in short. Vamos a explicar cómo una declaración de bean se parece en suma.

On the Java side three entities are involved in the creation of a bean: Por el lado de Java tres entidades participan en la creación de un grano:

  • A bean factory : This is an object that implements the BeanFactory interface and knows how to create an instance of a bean class. Una fábrica de bean: Este es un objeto que implementa la BeanFactory interfaz y sabe cómo crear una instancia de una clase de bean. In most cases calling code does not directly deal with a bean factory. En la mayoría de los casos llamar a código no se ocupan directamente de una fábrica de bean.
  • An implementation of the BeanDeclaration interface. Una aplicación de la BeanDeclaration interfaz. This object knows how the bean declaration in the configuration file is organized and how the needed information can be extracted. Este objeto sabe la declaración de bean en el archivo de configuración está organizada y cómo la información necesaria se puede extraer. So the way the bean is declared in the configuration file must match the expectations of this object. Así que la forma en que se declaró el bean en el archivo de configuración debe coincidir con las expectativas de este objeto.
  • The utility class BeanHelper brings all these together and performs the bean creation operation. Usually client code will create a BeanDeclaration object from a Configuration implementation and then pass it to one of the createBean() methods of BeanHelper . That’s it! La clase de utilidad BeanHelper trae todos estos juntos y realiza la operación de creación de bean. Por lo general, el código de cliente creará un BeanDeclaration objeto a partir de una Configuration aplicación y después pasarlo a una de las createBean() los métodos de BeanHelper . Eso es todo!

For all of the interfaces mentioned above default implementations are provided, which in many cases can be used out of the box. Para todas las interfaces mencionadas anteriormente se proporcionan implementaciones predeterminadas, que en muchos casos se puede utilizar fuera de la caja.

An Example Un ejemplo

After this theory let’s get into practice using an example. Después de esto vamos a la teoría a la práctica con un ejemplo. Consider a GUI application that makes use of a Window manager to display its windows and dialogs to the user. Considere la posibilidad de una aplicación con interfaz gráfica que hace uso de un gestor de ventanas para mostrar sus ventanas y cuadros de diálogo al usuario. There is a WindowManager interface containing methods for opening, displaying, hiding, and disposing windows. Hay un WindowManager interfaz que contiene métodos para abrir, visualizar, ocultar y eliminar ventanas. Different implementations of this interface exist, eg providing different look & feel or special functionality. Existen implementaciones de esta interfaz existe, por ejemplo, proporcionando un aspecto diferente y se siente o funcionalidad especial. The concrete set of methods of the interface does not matter for this example. El hormigón conjunto de métodos de la interfaz no es importante para este ejemplo.

Now in the application’s configuration it shall be specified that the concrete implementation DefaultWindowManager should be used as WindowManager . Ahora bien, en aplicación de configuración de la que se especifica que la aplicación concreta DefaultWindowManager debe ser utilizado como WindowManager . This is a plain Java class implementing the WindowManager interface. Esta es una clase Java normal ejecución del WindowManager de la interfaz. Some fragments are shown in the following listing: Algunos fragmentos se muestran en el siguiente listado:

package examples.windows; package examples.windows;

public class DefaultWindowManager implements WindowManager

{

// Son las ventanas permite cambiar el tamaño?

private boolean resizable;

// Hacer las ventanas tienen un botón de cierre?

private boolean closable;

// Por defecto tamaño de las ventanas nuevas

private int defaultWidth;

private int defaultHeight;

WindowStyleDefinition styleDefinition;

// Getters y setters omite, también los métodos gestor de ventanas

}

As you can see, the DefaultWindowManager class has some simple properties for defining the windows.

Como puede ver, el DefaultWindowManager clase tiene algunas propiedades simples para definir las ventanas. There is also a property named StyleDefinition whose type is another bean (such a style definition may contain information about themes, colors, fonts of the window and so on). Hay también una propiedad denominada StyleDefinition cuyo tipo es otra de bean (como una definición de estilo puede contener información sobre los temas, colores, fuentes de la ventana y así sucesivamente). How can we now write a configuration file so that a bean of the DefaultWindowManager class is declared and initialization properties are defined? ¿Cómo podemos escribir un fichero de configuración de modo que una judía del DefaultWindowManager clase se declara y define las propiedades de inicialización son? In an XML configuration file this will look as follows: En un archivo de configuración XML de este se verá como sigue:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<config>

<gui>

<windowManager config-class=”examples.windows.DefaultWindowManager”

closable=”false” resizable=”true” defaultWidth=”400″

defaultHeight=”250″>

<styleDefinition config-class=”examples.windows.WindowStyleDefinition”

backColor=”#ffffff” foreColor=”0080ff” iconName=”myicon” />

</windowManager>

</gui>

</config>

This XML document contains a valid bean declaration starting with the windowManager element and including its sub elements. Este documento XML contiene una declaración válida de bean a partir del windowManager de elementos y sub incluidos sus elementos. Note the following points: Tenga en cuenta los siguientes puntos:

  • The (full qualified) class of the bean is specified using the config-class attribute. El (completa cualificada) de clase del bean se especifica mediante la config-class de atributo. (Attributes starting with the prefix “config-” are reserved; they contain special meta data for the bean creation process.) (Atributos de partida con el prefijo “config-” están reservados, que no contiene metadatos de datos especial para el proceso de creación de bean).
  • Other attributes of the windowManager element correspond to properties of the DefaultWindowManager class. Otros atributos del windowManager elemento corresponden a las propiedades de la DefaultWindowManager clase. These properties will be initialized with the values specified here. Estas propiedades se inicializa con los valores especificados aquí.
  • For the styleDefinition property, which is itself a bean, a sub element (matching the property’s name) exists. Para el styleDefinition propiedad, que es en sí misma una de bean, un elemento secundario (que se corresponda la propiedad es el nombre del) existe. The structure of this element is analogous to the structure of the windowManager element; indeed it could even have further sub elements defining bean properties of the WindowStyleDefinition class. La estructura de este elemento es análogo a la estructura del windowManager elemento y, de hecho incluso podría tener elementos sub definir con más precisión las propiedades de bean de la WindowStyleDefinition clase.

The basic structure of a bean declaration should have become clear by this example. La estructura básica de una declaración de bean debería haber quedado claro en este ejemplo.

Now let’s see how we can access this declaration and create an instance. This is demonstrated in the code fragment below: Ahora vamos a ver cómo podemos acceder a esta declaración y crear una instancia. Esto se demuestra en el fragmento de código a continuación:

XMLConfiguration config = new XMLConfiguration(“windowconfig.xml”); XMLConfiguration config = new XMLConfiguration(“windowconfig.xml”);

BeanDeclaration decl = new XMLBeanDeclaration(config, “gui.windowManager”);

WindowManager wm = (WindowManager) BeanHelper.createBean(decl);

This fragment loads the configuration file using a XMLConfiguration object. Esto carga una fragmentación del archivo de configuración mediante una XMLConfiguration objeto. Then a bean declaration object is created, in this case an instance of the XMLBeanDeclaration class, which can deal with bean declarations in XML documents. A continuación, un objeto de una declaración de bean se crea, en este caso una instancia de la XMLBeanDeclaration clase, lo que puede hacer frente a las declaraciones de bean en los documentos XML. This declaration is passed to the static createBean() method of the BeanHelper class, which returns the new bean instance. Esta declaración se pasa a la estática createBean() método de la BeanHelper clase, que devuelve la instancia de bean nuevo.

BeanHelper defines some overloaded versions of the createBean() method. BeanHelper define algunas versiones sobrecargadas de la createBean() método. Some allow to pass in a default bean class; then it is not necessary to define the class in the bean declaration – an instance of this default class will be created if it is lacking in the configuration file. Algunos permiten pasar a una clase de bean por defecto; entonces no es necesario definir la clase en la declaración de bean – una instancia de esta clase por defecto será creado si no existe en el archivo de configuración. If the bean cannot be created for some reason (eg a wrong class name was specified), a ConfigurationRuntimeException will be thrown. Si el grano no se puede crear por alguna razón (por ejemplo, un mal nombre de la clase se ha especificado), un ConfigurationRuntimeException será lanzada.

Extending the Basic Mechanism Ampliar el mecanismo básico

As was pointed out in the introduction of this chapter support for creating beans is focused on the basics. Como se señaló en la introducción de este capítulo de apoyo para la creación de bean se centra en los fundamentos. But there are some possibilities of hooking in and add custom extensions. Pero hay algunas posibilidades de enganchar y añadir extensiones personalizadas. This can be done in the following ways: Esto se puede realizar de las siguientes maneras:

  • By defining a custom BeanDeclaration implementation Al definir una costumbre BeanDeclaration aplicación
  • By providing a custom BeanFactory implementation Al proporcionar una costumbre BeanFactory aplicación

A specialized bean declaration is needed when you have to deal with configuration files that contain bean declarations in a different format than the ones supported by the available default implementations. Una declaración de bean especializados necesarios cuando se tienen que tratar con los archivos de configuración que contienen declaraciones de bean en un formato diferente que las soportadas por las implementaciones predeterminadas disponibles. Then it is the responsibility of your implementation to parse the configuration data and extract the required information to create the bean. Entonces es la responsabilidad de su aplicación para analizar los datos de configuración y extraer la información necesaria para crear el bean. Basically your BeanDeclaration implementation must be able to provide the following data: Básicamente, la caja BeanDeclaration la aplicación debe ser capaz de proporcionar los siguientes datos:

  • The name of the class for which an instance is to be created. El nombre de la clase para la cual es una instancia que se creará.
  • The name of the bean factory that is used to create the bean. El nombre de la fábrica de bean que se utiliza para crear el bean. Here null can be returned, then a default factory is used. Aquí nula puede ser devuelto, a continuación, una por defecto es usada. (See below for more information about working with custom bean factories.) (Véase más abajo para obtener más información acerca de cómo trabajar con las fábricas de bean personalizados.)
  • An optional parameter to be passed to the bean factory. Un parámetro opcional que se pasa a la fábrica de bean. If a factory is used that supports additional parameters, the current parameter values are also obtained from the bean declaration. Si se utiliza una fábrica que admite parámetros adicionales, los valores de los parámetros actuales se obtiene también de la declaración de bean.
  • A map with the properties to be set on the newly created bean. This map’s keys are names of properties, its values are the corresponding property values. Un mapa con las propiedades que se establece en el recién creado de bean. Mapa de teclas Estos son los nombres de las propiedades, sus valores son los valores de la propiedad correspondiente. The default bean factory will process this map and call the corresponding setter methods on the newly created bean object. La fábrica de bean por defecto proceso de este mapa y llamar a los métodos setter correspondiente en el bean objeto de nueva creación.
  • A map with further BeanDeclaration objects for initializing properties of the new bean that are itself beans. Un mapa con más BeanDeclaration objetos para inicializar las propiedades del grano nuevo que se son los beanes. These bean declarations are treated exactly as the one that is currently processed. Estas declaraciones de bean son tratados exactamente como la que se encuentra actualmente procesado. The resulting beans will then be set as properties on the processed bean (the names of these properties are again obtained from the keys of the map). Los granos resultante se configurará como propiedades del bean procesado (los nombres de estas propiedades son de nuevo obtenidos a partir de las claves del mapa).

While creating a custom BeanDeclaration implementation allows you to adapt the format of bean declarations in configuration files, you can manipulate the bean creation mechanism itself by creating a specialized implementation of the BeanFactory interface. Si bien la creación de una costumbre BeanDeclaration aplicación le permite adaptar el formato de las declaraciones de bean en los archivos de configuración, usted puede manipular el mecanismo de creación de bean por sí solo la creación de una aplicación especializada de la BeanFactory interfaz. For this purpose the following steps are necessary: Para ello, los pasos siguientes son necesarios:

  1. Create a class implementing the BeanFactory interface. This interface is quite simple. Crear una clase que implementa el BeanFactory interfaz. Esta interfaz es bastante simple. It defines one method for creating an instance of a class whose Class object is provided, and another method, which is called for querying a default class. Se define un método para crear una instancia de una clase cuya Class de objetos es siempre, y otro método, que se llama para consultar una clase predeterminada.
  2. Register this new factory class at the BeanHelper class. Registro de esta clase en la nueva fábrica BeanHelper clase.
  3. In the bean declaration in your configuration file refer to the factory that should be used for creating the bean. En la declaración de bean en el archivo de configuración se refieren a la fábrica que se debe utilizar para la creación de la haba.

We will provide an example that covers all these steps. Vamos a dar un ejemplo que cubre todos estos pasos. This example deals with a singleton factory, ie an implementation of BeanFactory that returns always the same instance of a provided bean class. En este ejemplo se trata de una fábrica de singleton, es decir, una aplicación de BeanFactory que devuelve siempre la misma instancia de una clase de bean siempre.

We start with the creation of the factory class. Comenzamos con la creación de la clase de fábrica. The basic idea is that the functionality for creating and initializing beans is already provided by the DefaultBeanFactory class, so we extend this class. La idea básica es que la funcionalidad para crear e inicializar los beanes ya estén cubiertos por el DefaultBeanFactory clase, por lo que extendemos esta clase. Our implementation only has to deal with the singleton stuff: We keep a map that stores already created bean instances and can be accessed by the name of their classes. Nuestra implementación sólo tiene que lidiar con las cosas singleton: Mantenemos un mapa que almacena ya ha creado las instancias de bean y se puede acceder por el nombre de sus clases. In the factory’s createBean() method we check if for the passed in class already an instance exists. En la fábrica createBean() método que compruebe si el pasado en la clase ya existe una instancia. If this is the case, it is directly returned. Si este es el caso, vuelva directamente. Otherwise we call the inherited createBean() method and store its result in the map. De lo contrario, llamar a la herencia createBean() método y almacenar su resultado en el mapa. (Note that this implementation is a bit simplicistic; a real world implementation would also have to take the initialization parameters into account. But for the purpose of an example it should be good enough). (Nótese que esta implementación es un poco simplicistic; una aplicación mundo real también tendría que tomar los parámetros de inicialización en cuenta. Sin embargo, con el propósito de un ejemplo que debería ser suficiente). Here is the code: Aquí está el código:

public class SingletonBeanFactory extends DefaultBeanFactory public class SingletonBeanFactory extends DefaultBeanFactory

{

/** Un mapa de las instancias creadas hasta ahora.*/

private Map beans;

public SingletonBeanFactory()

{

super();

beans = new HashMap();

}

// Crea el bean. Checks if already an instance exists.Comprueba si ya existe una instancia.

public synchronized Object createBean(Class beanClass, BeanDeclaration decl,Object param) throws Exception

{

Object bean = beans.get(beanClass.getName());

if (bean != null)

{

// Sí, ya existe una instancia

return bean;

}

else

{

// No, crear ahora (realizada por la superclase)

bean = super.createBean(beanClass, decl, param);

// Que la tienda en el mapa

beans.put(beanClass.getName(), bean);

return bean;

}

}

}

Note the synchronized key word, which is necessary because the method can be accessed by multiple threads concurrently. Nótese la palabra clave sincronizados, lo que es necesario porque el método se puede acceder por varios subprocesos al mismo tiempo. Now we have to register an instance of this class at the BeanHelper class. This can be done in the initialization phase of your application and looks as follows: Ahora tenemos que registrar una instancia de esta clase en el BeanHelper clase. Esto se puede hacer en la fase de inicialización de la aplicación y es el siguiente:

BeanHelper.registerBeanFactory(“SINGLETON”, new SingletonBeanFactory()); BeanHelper.registerBeanFactory(“SINGLETON”, new SingletonBeanFactory());

To make use of the new factory a bean declaration must contain an attribute that refers to the name under which the factory was registered. This is demonstrated by the fragment below:

Para hacer uso de la nueva fábrica de una declaración de bean debe contener un atributo que se refiere al nombre con el que se registró en la fábrica. Así lo demuestra el fragmento a continuación:

<config>


<services>

<fileService config-class=”my.package.services.FileServiceImpl”

config-factory=”SINGLETON”

property1=”value1″ property2=”value2″>

<!– Here can be nested bean declarations –>

</fileService>


</config>

In this fragment the fileService element contains a bean declaration for some service object. En este fragmento del fileService elemento contiene una declaración de bean para un objeto de servicio. Apart from the config-class attribute the important part is the config-factory attribute. This attribute tells the BeanHelper class that it should use a special factory when it processes this bean declaration. Aparte de la config-class atribuyen la parte importante es la config-factory atributo. Este atributo le dice al BeanHelper clase que debería usar una fábrica especial cuando se procesa esta declaración de bean. As was demonstrated by this example, it should not be too difficult to extend the custom mechanism for creating beans. Como se muestra en este ejemplo, no debería ser demasiado difícil extender el mecanismo de encargo para la creación de beans.

Usando una configuración de fábrica

This section explains how a ConfigurationFactory object is setup that provides access to a collection of different configuration sources. En esta sección se explica cómo un ConfigurationFactory objeto de configuración que proporciona acceso a una colección de fuentes de configuración diferente.

Note: In earlier versions of Commons Configuration the ConfigurationFactory class was the only means for combining multiple configuration sources to a single configuration. With the newer DefaultConfigurationBuilder class there is now an alternative available that provides more features. Nota: En versiones anteriores de los Comunes de configuración de la ConfigurationFactory clase era el único medio para conciliar la configuración de múltiples fuentes para una configuración única. Con los nuevos DefaultConfigurationBuilder clase ahora hay una alternativa disponible que proporciona más características. So it is recommended to use DefaultConfigurationBuilder instead of ConfigurationFactory whereever possible. Por lo tanto, se recomienda utilizar DefaultConfigurationBuilder lugar de ConfigurationFactory siempre que sea posible. More details about DefaultConfigurationBuilder can be found here . Más informaciones sobre DefaultConfigurationBuilder se puede encontrar aquí .

The configuration definition file La definición de fichero de configuración

When a single configuration file (eg a properties file) is the only source of configuration data it is very simple to load it using the specific configuration class that deals with the corresponding format (eg PropertiesConfiguration for properties files or XMLConfiguration for XML files). Cuando un archivo de configuración (por ejemplo, un archivo de propiedades) es la única fuente de datos de configuración es muy simple para cargar usando la clase de configuración específica que se ocupa del formato correspondiente (por ejemplo, PropertiesConfiguration para los archivos de propiedades o XMLConfiguration para los archivos XML). But because we think that later other sources will be added (otherwise this example section would be too silly) we will use a ConfigurationFactory object to load it. Pero porque pensamos que más tarde otras fuentes serán añadidas (de lo contrario esta sección de ejemplo sería demasiado tonto) vamos a utilizar una ConfigurationFactory objeciones a la misma carga.

ConfigurationFactory allows to combine multiple configuration sources. ConfigurationFactory permite combinar la configuración de múltiples fuentes. The properties defined in these sources can then be accessed as if they were defined in a single configuration file. Las propiedades definidas en estas fuentes se puede acceder como si se definieron en un único archivo de configuración. To make use of this we have to create a XML file which tells the factory from which sources the properties are to be collected. Para hacer uso de esto tenemos que crear un archivo XML que cuenta la fábrica de la que fuentes de las propiedades se recogen. The following listing shows the content of this file: La siguiente lista muestra el contenido de este archivo:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<configuration>

<properties fileName=”usergui.properties”/>

</configuration>

Definition files for ConfigurationFactory are normal XML files. Definición de archivos ConfigurationFactory son normales archivos XML. The root element must be named configuration . El elemento raíz debe ser nombrado configuration . It can contain different sub elements that specify the configuration sources to load. Puede contener elementos de diferentes sub que especifican las fuentes de configuración para cargar. The properties element is one of these; it is used to include properties files. Las properties los elementos es una de ellas, sino que se utiliza para incluir archivos de propiedades.

For this example we store the definition file for ConfigurationFactory in the same directory as the properties file and call it config.xml . Para este ejemplo se guarda el archivo de definición para ConfigurationFactory en el mismo directorio que el archivo de propiedades y lo llaman config.xml . The properties file used in this example is the same as in the section about properties files . Las propiedades de archivo utilizado en este ejemplo es el mismo que en la sección de archivos de propiedades .

Setting up a ConfigurationFactory La creación de un ConfigurationFactory

Now we have to create a ConfigurationFactory object and let it read this definition file. Ahora tenemos que crear un ConfigurationFactory objeto y se deja leer este archivo de definición. This is quite simple: Just create a new instance and set the name of the definition file with the setConfigurationFileName() method. Esto es bastante simple: Basta con crear una nueva instancia y establecer el nombre del archivo de definición con la setConfigurationFileName() método.

ConfigurationFactory factory = new ConfigurationFactory(); ConfigurationFactory factory = new ConfigurationFactory();

URL configURL = new File(“config.xml”).toURL();

factory.setConfigurationFileName(configURL.toString());

Configuration config = factory.getConfiguration();

As this code fragment shows the file name passed to the factory can be a full URL. Como este fragmento de código muestra el nombre del archivo pasa a la fábrica puede ser una URL completa. This is also the recommended way of specifying the file because it provides the greatest flexibility and a consistent way of handling relative file names found in the definition file. Este es también el método recomendado de especificar el archivo, ya que proporciona la mayor flexibilidad y una forma coherente de manejo de archivos de nombres relativos se encuentran en el archivo de definición.

Here we assumed the configuration definition file to be located in the current directory. Aquí asumimos la definición fichero de configuración que se encuentra en el directorio actual. It is also possible (and probably a better approach) to load the file from the class path. También es posible (y probablemente un mejor enfoque) para cargar el archivo de la ruta de clase. This could be done as follows: Esto podría hacerse de la siguiente manera:

ConfigurationFactory factory = new ConfigurationFactory(); ConfigurationFactory factory = new ConfigurationFactory();

URL configURL = getClass().getResource(“/config.xml”);

factory.setConfigurationURL(configURL);

Configuration config = factory.getConfiguration();

Accessing properties Obtener acceso a propiedades

Whatever way we used to load the configuration factory, we should now have a Configuration object that was returned by the factory’s getConfiguration() method. Cualquiera que sea nuestra forma de utilizar para cargar la fábrica de configuración, que ahora debe tener una Configuration objeto que fue devuelto por la fábrica getConfiguration() método. This object is actually an instance of the CompositeConfiguration class, a specific implementation of the Configuration interface that is able to deal with multiple contained configuration objects. Este objeto es en realidad una instancia de la CompositeConfiguration clase, una aplicación específica de la Configuration interfaz que es capaz de tratar con múltiples objetos de configuración de contenidos. Of course this class provides all the getter methods defined in the Configuration interface, so for accessing a string property for instance we would use the getString() method: Por supuesto, esta clase proporciona todos los métodos getter definido en la Configuration de la interfaz, así que para acceder a una propiedad de cadena, por ejemplo, deberemos usar la getString() método:

String backColor = config.getString(“color.background”); String backColor = config.getString(“color.background”);

Multiple configuration sources Múltiples fuentes de configuración

Using ConfigurationFactory to collect configuration sources does not make much sense if there is only one source to be loaded. Usando ConfigurationFactory para recoger las fuentes de configuración no tiene mucho sentido si sólo hay una fuente que se cargue. So let’s add another one! Así que vamos a añadir otro! This time we will embedd a XML file. Esta vez vamos a embedd un archivo XML.

Overriding properties Reemplazar propiedades

Many applications use the popular XML format for storing configuration information. Muchas aplicaciones utilizan el popular formato XML para almacenar información de configuración. So it is no wonder that Configuration also supports this type of configuration sources. Así, no es de extrañar que también soporta configuración de este tipo de fuentes de configuración. In general each XML document can be used to define configuration settings. We start here with a rather simple one: En general cada documento XML se puede utilizar para definir los ajustes de configuración. Comenzamos aquí con una bien sencilla:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<gui-definition>

<colors>

<background>#808080</background>

<text>#000000</text>

<header>#008000</header>

<link normal=”#000080″ visited=”#800080″/>

</colors>

<rowsPerPage>15</rowsPerPage>

</gui-definition>

To make this XML document part of our global configuration we have to modify our configuration definition file to also include the new file. Para realizar esta parte de nuestro documento XML de configuración global tenemos que modificar nuestra definición fichero de configuración para incluir también el nuevo archivo. For XML documents the element xml can be used so that we have now: Para documentos XML del elemento xml se puede utilizar de modo que tenemos ahora:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<configuration>

<properties fileName=”usergui.properties”/>

<xml fileName=”gui.xml”/>

</configuration>

The code for setting up the ConfigurationFactory object remains the same. El código para la creación de la ConfigurationFactory objeto sigue siendo el mismo. From the Configuration object returned by the factory the new properties can be accessed in the usual way. Desde la Configuration objeto devuelto por la fábrica de las nuevas propiedades se puede acceder de la forma habitual.

There is one problem with this example configuration setup: The color.background property is defined in both the properties and the XML file, and – to make things worse – with different values. Hay un problema con esta configuración de configuración de ejemplo: El color.background propiedad se define tanto en las propiedades y el archivo XML, y – para empeorar las cosas – con diferentes valores. Which value will be returned by a call to getString() ? ¿Qué valor le será devuelto por una llamada a getString() ?

The answer is that the configuration sources are searched in the order they are defined in the configuration definition file. Here the properties file is included first, then comes the XML file. La respuesta es que las fuentes de configuración se buscan en el orden en que se definen en el archivo de definición de configuración. Aquí las propiedades del archivo se incluye en primer lugar, luego viene el archivo XML. Because the color.background property can be found in the properties file the value specified there will be returned (which happens to be #FFFFFF ). Debido a que el color.background propiedad se puede encontrar en el archivo de propiedades el valor especificado no serán devueltos (que pasa a ser #FFFFFF ).

It might not be obvious why it makes sense to define the value of one and the same property in multiple configuration sources. But consider the following scenario: An application comes with a set of default properties and allows the user to override some or all of them. Tal vez no sea obvio por qué tiene sentido para definir el valor de una y la misma propiedad en las fuentes de configuración múltiple. Pero consideremos la situación siguiente: Una aplicación viene con un conjunto de propiedades por defecto y permite al usuario escribir algunos de ellos o todos . This can now easy be realized by saving the user’s settings in a file and the default settings in another. Then in the configuration definition file the file with the user settings is included first and after that the file with the default values. Ahora puede fácilmente ser realizado por el ahorro del usuario la configuración en un archivo y los ajustes por defecto en otro. Luego, en la definición de fichero de configuración del archivo con la configuración de usuario se incluyó por primera vez y después de que el archivo con los valores por defecto. The application code that queries these settings need not be aware whether a property was overriden by the user. El código de aplicación que las consultas de estos ajustes no necesitan ser conscientes de si un bien fue anulado por el usuario. The ConfigurationFactory takes care that properties defined in the first file (the user file) are found; other properties which the user has not changed will still be returned from the second file (the defaults file). El ConfigurationFactory se preocupa de que las propiedades definidas en el primer archivo (el archivo de usuario) se encuentran; otras propiedades que el usuario no ha cambiado todavía se devuelve desde el segundo archivo (el archivo por defecto).

Optional configuration sources Fuentes opcionales de configuración

The example above with two configuration sources – one for user settings and one with default values – raises an interesting question: What will happen if the user has not defined specific properties yet? El ejemplo anterior con dos fuentes de configuración – uno para la configuración de usuario y una con los valores por defecto – plantea una pregunta interesante: ¿Qué pasará si el usuario no ha definido aún las propiedades específicas? Or what if a new user starts our application for the first time and thus no user specific properties exist? ¿O qué si un nuevo usuario inicia nuestra aplicación por primera vez y por ende no existen propiedades específicas de usuario?

The default behavior of ConfigurationFactory is to throw a ConfigurationException exception if one of the sources defined in the configuration definition file cannot be loaded. El comportamiento predeterminado de ConfigurationFactory es lanzar un ConfigurationException excepción si una de las fuentes se definen en el archivo de definición de configuración no se puede cargar. For our example this behavior is not desired: the properties file with specific user settings is not required. Para nuestro ejemplo este comportamiento no es deseada: las propiedades del archivo con los ajustes específicos del usuario no es necesario. If it cannot be loaded, the example application will still work because a complete set of configuration properties is defined in the second file. Si no se puede cargar, el ejemplo de aplicación seguirá funcionando debido a un conjunto completo de propiedades de configuración se define en el segundo archivo.

ConfigurationFactory supports such optional configuration sources. ConfigurationFactory apoya ese tipo de fuentes de configuración opcional. For this purpose in the definition of a (file based) configuration source the optional attribute can be placed. Para ello en la definición de un (archivo basado) de configuración de la fuente optional de atributos se pueden colocar. An example of this is shown below: Un ejemplo de esto se muestra a continuación:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<configuration>

<properties fileName=”usersettings.properties” optional=”true”/>

<properties fileName=”default.properties”/>

</configuration>

In this configuration definition file the first properties file with user specific settings is marked as optional. En esta definición fichero de configuración de las propiedades primer archivo con configuraciones específicas de usuario se marca como opcional. This means that if it cannot be loaded, ConfigurationFactory will not throw an exception, but only write a warning message to its logger. Esto significa que si no se puede cargar, ConfigurationFactory no una excepción, pero sólo escribir un mensaje de advertencia a su registrador. Note that the optional attribute is absent for the second properties file. Tenga en cuenta que la optional de atributo está ausente por el segundo archivo de propiedades. Thus it is mandatory, and the getConfiguration() method of ConfigurationFactory would throw an exception if it could not be found. Por lo tanto, es obligatoria, y el getConfiguration() método de ConfigurationFactory sería una excepción si no se ha encontrado.

Union configuration Unión de configuración

In an earlier section about the configuration definition file for ConfigurationFactory it was stated that configuration files included first can override properties in configuraton files included later and an example use case for this behaviour was given. There may be times when there are other requirements. En una sección anterior sobre el archivo de definición de configuración para ConfigurationFactory se dijo que los archivos de configuración incluyó por primera vez se puede reemplazar las propiedades de los archivos configuraton incluyen más adelante y un ejemplo de casos de uso para este comportamiento se le dio. Puede haber ocasiones cuando hay otros requisitos.

Let’s continue the example with the application that somehow process database tables and that reads the definitions of the affected tables from its configuration. Sigamos el ejemplo con la aplicación que de alguna manera proceso de base de datos y tablas que lee las definiciones de las tablas afectadas de su configuración. This example and the corresponding XML configuration files were introduced in the section about XMLConfiguration . Now consider that this application grows larger and must be maintained by a team of developers. Este ejemplo y los correspondientes archivos de configuración XML se introdujeron en la sección sobre XMLConfiguration . Consideremos ahora que esta solicitud se hace más grande y debe ser gestionada por un equipo de desarrolladores. Each developer works on a separated set of tables. Cada desarrollador trabaja en un conjunto de cuadros separados. In such a scenario it would be problematic if the definitions for all tables would be kept in a single file. En tal escenario, sería problemático si las definiciones para todas las tablas se mantendrían en un solo archivo. It can be expected that this file needs to be changed very often and thus can be a bottleneck for team development when it is nearly steadily checked out. Es de esperar que este archivo debe ser cambiado con mucha frecuencia y por lo tanto puede ser un cuello de botella para el desarrollo del equipo cuando esté casi constantemente desprotegido. It would be much better if each developer had an associated file with table definitions and all these information could be linked together at the end. Sería mucho mejor si cada desarrollador había un archivo asociado con definiciones de tabla y toda la información, podrían ser unidos entre sí al final.

ConfigurationFactory provides support for such a use case, too. ConfigurationFactory proporciona soporte para un caso de uso, también. It is possible to specify in the configuration definition file that from a set of configuration sources a logic union configuration is to be constructed. Es posible especificar en el archivo de definición de la configuración que a partir de un conjunto de fuentes de configuración de una configuración de la unión lógica se va a construir. Then all properties defined in the provided sources are collected and can be accessed as if they had been defined in a single source. A continuación, todas las propiedades definidas en las fuentes siempre se recogen y se puede acceder como si hubieran sido definido en una sola fuente. To demonstrate this feature let us assume that a developer of the database application has defined a specific XML file with a table definition named tasktables.xml : Para demostrar esta característica, supongamos que un desarrollador de la aplicación de base de datos ha definido un determinado archivo XML con una definición de la tabla con nombre tasktables.xml :

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<config>

<table tableType=”application”>

<name>tasks</name>

<fields>

<field>

<name>taskid</name>

<type>long</type>

</field>

<field>

<name>name</name>

<type>java.lang.String</type>

</field>

<field>

<name>description</name>

<type>java.lang.String</type>

</field>

<field>

<name>responsibleID</name>

<type>long</type>

</field>

<field>

<name>creatorID</name>

<type>long</type>

</field>

<field>

<name>startDate</name>

<type>java.util.Date</type>

</field>

<field>

<name>endDate</name>

<type>java.util.Date</type>

</field>

</fields>

</table>

</config>

This file defines the structure of an additional table, which should be added to the so far existing table definitions.

Este archivo define la estructura de una tabla adicional, que hay que añadir a la tabla de definiciones existentes hasta ahora. To achieve this the configuration definition file has to be changed: A new section is added that contains the include elements of all configuration sources which are to be combined. Para lograr esta definición fichero de configuración tiene que ser cambiado: Una nueva sección se agrega que contiene los elementos de incluir todas las fuentes de configuración que se trata de combinar.

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<!– Configuration definition file that demonstrates the

override and additional sections –>

<configuration>

<override>

<properties fileName=”usergui.properties”/>

<xml fileName=”gui.xml”/>

</override>

<additional>

<xml fileName=”tables.xml”/>

<xml fileName=”tasktables.xml” at=”tables”/>

</additional>

</configuration>

Compared to the older versions of this file a couple of changes has been done. En comparación con las versiones más antiguas de este archivo un par de cambios se ha hecho. One major difference is that the elements for including configuration sources are no longer direct children of the root element, but are now contained in either an override or additional section. Una diferencia importante es que los elementos de configuración, incluidas las fuentes ya no son hijos directos del elemento raíz, pero ahora están contenidas en cualquiera de una override o additional sección. The names of these sections already imply their purpose. Los nombres de estas secciones implican ya su propósito.

The override section is not strictly necessary. El override la sección no es estrictamente necesario. Elements in this section are treated as if they were children of the root element, ie properties in the included configuration sources override properties in sources included later. Elementos en esta sección se tratan como si fueran sus hijos del elemento raíz, es decir, en propiedades de las fuentes de configuración que se incluye propiedades en reemplazar las fuentes incluidas más adelante. So the override tags could have been ommitted, but for sake of clearity it is recommended to use them when there is also an additional section. Así que la override etiquetas podrían haber sido omitidos, sino para bien de clearity se recomienda usarlas cuando hay también un additional sección.

It is the additonal section that introduces a new behaviour. All configuration sources listed here are combined to a union configuration. In our example we have put two xml elements in this area that load the available files with database table definitions. Es la additonal sección que introduce un nuevo comportamiento. Todas las fuentes figuran en esta lista de configuración se combinan para una configuración de unión. En nuestro ejemplo hemos puesto dos xml elementos en este ámbito que se cargan los archivos disponibles con definiciones de tabla de base de datos. The syntax of elements in the additional section is analogous to the syntax described so far. La sintaxis de elementos de la additional sección es análoga a la sintaxis descrita hasta ahora. The only difference is an additionally supported at attribute that specifies the position in the logic union configuration where the included properties are to be added. La única diferencia es un apoyo adicional at atributo que especifica la posición en la configuración de la unión lógica cuando las propiedades se incluyen los que se añade. In this example we set the at attribute of the second element to tables . En este ejemplo ponemos la at atributo del segundo elemento a las tablas. This is because the file starts with a table element, but to be compatible with the other table definition file it should be accessable under the key tables.table . Esto es porque el archivo comienza con una table elementos, pero para ser compatible con la definición de tabla de otros expedientes, debe ser accesible en la clave tables.table .

After these modifications have been performed the configuration obtained from the ConfigurationFactory will allow access to three database tables. Después de estas modificaciones se han realizado la configuración obtenida de la ConfigurationFactory podrá acceder a tres tablas de bases de datos. A call of config.getString(“tables.table(2).name”); will result in a value of tasks . Una llamada de config.getString(“tables.table(2).name”); tendrá como resultado un valor de tareas. In an analogous way it is possible to retrieve the fields of the third table. De manera análoga, es posible recuperar los campos de la tercera tabla.

Note that it is also possible to override properties defined in an additonal section. Tenga en cuenta que también es posible reemplazar las propiedades definidas en una additonal sección. This can be done by placing a configuration source in the override section that defines properties that are also defined in one of the sources listed in the additional section. Esto se puede hacer mediante la colocación de una fuente de configuración en el override de sección que define las propiedades que se definen también en una de las fuentes que se indican en el additional sección. The example does not make use of that. Note also that the order of the override and additional sections in a configuration definition file does not matter. El ejemplo no hacer uso de ello. Tenga en cuenta también que el orden de la override y additional secciones de un archivo de definición de configuración no importa. Sources in an override section are always treated with higher priority (otherwise they could not override the values of other sources). Fuentes de una override sección son siempre tratados con mayor prioridad (de lo contrario no podían prevalecer sobre los valores de otras fuentes).

Configuration definition file reference Configuración del archivo de definición de referencia

We have seen how to write configuration definition files for including properties and XML files. Hemos visto cómo escribir archivos de configuración para la definición incluidas las propiedades y archivos XML. This section deals with other options that can be specified in such a definition file and that are evaluated by ConfigurationFactory . Esta sección se ocupa de otras opciones que se pueden especificar en el fichero definición y que son evaluados por ConfigurationFactory .

From time to time the question is raised whether there is a document type definition that exactly defines the structure of a configuration definition file. De vez en cuando la cuestión se plantea si existe una definición de tipo de documento que define exactamente la estructura de un archivo de definición de la configuración. Frankly, the answer is no. Francamente, la respuesta es no. This is because for a future version of Commons Configuration it is planed to make the configuration definition files extensible, ie allow developers to register their own tags and corresponding implementations of the Configuration interface. Esto se debe a que para una futura versión de los Comunes de configuración que se planea que la definición archivos de configuración extensible, es decir, permitir a los desarrolladores a registrar sus propias etiquetas y las implementaciones correspondientes de la interfaz de configuración.

In the current version the set of supported XML elements is fixed. Below is a list of all supported tags and a description of each: En la versión actual del conjunto de elementos XML apoyo es fijo. A continuación se muestra una lista de todos los tags y una descripción de cada uno:

properties propiedades

With this element properties files can be included. Con este elemento de las propiedades se pueden incluir archivos. The name of the file to load is specified using the fileName attribute. El nombre del archivo a cargar se especifica mediante la fileName atributo. Which configuration class is created by this tag depends on the extension of the file to load: If the extension is “.xml”, a XMLPropertiesConfiguration object is created, which is able to process the XML properties format introduced in Java 5.0. configuración de clase que se crea por esta etiqueta depende de la extensión del archivo a cargar: Si la extensión es “. xml”, un XMLPropertiesConfiguration objeto se crea, que es capaz de procesar el formato XML propiedades introducidas en Java 5.0. Otherwise a PropertiesConfiguration object is created, the default reader for properties files. De lo contrario una PropertiesConfiguration objeto es creado, el lector por defecto para los archivos de propiedades.

xml xml

The xml element can be used to load XML configuration files. El xml elemento puede ser usado para cargar archivos de configuración XML. It also uses the fileName attribute to determine the name of the file to load and creates an instance of XMLConfiguration . También utiliza el fileName atributo para determinar el nombre del archivo a cargar y crea una instancia de XMLConfiguration .

jndi jndi

As the name implies, with this element JNDI resources can be included in the resulting configuration. Como su nombre lo indica, con este JNDI recursos elemento puede ser incluido en la configuración resultante. Under the hood this is done by an instance of the JNDIConfiguration class. Bajo el capó se hace esto por una instancia de la JNDIConfiguration clase. The prefix attribute can be used to select a subset of the JNDI tree. El prefix atributo se puede usar para seleccionar un subconjunto del árbol JNDI.

plist plist

The plist element allows to embedd configuration files in the NeXT / OpenStep or Mac OS X format. El plist elemento permite embedd ficheros de configuración en la siguiente / OpenStep o Mac OS X en formato. Again the name of the file to load is specified through the fileName attribute. Una vez más el nombre del archivo a cargar se especifica a través de la fileName atributo. If a XML file is specified, a XMLPropertyListConfiguration object is created to process the file. Si un archivo XML se especifica, una XMLPropertyListConfiguration objeto se crea para procesar el archivo. Otherwise this task is delegated to a PropertyListConfiguration instance. De lo contrario esta tarea se delega en un PropertyListConfiguration instancia.

system sistema

With this element an instance of SystemConfiguration is added to the resulting configuration allowing access to system properties. Note: This element is only present for reasons of backward compatibility. Con este elemento de una instancia de SystemConfiguration se agrega a la configuración resultante permite el acceso a las propiedades del sistema. Nota: Este elemento sólo está presente por razones de compatibilidad con versiones anteriores. With the interpolation features introduced in version 1.4 (see Variable Interpolation for more details) there is a much easier way of accessing system properties. Con la interpolación características introducidas en la versión 1.4 (véase la interpolación de variables para obtener más detalles) hay una forma mucho más fácil de acceder a las propiedades del sistema.

All of these elements can occur in a configuration definition file in arbitrary number and order. Todos estos elementos pueden ocurrir en un archivo de definición de configuración en número arbitrario y el orden. The following listing shows an example file using many of these tags. El siguiente listado muestra un ejemplo de archivo usando muchas de estas etiquetas.

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<configuration>

<system/>

<jndi prefix=”java:comp/env”/>

<properties fileName=”test.properties”/>

<xml fileName=”test.xml”/>

<properties fileName=”test.properties.xml”/>

</configuration> Setting further options

Configuración de más opciones

Many specialized configuration classes support initialization properties that influence the behavior of their instances. Muchas clases de configuración de apoyo especializado propiedades de inicialización que influyen en el comportamiento de sus instancias. For example for file based configurations the encoding of the files to load can be specified using the setEncoding() method, or an XMLConfiguration can be told to perform validation by calling the setValidating() method. Por ejemplo para el archivo de configuraciones basadas en la codificación de los archivos de carga puede ser especificado utilizando el setEncoding() el método o una XMLConfiguration se puede contar para realizar la validación mediante una llamada al setValidating() método. How can such properties be set in a configuration definition file? ¿Cómo pueden estas propiedades se encuentra en un archivo de definición de configuración?

Fortunately this is easy possible. Afortunadamente esto es fácil posible. For each XML element in a configuration definition file additional attributes can be specified that correspond to (bean) setter methods defined in the associated configuration class. Para cada elemento XML en un fichero de configuración definición de atributos adicionales se puede especificar que corresponden a (bean) los métodos setter definido en la clase de configuración asociado. To derive the name of an attribute from a setter method to be called, just drop the prefix “set” and make the first letter lower case. Para obtener el nombre de un atributo de un método setter a ser llamado, simplemente introduce el prefijo “set” y hacer primero la letra en minúscula. So for instance the attribute that invokes the setEncoding() method would be encoding . Así, por ejemplo, el atributo que invoca el setEncoding() método sería encoding . The following example shows how a XML document with a certain encoding and enabled validation can be loaded: El siguiente ejemplo muestra cómo un documento XML con una codificación de ciertos y han permitido la validación se puede cargar:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<configuration> <xml fileName=”test.xml” encoding=”UTF-8″ validating=”true”/>

</configuration> Using this mechanism many properties of configuration classes can be set when they are used together with ConfigurationFactory . To find out, which attributes are supported by a specific XML element, refer to the list in the previous section that explains, which configuration classes are used for which tags.

Utilizando este mecanismo de muchas propiedades de las clases de configuración se puede establecer cuando se utilizan junto con ConfigurationFactory . Para averiguarlo, los atributos que están apoyados por un determinado elemento XML, consulte la lista en la sección anterior que explica que las clases de configuración se utilizan para ¿Qué etiquetas. In the JavaDoc of the corresponding class you can find the setter methods you can address by attributes. En el JavaDoc de la clase correspondiente usted puede encontrar los métodos setter puede dirigirse por atributos.

Referencing system properties Hacer referencia a las propiedades del sistema

Often the configuration definition files are contained in a distribution unit like a war file that should not be manipulated after packaging. A menudo, los archivos de definición de configuración se encuentran en una unidad de distribución como un archivo de guerra que no deben ser manipulados después del envasado. The path names these files refer to need some way of making them externally customizable so that the packaging unit can be adoped to a special environment without repackaging. Los nombres de ruta de estos archivos se refieren a necesitar una cierta forma de hacer que el exterior personalizable para que la unidad de embalaje se puede adoped a un medio ambiente especial sin éste. One way to achieve this is to allow system properties in the file names. Una forma de lograrlo es permitir que las propiedades del sistema en los nombres de archivo.

ConfigurationFactory supports a simple way of adding references to system properties to the configuration definition files. ConfigurationFactory soporta una forma sencilla de añadir referencias a propiedades del sistema para la definición de los archivos de configuración. Below is an example that demonstrates this feature: A continuación se muestra un ejemplo que muestra esta característica:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<!– Un archivo de configuración de prueba para la carga de un archivo especificado por un system property.–>

<configuration>

<properties fileName=”${config.file}”/>

</configuration>

In this configuration definition file the name of the properties file to be loaded is specified by means of a variable (which is marked using the typical ${} syntax). En esta definición fichero de configuración el nombre de las propiedades del archivo a cargar se especifica por medio de una variable (que está marcado con el típico $ () sintaxis). When this file is parsed the name of the variable is looked up in the set of defined system properties. Cuando este archivo se analiza el nombre de la variable se localiza en el conjunto de propiedades del sistema definido. So to set a concrete file name for the properties file the config.file system property must be defined (eg by calling System.setProperty(“config.file”, “myfile.properties”); or using the -D command line switch when starting your Java application). Así que para establecer un nombre de archivo concreto para las propiedades de archivo del config.file propiedad del sistema debe ser definido (por ejemplo, llamando System.setProperty(“config.file”, “myfile.properties”); o con el -D conmutador de línea de comandos cuando iniciar la aplicación Java).

Note: Configuration definition files for ConfigurationFactory are treated differently than other configuration sources. Nota: Los archivos de configuración para la definición ConfigurationFactory son tratados de manera diferente que las fuentes de configuración. So the standard interpolation features as described in the section Variable Interpolation do not work here. Así que la interpolación características estándar como se describe en la sección de interpolación de variables no funcionan aquí. The variable substitution facilities described in this section are specific to ConfigurationFactory and differ from the default handling of variables. Las instalaciones de la sustitución de variables descritas en esta sección son específicas para ConfigurationFactory y difieren de la manipulación de variables por defecto.

Usando DefaultConfigurationBuilder

The ConfigurationFactory class that was introduced in the last section is a powerful tool for dealing with multiple different configuration sources, but it also has some shortcomings: El ConfigurationFactory clase que se introdujo en la última sección es una herramienta poderosa para tratar con múltiples fuentes de configuración diferente, pero también presenta algunos inconvenientes:

  • The format for configuration definition files is not extensible. El formato de los archivos de definición de configuración no es extensible.
  • Complex initializations of the declared configuration sources (eg for assigning a reloading strategy) are not supported. inicializaciones complejas de las fuentes de configuración declarado (por ejemplo, para la asignación de una estrategia de recarga) no son compatibles.
  • The returned configuration object is not hierarchical, which limits the query facilities somewhat. El objeto de configuración de retorno no es jerárquica, lo que limita un poco las instalaciones de consulta.
  • Declared configuration sources can only be accessed by index from the returned composite configuration, which means that code using a ConfigurationFactory depends on the order of declarations in a configuration definition file. configuración de las fuentes Admitida sólo se puede acceder por el índice compuesto de la configuración devuelta, lo que significa que el uso de un código de ConfigurationFactory depende del orden de las declaraciones en un archivo de definición de la configuración.

To work around these limitations the class DefaultConfigurationBuilder was introduced. Para evitar estas limitaciones de la clase DefaultConfigurationBuilder se introdujo.

ConfigurationFactory Differences Las diferencias ConfigurationFactory

From its basic usage scenarios DefaultConfigurationBuilder is very similar to ConfigurationFactory . Desde sus escenarios de uso básicos DefaultConfigurationBuilder es muy similar a ConfigurationFactory . It is able to process the same configuration definition files as can be read by ConfigurationFactory , but supports more options. Es capaz de procesar la definición de configuración de los mismos archivos que pueden ser leídos por ConfigurationFactory , pero es compatible con más opciones. The following list identifies the main differences between these classes: La siguiente lista identifica las principales diferencias entre estas clases:

  • DefaultConfigurationBuilder extends XMLConfiguration . This means that it is a file-based configuration , and thus supports multiple ways of specifying the location of the configuration definition file (eg as java.io.File object, as URL, etc.). DefaultConfigurationBuilder extiende XMLConfiguration . Esto significa que es un archivo de configuración basadas en , por lo que soporta múltiples formas de especificar la ubicación del archivo de definición de configuración (por ejemplo, como java.io.File objeto, como dirección, etc.)
  • The configuration object returned by a DefaultConfigurationBuilder is an instance of the CombinedConfiguration class, ie a truely hierarchical configuration supporting enhanced query facilities. La configuración del objeto devuelto por un DefaultConfigurationBuilder es una instancia de la CombinedConfiguration clase, es decir, una configuración jerárquica verdaderamente apoyar consulta instalaciones mejoradas.
  • Each declaration of a configuration source in the configuration definition file is interpreted as a bean declaration , so complex initializations are supported. Cada declaración de una fuente de configuración en el archivo de definición de la configuración se interpreta como una declaración de bean , para inicializaciones complejas son compatibles.
  • DefaultConfigurationBuilder supports custom tags in its configuration definition file. DefaultConfigurationBuilder soporta etiquetas personalizadas en su archivo de definición de la configuración. For this purpose a so-called configuration provider has to be registered, which will be called when a corresponding tag is encountered. A tal fin una llamada configuración del proveedor, de modo tiene que ser registrado, que se llama cuando una etiqueta correspondiente se encuentra.

Enhancements to the configuration definition file Mejoras en la definición de fichero de configuración

As was already pointed out, DefaultConfigurationBuilder maintains compatibility with ConfigurationFactory in that it understands the same configuration definition files. Como ya se señaló, DefaultConfigurationBuilder mantiene la compatibilidad con ConfigurationFactory en que entiende la definición de configuración de los mismos archivos. In addition to the elements that are allowed in a configuration definition file for ConfigurationFactory the data files for DefaultConfigurationBuilder support some additional options providing greater flexibility. Además de los elementos que se permiten en un archivo de definición de configuración para ConfigurationFactory los archivos de datos para DefaultConfigurationBuilder apoyar algunas opciones adicionales que proporciona mayor flexibilidad. This section explains these enhanced features. En esta sección se explica estas características mejoradas.

Overall structure of a configuration definition file
Estructura general de una definición de fichero de configuración

A configuration definition file for DefaultConfigurationBuilder can contain three sections, all of which are optional. Un archivo de definición de configuración para DefaultConfigurationBuilder puede contener tres secciones, todos los cuales son opcionales. A skeleton looks as follows: Un esqueleto es el siguiente:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<configuration systemProperties=”path to property file”>

<header>

<!–Los metadatos acerca de la configuración combinada resultante –>

</header>

<override>

<!– Declaraciones de configuración con la semántica de anulación –>

</override>

<additional>

<!– Declaraciones de configuración que forman una unión de configuración –>

</additional>

</configuration>

Declaring configuration sources
La declaración de las fuentes de configuración

The override and additional sections should look familar to users that have already worked with ConfigurationFactory . La override y additional sectores deben buscar familiarizados a los usuarios que ya han trabajado con ConfigurationFactory . They have the exact same purpose here, ie they contain declarations for the configuration sources to be embedded. Ellos tienen la misma finalidad exacta aquí, es decir, contienen declaraciones de las fuentes de configuración para ser empotrado. For compatibility reasons it is also allowed to declare configuration sources outside these sections; they are then treated as if they were placed inside the override section. Por razones de compatibilidad también se pueden declarar las fuentes de información fuera de estas secciones, sino que son tratados como si fueran colocados dentro de la override sección.

Each declaration of a configuration source is represented by an XML element whose name determines the type of the configuration source (eg properties for properties files, or xml for XML documents). Cada declaración de una fuente de configuración está representado por un elemento XML cuyo nombre determina el tipo de configuración de la fuente (por ejemplo, properties de archivos de propiedades, o xml para documentos XML). Per default all configuration types are supported that are also allowed for ConfigurationFactory . Por defecto todos los tipos de configuración compatible que también están autorizados para ConfigurationFactory . A list of all supported tags can be found here . In addition to the default tags provided by ConfigurationFactory DefaultConfigurationBuilder knows the following tags: Una lista de todas las etiquetas soportados puede encontrarse aquí . Además de las etiquetas por defecto proporcionadas por ConfigurationFactory DefaultConfigurationBuilder sabe las siguientes etiquetas:

configuration configuración

The configuration tag allows other configuration definition files to be included. La configuration etiqueta permite la definición de configuración de otros archivos que se incluirán. This makes it possible to nest these definition files up to an arbitrary depth. Esto hace que sea posible anidar estos archivos de definición hasta una profundidad arbitraria. In fact, this tag will create another DefaultConfigurationBuilder object, initialize it, and obtain the CombinedConfiguation from it. This combined configuration will then be added to the resulting combined configuration. De hecho, esta etiqueta creará otra DefaultConfigurationBuilder objeto, inicializarlo, y obtener el CombinedConfiguation de ella. Esta configuración combinada será añadido a la combinación de configuración resultante. Like all file-based configurations the fileName attribute can be used to specify the configuration definition file to be loaded. Como todas las configuraciones basadas en el expediente de la fileName atributo puede ser usado para especificar la definición de archivo de configuración para cargar. This file must be an XML document that conforms to the format described here. Este archivo debe ser un documento XML que se ajusta al formato que se describe aquí.

In the declaration of a configuration source it is possible to set properties on the corresponding configuration objects. En la declaración de una fuente de configuración es posible establecer las propiedades de los objetos de configuración correspondiente. Configuration declarations are indeed Bean declarations . declaraciones de configuración son de hecho las declaraciones Bean . That means they can have attributes matching simple properties of the configuration object to create and sub elements matching complex properties. Eso significa que pueden tener atributos coincidentes propiedades simples de la configuración del objeto para crear y subelementos se pongan en venta propiedades complejas. The following example fragment shows how complex initialization can be performed in a configuration declaration: El fragmento siguiente ejemplo muestra lo complejo de inicialización se puede realizar en una declaración de configuración:

<properties fileName=”test.properties” throwExceptionOnMissing=”true”> <properties fileName=”test.properties” throwExceptionOnMissing=”true”>

<reloadingStrategy refreshDelay=”10000″

config-class=”org.apache.commons.configuration.reloading.FileChangedReloadingStrategy”/>

</properties>

<xml fileName=”test.xml” delimiterParsingDisabled=”true”>

<expressionEngine config-class=”org.apache.commons.configuration.tree.DefaultExpressionEngine”

propertyDelimiter=”/” indexStart=”[” indexEnd=”]”/>

</xml> In this example a configuration source for a properties file and one for an XML document are defined.

En este ejemplo una fuente de configuración de las propiedades del archivo y otra para un documento XML se definen. For the properties source the throwExceptionOnMissing property is set to true , which means that it should throw an exception if a requested property is not found. Para la fuente de las propiedades de la throwExceptionOnMissing propiedad se establece en true, lo que significa que debe lanzar una excepción si una propiedad solicitada no se encuentra. In addition it is assigned a reloading strategy, which is declared and configured in a sub element. Además se le asigna una estrategia de recarga, que se declara y se configura en un elemento secundario. The XML configuration source is initialized in a similar way: a simple property is set, and an expression engine is assigned. La fuente de configuración XML se inicializa de forma similar: una simple propiedad está definida, y un motor de expresiones es asignado. More information about the format for declaring objects and initializing their properties can be found in the section about bean declarations . Más información sobre el formato para declarar e inicializar los objetos de sus propiedades se pueden encontrar en la sección acerca de las declaraciones de bean .

In addition to the attributes that correspond to properties of the configuration object to be created, a configuration declaration can have a set of special attributes that are evaluated by DefaultConfigurationBuilder when it creates the objects. These attributes are listed in the following table: Además de los atributos que corresponden a las propiedades de la configuración del objeto a ser creado, una declaración de configuración puede tener un conjunto de atributos especiales que son evaluados por DefaultConfigurationBuilder cuando crea los objetos. Estos atributos se enumeran en el cuadro siguiente:

Attribute Atributo Meaning Significado
config-name
Allows a name to be specified for this configuration. Permite a un nombre que se especifica para esta configuración. This name can be used to obtain a reference to the configuration from the resulting combined configuration (see below). Este nombre se puede utilizar para obtener una referencia a la configuración de la configuración mixta resultante (véase más adelante).
config-at
With this attribute an optional prefix can be specified for the properties of the corresponding configuration. Con este atributo un prefijo opcional se puede especificar para las propiedades de la configuración correspondiente.
config-optional
Declares a configuration as optional. Declara una configuración como opcional. This means that errors that occur when creating the configuration are silently ignored. Esto significa que los errores que se producen cuando se crea la configuración se ignora silenciosamente. The default behavior when an error occurs is that no configuration is added to the resulting combined configuration. El comportamiento por defecto cuando se produce un error es que ninguna configuración se agrega a la configuración mixta resultante. This behavior can be used to find out whether an optional configuration could be successfully created or not. Este comportamiento puede ser utilizado para determinar si una configuración opcional puede ser creado con éxito o no. If you specify a name for the optional configuration (using the config-name attribute), you can later check whether the combined configuration contains a configuration with this name. Si se especifica un nombre para la configuración opcional (usando la config-name atributo), después podrá comprobar si la configuración combinada contiene una configuración con este nombre. With the config-forceCreate attribute (see below) this default behavior can be changed. Con la config-forceCreate atributo (véase más adelante) este comportamiento por defecto puede ser cambiado.
config-forceCreate
This boolean attribute is only evaluated for configurations declared as optional. Este atributo booleano sólo se evalúa para configuraciones declarado como opcional. It determines the behavior of the configuration builder when the optional configuration could not be created. Se determina el comportamiento del constructor de configuración cuando la configuración opcional no se pudo crear. If set to true , the builder tries to create an empty, uninitialized configuration of the correct type and add it to the resulting combined configuration. Si se establece en true, el constructor intenta crear una, sin inicializar configuración vacía del tipo correcto y agregarlo a la combinación de configuración resultante. This is especially useful for file-based configurations. Esto es especialmente útil para configuraciones basadas en archivos. Consider a use case where an application wants to store user specific configuration files in the users’ home directories. Considere la posibilidad de un caso de uso cuando la solicitud se quiere almacenar ficheros de configuración específicos del usuario en ‘casa directorios de los usuarios. When a user starts this application for the first time, the user configuration does not exist yet. Cuando un usuario inicia esta aplicación por primera vez, la configuración de usuario no existe todavía. If it is declared as optional and forceCreate , the missing configuration file won’t cause an error, but an empty configuration will be created. The application can then obtain this configuration, add properties to it (eg user specific settings) and save it. Si se declara como opcional y forceCreate, el archivo de configuración faltante, no se producirá un error, pero una configuración vacía será creada. La aplicación puede entonces obtener esta configuración, agregar propiedades a la misma (por ejemplo, la configuración específica del usuario) y guárdelo. Without the config-forceCreate attribute the application would have to check whether the user configuration exists in the combined configuration and eventually create it manually. Sin la config-forceCreate atributo de la solicitud tendría que comprobar si la configuración de usuario existe en la configuración combinada y eventualmente crear manualmente. Note that not all configuration providers support this mechanism. Tenga en cuenta que no todos los proveedores de soporte de configuración de este mecanismo. Sometimes it may not be possible to create an empty configuration if the standard initialization fails. A veces puede que no sea posible crear una configuración vacía si la inicialización estándar falla. In this case no configuration will be added to the combined configuration (with other words: the config-forceCreate attribute will not have any effect). En este caso, sin necesidad de configuración se añadirá a la configuración combinada (con otras palabras: la config-forceCreate atributo no tendrá ningún efecto).

The config-at and config-optional attributes have the same meaning as the at and optional attributes for ConfigurationFactory . La config-at y config-optional atributos tienen el mismo significado que la at y optional para los atributos ConfigurationFactory . For compatibility reasons the old attributes without the config- prefix are still supported. Por razones de compatibilidad de los atributos de edad sin la config- prefijo se sigue admitiendo. Note that the config-at is now allowed for override configurations, too ( ConfigurationFactory evaluated the at attribute only for configuration declarations in the additional section). Tenga en cuenta que la config-at la actualidad se concede para las configuraciones override, también ( ConfigurationFactory evaluó la at atributo sólo de las declaraciones de configuración en el additional sección).

Another useful feature is the built-in support for interpolation (ie variable substitution): You can use variables in your configuration definition file that are defined in declared configuration sources. Otra característica útil es el soporte integrado para la interpolación (es decir, la sustitución de variables): Puede usar variables en el archivo de definición de configuración que se definen en las fuentes de configuración declarado. For instance, if the name of a configuration file to be loaded is defined by the system property CONFIG_FILE , you can do something like this: Por ejemplo, si el nombre de un archivo de configuración para cargar se define por la propiedad del sistema CONFIG_FILE , puede hacer algo como esto:

<configuration> <configuration>

<!– Load the system properties –> <! – Cargar las propiedades del sistema ->

<system/> <system/>

<!– Now load the config file, using a system property as file name –> <! – Ahora carga el archivo de configuración, utilizando una propiedad del sistema como nombre de archivo ->

<properties fileName=”${CONFIG_FILE}”/> <properties fileName=”${CONFIG_FILE}”/>

</configuration> </ Configuration>

Note that you can refer only to properties that have already been loaded. If you change the order of the <system> and the <properties> elements in the example above, an error will occur because the ${CONFIG_FILE} variable will then be undefined at the moment it is evaluated. Tenga en cuenta que sólo puede referirse a las propiedades que ya se han cargado. Si cambia el orden de los <system> y el <properties> elementos en el ejemplo anterior, se producirá un error debido a que el ${CONFIG_FILE} variable, entonces será indefinido en el momento en que se evalúa.

<configuration systemProperties=”systemProperties.xml”>

<!– Cargar las propiedades del sistema –>

<system/>

<!– Ahora carga el archivo de configuración, utilizando una propiedad del sistema como nombre de archivo –>

<properties fileName=”${CONFIG_FILE}”/>

</configuration <configuration systemProperties=”systemProperties.xml”>This example differs from the previous one by allowing CONFIG_FILE, and other properties, to be defined in a properties file and added to the system properties before the configuration is constructed.

Este ejemplo se diferencia de la anterior al permitir CONFIG_FILE, y otras propiedades, que se definirán en un archivo de propiedades y se agrega a las propiedades del sistema antes de que la configuración se construye.

The header section
La sección de encabezado

In the header section properties of the resulting combined configuration object can be set. En la sección de encabezado de propiedades del objeto de configuración combinada resultante puede ser ajustado. The main part of this section is a bean declaration that is used for creating the resulting configuration object. La parte principal de esta sección es una declaración de bean que se utiliza para crear el objeto de configuración resultante. Other elements can be used for customizing the Node combiners used by the override and the union combined configuration. Otros elementos se pueden utilizar para personalizar el Nodo combinadores utilizado por el aumento al presupuesto y la unión de configuración combinada. The following example shows a header section that uses all supported properties: El siguiente ejemplo muestra una sección de encabezado que utiliza todas las propiedades admitidas:

<header> <header>

<result delimiterParsingDisabled=”true” forceReloadCheck=”true”>

<nodeCombiner config-class=”org.apache.commons.configuration.tree.OverrideCombiner”/>

<expressionEngine config-class=”org.apache.commons.configuration.tree.xpath.XPathExpressionEngine”/>

</result>

<combiner>

<override>

<list-nodes>

<node>table</node>

<node>list</node>

</list-nodes>

</override>

<additional>

<list-nodes>

<node>table</node>

</list-nodes>

</additional>

</combiner>

</header>

The result element points to the bean declaration for the resulting combined configuration. El result puntos de elemento para la declaración de bean para la configuración mixta resultante. In this example we set some attributes and initialize the node combiner (which is not necessary because the default override combiner is specified) and the expression engine to be used. En este ejemplo que damos algunos atributos y combinador de inicializar el nodo (que no es necesario porque el combinador de anulación por defecto se especifica) y el motor de expresiones que se utilizarán. Note that the config-class attribute makes it possible to inject custom classes for the resulting configuration or the node combiner. Tenga en cuenta que la config-class de atributos permite inyectar clases personalizadas para la configuración resultante o el combinador de nodo.

The combiner section allows nodes to be defined as list nodes. This can be necessary for certain node combiner implementations to work correctly. El combiner la sección permite que los nodos que se definen como nodos de la lista. Esto puede ser necesario para algunas implementaciones combinador de nodo para funcionar correctamente. More information can be found in the section about Node combiners . Más información se puede encontrar en la sección sobre combinadores Nodo .

An example Un ejemplo

After all that theory let’s go through an example! Después de todo lo que vamos a ir a través teoría un ejemplo! We start with the configuration definition file that looks like the following: Comenzamos con el archivo de definición de configuración que tiene el siguiente aspecto:

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<!– Test configuration definition file that demonstrates complex initialization –>

<configuration>

<header>

<result delimiterParsingDisabled=”true” forceReloadCheck=”true”>

<expressionEngine config-class=”org.apache.commons.configuration.tree.xpath.XPathExpressionEngine”/>

</result>

<combiner>

<additional>

<list-nodes>

<node>table</node>

</list-nodes>

</additional>

</combiner>

</header>

<override>

<properties fileName=”user.properties” throwExceptionOnMissing=”true”

config-name=”properties” config-optional=”true”>

<reloadingStrategy refreshDelay=”10000″

config-class=”org.apache.commons.configuration.reloading.FileChangedReloadingStrategy”/>

</properties>

<xml fileName=”settings.xml” config-name=”xml”/>

</override>

<additional>

<xml config-name=”tab1″ fileName=”table1.xml” config-at=”database.tables”/>

<xml config-name=”tab2″ fileName=”table2.xml” config-at=”database.tables”

validating=”true”/>

</additional>

</configuration>

This configuration definition file includes four configuration sources and sets some properties for the resulting CombinedConfiguration . Of special interest is the forceReloadCheck property, which enables a special check for detecting property changes in the contained configuration sources. Este archivo de definición de configuración incluye cuatro fuentes de configuración y establece algunas propiedades para el resultado CombinedConfiguration . De especial interés es el forceReloadCheck propiedad, que permite un control especial para detectar los cambios de propiedad en las fuentes de configuración contenida. If this property is not set, reloading won’t work. Because we have configured a reloading strategy for one of the included configuration sources we have to set this flag so that this reloading strategy can function properly. Si esta propiedad no está establecida, la carga no funcionará. Dado que ya hemos configurado una estrategia de recarga para una de las fuentes de configuración que se incluye que tenemos que establecer este indicador para que esta estrategia de recarga puede funcionar adecuadamente. More details about this topic can be found in the Javadocs for CombinedConfiguration . Más detalles sobre este tema pueden encontrarse en el Javadocs para CombinedConfiguration . We also set some properties for the configurations to be loaded; for instance we declare that one of the XML configurations should be validated. También establecemos algunas propiedades de las configuraciones que se cargan, por ejemplo, se declara que una de las configuraciones XML deben ser validados.

With the following code we can create a DefaultConfigurationBuilder and load this file: Con el siguiente código podemos crear un DefaultConfigurationBuilder y cargar este archivo:

DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();

builder.setFile(new File(“configuration.xml”));

CombinedConfiguration cc = builder.getConfiguration(true);

It would have been possible to specify the location of the configuration definition file in multiple other ways, eg as a URL. Habría sido posible especificar la ubicación del archivo de definición de configuración en múltiples otras formas, por ejemplo, como una dirección URL. The boolean argument in the call to getConfiguration() determines whether the configuration definition file should be loaded. El argumento booleano en la llamada a getConfiguration() determina si el archivo de definición de configuración debe ser cargado. For our simple example we want this to happen, but it would also be possible to load the file manually (by calling the load() method), and after that updating the configuration. Para nuestro ejemplo simple, queremos que esto ocurra, pero también sería posible cargar el archivo manualmente (mediante una llamada al load() del método), y después de que la actualización de la configuración. (Remember that DefaultConfigurationBuilder is derived from XMLConfiguration , that means you can use all methods provided by this class to alter its data, eg to add further configuration sources.) If the configuration’s data was manually changed, you should call getConfiguration() with the argument false . XMLConfiguration also provides the registerEntityId() method that can be used to define the location of DTD files (refer to the section Validation of XML configuration files for more details). (Recuerde que DefaultConfigurationBuilder se deriva de XMLConfiguration , que significa que puede utilizar todos los métodos proporcionados por esta clase de modificar sus datos, por ejemplo, para agregar la configuración otras fuentes.) Si la configuración de datos fue cambiado de forma manual, debe llamar getConfiguration() con el argumento falsa.
XMLConfiguration también proporciona la registerEntityId() método que se puede utilizar para definir la ubicación de los archivos DTD (consulte la sección de
Validación de archivos de configuración XML para más detalles). This method is available for DefaultConfigurationBuilder , too. Este método está disponible para DefaultConfigurationBuilder , también. The entities registered here will be passed to the loaded child XML configurations. Las entidades registradas que aquí se pasa al niño configuraciones XML cargado. So you can register the DTDs of all child XML configurations globally at the configuration builder. Así que usted puede registrar el DTD XML de todas las configuraciones de niñez a nivel mundial en el constructor de configuración.

In the header section we have chosen an XPATH expression engine for the resulting configuration. En el header la sección que hemos elegido un motor de expresiones XPath para la configuración resultante. So we can query our properties using the convenient XPATH syntax. Por lo tanto, puede consultar nuestras propiedades utilizando la sintaxis XPath conveniente. By providing the config-name attribute we have given all configuration sources a name. Al proporcionar el config-name atributo que hemos dado todas las fuentes de configuración de un nombre. This name can be used to obtain the corresponding sources from the combined configuration. Este nombre puede ser utilizado para obtener las fuentes correspondientes desde la configuración combinada. For configurations in the override section this is directly possible: Para las configuraciones en la sección de reemplazar este es directamente posible:

Configuration propertiesConfig = cc.getConfiguration(“properties”); Configuration propertiesConfig = cc.getConfiguration(“properties”);

Configuration xmlConfig = cc.getConfiguration(“xml”); Configurations in the additional section are treated a bit differently: they are all packed together in another combined configuration and then added to the resulting combined configuration.

Configuraciones en el additional sección se tratan un poco diferente: todos ellos son empaquetadas de otra configuración combinada y añade a continuación a la combinación de configuración resultante. So in our example the combined configuration cc will contain three configurations: the two configurations from the override section, and the combined configuration with the additional configurations. Así que en nuestro ejemplo, la configuración combinada cc contendrá tres configuraciones: las dos configuraciones de la sección de aumento al presupuesto, y la configuración combinada con la additional configuraciones. The latter is stored under a name determined by the ADDITIONAL_NAME constant of DefaultConfigurationBuilder . Este último se almacena bajo un nombre determinado por el ADDITIONAL_NAME constante de DefaultConfigurationBuilder . The following code shows how the configurations of the additional section can be accessed: El código siguiente se muestra cómo las configuraciones de los additional sección se puede acceder a:

CombinedConfiguration ccAdd = (CombinedConfiguration) CombinedConfiguration ccAdd = (CombinedConfiguration)

cc.getConfiguration(DefaultConfigurationBuilder.ADDITIONAL_NAME);

Configuration tab1Config = ccAdd.getConfiguration(“tab1”);

Configuration tab2Config = ccAdd.getConfiguration(“tab2”);

Extending the configuration definition file format La extensión de la definición de formato de archivo de configuración

If you have written a custom configuration class, you might want to declare instances of this class in a configuration definition file, too. With DefaultConfigurationBuilder this is now possible by registering a ConfigurationProvider . Si usted ha escrito una clase de configuración personalizada, es posible que desee declarar instancias de esta clase en un archivo de definición de la configuración, también. Con DefaultConfigurationBuilder esto es ahora posible mediante el registro de una ConfigurationProvider.

ConfigurationProvider is an inner class defined in DefaultConfigurationBuilder . ConfigurationProvider es una clase interna se define en DefaultConfigurationBuilder . Its task is to create and initialize a configuration object. Su tarea es crear e inicializar un objeto de configuración. Whenever DefaultConfigurationBuilder encounters a tag in the override or the additional section it checks whether for this tag a ConfigurationProvider was registered. Siempre DefaultConfigurationBuilder se encuentra con una etiqueta en la override o el additional comprueba si la sección de esta etiqueta un ConfigurationProvider se registró. If this is the case, the provider is asked to create a new configuration instance; otherwise an exception will be thrown. Si este es el caso, el proveedor se le pide que cree una instancia nueva configuración, de lo contrario una excepción será lanzada.

So for adding support for a new configuration class you have to create an instance of ConfigurationProvider (or a derived class) and register it at the configuration builder using the addConfigurationProvider() method. Así que para añadir soporte para una clase nueva configuración que tienes que crear una instancia de ConfigurationProvider (o una clase derivada) y registrarlo en el constructor de la configuración mediante el addConfigurationProvider() método. This method expects the name of the associated tag and the provider instance as arguments. Este método espera que el nombre de la etiqueta asociada y la instancia del proveedor como argumentos.

If your custom configuration class does not need any special initialization, you can use the ConfigurationProvider class directly. Si la clase de configuración personalizada no necesita inicialización especial, usted puede utilizar el ConfigurationProvider clase directamente. It is able of creating an instance of a specified class (which must be derived from AbstractConfiguration ). Es capaz de crear una instancia de una determinada categoría (que debe derivarse de AbstractConfiguration ). Let’s take a look at an example where we want to add support for a configuration class called MyConfiguration . Echemos un vistazo a un ejemplo en el que desea agregar soporte para una clase de configuración llamado MyConfiguration . The corresponding tag in the configuration definition file should have the name myconfig . La etiqueta correspondiente en el archivo de definición de configuración debe tener el nombre myconfig . The code for registering the new provider and loading the configuration definition file looks as follows: El código para el registro del nuevo proveedor y cargando el archivo de definición de configuración es el siguiente:

DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder(); DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();

DefaultConfigurationBuilder.ConfigurationProvider provider = new

DefaultConfigurationBuilder.ConfigurationProvider(MyConfiguration.class);

builder.addConfigurationProvider(“myconfig”, provider);

builder.setFileName(“configuration.xml”);

Configuration config = builder.getConfiguration(); If your configuration provider is registered this way, your configuration definition file can contain the myconfig tag just as any other tag for declaring a configuration source:

Si su proveedor de configuración se registra esta manera, su archivo de definición de configuración puede contener la myconfig etiqueta al igual que cualquier otra etiqueta para declarar una fuente de configuración:

<configuration> <configuration>

<additional>

<xml fileName=”settings.xml”/>

<myconfig delimiterParsingDisabled=”true”/>

</additional>

</configuration>

As is demonstrated in this example, it is possible to specify attributes for initializing properties of your configuration object. Como se demuestra en este ejemplo, es posible especificar los atributos de la inicialización de propiedades de su objeto de configuración. In this example we set the default delimiterParsingDisabled property inherited from AbstractConfiguration . En este ejemplo, establecer el valor predeterminado delimiterParsingDisabled la propiedad heredada de AbstractConfiguration . Of course you can set custom properties of your configuration class, too. Por supuesto, usted puede establecer las propiedades de las costumbres de su clase de configuración, también.

If your custom configuration class is a file-based configuration, you should use the FileConfigurationProvider class instead of ConfigurationProvider . FileConfigurationProvider is another inner class of DefaultConfigurationBuilder that knows how to deal with file-based configurations: it ensures that the correct base path is set and takes care of invoking the load() method. Si la clase es una configuración personalizada basada en archivo de configuración, debe utilizar el FileConfigurationProvider clase en lugar de ConfigurationProvider . FileConfigurationProvider es otra clase interna de DefaultConfigurationBuilder que sabe cómo lidiar con configuraciones basadas en archivo: asegura que el camino correcto de la base se establece y se encarga de invocar el load() método.

If your custom configuration class requires special initialization, you need to create your own provider class that extends ConfigurationProvider . Si la clase de configuración personalizada requiere una inicialización especial, usted necesita para crear su propia clase de proveedor que se extiende ConfigurationProvider . Here you will have to override the getConfiguration(ConfigurationDeclaration) method, which is responsible for creating the configuration instance (all information necessary for this purpose can be obtained from the passed in declaration object). Aquí usted tendrá que reemplazar el getConfiguration(ConfigurationDeclaration) método, que es responsable de crear la instancia de configuración (toda la información necesaria para este fin se puede obtener desde el pasado en la declaración objeto). It is recommended that you call the inherited method first, which will instantiate and initialize the new configuration object. Se recomienda que se llama al método heredado en primer lugar, que instanciar e inicializar el objeto de configuración nueva. Then you can perform your specific initialization. Entonces usted puede realizar su inicialización específico.

Configuraciones multi-tenant

In a multi-tenant environment a single instance of the application while run on behalf of many clients. En un entorno multi-tenant una única instancia de la aplicación mientras se ejecutan en nombre de muchos clientes. Typically, this will require that each client have its own unique configuration. Normalmente, para ello será necesario que cada cliente tiene su propia configuración única. The simplest approach to enable an application to be multi-tenant is for it to not really be aware of it at all. El enfoque más simple para que una solicitud para ser multi-inquilino es para que no sea realmente consciente de ello en absoluto. This requires that the configuration framework take on some of the responsility for making the application work correctly. Para ello es necesario que el marco de configuración de asumir algunas de las responsility del buen funcionamiento de la aplicación correctamente.

One approach to enable this support in a web application might be to use a Servlet Filter and then use the Log4j or SLF4J MDC to save the attributes needed to identify the client. Un procedimiento para que este apoyo en una aplicación web puede ser el uso de un filtro de servlet y luego usar el Log4j o MDC SLF4J para guardar los atributos necesarios para identificar al cliente. These attributes can then be used to identify the specific client configuration to be used. Estos atributos pueden ser utilizados para identificar la configuración de cliente específico que se utilizará. The classes described below use this technique to allow configurations to transparently provide the configuration appropriate for the clients. Los tipos que se describen a continuación utilizan esta técnica para permitir configuraciones para proporcionar de forma transparente la configuración adecuada para los clientes.

MultiFileHierarchicalConfiguration MultiFileHierarchicalConfiguration

The constructor for this class accepts a pattern. El constructor de esta clase acepta un patrón. The pattern can contain keys that will be resolved using the ConfigurationInterpolator on each call to a method in the class. El patrón puede contener las claves que serán resueltas mediante el ConfigurationInterpolator en cada llamada a un método en la clase. The configuration file will then be located using the resolved pattern and a new XMLConfiguration will be created and cached for subsequent requests. El archivo de configuración se encuentra usando el patrón de resolver y una XMLConfiguration nuevo será creado y almacenado en caché para las solicitudes posteriores. The ExpressionEngine, ReloadingStrategy and listeners will be propogated to each of the created configurations. El ExpressionEngine, ReloadingStrategy y los oyentes se propogated a cada una de las configuraciones creadas.

DynamicCombinedConfiguration DynamicCombinedConfiguration

The CombinedConfiguration class allows multiple configuration files to be merged together. La clase CombinedConfiguration permite la configuración de varios archivos que se fusionaron. However, it will not merge a MultiFileHierarchicalConfiguration properly since the underlying configuration file will be different depending on the resolution of the location pattern. Sin embargo, no va a combinar un MultiFileHierarchicalConfiguration correctamente desde el archivo de configuración subyacentes será diferente dependiendo de la resolución del modelo de localización. DynamicCombinedConfiguration solves this by creating a new CombinedConfiguration for each pattern. DynamicCombinedConfiguration soluciona esto creando un nuevo CombinedConfiguration para cada patrón.

Sample Configuration Ejemplo de Configuración

This sample configuration illustrates how to use DynamicCombinedConfiguration in combination with MultiFileHierarchicalConfiguration to create a multi-tenant configuration. Esta configuración de ejemplo muestra cómo utilizar en combinación con DynamicCombinedConfiguration MultiFileHierarchicalConfiguration para crear una configuración multi-arrendatario.

<?xml version=”1.0″ encoding=”ISO-8859-1″ ?> <?xml version=”1.0″ encoding=”ISO-8859-1″ ?>

<!– Configuración del archivo de definición de prueba que pueda servir para la inicialización compleja –>

<configuration>

<header>

<result delimiterParsingDisabled=”true” forceReloadCheck=”true”

config-class=”org.apache.commons.configuration.DynamicCombinedConfiguration”

keyPattern=”${sys:Id}”>

<expressionEngine

config-class=”org.apache.commons.configuration.tree.xpath.XPathExpressionEngine”/>

</result>

<providers>

<provider config-tag=”multifile”

config-class=”org.apache.commons.configuration.DefaultConfigurationBuilder$FileConfigurationProvider”

configurationClass=”org.apache.commons.configuration.MultiFileHierarchicalConfiguration”/>

</providers>

</header>

<override>

<multifile filePattern=”/opt/configs/${sys:Id}/config.xml” config-name=”clientConfig”/>

<xml fileName=”/opt/configs/default/config.xml” config-name=”defaultConfig”/>

</override>

</configuration>

PatternSubtreeConfigurationWrapper PatternSubtreeConfigurationWrapper

Applications are often composed of many components each of which need their own configuration. Las solicitudes están a menudo compuestos por varios componentes cada uno de los cuales necesitan su propia configuración. This can be accomodated by having a configuration file per component, but this can make things hard to manage when there are many clients and many components. Esto puede ser satisfecha por tener un archivo de configuración de cada componente, pero esto puede hacer que las cosas son difíciles de manejar cuando hay muchos clientes y muchos componentes. A second approach is to combine them into a single configuration file. Un segundo enfoque consiste en combinar en un único archivo de configuración. However, this either means the subcomponent has to be aware of the surrounding configuration and navigate past it or the application must be provided just the portion of the configuration it can process. Sin embargo, esto tampoco significa que el sub-componente tiene que ser consciente de la configuración de los alrededores y navegar pasado o la aplicación debe proporcionar sólo la parte de la configuración que puede procesar. PatternSubtreeConfigurationWrapper can be used for this purpose. PatternSubtreeConfigurationWrapper se puede utilizar para este propósito.

Normal practice when using dependency injection frameworks is to have the attributes needed to make components work correctly injected into them. When working with Commons Configuration this works very well. La práctica normal cuando se utiliza la inyección marcos de dependencia es tener los atributos necesarios para hacer que los componentes funcionen correctamente inyecta en ellos. Cuando se trabaja con esta configuración Commons funciona muy bien. Components simply need to have a HierarchicalConfiguration attribute along with a corresponding setter and getter. Componentes simplemente necesitan tener un atributo HierarchicalConfiguration junto con un setter y getter correspondiente. The injection framework can then be used to provide the component with the correct configuration using PatternSubtreeConfigurationWrapper as shown in the next example. El marco de la inyección puede ser utilizado para proporcionar el componente con la configuración correcta con PatternSubtreeConfigurationWrapper como se muestra en el siguiente ejemplo.

<bean id=”configurationBuilder”

class=”org.apache.commons.configuration.DefaultConfigurationBuilder”>

<property name=”fileName”>

<value>configuration.xml</value>

</property>

</bean>

<bean id=”applicationConfig” factory-bean=”configurationBuilder”

factory-method=”getConfiguration”>

</bean>

<bean id=”subcomponentConfig”

class=”org.apache.commons.configuration.PatternSubtreeConfigurationWrapper”

autowire=’autodetect’>

<constructor-arg index=”0″>

<ref bean=”applicationConfig”/>

</constructor-arg>

<constructor-arg index=”1″ value=”/Components/MyComponent”

</bean>

<bean id=’MyComponent’ class=’org.test.MyComponent’ autowire=’autodetect’>

<property name=”configuration”>

<ref bean=”subcomponentConfig”/>

</property>

</bean>

Configuración de Eventos

All configuration classes derived from AbstractConfiguration allow to register event listeners, which are notified whenever the configuration’s data is changed. Todas las clases de configuración derivados de AbstractConfiguration permiten registrar detectores de eventos, que se notifiquen cada vez que la configuración de datos se cambia. This provides an easy means for tracking updates on a configuration. Esto proporciona un medio fácil para el seguimiento de las actualizaciones en una configuración.

Configuration listeners Configuración de oyentes

Objects that are interested in update events triggered by configurations must implement the ConfigurationListener interface. Los objetos que están interesados en los eventos de actualización desencadenada por configuraciones debe implementar la ConfigurationListener interfaz. This interface defines a single method configurationChanged() , which is passed a ConfigurationEvent object. Esta interfaz define un único método configurationChanged() , que se pasa un ConfigurationEvent objeto. The event object contains all information available about the modification, including: El objeto de evento contiene toda la información disponible acerca de la modificación, incluyendo:

  • A source object, which is usually the configuration object that was modified. Un objeto de origen, que suele ser el objeto de configuración que se ha modificado.
  • The event’s type. El evento de tipo. This is a numeric value that corresponds to constant declarations in concrete configuration classes. Este es un valor numérico que corresponde a las declaraciones constantes en las clases de configuración concreta. It describes what exactly has happended. En ella se describe lo que ocurrió exactamente.
  • If available, the name of the property whose modification caused the event. Si está disponible, el nombre de la propiedad cuyo cambio provocó el evento.
  • If available, the value of the property that caused this event. Si está disponible, el valor de la propiedad que causó este evento.
  • A flag whether this event was generated before or after the update of the source configuration. Una bandera si este evento fue generado antes o después de la actualización de la configuración de origen. A modification of a configuration typically causes two events: one event before and one event after the modification is performed. Una modificación de una configuración típicamente causa dos eventos: un evento antes y después del evento de una modificación se realiza. This allows event listeners to react at the correct point of time. Esto permite que los detectores de eventos para reaccionar en el punto correcto de tiempo.

Depending on the event type not all of this data may be available. Dependiendo no en el tipo de evento todos estos datos pueden estar disponibles.

For resolving the numeric event type use constants defined in AbstractConfiguration or derived classes. Para resolver el caso constantes numéricas usar el tipo definido en AbstractConfiguration o clases derivadas. These constants start with the prefix EVENT_ and have a speaking name. Estas constantes comienzan con el prefijo EVENT_ y tener un nombre de habla hispana. Here is an incomplete list of available event types with the configuration classes, in which they are defined: He aquí una lista incompleta de tipos de eventos disponibles con las clases de configuración, en el que se definen:

AbstractConfiguration AbstractConfiguration

EVENT_ADD_PROPERTY (a property was added; the name of the affected property and the value that was added can be obtained from the event object), EVENT_SET_PROPERTY (a property’s value was changed; the event object stores the name of the affected property and its new value), EVENT_CLEAR_PROPERTY (a property was removed from the configuration; its name is stored in the event object), EVENT_CLEAR (the configuration was cleared) EVENT_ADD_PROPERTY (una propiedad se añadió el nombre de la propiedad afectada y el valor que se ha añadido puede ser obtenido a partir del objeto de evento), EVENT_SET_PROPERTY (propiedad de un valor había cambiado; las tiendas objeto de evento el nombre de la propiedad afectada y su nuevo valor ), EVENT_CLEAR_PROPERTY (una propiedad fue retirado de la configuración, su nombre se almacena en el objeto de evento), EVENT_CLEAR (la configuración se ha borrado)

AbstractFileConfiguration AbstractFileConfiguration

EVENT_RELOAD (the configuration was reloaded) EVENT_RELOAD (la configuración se vuelve a cargar)

HierarchicalConfiguration HierarchicalConfiguration

EVENT_ADD_NODES (the addNodes() method was called; the event object contains the key, to which the nodes were added, and a collection with the new nodes as value), EVENT_CLEAR_TREE (the clearTree() method was called; the event object stores the key of the removed sub tree), EVENT_SUBNODE_CHANGED (a SubnodeConfiguration that was created from this configuration has been changed. The value property of the event object contains the original event object as it was sent by the subnode configuration. Note: At the moment it is not possible to map the property key as it was received from the subnode configuration into the namespace of the parent configuration.) EVENT_ADD_NODES (el addNodes() fue llamado método, el objeto de evento contiene la clave, a la que los nodos se han añadido, y una colección con los nuevos nodos como valor), EVENT_CLEAR_TREE (el clearTree() fue llamado método; las tiendas el objeto de evento clave de la sub árbol que es removido), EVENT_SUBNODE_CHANGED (un SubnodeConfiguration que fue creado a partir de esta configuración se ha cambiado. El valor de la propiedad del objeto de evento contiene el objeto de evento original que fue enviado por la configuración subnodo. Nota: En el momento en que se no es posible asignar la tecla de propiedad, ya que se recibió la configuración subnodo en el espacio de nombres de la configuración de los padres.)

An example Un ejemplo

Implementing an event listener is quite easy. La aplicación de un detector de eventos es bastante fácil. As an example we are going to define an event listener, which logs all received configuration events to the console. Como ejemplo vamos a definir un detector de eventos, que registra todos los eventos de configuración recibidos en la consola. The class could look as follows: La clase podría ser el siguiente:

import org.apache.commons.configuration.event.ConfigurationEvent; import org.apache.commons.configuration.event.ConfigurationEvent;

import org.apache.commons.configuration.event.ConfigurationListener;

public class ConfigurationLogListener implements ConfigurationListener

{

public void configurationChanged(ConfigurationEvent event)

{

if (!event.isBeforeUpdate())

{

// only display events after the modification was done

System.out.println(“Received event!”);

System.out.println(“Type = ” + event.getType());

if (event.getPropertyName() != null)

{

System.out.println(“Property name = ” + event.getPropertyName());

}

if (event.getPropertyValue() != null)

{

System.out.println(“Property value = ” + event.getPropertyValue());

}

}

}

}

Now an instance of this event listener class has to be registered at a configuration object:

Ahora un ejemplo de esta clase de detector de eventos tiene que ser registrada en un objeto de configuración:

AbstractConfiguration config = … AbstractConfiguration config = … // Alguna manera de crear la configuración

ConfigurationListener listener = new ConfigurationLogListener();

config.addConfigurationListener(listener);


config.addProperty(“newProperty”, “newValue”); // / se disparará un evento

Error listeners Error oyentes

Some implementations of the Configuration interface operate on underlying storages that can throw exceptions on each property access. As an example consider DatabaseConfiguration : this configuration class issues an SQL statement for each accessed property, which can potentially cause a SQLException . Algunas implementaciones de la Configuration interfaz de operar en almacenes subyacentes que pueden producir excepciones en cada acceso a la propiedad. Como ejemplo, consideremos DatabaseConfiguration : esta clase de configuración emite una instrucción SQL para cada propiedad visitada, lo cual puede provocar una SQLException .

In earlier versions of Commons Configuration such exceptions were simply logged and then swallowed. En versiones anteriores de los Comunes tales excepciones se registra configuración sencilla y luego tragarse. So for clients it was impossible to find out if something went wrong. Así que para los clientes que era imposible saber si algo salió mal. From version 1.4 on there is a new way of dealing with those internal errors: the concept of error listeners . Desde la versión 1.4 de la existencia es una nueva forma de tratar con los errores internos: el concepto de oyentes de error.

A configuration error listener is very similar to a regular configuration event listener. Un oyente error de configuración es muy similar a un detector de configuración evento regular. Instead of the ConfigurationListener interface it has to implement the ConfigurationErrorListener interface, which defines a single method configurationError() . En lugar de la ConfigurationListener interfaz tiene que aplicar el ConfigurationErrorListener interfaz, que define un único método configurationError() . In case of an internal error this method is invoked, and a ConfigurationErrorEvent with information about that error is passed. En caso de un error interno de este método es invocado, y un ConfigurationErrorEvent con información sobre el error pasado es. By inheriting from ConfigurationEvent ConfigurationErrorEvent supports all information that is available for normal configuration listeners, too (eg the event type or the property that was accessed when the problem occurred; note that the isBefore() method does not really make sense for error events because an error can only occur after something was done, so it returns always false is this context). Al heredar de ConfigurationEvent ConfigurationErrorEvent apoya toda la información que está disponible para los oyentes de configuración normal, también (por ejemplo, el tipo de evento o la propiedad que se accede a ellos cuando se produjo el problema, tenga en cuenta que la isBefore() método no tiene mucho sentido para los eventos de error porque una error sólo puede ocurrir después de que se hiciera algo, así que retorna siempre falso es este contexto). This data can be used to find out when and where the error happened. Estos datos pueden utilizarse para averiguar cuándo y dónde ocurrió el error. In addition there is the getCause() method that returns the Throwable object, which generated this event (ie the causing exception). Además existe la getCause() que devuelve el método Throwable objeto, lo que generó este evento (es decir, la excepción que causa).

We can now continue our example from the previous section and make our example configuration listener also capable of tracing error events. Ahora podemos continuar con nuestro ejemplo de la sección anterior y hacer que nuestro oyente ejemplo de configuración también es capaz de localizar a los eventos de error. To achieve this we let the ConfigurationLogListener class also implement the ConfigurationErrorListener interface: Para ello dejamos que el ConfigurationLogListener clase también aplicar el ConfigurationErrorListener interfaz:

import org.apache.commons.configuration.event.ConfigurationEvent; import org.apache.commons.configuration.event.ConfigurationEvent;

import org.apache.commons.configuration.event.ConfigurationListener;

import org.apache.commons.configuration.event.ConfigurationListener;

public class ConfigurationLogListener

implements ConfigurationListener, ConfigurationErrorListener

{

public void configurationChanged(ConfigurationEvent event)

{

//Se mantiene sin cambios, ver arriba


}


public void configurationError(ConfigurationErrorEvent event)

{

System.out.println(“An internal error occurred!”);

// Registro de las propiedades estándar del evento de configuración

configurationChanged(event);

// Ahora el diario de excepción

event.getCause().printStackTrace();

}

}}

Now the listener object has to be registered as an error listener, too. For this purpose AbstractConfiguration provides the addErrorListener() method. Ahora el objeto oyente tiene que ser registrado como un detector de error, también. Para ello AbstractConfiguration proporciona la addErrorListener() método. The following example fragment shows the registration of the log listener object: El fragmento siguiente ejemplo muestra el registro del objeto de escucha de registro:

AbstractConfiguration config = … AbstractConfiguration config = … // somehow create the configuration

ConfigurationListener listener = new ConfigurationLogListener();

config.addConfigurationListener(listener);

config.addErrorListener((ConfigurationErrorListener) listener);


config.addProperty(“newProperty”, “newValue”); // will fire an eventNote: AbstractConfiguration already implements a mechanism for writing internal errors to a logger object: It has the protected addErrorLogListener() method that can be called by derived classes to register a listener that will output all occurring internal errors using the default logger.

Nota: AbstractConfiguration ya implementa un mecanismo de errores de grabación interna de un objeto registrador: Tiene la protegida addErrorLogListener() método que puede ser llamado por las clases derivadas de registro de un oyente que da salida a todos que ocurren errores internos de utilizar el registrador por defecto. Configuration implementations like DatabaseConfiguration that are affected by potential internal errors call this method during their initialization. implementaciones de configuración como DatabaseConfiguration que se ven afectados por el potencial de errores internos llamar a este método durante su inicialización. So the default behavior of Commons Configuration for these classes is not changed: they still catch occurring exceptions and log them. Así, el comportamiento predeterminado de configuración de los Comunes para estas clases no se modifica aún capturas se producen excepciones y registro de ellos. However by registering specific error listeners it is now possible for clients to implement their own handling of such errors. Sin embargo mediante el registro de error específicos oyentes, ahora es posible para los clientes a implementar sus propias manejo de dichos errores.

Utilidad de las clases y consejos y trucos

In this section some utility classes will be introduced that can be used to make handling of configuration objects easier. En esta sección algunas clases de utilidad se introducirán que se pueden utilizar para facilitar la manipulación de objetos de configuración más fácil. These classes already provide solutions for some often occurring problems. Estas clases ya proporcionan soluciones para algunos problemas que ocurren a menudo. We will list these problems in no specific order and show how they can be solved with classes provided by Commons Configuration . Vamos a enumerar estos problemas en ningún orden específico y mostrar cómo se pueden resolver con las clases de configuración proporcionada por los Comunes.

Copy a configuration Copiar una configuración

Often it is required to copy the data of one Configuration object into another one. A menudo es necesario para copiar los datos de una Configuration un objeto en otro. For this purpose the AbstractConfiguration class (which serves as the base class for most of the configuration implementations shipped with this library) provides two methods implementing a basic copy operation: Para ello, el AbstractConfiguration clase (que sirve como clase base para la mayoría de las implementaciones de configuración de fábrica con esta biblioteca) ofrece dos métodos de aplicación de una operación de copia de base:

  • append() takes the configuration to be copied as argument and adds all of its properties to the current configuration. append() toma la configuración que desea copiar como argumento y agrega todas sus propiedades a la configuración actual.
  • copy() is very similar to append() . copy() es muy similar a append() . The difference is that properties that already exist in the target configuration are replaced by the properties of the source configuration. La diferencia es que las propiedades que ya existen en la configuración de destino se sustituyen por las propiedades de la configuración de origen.

These methods work fine if the target configuration is not a hierarchical configuration. Estos métodos funcionan bien si la configuración de destino no es una configuración jerárquica. If a hierarchical configuration is to be copied into another one, the methods are not able to handle the hierarchical structure; so the resulting configuration will contain all of the properties of the source configuration, but the specific parent-child relations will probably be lost. Si una configuración jerárquica se va a copiar en otro, los métodos no son capaces de manejar la estructura jerárquica, lo que la configuración resultante contendrá todas las propiedades de la configuración de fuente, pero la relación entre padres e hijos-específicas, probablemente se perderá. If a hierarchical configuration needs to be copied, there are the following options: Si una configuración jerárquica debe ser copiada, existen las siguientes opciones:

  • The clone() method can be used to create a copy of a hierarchical configuration. El clone() método se puede utilizar para crear una copia de una configuración jerárquica. This also works for non-hierarchical configurations. Esto también funciona para configuraciones no-jerárquica. Most of the configuration implementations provided by Commons Configurations support cloning. La mayoría de las implementaciones de configuración proporcionada por los Comunes Configuraciones favor de la clonación. The cloneConfiguration() method of ConfigurationUtils can be used for creating a copy of an arbitrary Configuration object. El cloneConfiguration() método de ConfigurationUtils se puede utilizar para crear una copia de una arbitraria Configuration objeto. This method checks whether the passed in configuration implements the Cloneable interface and, if so, invokes its clone() method. Este método comprueba si la implementa en la configuración pasado la Cloneable interfaz y, si es así, invoca su clone() método.
  • Most hierarchical configurations have a constructor, which takes another hierarchical configuration as argument. La mayoría de las configuraciones jerárquicas tener un constructor, que tiene otra configuración jerárquica como argumento. This constructor copies the content of the specified configuration into the newly created object. Este constructor de copias del contenido de la configuración especificada en el objeto recién creado.

Converting a flat configuration into a hierarchical one La conversión de una configuración de plano en un jerárquica

Hierarchical configurations provide some enhanced features that are not available for “flat” configurations. configuraciones jerárquica proporcionar algunas características mejoradas que no están disponibles para los “planos” de las configuraciones. For instance they support more sophisticated query facilities. Por ejemplo que apoyan consulta instalaciones más sofisticadas. Because of that it may be sometimes useful to transform an ordinary configuration into a hierarchical one. Debido a que puede ser a veces útil para transformar una configuración normal en una jerárquica. The following code fragment shows how this can be done: El fragmento de código siguiente se muestra cómo se puede hacer esto:

// Create a flat configuration / / Crear una configuración plana

PropertiesConfiguration flatConfig = new PropertiesConfiguration(); PropertiesConfiguration flatConfig = new PropertiesConfiguration();

flatConfig.load(…);

HierarchicalConfiguration hc =

ConfigurationUtils.convertToHierarchical(flatConfig);

The convertToHierarchical() method of ConfigurationUtils checks whether the passed in object is already a hierarchical configuration. El convertToHierarchical() método de ConfigurationUtils comprueba si el objeto está en el pasado ya una configuración jerárquica. If this is the case, it is returned unchanged. Si este es el caso, se devuelve sin cambios. Otherwise a new HierarchicalConfiguration object is created, and the properties of the source configuration are copied into it. De lo contrario un nuevo HierarchicalConfiguration objeto se crea, y las propiedades de la fuente de configuración se copian en ella.

Sometimes a flat configuration contains keys with special characters that are not compatible with the expression engine of a hierarchical configuration. A veces una configuración plana contiene las claves con caracteres especiales que no son compatibles con el motor de la expresión de una configuración jerárquica. For instance, a properties configuration could have the following property: Por ejemplo, una configuración de propiedades podría tener la propiedad siguiente:

test(xy)=true test(xy)=true

When processing this property during conversion the default expression engine of the resulting hierarchical configuration will interpret the brackets as an index marker and try to convert the string between the brackets into a number. Cuando el tratamiento de esta propiedad durante la conversión del motor de expresiones por defecto de la configuración resultante jerárquico interpretará los soportes como un índice del marcador y tratar de convertir la cadena entre los paréntesis en un número. In this example this fails with a NumberFormatException ! En este ejemplo no lo consigue con un NumberFormatException ! The cause for this problem is that the property key contains characters with a special meaning for the default expression engine. La causa de este problema es que la clave de propiedad contiene caracteres con un significado especial para el motor de expresiones por defecto.

To solve this problem, it is possible to specify an alternative expression engine that will be used for the conversion. Para solucionar este problema, es posible especificar un motor de expresiones alternativas que se utilizarán para la conversión. For instance, if you know that your property keys can contain brackets, you could use an instance of DefaultExpressionEngine that is configured with a different index marker. Por ejemplo, si usted sabe que su propiedad puede contener claves de soportes, se puede utilizar una instancia de DefaultExpressionEngine que está configurado con un marcador de índice diferentes. This could look as follows: Esto podría ser el siguiente:

DefaultExpressionEngine engineConvert = new DefaultExpressionEngine(); DefaultExpressionEngine engineConvert = new DefaultExpressionEngine();

engineConvert.setIndexStart(“[“);

engineConvert.setIndexEnd(“]”);

HierarchicalConfiguration hc =

ConfigurationUtils.convertToHierarchical(flatConfig, engineConvert);

In this example an expression engine is constructed that uses square brackets as index markers. En este ejemplo un motor de expresiones que utiliza se construye entre corchetes como marcadores de índice. Therefore normal brackets do not have a special meaning and thus are no more problematic during conversion. Por lo tanto los soportes normales no tienen un significado especial y por lo tanto no son más problemáticos durante la conversión.

Note: When using a CombinedConfiguration flat configurations contained in the combined configuration are also converted into hierarchical configurations using the methods discussed here. Nota: Si utiliza una CombinedConfiguration configuraciones planas contenidas en la configuración combinada también se convierten en configuraciones jerárquica utilizando los métodos descritos aquí. The CombinedConfiguration class defines the method setConversionExpressionEngine() , which can be called to specify an expression engine to be used during this conversion. El CombinedConfiguration clase define el método setConversionExpressionEngine() , que se puede llamar para especificar un motor de expresiones que se utilizarán durante esta conversión. The expression engine passed to this method will be propagated to ConfigurationUtils.convertToHierarchical(). El motor de expresiones pasado a este método se propagarán a ConfigurationUtils.convertToHierarchical ().

Converting between properties and configurations La conversión entre las propiedades y configuraciones

When working with the JDK the java.util.Properties class is typically used for storing configuration data. Al trabajar con el JDK el java.util.Properties clase se suele utilizar para almacenar datos de configuración. If Commons Configuration is to be integrated in such an application, there may be the requirement of converting from Properties objects to Configuration objects and vice versa. Si Commons configuración se va a integrar en la solicitud, es posible que la exigencia de la conversión de Properties objetos de Configuration los objetos y viceversa. For this purpose an utility class can be used: ConfigurationConverter . Para ello se puede una clase de herramienta que usa: ConfigurationConverter .

Usage of this class is pretty simple. El uso de esta clase es bastante simple. It provides some static utility methods that perform different conversions. Proporciona algunos métodos de utilidad estática que realizan diferentes conversiones. Below you can see some examples. A continuación puede ver algunos ejemplos. In this fragment we assume that we have a method processConfiguration() that is called from older parts of an application that are not aware of the Commons Configuration API. So they pass in a Properties object and expect one as return value. En este fragmento se supone que tenemos un método processConfiguration() que se llama desde las partes más antiguas de una aplicación que no son conscientes de la API de configuración de los Comunes. Así que pasan en un Properties objeto y esperar que uno como valor de retorno. Inside the method a temporary Configuration object is created and used. Dentro del método temporal Configuration objeto se crea y utiliza.

/** / **

* Does some processing of properties. * ¿Existe algún tratamiento de propiedades.

* @param props the source properties * @ Param puntales la fuente de propiedades

* @return the processed properties * @ Return las propiedades procesados

*/ * /

Properties processConfiguration(Properties props)

{

// Crear una configuración para las propiedades de fácil acceso

Configuration config = ConfigurationConverter.getConfiguration(props);

// Ahora usar el API de configuración para la manipulación de los datos de configuración


// Devuelve un objeto Properties con los resultados

return ConfigurationConverter.getProperties(config);

}Properties processConfiguration(Properties props)

Please refer to the Javadocs of ConfigurationConverter to learn more about the available conversion methods and their limitations.

Por favor refiérase a la Javadocs de ConfigurationConverter para aprender más sobre los métodos de conversión disponibles y sus limitaciones.

Interpolation of all variables La interpolación de todas las variables

Another issue with the integration of Commons Configuration with native Java applications can be variables: Configuration implementations are able to detect variables like ${myReference} or ${sys:java.version} in the values of their properties and substitute them by their current values (see the section Variable Interpolation for more details). Otro problema con la integración de los Comunes de configuración con aplicaciones nativas de Java pueden ser variables: las implementaciones de configuración son capaces de detectar las variables como ${myReference} o ${sys:java.version} en los valores de sus propiedades y sustituirlas por sus valores actuales (véase la sección Interpolación variable para más detalles). External components probably do not know how to handle such placeholders when processing configuration files written by Commons Configuration . Los componentes externos probablemente no sabe cómo manejar los marcadores de posición como el procesamiento de archivos de configuración cuando escrita por libre configuración.

AbstractConfiguration provides the method interpolatedConfiguration() . AbstractConfiguration proporciona el método interpolatedConfiguration() . This method creates a clone of the current configuration and then performs interpolation on all of its properties. Este método crea un clon de la configuración actual y, a continuación ejecuta la interpolación de todas sus propiedades. So the result of this method is a configuration object with basically the same content as the original configuration, but with all variables replaced by their actual values (as far as this was possible). The following code fragment shows how a PropertiesConfiguration object can be saved in a way that the resulting properties file does not contain any variables: Así, el resultado de este método es un objeto de configuración con básicamente el mismo contenido que la configuración original, pero con todas las variables reemplazadas por sus valores reales (por lo que esto era posible). El fragmento de código siguiente se muestra cómo un PropertiesConfiguration se pueden guardar directamente de manera que las propiedades de archivo resultante no contiene variables:

// Load a properties file (which may contain variables) // Cargar un archivo de propiedades (que pueden contener variables)

PropertiesConfiguration config = new PropertiesConfiguration(“config.properties”);

PropertiesConfiguration config = new PropertiesConfiguration(“config.properties”);

// Realizar la interpolación en todas las variables

PropertiesConfiguration extConfig =

(PropertiesConfiguration) config.interpolatedConfiguration();

// Guardar la configuración interpolado (sin variables más)

extConfig.save(“external_config.properties”);

Handling of runtime exceptions Manejo de excepciones en tiempo de ejecución

Section Error listeners introduces a way of dealing with runtime exceptions that can occur on accessing configuration properties by registering an event listener. Sección oyentes error introduce un modo de tratar las excepciones en tiempo de ejecución que puede ocurrir en el acceso a las propiedades de configuración mediante el registro de un detector de eventos. If you do not want to provide a special error handler, but only need to propagate the exception that caused the error event, you can make use of a convenience method of the ConfigurationUtils class: enableRuntimeExceptions() registers a special error listener at the passed in configuration that will throw a ConfigurationRuntimeException exception for each received error event. Si usted no desea proporcionar un controlador de errores especiales, pero sólo necesidad de propagar la excepción que provocó el evento de error, puede hacer uso de un método de conveniencia de la ConfigurationUtils clase: enableRuntimeExceptions() registra un oyente de error especial en el pasado en configuración que lanzará una ConfigurationRuntimeException excepción para cada evento de error recibido. The following code fragment shows an example of using this method: El fragmento de código siguiente se muestra un ejemplo del uso de este método:

JNDIConfiguration config = new JNDIConfiguration(); JNDIConfiguration config = new JNDIConfiguration();

ConfigurationUtils.enableRuntimeExceptions(config);

// Esto ahora puede lanzar una ConfigurationRuntimeException

String value = config.getString(“myKey”);

enableRuntimeExceptions() can be called for all Configuration implementations that are derived from EventSource (which is the case for almost all configuration classes provided by this library). enableRuntimeExceptions() puede ser llamado para todos Configuration implementaciones que se derivan de EventSource (que es el caso de casi todas las clases de configuración que ofrece esta biblioteca). Of course the affected implementation must support the mechanism of error events, otherwise the registered listener will not be triggered. Por supuesto, la aplicación afectada debe ser compatible con el mecanismo de eventos de error, de lo contrario el oyente registrado no se activará. In Error listeners more information can be found. En oyentes error más información se puede encontrar.

Minientrada | Esta entrada fue publicada en Apache. Guarda el enlace permanente.

Responder

Por favor, inicia sesión con uno de estos métodos para publicar tu comentario:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s