diff --git a/documentation/reference/pt-BR/configuracao.xml b/documentation/reference/pt-BR/configuracao.xml
index 50bf91c..3015516 100644
--- a/documentation/reference/pt-BR/configuracao.xml
+++ b/documentation/reference/pt-BR/configuracao.xml
@@ -8,38 +8,50 @@
Configurações em uma aplicação
- Muitas vezes é necessário parametrizar a aplicação à partir de arquivos de configuração ou variáveis de
- ambiente. O Demoiselle Framework traz algumas facilidades para você utilizar este
- recurso na sua aplicação para os casos mais comuns:
+ Muitas vezes, por motivos diversos, é necessário parametrizar a aplicação à partir de algum mecanismo de
+ configuração. E em java é comum se utilizar as seguintes abordagens para armazenas as configurações:
- arquivo de propriedades: tratam-se de simples arquivos de texto nomeados com a extensão
- .properties e que internamente são escritos com a sintaxe chave=valor,
- armazenando uma única chave por linha;
+
+ arquivo de propriedades: tratam-se de simples arquivos de texto nomeados com a
+ extensão .properties, os quais são escritos com a sintaxe chave=valor
+ , armazenando uma única chave por linha;
+
- arquivo XML: são arquivos de texto altamente estruturados com a sintaxe de tags e que
- permitem uma maior validação dos seus valores, sendo geralmente nomeados com a extensão .xml;
+
+ arquivo XML: são arquivos de texto altamente estruturados com a sintaxe de tags e
+ que permitem uma maior validação dos seus valores, sendo geralmente nomeados com a extensão
+ .xml;
+
- variáveis de ambiente: valores definidos no sistema operacional, independente de
- plataforma (Windows, Linux, etc) e que podem ser recuperados durante a execução da aplicação.
+
+ variáveis de ambiente: valores definidos no sistema operacional, independente de
+ plataforma (Windows, Linux, Mac OS, etc) e que podem ser recuperados durante a execução da aplicação.
+
+
+ Esse capítulo mostra de que maneira o Demoiselle Framework pode facilitar a utilização dessas
+ formas de configuração, oferencendo vários recursos interessantes e poderosos para a sua aplicação.
+
+
As classes de configuração
- A primeira etapa para a utilização do mecanismo de configuração em uma aplicação consiste em criar uma classe específica
- para armazenar os parâmetros desejados e anotá-la com @Configuration. Eis um exemplo:
+ O primeiro passo para a utilização do mecanismo de configuração em uma aplicação consiste em criar uma classe
+ específica para armazenar os parâmetros desejados e anotá-la com @Configuration. O código
+ abaixo mostra um exemplo de classe de configuração:
-
-
- Sugere-se criar apenas os acessores para leitura (getters). Para definir valores padrão,
- especifique-os na própria declaração do atributo (ex: boolean loadInitialData=true).
-
As classes anotadas com @Configuration são instanciadas uma única vez (seguindo o padrão
@@ -61,73 +69,65 @@ public class BookmarkConfig {
primeiro acesso à respectiva classe de configuração, quando os seus atributos são preenchidos automaticamente.
-
- No exemplo a seguir será buscado um arquivo de propriedades com o nome bookmark.properties
- contendo as seguintes chaves:
-
-
- Recomenda-se usar o sufixo Config
nas classes de configuração.
+ Recomenda-se usar o sufixo Config
nas classes de configuração, e que sejam criados
+ apenas os acessores para leitura (getters).
-
- O nome do recurso (resource) e o tipo de configuração (type) são argumentos
- opcionais na anotação @Configuration. Caso não sejam especificados, será considerado o arquivo
- de propriedades padrão do Demoiselle Framework, o demoiselle.properties.
-
-
+
-
- Especificando os parâmetros
- Por padrão todos os atributos existentes em uma classe anotada com @Configuration são tratados
- como parâmetros de configuração e serão automaticamente preenchidos durante a leitura do recurso.
+ Esse é um exemplo bastante simples, no qual não são especificados nem nome nem tipo do arquivo de configuração. Nessa
+ situação os parâmetros de nome applicationTitle e loadInitialData serão
+ procurados em um arquivo de propriedades de nome demoiselle.properties. Ou seja, quando não
+ especificados nome e tipo do arquivo, assume-se que o arquivo é do tipo propriedades
+ e seu nome é demoiselle. Mas como fazer para não utilizar o valor padrão e definir
+ nome e tipo do arquivo? Bastante simples. Basta adicionar esses parâmetros à anotação @Configuration, como mostra o
+ exemplo a seguir:
-
-
- Para ignorar um determinado atributo no processo automático de carregamento, anote-o com @Ignore.
- Para torná-lo obrigatório, anote-o com @NotNull.
-
-
-
- No arquivo de recursos será buscada a chave correspondente ao nome do atributo da classe.
- Por exemplo, para atributo loadInitialData será buscada a chave loadInitialData
- no recurso de configuração.
-
-
-
- Para redefinir os nomes das chaves, utilize a anotação @Name no atributo.
-
-
+
+
- Em determinadas situações é utilizado um prefixo comum a todos as chaves de configuração.
- Nestes casos, especifique atributo prefix da anotação @Configuration.
+ Devemos atribuir o nome do arquivo de configuração ao parâmetro resource, sem a extensão.
+ Ao parâmetro type pode ser atribuída uma das três possibilidades:
+ ConfigType.PROPERTIES, que é o valor padrão e indica que as configurações daquela classe
+ estão em um arquivo do tipo properties; ConfigType.XML, que indica que
+ as configurações daquela classe estão em um arquivo do tipo xml; e
+ ConfigType.SYSTEM, que indica que as configurações daquela classe são valores definidos pelo Sistema
+ Operacional. Nesse exemplo, ao definir resource e type os parâmetros de
+ nome applicationTitle e loadInitialData serão procurados em um arquivo
+ xml de nome my-property-file (my-property-file.xml).
- Veja na listagem abaixo um código fonte que ilustra a utilização das anotações descritas nesta seção:
+ Outro parâmetro que você pode ajustar nessa anotação é o prefixo. Ao definir um valor de prefixo você informa que
+ o nome das propriedades definidas naquela classe devem ser concatenados com o prefixo, de forma que o nome dos
+ atributos procurados no arquivo seja prefixo.nomeatributo. O exemplo abaixo mostra a
+ utilização desse parâmetro. Nesse caso, os parâmetros de nome info.applicationTitle e
+ info.loadInitialData serão procurados em um arquivo de propriedade de nome
+ my-property-file (my-property-file.properties).
-
-
-
-
-
-
-
-
-
-
-
- Na anotação @Configuration foram especificados o arquivo de recursos
- bookmark.properties e o prefixo general. para as
- chaves de configuração.
-
-
-
-
- Ao invés de adotar o padrão convencionado, a anotação @Name definirá a chave
- app.title após o prefixo.
-
-
-
-
- Como o atributo é anotado com @NotNull, presume-se que ele sempre
- estará presente no recurso. Caso contrário, uma exceção ocorrerá.
-
-
-
-
- Este atributo, por estar anotado com @Ignore, não será considerado
- no carregamento automático das configurações.
-
-
-
-
-
- Neste caso, será buscado um arquivo de propriedades com o nome bookmark.properties
- contendo as seguintes chaves:
-
-
+
+
+ O Demoiselle Framework adiciona automaticamente o ponto entre o prefixo e o nome do
+ atributo, você não precisa se preocupar com isso.
+
+
- Além de String e boolean, existe a possibilidade de se recuperar valores de qualquer
- tipo primitivo do Java (i.e., int, byte, short, char, long, float, double e boolean)
- e também arrays desses tipos e de alguns tipos complexos (i.e., Integer, BigDecimal, BigInteger, Calendar, Date,
- Color, Locale, URL e String).
+ No arquivo xml o prefixo corresponde a uma tag acima das tag que correspondem aos
+ atributos. O exemplo acima ficaria da seguinte forma em um arquivo xml:
+
+ Demoiselle Application<\applicationTitle>
+ true<\loadInitialData>
+
+
+]]>
+
-
+
- Usando a configuração na aplicação
+ Especificando os parâmetros
- A fim de utilizar o objeto de configuração previamente instanciado e preenchido pelo contêiner, basta criar uma variável numa
- classe qualquer da aplicação e anotá-la com @Inject. Tal variável será injetada automaticamente e pode ser
- usada dentro de um método. Veja na listagem a seguir um exemplo de injeção e uso de uma classe de configuração:
+ Atualmente são suportados nativamente pelo Demoiselle Framework parâmetros de cinco tipos
+ diferentes, são eles: primitivo, wrapped, String,
+ class, map e array, sendo que os três últimos
+ são suportados a partir da versão 2.4.0. A seguir vamos explicar e exemplificar como utilizar cada um desses
+ tipos, e alertar para as possíveis exceções que poderão ser lançadas para sua aplicação.
-
+
+ A partir da versão 2.4.0 não são mais reconhecidas as convenções. Os parâmetros serão procurados exatamente
+ como foram definidos na classe de configuração.
+
+
+
+
+
+
+
+
+ Primitivos
+
+
+
+
+
+ A utilização dos tipos primitivos é bastante simples. Veja no exemplo abaixo uma classe de configuração um arquivo
+ de configurações, que ilustram como é o procedimento para adicionar parâmetros do tipo primitivo.
+
+
-
-
- O Demoiselle Framework utiliza internamente o mecanismo de configurações na leitura do arquivo
- demoiselle.properties para outras funcionalidades, tais como transação, segurança, persistência e paginação.
-
-
-
-
- Lendo arquivos XML
-
- Agora veja como ficaria a abordagem de configuração usando arquivos XML. Eis um arquivo de exemplo, o
- escola.xml, possuindo um valor numérico e um conjunto de strings:
-
-
- 125
-
- Aluno
- Professor
- Administrador
-
-]]>
-
- Neste caso, na classe de configuração EscolaConfig a anotação @Configuration
- precisa apontar para o tipo de recursos XML e usar o respectivo arquivo escola.xml. Eis a
- implementação necessária para que o referido arquivo XML seja lido e os seus valores carregados automaticamente:
-
-
+ Para essa classe, o arquivo de propriedade correspondente (demoiselle.properties) deveria
+ apresentar o seguinte conteúdo:
+
+
+
+ Bastante simples, não? Mesmo assim, é bom ficarmos atentos, pois alguns cenários diferentes podem
+ acontecer. Vamos supor por exemplo que, por um motivo qualquer, a classe de configuração não esteja associada a um arquivo que contenha a chave de um de
+ seus parâmetros. Nesse caso será atribuido o valor padrão da linguagem ao atributo, que para os tipos primitivos
+ é 0, exceto para os tipos boolean, cujo valor padrão é false, e
+ char, cujo valor padrão é o caracter nulo ('\u0000').
+ Outro cenário possível é a existência da chave, mas sem valor atribuído (pageSize=). Nesse
+ caso o valor encontrado no arquivo é equivalente a uma String vazia, e a exceção
+ ConfigurationException, cuja causa foi uma ConversionException, será
+ lançada.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Wrappers
+
+
+
+
+
+ Os atributos do tipo wrapper devem ser utilizados da mesma forma que os atributos do tipo
+ primitivo. A única diferença entre eles é que o valor padrão atribuído a um parâmetro, no caso da classe de
+ configuração não estar associada a um arquivo que contenha sua chave, é nulo.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Strings
+
+
+
+
+
+ Por sua vez, as configurações do tipo String tem funcionalidade bastante similar às
+ configurações do tipo Wrapper. A diferença fica por conta de que, ao deixar a chave sem valor atribuído, para
+ atributo desse tipo, não será lançada exceção, pois que não haverá o problema de conversão, e à configuração
+ será atribuido o valor de uma String vazia.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Class
+
+
+
+
+
+ A partir da versão 2.4.0 é possível ter atributos do tipo Class como parâmetro. O atributo
+ pode ou não ser tipado, e no arquivo o valor atribuído à chave deve corresponder ao nome (
+ Canonical Name) de uma classe existente. Abaixo temos um exemplo de uma classe de configuração com
+ dois atributos do tipo Class, um tipado e outro não tipado:
+
+ typedClass;
- @Name("papeis.papel")
- private List papeis;
+ private Class> untypedClass;
- private Integer getQtdeInicial() {
- return qtdeInicial;
+ public Class getTypedClass() {
+ return typedClass;
}
- public List getPapeis() {
- return papeis;
+ public Class> getUntypedClass() {
+ return untypedClass;
}
-}]]>
-
+}
+ ]]>
+ O arquivo de propriedades teria o seguinte conteúdo:
+
+
+ Caso uma chave de uma configuração do tipo Class não tenha valor atribuído ou seja
+ atribuído um nome de classe que não existe (ou não possa ser encontrada pela aplicação), no momento do
+ seu carregamento sera lançada uma exceção do tipo ConfigurationException, cuja causa é uma
+ ClassNotFoundException. Caso a classe de configuração não esteja associada a um
+ arquivo que contenha a chave de um de seus parâmetros do tipo Class, este será carregado
+ com valor nulo.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Map
+
+
+
+
+
+ Para utilizar parâmetros do tipo Map, o arquivo de configurações deve usar a seguinte
+ estrutura na formação da chave: prefixo+chavedomap+nomedoatributo. Vejamos um exemplo.
+ Se temos em nossa aplicação uma classe de configuração como a mostrada abaixo:
+
+ url;
+
+ private Map driverClass;
+
+ public Map getUrl() {
+ return url;
+ }
+
+ public Map DriverClass() {
+ return driverClass;
+ }
+}
+ ]]>
+
+ O arquivo de configuração deverá ser preenchido no formato seguinte (se for do tipo properties):
+
+
+
+ Dessa forma, ao fazer a chamada url.get("mapkey2");por exemplo, o valor retornado será
+ jdbc:mysql://localhost:3306/app.
+
+
+
+ O ponto entre a chave do Map e o nome do parâmetro é adicionado automaticamente pelo
+ framework.
+
+
+
+
+ Você pode utilizar a chave do Map com nome "default" para indicar que, no arquivo de configuração, a chave é formada
+ apenas pela junção do prefixo com o atributo, sem utilizar a própria chave do Map. Por exemplo, se na sua classe
+ existir um comando como este:
+
+
+ o framework irá procurar no arquivo de configuração uma linha como esta:
+
+
+
+ Caso a classe de configuração não esteja associada a um arquivo que contenha a chave de um de seus parâmetros
+ do tipo Map, este será carregado com valor nulo, e estará sujeito às exceções
+ informadas anteriormente, conforme o tipo de variáveis que ele contenha.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Array
+
+
+
+
+
+ No caso do Array, a principal diferença em relação às demais formas de declarar
+ configurações é a maneira de atribuir valores aos seus respectivos elementos no arquivo de configuração.
+ Por exemplo, para que um Array de inteiros, de nome integerArray
+ tenha o conteúdo {-1, 0, 1}, você deve criar um arquivo de propriedades que contenha
+ as seguintes linhas:
+
+
+
+ Exceto a forma de atribuir os valores às configurações, se comporta de acordo com o tipo de variável que ele
+ contém, conforme o espeficifcado para cada um.
+
+
+
+
+
+
+
+
+
- Lendo variáveis de ambiente
-
- A terceira abordagem na configuração consiste em utilizar as variáveis de ambiente do sistema operacional.
- Estas variáveis geralmente são carregadas na inicialização do sistema ou após a criação da sessão do usuário
- (i.e., após o login), mas também podem ser modificadas manualmente através de comandos como set
- ou export.
-
-
- O mecanismo de configurações no Demoiselle Framework faz uso da classe
-
- java.lang.System fornecida pela API do Java para carregar os valores nas
- propriedades a partir de variáveis de ambiente independente do sistema operacional.
-
+ Mais Recursos
- Veja na listagem abaixo o código necessário para a leitura de uma variável de ambiente:
+ Além das possibilidades relacionadas acima, existem ainda algumas anotações e recursos extras que o
+ Demoiselle Framework oferece para o desenvolvedor na utilização das configurações. A seguir
+ listamos e explicamos como utilizar esses recursos em sua aplicação.
-
+
+
+
+
+
+ Ignore
+
+
+
+
+
+ Por padrão, todos os atributos existentes em uma classe anotada com @Configuration são tratados
+ como parâmetros de configuração e serão automaticamente preenchidos durante a leitura do recurso. Porém, caso você
+ não queira que determinado atributo seja tratado como parâmetro dentro desse tipo de classe, basta anotá-lo com
+ a anotação @Ignore, que o atributo será ignorado (como indica a própria anotação) pelo carregador
+ de configurações.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Valor Padrão
+
+
+
+
+
+ Muitas vezes é interessante que especifiquemos um valor padrão para o parâmetro, para o caso dele não estar
+ presente no arquivo de configuração. Para isso, basta atribuir o valor desejado no momento da declaração do
+ atributo, como exemplificado abaixo:
+
+
-
+} ]]>
+
+ Com essa atribuição, se no arquivo de propriedades não existir uma chave com valor applicationTitle
+ esse parametro será carregado com o valor My App.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Bean Validation
+
+
+
+
+
+ Fazer validação mantém a integridade dos dados e pode ser fator importante na lógica da aplicação. A partir da
+ versão 2.4.0 o Demoiselle permite que os atributos das classes de configuração sejam
+ anotados com todas as anotações definidas pela JSR 303 (Bean Validation). Com esse recurso você pode exigir que
+ determinado parâmetro não seja nulo (@NotNull), limitar um valor máximo ou mínimo para ele
+ (@Max e @Min, respectivamente), dentre outras restrições (que podem
+ ser feitas simultâneamente). A lista completa das restrições que podem ser aplicadas nos atributos das classes
+ de configuração pode ser conferida aqui:
+
+ http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html.
+
+
+ Para utilizar esse recurso você deve ter como dependência de seu projeto alguma implementação da especificação
+ Bean Validation. A implementação de referência é o
+ Hibernate Validator.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Name
+
+
+
+
+
+ Em alguns casos você pode querer que um determinado parâmetro tenha nomes diferentes na classe de configuração e
+ no arquivo de propriedades. Para isso você pode utilizar a anotação @Name. Basta anotar
+ o atributo passando como parâmetro o nome pelo qual você deseja que ele seja procurado no arquivo de propriedades,
+ como mostra o exemplo abaixo:
+
+
+
+ Com essa anotação, ao invés de procurar pela chave applicationTitle, o
+ Demoiselle irá buscar pela chave app.title.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Escopo
+
+
+
+
+
+ A partir da versão 2.3.3 do Demoiselle Framework as classes anotadas com
+ @Configuration estarão por padrão no escopo estático (@StaticScoped).
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Extratores
+
+
+
+
+
+ Você precisa de parâmetros de um tipo que ainda não é suportado pelo Demoiselle? Você
+ pode implementar sua própria classe extratora. A partir da versão 2.4.0 as aplicações
+ podem implementar a interface ConfigurationValueExtractor, e ter um
+ extrator de configurações para atributos de qualquer tipo. Essa interface obriga a classe
+ a implementar os métodos: boolean isSupported(Field field), que retorna true
+ caso a classe seja extratora daquele tipo de campo, e
+ Object getValue(String prefix, String key, Field field, Configuration configuration)
+ throws Exception que deve extrair o valor do campo da forma correta.
+
+
+
+
+
+
+
--
libgit2 0.21.2