Commit 2db71850f5b8f63fab14991f823f679572589f74
1 parent
7c6c4e7f
Exists in
master
Atualização da documentação de referência do Configuration.
Showing
1 changed file
with
522 additions
and
178 deletions
Show diff stats
documentation/reference/pt-BR/configuracao.xml
@@ -8,38 +8,50 @@ | @@ -8,38 +8,50 @@ | ||
8 | <section> | 8 | <section> |
9 | <title>Configurações em uma aplicação</title> | 9 | <title>Configurações em uma aplicação</title> |
10 | <para> | 10 | <para> |
11 | - Muitas vezes é necessário parametrizar a aplicação à partir de arquivos de configuração ou variáveis de | ||
12 | - ambiente. O <emphasis>Demoiselle Framework</emphasis> traz algumas facilidades para você utilizar este | ||
13 | - recurso na sua aplicação para os casos mais comuns: | 11 | + Muitas vezes, por motivos diversos, é necessário parametrizar a aplicação à partir de algum mecanismo de |
12 | + configuração. E em java é comum se utilizar as seguintes abordagens para armazenas as configurações: | ||
14 | <itemizedlist> | 13 | <itemizedlist> |
15 | <listitem> | 14 | <listitem> |
16 | - <emphasis>arquivo de propriedades</emphasis>: tratam-se de simples arquivos de texto nomeados com a extensão | ||
17 | - <filename>.properties</filename> e que internamente são escritos com a sintaxe <literal>chave=valor</literal>, | ||
18 | - armazenando uma única chave por linha; | 15 | + <para> |
16 | + <emphasis>arquivo de propriedades</emphasis>: tratam-se de simples arquivos de texto nomeados com a | ||
17 | + extensão <filename>.properties</filename>, os quais são escritos com a sintaxe <literal>chave=valor | ||
18 | + </literal>, armazenando uma única chave por linha; | ||
19 | + </para> | ||
19 | </listitem> | 20 | </listitem> |
20 | <listitem> | 21 | <listitem> |
21 | - <emphasis>arquivo XML</emphasis>: são arquivos de texto altamente estruturados com a sintaxe de tags e que | ||
22 | - permitem uma maior validação dos seus valores, sendo geralmente nomeados com a extensão <filename>.xml</filename>; | 22 | + <para> |
23 | + <emphasis>arquivo XML</emphasis>: são arquivos de texto altamente estruturados com a sintaxe de tags e | ||
24 | + que permitem uma maior validação dos seus valores, sendo geralmente nomeados com a extensão | ||
25 | + <filename>.xml</filename>; | ||
26 | + </para> | ||
23 | </listitem> | 27 | </listitem> |
24 | <listitem> | 28 | <listitem> |
25 | - <emphasis>variáveis de ambiente</emphasis>: valores definidos no sistema operacional, independente de | ||
26 | - plataforma (Windows, Linux, etc) e que podem ser recuperados durante a execução da aplicação. | 29 | + <para> |
30 | + <emphasis>variáveis de ambiente</emphasis>: valores definidos no sistema operacional, independente de | ||
31 | + plataforma (Windows, Linux, Mac OS, etc) e que podem ser recuperados durante a execução da aplicação. | ||
32 | + </para> | ||
27 | </listitem> | 33 | </listitem> |
28 | </itemizedlist> | 34 | </itemizedlist> |
29 | </para> | 35 | </para> |
36 | + <para> | ||
37 | + Esse capítulo mostra de que maneira o <emphasis>Demoiselle Framework</emphasis> pode facilitar a utilização dessas | ||
38 | + formas de configuração, oferencendo vários recursos interessantes e poderosos para a sua aplicação. | ||
39 | + </para> | ||
40 | + | ||
30 | </section> | 41 | </section> |
31 | <section> | 42 | <section> |
32 | <title>As classes de configuração</title> | 43 | <title>As classes de configuração</title> |
33 | <para> | 44 | <para> |
34 | - A primeira etapa para a utilização do mecanismo de configuração em uma aplicação consiste em criar uma classe específica | ||
35 | - para armazenar os parâmetros desejados e anotá-la com <literal>@Configuration</literal>. Eis um exemplo: | 45 | + O primeiro passo para a utilização do mecanismo de configuração em uma aplicação consiste em criar uma classe |
46 | + específica para armazenar os parâmetros desejados e anotá-la com <literal>@Configuration</literal>. O código | ||
47 | + abaixo mostra um exemplo de classe de configuração: | ||
36 | </para> | 48 | </para> |
37 | - <programlisting role="JAVA"><![CDATA[@Configuration(resource = "bookmark") | 49 | + <programlisting role="JAVA"><![CDATA[@Configuration |
38 | public class BookmarkConfig { | 50 | public class BookmarkConfig { |
39 | 51 | ||
40 | private String applicationTitle; | 52 | private String applicationTitle; |
41 | 53 | ||
42 | - private boolean loadInitialData = true; | 54 | + private boolean loadInitialData; |
43 | 55 | ||
44 | public String getApplicationTitle() { | 56 | public String getApplicationTitle() { |
45 | return applicationTitle; | 57 | return applicationTitle; |
@@ -49,10 +61,6 @@ public class BookmarkConfig { | @@ -49,10 +61,6 @@ public class BookmarkConfig { | ||
49 | return loadInitialData; | 61 | return loadInitialData; |
50 | } | 62 | } |
51 | }]]></programlisting> | 63 | }]]></programlisting> |
52 | - <para> | ||
53 | - Sugere-se criar apenas os acessores para leitura (<emphasis>getters</emphasis>). Para definir valores padrão, | ||
54 | - especifique-os na própria declaração do atributo (ex: <literal>boolean loadInitialData=true</literal>). | ||
55 | - </para> | ||
56 | <note> | 64 | <note> |
57 | <para> | 65 | <para> |
58 | As classes anotadas com <literal>@Configuration</literal> são instanciadas uma única vez (seguindo o padrão | 66 | As classes anotadas com <literal>@Configuration</literal> são instanciadas uma única vez (seguindo o padrão |
@@ -61,73 +69,65 @@ public class BookmarkConfig { | @@ -61,73 +69,65 @@ public class BookmarkConfig { | ||
61 | primeiro acesso à respectiva classe de configuração, quando os seus atributos são preenchidos automaticamente. | 69 | primeiro acesso à respectiva classe de configuração, quando os seus atributos são preenchidos automaticamente. |
62 | </para> | 70 | </para> |
63 | </note> | 71 | </note> |
64 | - <para> | ||
65 | - No exemplo a seguir será buscado um arquivo de propriedades com o nome <filename>bookmark.properties</filename> | ||
66 | - contendo as seguintes chaves: | ||
67 | - </para> | ||
68 | - <programlisting><![CDATA[application.title=Título da Aplicação | ||
69 | -load.initial.data=false | ||
70 | -]]></programlisting> | ||
71 | <note> | 72 | <note> |
72 | <para> | 73 | <para> |
73 | - Recomenda-se usar o sufixo <quote>Config</quote> nas classes de configuração. | 74 | + Recomenda-se usar o sufixo <quote>Config</quote> nas classes de configuração, e que sejam criados |
75 | + apenas os acessores para leitura (<emphasis>getters</emphasis>). | ||
74 | </para> | 76 | </para> |
75 | </note> | 77 | </note> |
76 | - <para> | ||
77 | - O nome do recurso (<literal>resource</literal>) e o tipo de configuração (<literal>type</literal>) são argumentos | ||
78 | - opcionais na anotação <literal>@Configuration</literal>. Caso não sejam especificados, será considerado o arquivo | ||
79 | - de propriedades padrão do <emphasis>Demoiselle Framework</emphasis>, o <filename>demoiselle.properties</filename>. | ||
80 | - </para> | ||
81 | - </section> | 78 | + |
82 | 79 | ||
83 | - <section> | ||
84 | - <title>Especificando os parâmetros</title> | ||
85 | <para> | 80 | <para> |
86 | - Por padrão todos os atributos existentes em uma classe anotada com <literal>@Configuration</literal> são tratados | ||
87 | - como parâmetros de configuração e serão automaticamente preenchidos durante a leitura do recurso. | 81 | + Esse é um exemplo bastante simples, no qual não são especificados nem nome nem tipo do arquivo de configuração. Nessa |
82 | + situação os parâmetros de nome <emphasis>applicationTitle</emphasis> e <emphasis>loadInitialData</emphasis> serão | ||
83 | + procurados em um arquivo de propriedades de nome <emphasis>demoiselle.properties</emphasis>. Ou seja, quando não | ||
84 | + especificados nome e tipo do arquivo, assume-se que o arquivo é do tipo <emphasis>propriedades</emphasis> | ||
85 | + e seu nome é <emphasis>demoiselle</emphasis>. Mas como fazer para não utilizar o valor padrão e definir | ||
86 | + nome e tipo do arquivo? Bastante simples. Basta adicionar esses parâmetros à anotação @Configuration, como mostra o | ||
87 | + exemplo a seguir: | ||
88 | </para> | 88 | </para> |
89 | - <tip> | ||
90 | - <para> | ||
91 | - Para ignorar um determinado atributo no processo automático de carregamento, anote-o com <literal>@Ignore</literal>. | ||
92 | - Para torná-lo obrigatório, anote-o com <literal>@NotNull</literal>. | ||
93 | - </para> | ||
94 | - </tip> | ||
95 | - <para> | ||
96 | - No arquivo de recursos será buscada a chave correspondente ao nome do atributo da classe. | ||
97 | - Por exemplo, para atributo <literal>loadInitialData</literal> será buscada a chave <literal>loadInitialData</literal> | ||
98 | - no recurso de configuração. | ||
99 | - </para> | ||
100 | - <tip> | ||
101 | - <para> | ||
102 | - Para redefinir os nomes das chaves, utilize a anotação <literal>@Name</literal> no atributo. | ||
103 | - </para> | ||
104 | - </tip> | 89 | + <programlisting role="JAVA"><![CDATA[@Configuration(resource="my-property-file", type=ConfigType.XML) |
90 | +public class BookmarkConfig { | ||
91 | + | ||
92 | + private String applicationTitle; | ||
93 | + | ||
94 | + private boolean loadInitialData; | ||
95 | + | ||
96 | + public String getApplicationTitle() { | ||
97 | + return applicationTitle; | ||
98 | + } | ||
99 | + | ||
100 | + public boolean isLoadInitialData() { | ||
101 | + return loadInitialData; | ||
102 | + } | ||
103 | +}]]></programlisting> | ||
104 | + | ||
105 | <para> | 105 | <para> |
106 | - Em determinadas situações é utilizado um prefixo comum a todos as chaves de configuração. | ||
107 | - Nestes casos, especifique atributo <literal>prefix</literal> da anotação <literal>@Configuration</literal>. | 106 | + Devemos atribuir o nome do arquivo de configuração ao parâmetro <emphasis>resource</emphasis>, sem a extensão. |
107 | + Ao parâmetro <emphasis>type</emphasis> pode ser atribuída uma das três possibilidades: | ||
108 | + <emphasis>ConfigType.PROPERTIES</emphasis>, que é o valor padrão e indica que as configurações daquela classe | ||
109 | + estão em um arquivo do tipo <emphasis>properties</emphasis>; <emphasis>ConfigType.XML</emphasis>, que indica que | ||
110 | + as configurações daquela classe estão em um arquivo do tipo <emphasis>xml</emphasis>; e <emphasis> | ||
111 | + ConfigType.SYSTEM</emphasis>, que indica que as configurações daquela classe são valores definidos pelo Sistema | ||
112 | + Operacional. Nesse exemplo, ao definir <emphasis>resource</emphasis> e <emphasis>type</emphasis> os parâmetros de | ||
113 | + nome <emphasis>applicationTitle</emphasis> e <emphasis>loadInitialData</emphasis> serão procurados em um arquivo | ||
114 | + xml de nome <emphasis>my-property-file</emphasis> (my-property-file.xml). | ||
108 | </para> | 115 | </para> |
109 | <para> | 116 | <para> |
110 | - Veja na listagem abaixo um código fonte que ilustra a utilização das anotações descritas nesta seção: | 117 | + Outro parâmetro que você pode ajustar nessa anotação é o prefixo. Ao definir um valor de prefixo você informa que |
118 | + o nome das propriedades definidas naquela classe devem ser concatenados com o prefixo, de forma que o nome dos | ||
119 | + atributos procurados no arquivo seja <emphasis>prefixo.nomeatributo</emphasis>. O exemplo abaixo mostra a | ||
120 | + utilização desse parâmetro. Nesse caso, os parâmetros de nome <emphasis>info.applicationTitle</emphasis> e | ||
121 | + <emphasis>info.loadInitialData</emphasis> serão procurados em um arquivo de propriedade de nome | ||
122 | + <emphasis>my-property-file</emphasis> (<emphasis>my-property-file.properties</emphasis>). | ||
111 | </para> | 123 | </para> |
112 | - <programlistingco> | ||
113 | - <areaspec> | ||
114 | - <area id="resource-prefix" coords="1"/> | ||
115 | - <area id="param-name" coords="4"/> | ||
116 | - <area id="param-notnull" coords="7"/> | ||
117 | - <area id="param-ignore" coords="10"/> | ||
118 | - </areaspec> | ||
119 | - <programlisting role="JAVA"><![CDATA[@Configuration(resource = "bookmark", prefix = "general.") | 124 | + <programlisting role="JAVA"><![CDATA[@Configuration(prefix="info", resource="my-property-file") |
120 | public class BookmarkConfig { | 125 | public class BookmarkConfig { |
121 | 126 | ||
122 | - @Name("app.title") | ||
123 | private String applicationTitle; | 127 | private String applicationTitle; |
124 | 128 | ||
125 | - @NotNull | ||
126 | private boolean loadInitialData; | 129 | private boolean loadInitialData; |
127 | 130 | ||
128 | - @Ignore | ||
129 | - private int dummy; | ||
130 | - | ||
131 | public String getApplicationTitle() { | 131 | public String getApplicationTitle() { |
132 | return applicationTitle; | 132 | return applicationTitle; |
133 | } | 133 | } |
@@ -136,141 +136,485 @@ public class BookmarkConfig { | @@ -136,141 +136,485 @@ public class BookmarkConfig { | ||
136 | return loadInitialData; | 136 | return loadInitialData; |
137 | } | 137 | } |
138 | }]]></programlisting> | 138 | }]]></programlisting> |
139 | - <calloutlist> | ||
140 | - <callout arearefs="resource-prefix"> | ||
141 | - <para> | ||
142 | - Na anotação <literal>@Configuration</literal> foram especificados o arquivo de recursos | ||
143 | - <filename>bookmark.properties</filename> e o prefixo <literal>general.</literal> para as | ||
144 | - chaves de configuração. | ||
145 | - </para> | ||
146 | - </callout> | ||
147 | - <callout arearefs="param-name"> | ||
148 | - <para> | ||
149 | - Ao invés de adotar o padrão convencionado, a anotação <literal>@Name</literal> definirá a chave | ||
150 | - <literal>app.title</literal> após o prefixo. | ||
151 | - </para> | ||
152 | - </callout> | ||
153 | - <callout arearefs="param-notnull"> | ||
154 | - <para> | ||
155 | - Como o atributo é anotado com <literal>@NotNull</literal>, presume-se que ele sempre | ||
156 | - estará presente no recurso. Caso contrário, uma exceção ocorrerá. | ||
157 | - </para> | ||
158 | - </callout> | ||
159 | - <callout arearefs="param-ignore"> | ||
160 | - <para> | ||
161 | - Este atributo, por estar anotado com <literal>@Ignore</literal>, não será considerado | ||
162 | - no carregamento automático das configurações. | ||
163 | - </para> | ||
164 | - </callout> | ||
165 | - </calloutlist> | ||
166 | - </programlistingco> | ||
167 | - <para> | ||
168 | - Neste caso, será buscado um arquivo de propriedades com o nome <filename>bookmark.properties</filename> | ||
169 | - contendo as seguintes chaves: | ||
170 | - </para> | ||
171 | - <programlisting><![CDATA[general.app.title=Título da Aplicação | ||
172 | -general.loadInitialData=true | ||
173 | -]]></programlisting> | 139 | + <note> |
140 | + <para> | ||
141 | + O <emphasis>Demoiselle Framework</emphasis> adiciona automaticamente o ponto entre o prefixo e o nome do | ||
142 | + atributo, você não precisa se preocupar com isso. | ||
143 | + </para> | ||
144 | + </note> | ||
174 | <tip> | 145 | <tip> |
175 | <para> | 146 | <para> |
176 | - Além de <literal>String</literal> e <literal>boolean</literal>, existe a possibilidade de se recuperar valores de qualquer | ||
177 | - tipo primitivo do Java (i.e., <literal>int, byte, short, char, long, float, double</literal> e <literal>boolean</literal>) | ||
178 | - e também arrays desses tipos e de alguns tipos complexos (i.e., <literal>Integer, BigDecimal, BigInteger, Calendar, Date, | ||
179 | - Color, Locale, URL</literal> e <literal>String</literal>). | 147 | + No arquivo xml o prefixo corresponde a uma <emphasis>tag</emphasis> acima das tag que correspondem aos |
148 | + atributos. O exemplo acima ficaria da seguinte forma em um arquivo xml: | ||
180 | </para> | 149 | </para> |
150 | + <programlisting role="XML"><![CDATA[ | ||
151 | +<info> | ||
152 | + <applicationTitle>Demoiselle Application<\applicationTitle> | ||
153 | + <loadInitialData>true<\loadInitialData> | ||
154 | +</info> | ||
155 | + | ||
156 | +]]></programlisting> | ||
157 | + | ||
181 | </tip> | 158 | </tip> |
182 | </section> | 159 | </section> |
183 | - | 160 | + |
184 | <section> | 161 | <section> |
185 | - <title>Usando a configuração na aplicação</title> | 162 | + <title>Especificando os parâmetros</title> |
186 | <para> | 163 | <para> |
187 | - A fim de utilizar o objeto de configuração previamente instanciado e preenchido pelo contêiner, basta criar uma variável numa | ||
188 | - classe qualquer da aplicação e anotá-la com <literal>@Inject</literal>. Tal variável será injetada automaticamente e pode ser | ||
189 | - usada dentro de um método. Veja na listagem a seguir um exemplo de injeção e uso de uma classe de configuração: | 164 | + Atualmente são suportados nativamente pelo <emphasis>Demoiselle Framework</emphasis> parâmetros de cinco tipos |
165 | + diferentes, são eles: <emphasis>primitivo</emphasis>, <emphasis>wrapped</emphasis>, <emphasis>String</emphasis>, | ||
166 | + <emphasis>class</emphasis>, <emphasis>map</emphasis> e <emphasis>array</emphasis>, sendo que os três últimos | ||
167 | + são suportados a partir da versão 2.4.0. A seguir vamos explicar e exemplificar como utilizar cada um desses | ||
168 | + tipos, e alertar para as possíveis exceções que poderão ser lançadas para sua aplicação. | ||
190 | </para> | 169 | </para> |
191 | -<programlisting role="JAVA"><![CDATA[public class BookmarkBC { | 170 | + <caution> |
171 | + <para> | ||
172 | + A partir da versão 2.4.0 não são mais reconhecidas as convenções. Os parâmetros serão procurados exatamente | ||
173 | + como foram definidos na classe de configuração. | ||
174 | + </para> | ||
175 | + </caution> | ||
176 | + <informaltable> | ||
177 | + <tgroup cols="1"> | ||
178 | + <colspec colwidth="100*" /> | ||
179 | + <tbody> | ||
180 | + <row> | ||
181 | + <entry> | ||
182 | + <emphasis role="bold">Primitivos</emphasis> | ||
183 | + </entry> | ||
184 | + </row> | ||
185 | + <row> | ||
186 | + <entry> | ||
187 | + <para> | ||
188 | + A utilização dos tipos primitivos é bastante simples. Veja no exemplo abaixo uma classe de configuração um arquivo | ||
189 | + de configurações, que ilustram como é o procedimento para adicionar parâmetros do tipo primitivo. | ||
190 | + </para> | ||
191 | + <programlisting role="JAVA"><![CDATA[@Configuration | ||
192 | + public class BookmarkConfig { | ||
192 | 193 | ||
193 | - @Inject | ||
194 | - private BookmarkConfig config; | 194 | + private int pageSize; |
195 | 195 | ||
196 | - public void startup() { | ||
197 | - if (config.isLoadInitialData()) { | ||
198 | - ... | ||
199 | - } | 196 | + public String getPageSize() { |
197 | + return pageSize; | ||
200 | } | 198 | } |
201 | }]]></programlisting> | 199 | }]]></programlisting> |
202 | - <note> | ||
203 | - <para> | ||
204 | - O <emphasis>Demoiselle Framework</emphasis> utiliza internamente o mecanismo de configurações na leitura do arquivo | ||
205 | - <filename>demoiselle.properties</filename> para outras funcionalidades, tais como transação, segurança, persistência e paginação. | ||
206 | - </para> | ||
207 | - </note> | ||
208 | - </section> | ||
209 | 200 | ||
210 | - <section> | ||
211 | - <title>Lendo arquivos XML</title> | ||
212 | - <para> | ||
213 | - Agora veja como ficaria a abordagem de configuração usando arquivos XML. Eis um arquivo de exemplo, o | ||
214 | - <filename>escola.xml</filename>, possuindo um valor numérico e um conjunto de strings: | ||
215 | - </para> | ||
216 | - <programlisting role="XML"><![CDATA[<configuration> | ||
217 | - <qtdeInicial>125</qtdeInicial> | ||
218 | - <papeis> | ||
219 | - <papel>Aluno</papel> | ||
220 | - <papel>Professor</papel> | ||
221 | - <papel>Administrador</papel> | ||
222 | - </papeis> | ||
223 | -</configuration>]]></programlisting> | ||
224 | - <para> | ||
225 | - Neste caso, na classe de configuração <literal>EscolaConfig</literal> a anotação <literal>@Configuration</literal> | ||
226 | - precisa apontar para o tipo de recursos XML e usar o respectivo arquivo <filename>escola.xml</filename>. Eis a | ||
227 | - implementação necessária para que o referido arquivo XML seja lido e os seus valores carregados automaticamente: | ||
228 | - </para> | ||
229 | - <programlisting role="JAVA"><![CDATA[@Configuration(resource = "escola", type = ConfigType.XML) | ||
230 | -public class EscolaConfig { | 201 | + <para> |
202 | + Para essa classe, o arquivo de propriedade correspondente (<emphasis>demoiselle.properties</emphasis>) deveria | ||
203 | + apresentar o seguinte conteúdo: | ||
204 | + </para> | ||
205 | + <programlisting role="JAVA"><![CDATA[ | ||
206 | +pageSize=10 | ||
207 | +]]></programlisting> | ||
208 | + <para> | ||
209 | + Bastante simples, não? Mesmo assim, é bom ficarmos atentos, pois alguns cenários diferentes podem | ||
210 | + 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 | ||
211 | + seus parâmetros. Nesse caso será atribuido o valor padrão da linguagem ao atributo, que para os tipos primitivos | ||
212 | + é 0, exceto para os tipos <emphasis>boolean</emphasis>, cujo valor padrão é <emphasis>false</emphasis>, e | ||
213 | + <emphasis>char</emphasis>, cujo valor padrão é o caracter nulo (<emphasis>'\u0000'</emphasis>). | ||
214 | + Outro cenário possível é a existência da chave, mas sem valor atribuído (<emphasis>pageSize=</emphasis>). Nesse | ||
215 | + caso o valor encontrado no arquivo é equivalente a uma <emphasis>String</emphasis> vazia, e a exceção | ||
216 | + <emphasis>ConfigurationException</emphasis>, cuja causa foi uma <emphasis>ConversionException</emphasis>, será | ||
217 | + lançada. | ||
218 | + </para> | ||
219 | + </entry> | ||
220 | + </row> | ||
221 | + </tbody> | ||
222 | + </tgroup> | ||
223 | + </informaltable> | ||
224 | + | ||
225 | + <informaltable> | ||
226 | + <tgroup cols="1"> | ||
227 | + <colspec colwidth="100*" /> | ||
228 | + <tbody> | ||
229 | + <row> | ||
230 | + <entry> | ||
231 | + <emphasis role="bold">Wrappers</emphasis> | ||
232 | + </entry> | ||
233 | + </row> | ||
234 | + <row> | ||
235 | + <entry> | ||
236 | + <para> | ||
237 | + Os atributos do tipo <emphasis>wrapper</emphasis> devem ser utilizados da mesma forma que os atributos do tipo | ||
238 | + primitivo. A única diferença entre eles é que o valor padrão atribuído a um parâmetro, no caso da classe de | ||
239 | + configuração não estar associada a um arquivo que contenha sua chave, é nulo. | ||
240 | + </para> | ||
241 | + </entry> | ||
242 | + </row> | ||
243 | + </tbody> | ||
244 | + </tgroup> | ||
245 | + </informaltable> | ||
246 | + | ||
247 | + <informaltable> | ||
248 | + <tgroup cols="1"> | ||
249 | + <colspec colwidth="100*" /> | ||
250 | + <tbody> | ||
251 | + <row> | ||
252 | + <entry> | ||
253 | + <emphasis role="bold">Strings</emphasis> | ||
254 | + </entry> | ||
255 | + </row> | ||
256 | + <row> | ||
257 | + <entry> | ||
258 | + <para> | ||
259 | + Por sua vez, as configurações do tipo <emphasis>String</emphasis> tem funcionalidade bastante similar às | ||
260 | + configurações do tipo Wrapper. A diferença fica por conta de que, ao deixar a chave sem valor atribuído, para | ||
261 | + atributo desse tipo, não será lançada exceção, pois que não haverá o problema de conversão, e à configuração | ||
262 | + será atribuido o valor de uma <emphasis>String</emphasis> vazia. | ||
263 | + </para> | ||
264 | + </entry> | ||
265 | + </row> | ||
266 | + </tbody> | ||
267 | + </tgroup> | ||
268 | + </informaltable> | ||
269 | + | ||
270 | + <informaltable> | ||
271 | + <tgroup cols="1"> | ||
272 | + <colspec colwidth="100*" /> | ||
273 | + <tbody> | ||
274 | + <row> | ||
275 | + <entry> | ||
276 | + <emphasis role="bold">Class</emphasis> | ||
277 | + </entry> | ||
278 | + </row> | ||
279 | + <row> | ||
280 | + <entry> | ||
281 | + <para> | ||
282 | + A partir da versão 2.4.0 é possível ter atributos do tipo <emphasis>Class</emphasis> como parâmetro. O atributo | ||
283 | + pode ou não ser tipado, e no arquivo o valor atribuído à chave deve corresponder ao nome (<emphasis> | ||
284 | + Canonical Name</emphasis>) de uma classe existente. Abaixo temos um exemplo de uma classe de configuração com | ||
285 | + dois atributos do tipo <emphasis>Class</emphasis>, um tipado e outro não tipado: | ||
286 | + </para> | ||
287 | + <programlisting role="JAVA"><![CDATA[ | ||
288 | +@Configuration | ||
289 | +public class BookmarkConfig { | ||
231 | 290 | ||
232 | - private Integer qtdeInicial = 50; | 291 | + private Class<MyClass> typedClass; |
233 | 292 | ||
234 | - @Name("papeis.papel") | ||
235 | - private List<String> papeis; | 293 | + private Class<?> untypedClass; |
236 | 294 | ||
237 | - private Integer getQtdeInicial() { | ||
238 | - return qtdeInicial; | 295 | + public Class<MyClass> getTypedClass() { |
296 | + return typedClass; | ||
239 | } | 297 | } |
240 | 298 | ||
241 | - public List<String> getPapeis() { | ||
242 | - return papeis; | 299 | + public Class<?> getUntypedClass() { |
300 | + return untypedClass; | ||
243 | } | 301 | } |
244 | -}]]></programlisting> | ||
245 | - </section> | 302 | +} |
303 | + ]]></programlisting> | ||
304 | + <para>O arquivo de propriedades teria o seguinte conteúdo:</para> | ||
305 | + <programlisting role="JAVA"><![CDATA[ | ||
306 | +typedClass=package.MyClass | ||
307 | +untypedClass=package.MyOtherClass | ||
308 | + ]]></programlisting> | ||
309 | + <para> | ||
310 | + Caso uma chave de uma configuração do tipo <emphasis>Class</emphasis> não tenha valor atribuído ou seja | ||
311 | + atribuído um nome de classe que não existe (ou não possa ser encontrada pela aplicação), no momento do | ||
312 | + seu carregamento sera lançada uma exceção do tipo <emphasis>ConfigurationException</emphasis>, cuja causa é uma | ||
313 | + <emphasis>ClassNotFoundException</emphasis>. Caso a classe de configuração não esteja associada a um | ||
314 | + arquivo que contenha a chave de um de seus parâmetros do tipo <emphasis>Class</emphasis>, este será carregado | ||
315 | + com valor nulo. | ||
316 | + </para> | ||
317 | + </entry> | ||
318 | + </row> | ||
319 | + </tbody> | ||
320 | + </tgroup> | ||
321 | + </informaltable> | ||
322 | + | ||
323 | + <informaltable> | ||
324 | + <tgroup cols="1"> | ||
325 | + <colspec colwidth="100*" /> | ||
326 | + <tbody> | ||
327 | + <row> | ||
328 | + <entry> | ||
329 | + <emphasis role="bold">Map</emphasis> | ||
330 | + </entry> | ||
331 | + </row> | ||
332 | + <row> | ||
333 | + <entry> | ||
334 | + <para> | ||
335 | + Para utilizar parâmetros do tipo <emphasis>Map</emphasis>, o arquivo de configurações deve usar a seguinte | ||
336 | + estrutura na formação da chave: <emphasis>prefixo+chavedomap+nomedoatributo</emphasis>. Vejamos um exemplo. | ||
337 | + Se temos em nossa aplicação uma classe de configuração como a mostrada abaixo: | ||
338 | + </para> | ||
339 | + <programlisting role="JAVA"><![CDATA[ | ||
340 | +@Configuration | ||
341 | +public class BookmarkConfig { | ||
246 | 342 | ||
343 | + private Map<String, String> url; | ||
344 | + | ||
345 | + private Map<String, String> driverClass; | ||
346 | + | ||
347 | + public Map<String, String> getUrl() { | ||
348 | + return url; | ||
349 | + } | ||
350 | + | ||
351 | + public Map<String, String> DriverClass() { | ||
352 | + return driverClass; | ||
353 | + } | ||
354 | +} | ||
355 | + ]]></programlisting> | ||
356 | + <para> | ||
357 | + O arquivo de configuração deverá ser preenchido no formato seguinte (se for do tipo <emphasis>properties</emphasis>): | ||
358 | + </para> | ||
359 | + <programlisting role="PROPERTIES"><![CDATA[ | ||
360 | +mapkey1.url=jdbc:postgresql://localhost:5432/app | ||
361 | +mapkey2.url=jdbc:mysql://localhost:3306/app | ||
362 | +mapkey1.driverClass=org.postgresql.Driver | ||
363 | +mapkey2.driverClass=com.mysql.Driver | ||
364 | + ]]></programlisting> | ||
365 | + <para> | ||
366 | + Dessa forma, ao fazer a chamada <emphasis>url.get("mapkey2");</emphasis>por exemplo, o valor retornado será | ||
367 | + <emphasis>jdbc:mysql://localhost:3306/app</emphasis>. | ||
368 | + </para> | ||
369 | + <note> | ||
370 | + <para> | ||
371 | + O ponto entre a chave do <emphasis>Map</emphasis> e o nome do parâmetro é adicionado automaticamente pelo | ||
372 | + framework. | ||
373 | + </para> | ||
374 | + </note> | ||
375 | + <tip> | ||
376 | + <para> | ||
377 | + Você pode utilizar a chave do Map com nome "default" para indicar que, no arquivo de configuração, a chave é formada | ||
378 | + apenas pela junção do prefixo com o atributo, sem utilizar a própria chave do Map. Por exemplo, se na sua classe | ||
379 | + existir um comando como este: | ||
380 | + </para> | ||
381 | + <programlisting role="JAVA"><![CDATA[ | ||
382 | + myMap.get("default"); | ||
383 | + ]]></programlisting> | ||
384 | + <para>o framework irá procurar no arquivo de configuração uma linha como esta:</para> | ||
385 | + <programlisting role="JAVA"><![CDATA[ | ||
386 | + prefix.myMap=Default Value | ||
387 | + ]]></programlisting> | ||
388 | + </tip> | ||
389 | + <para> | ||
390 | + Caso a classe de configuração não esteja associada a um arquivo que contenha a chave de um de seus parâmetros | ||
391 | + do tipo <emphasis>Map</emphasis>, este será carregado com valor nulo, e estará sujeito às exceções | ||
392 | + informadas anteriormente, conforme o tipo de variáveis que ele contenha. | ||
393 | + </para> | ||
394 | + </entry> | ||
395 | + </row> | ||
396 | + </tbody> | ||
397 | + </tgroup> | ||
398 | + </informaltable> | ||
399 | + | ||
400 | + <informaltable> | ||
401 | + <tgroup cols="1"> | ||
402 | + <colspec colwidth="100*" /> | ||
403 | + <tbody> | ||
404 | + <row> | ||
405 | + <entry> | ||
406 | + <emphasis role="bold">Array</emphasis> | ||
407 | + </entry> | ||
408 | + </row> | ||
409 | + <row> | ||
410 | + <entry> | ||
411 | + <para> | ||
412 | + No caso do <emphasis>Array</emphasis>, a principal diferença em relação às demais formas de declarar | ||
413 | + configurações é a maneira de atribuir valores aos seus respectivos elementos no arquivo de configuração. | ||
414 | + Por exemplo, para que um <emphasis>Array</emphasis> de inteiros, de nome <emphasis>integerArray</emphasis> | ||
415 | + tenha o conteúdo <emphasis>{-1, 0, 1}</emphasis>, você deve criar um arquivo de propriedades que contenha | ||
416 | + as seguintes linhas: | ||
417 | + </para> | ||
418 | + <programlisting role="JAVA"><![CDATA[ | ||
419 | +integerArray=-1 | ||
420 | +integerArray=0 | ||
421 | +integerArray=1 | ||
422 | + ]]></programlisting> | ||
423 | + <para> | ||
424 | + Exceto a forma de atribuir os valores às configurações, se comporta de acordo com o tipo de variável que ele | ||
425 | + contém, conforme o espeficifcado para cada um. | ||
426 | + </para> | ||
427 | + </entry> | ||
428 | + </row> | ||
429 | + </tbody> | ||
430 | + </tgroup> | ||
431 | + </informaltable> | ||
432 | + | ||
433 | + </section> | ||
434 | + | ||
247 | <section> | 435 | <section> |
248 | - <title>Lendo variáveis de ambiente</title> | ||
249 | - <para> | ||
250 | - A terceira abordagem na configuração consiste em utilizar as variáveis de ambiente do sistema operacional. | ||
251 | - Estas variáveis geralmente são carregadas na inicialização do sistema ou após a criação da sessão do usuário | ||
252 | - (i.e., após o login), mas também podem ser modificadas manualmente através de comandos como <literal>set</literal> | ||
253 | - ou <literal>export</literal>. | ||
254 | - </para> | ||
255 | - <para> | ||
256 | - O mecanismo de configurações no <emphasis>Demoiselle Framework</emphasis> faz uso da classe | ||
257 | - <ulink url="http://download.oracle.com/javase/6/docs/api/java/lang/System.html"> | ||
258 | - <literal>java.lang.System</literal></ulink> fornecida pela API do Java para carregar os valores nas | ||
259 | - propriedades a partir de variáveis de ambiente independente do sistema operacional. | ||
260 | - </para> | 436 | + <title>Mais Recursos</title> |
261 | <para> | 437 | <para> |
262 | - Veja na listagem abaixo o código necessário para a leitura de uma variável de ambiente: | 438 | + Além das possibilidades relacionadas acima, existem ainda algumas anotações e recursos extras que o |
439 | + <emphasis>Demoiselle Framework</emphasis> oferece para o desenvolvedor na utilização das configurações. A seguir | ||
440 | + listamos e explicamos como utilizar esses recursos em sua aplicação. | ||
263 | </para> | 441 | </para> |
264 | - <programlisting role="JAVA"><![CDATA[@Configuration(type = ConfigType.SYSTEM) | ||
265 | -public class EscolaConfig { | 442 | + |
443 | + <informaltable> | ||
444 | + <tgroup cols="1"> | ||
445 | + <colspec colwidth="100*" /> | ||
446 | + <tbody> | ||
447 | + <row> | ||
448 | + <entry> | ||
449 | + <emphasis role="bold">Ignore</emphasis> | ||
450 | + </entry> | ||
451 | + </row> | ||
452 | + <row> | ||
453 | + <entry> | ||
454 | + <para> | ||
455 | + Por padrão, todos os atributos existentes em uma classe anotada com <literal>@Configuration</literal> são tratados | ||
456 | + como parâmetros de configuração e serão automaticamente preenchidos durante a leitura do recurso. Porém, caso você | ||
457 | + não queira que determinado atributo seja tratado como parâmetro dentro desse tipo de classe, basta anotá-lo com | ||
458 | + a anotação <literal>@Ignore</literal>, que o atributo será ignorado (como indica a própria anotação) pelo carregador | ||
459 | + de configurações. | ||
460 | + </para> | ||
461 | + </entry> | ||
462 | + </row> | ||
463 | + </tbody> | ||
464 | + </tgroup> | ||
465 | + </informaltable> | ||
466 | + | ||
467 | + <informaltable> | ||
468 | + <tgroup cols="1"> | ||
469 | + <colspec colwidth="100*" /> | ||
470 | + <tbody> | ||
471 | + <row> | ||
472 | + <entry> | ||
473 | + <emphasis role="bold">Valor Padrão</emphasis> | ||
474 | + </entry> | ||
475 | + </row> | ||
476 | + <row> | ||
477 | + <entry> | ||
478 | + <para> | ||
479 | + Muitas vezes é interessante que especifiquemos um valor padrão para o parâmetro, para o caso dele não estar | ||
480 | + presente no arquivo de configuração. Para isso, basta atribuir o valor desejado no momento da declaração do | ||
481 | + atributo, como exemplificado abaixo: | ||
482 | + </para> | ||
483 | + <programlisting role="JAVA"><![CDATA[@Configuration | ||
484 | +public class BookmarkConfig { | ||
266 | 485 | ||
267 | - @Name("java.home") | ||
268 | - private String javaDirectory; | 486 | + private String applicationTitle = "My App"; |
269 | 487 | ||
270 | - public String getJavaDirectory() { | ||
271 | - return javaDirectory; | 488 | + public String getApplicationTitle() { |
489 | + return applicationTitle; | ||
272 | } | 490 | } |
273 | -}]]></programlisting> | ||
274 | - </section> | 491 | +} ]]></programlisting> |
492 | + <para> | ||
493 | + Com essa atribuição, se no arquivo de propriedades não existir uma chave com valor <literal>applicationTitle</literal> | ||
494 | + esse parametro será carregado com o valor <literal>My App</literal>. | ||
495 | + </para> | ||
496 | + </entry> | ||
497 | + </row> | ||
498 | + </tbody> | ||
499 | + </tgroup> | ||
500 | + </informaltable> | ||
501 | + | ||
502 | + <informaltable> | ||
503 | + <tgroup cols="1"> | ||
504 | + <colspec colwidth="100*" /> | ||
505 | + <tbody> | ||
506 | + <row> | ||
507 | + <entry> | ||
508 | + <emphasis role="bold">Bean Validation</emphasis> | ||
509 | + </entry> | ||
510 | + </row> | ||
511 | + <row> | ||
512 | + <entry> | ||
513 | + <para> | ||
514 | + Fazer validação mantém a integridade dos dados e pode ser fator importante na lógica da aplicação. A partir da | ||
515 | + versão 2.4.0 o <emphasis>Demoiselle</emphasis> permite que os atributos das classes de configuração sejam | ||
516 | + anotados com todas as anotações definidas pela JSR 303 (Bean Validation). Com esse recurso você pode exigir que | ||
517 | + determinado parâmetro não seja nulo (<emphasis>@NotNull</emphasis>), limitar um valor máximo ou mínimo para ele | ||
518 | + (<emphasis>@Max</emphasis> e <emphasis>@Min</emphasis>, respectivamente), dentre outras restrições (que podem | ||
519 | + ser feitas simultâneamente). A lista completa das restrições que podem ser aplicadas nos atributos das classes | ||
520 | + de configuração pode ser conferida aqui: | ||
521 | + <ulink url="http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html"> | ||
522 | + <literal>http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html</literal></ulink>. | ||
523 | + </para> | ||
524 | + <para> | ||
525 | + Para utilizar esse recurso você deve ter como dependência de seu projeto alguma implementação da especificação | ||
526 | + Bean Validation. A implementação de referência é o | ||
527 | + <ulink url="http://www.hibernate.org/subprojects/validator"><emphasis>Hibernate Validator</emphasis></ulink>. | ||
528 | + </para> | ||
529 | + </entry> | ||
530 | + </row> | ||
531 | + </tbody> | ||
532 | + </tgroup> | ||
533 | + </informaltable> | ||
534 | + | ||
535 | + <informaltable> | ||
536 | + <tgroup cols="1"> | ||
537 | + <colspec colwidth="100*" /> | ||
538 | + <tbody> | ||
539 | + <row> | ||
540 | + <entry> | ||
541 | + <emphasis role="bold">Name</emphasis> | ||
542 | + </entry> | ||
543 | + </row> | ||
544 | + <row> | ||
545 | + <entry> | ||
546 | + <para> | ||
547 | + Em alguns casos você pode querer que um determinado parâmetro tenha nomes diferentes na classe de configuração e | ||
548 | + no arquivo de propriedades. Para isso você pode utilizar a anotação <emphasis>@Name</emphasis>. Basta anotar | ||
549 | + o atributo passando como parâmetro o nome pelo qual você deseja que ele seja procurado no arquivo de propriedades, | ||
550 | + como mostra o exemplo abaixo: | ||
551 | + </para> | ||
552 | + <programlisting role="JAVA"><![CDATA[@Configuration(resource = "bookmark", prefix = "general.") | ||
553 | +public class BookmarkConfig { | ||
275 | 554 | ||
555 | + @Name("app.title") | ||
556 | + private String applicationTitle; | ||
557 | + | ||
558 | + public String getApplicationTitle() { | ||
559 | + return applicationTitle; | ||
560 | + } | ||
561 | +} ]]></programlisting> | ||
562 | + <para> | ||
563 | + Com essa anotação, ao invés de procurar pela chave <emphasis>applicationTitle</emphasis>, o | ||
564 | + <emphasis>Demoiselle</emphasis> irá buscar pela chave <emphasis>app.title</emphasis>. | ||
565 | + </para> | ||
566 | + </entry> | ||
567 | + </row> | ||
568 | + </tbody> | ||
569 | + </tgroup> | ||
570 | + </informaltable> | ||
571 | + | ||
572 | + <informaltable> | ||
573 | + <tgroup cols="1"> | ||
574 | + <colspec colwidth="100*" /> | ||
575 | + <tbody> | ||
576 | + <row> | ||
577 | + <entry> | ||
578 | + <emphasis role="bold">Escopo</emphasis> | ||
579 | + </entry> | ||
580 | + </row> | ||
581 | + <row> | ||
582 | + <entry> | ||
583 | + <para> | ||
584 | + A partir da versão 2.3.3 do <emphasis>Demoiselle Framework</emphasis> as classes anotadas com | ||
585 | + <emphasis>@Configuration</emphasis> estarão por padrão no escopo estático (<emphasis>@StaticScoped</emphasis>). | ||
586 | + </para> | ||
587 | + </entry> | ||
588 | + </row> | ||
589 | + </tbody> | ||
590 | + </tgroup> | ||
591 | + </informaltable> | ||
592 | + | ||
593 | + <informaltable> | ||
594 | + <tgroup cols="1"> | ||
595 | + <colspec colwidth="100*" /> | ||
596 | + <tbody> | ||
597 | + <row> | ||
598 | + <entry> | ||
599 | + <emphasis role="bold">Extratores</emphasis> | ||
600 | + </entry> | ||
601 | + </row> | ||
602 | + <row> | ||
603 | + <entry> | ||
604 | + <para> | ||
605 | + Você precisa de parâmetros de um tipo que ainda não é suportado pelo <emphasis>Demoiselle</emphasis>? Você | ||
606 | + pode implementar sua própria classe extratora. A partir da versão 2.4.0 as aplicações | ||
607 | + podem implementar a interface <emphasis>ConfigurationValueExtractor</emphasis>, e ter um | ||
608 | + extrator de configurações para atributos de qualquer tipo. Essa interface obriga a classe | ||
609 | + a implementar os métodos: <emphasis>boolean isSupported(Field field)</emphasis>, que retorna <literal>true</literal> | ||
610 | + caso a classe seja extratora daquele tipo de campo, e | ||
611 | + <emphasis>Object getValue(String prefix, String key, Field field, Configuration configuration) | ||
612 | + throws Exception</emphasis> que deve extrair o valor do campo da forma correta. | ||
613 | + </para> | ||
614 | + </entry> | ||
615 | + </row> | ||
616 | + </tbody> | ||
617 | + </tgroup> | ||
618 | + </informaltable> | ||
619 | + </section> | ||
276 | </chapter> | 620 | </chapter> |