configuracao.xml
25.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
<?xml version='1.0' encoding="utf-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []>
<chapter id="configuracao">
<title>Configuração</title>
<section>
<title>Configurações em uma aplicação</title>
<para>
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:
<itemizedlist>
<listitem>
<para>
<emphasis>arquivo de propriedades</emphasis>: tratam-se de simples arquivos de texto nomeados com a
extensão <filename>.properties</filename>, os quais são escritos com a sintaxe <literal>chave=valor</literal>,
armazenando uma única chave por linha;
</para>
</listitem>
<listitem>
<para>
<emphasis>arquivo XML</emphasis>: 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<filename>.xml</filename>;
</para>
</listitem>
<listitem>
<para>
<emphasis>variáveis de ambiente</emphasis>: 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.
</para>
</listitem>
</itemizedlist>
</para>
<para>
Esse capítulo mostra de que maneira o <emphasis>Demoiselle Framework</emphasis> pode facilitar a utilização dessas
formas de configuração, oferencendo vários recursos interessantes para a sua aplicação.
</para>
</section>
<section>
<title>As classes de configuração</title>
<para>
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 <literal>@Configuration</literal>. O código
abaixo mostra um exemplo de classe de configuração:
</para>
<programlisting role="JAVA"><![CDATA[@Configuration
public class BookmarkConfig {
private String applicationTitle;
private boolean loadInitialData;
public String getApplicationTitle() {
return applicationTitle;
}
public boolean isLoadInitialData() {
return loadInitialData;
}
}]]></programlisting>
<note>
<para>
As classes anotadas com <literal>@Configuration</literal> são instanciadas uma única vez (seguindo o padrão
de projeto <emphasis>singleton</emphasis>) e podem ser injetadas em qualquer ponto da aplicação. Seu ciclo
de vida é gerenciado automaticamente pelo CDI. Os recursos (arquivo ou variável de ambiente) são lidos no
primeiro acesso à respectiva classe de configuração, quando os seus atributos são preenchidos automaticamente.
</para>
</note>
<note>
<para>
Recomenda-se usar o sufixo <quote>Config</quote> nas classes de configuração, e que sejam criados
apenas os acessores para leitura (<emphasis>getters</emphasis>).
</para>
</note>
<para>
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 <emphasis>applicationTitle</emphasis> e <emphasis>loadInitialData</emphasis> serão
procurados em um arquivo de propriedades de nome <emphasis>demoiselle.properties</emphasis>. Ou seja, quando não
especificados nome e tipo do arquivo, assume-se que o arquivo é do tipo <emphasis>propriedades</emphasis>
e seu nome é <emphasis>demoiselle</emphasis>. 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>
<programlisting role="JAVA"><![CDATA[@Configuration(resource="my-property-file", type=ConfigType.XML)
public class BookmarkConfig {
private String applicationTitle;
private boolean loadInitialData;
public String getApplicationTitle() {
return applicationTitle;
}
public boolean isLoadInitialData() {
return loadInitialData;
}
}]]></programlisting>
<para>
Devemos atribuir o nome do arquivo de configuração ao parâmetro <emphasis>resource</emphasis>, sem a extensão.
Ao parâmetro <emphasis>type</emphasis> pode ser atribuída uma das três possibilidades:
<emphasis>ConfigType.PROPERTIES</emphasis>, que é o valor padrão e indica que as configurações daquela classe
estão em um arquivo do tipo <emphasis>properties</emphasis>; <emphasis>ConfigType.XML</emphasis>, que indica que
as configurações daquela classe estão em um arquivo do tipo <emphasis>xml</emphasis>; e <emphasis>
ConfigType.SYSTEM</emphasis>, que indica que as configurações daquela classe são valores definidos pelo Sistema
Operacional. Nesse exemplo, ao definir <emphasis>resource</emphasis> e <emphasis>type</emphasis> os parâmetros de
nome <emphasis>applicationTitle</emphasis> e <emphasis>loadInitialData</emphasis> serão procurados em um arquivo
xml de nome <emphasis>my-property-file</emphasis> (my-property-file.xml).
</para>
<para>
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 <emphasis>prefixo.nomeatributo</emphasis>. O exemplo abaixo mostra a
utilização desse parâmetro. Nesse caso, os parâmetros de nome <emphasis>info.applicationTitle</emphasis> e
<emphasis>info.loadInitialData</emphasis> serão procurados em um arquivo de propriedade de nome
<emphasis>my-property-file</emphasis> (<emphasis>my-property-file.properties</emphasis>).
</para>
<programlisting role="JAVA"><![CDATA[@Configuration(prefix="info", resource="my-property-file")
public class BookmarkConfig {
private String applicationTitle;
private boolean loadInitialData;
public String getApplicationTitle() {
return applicationTitle;
}
public boolean isLoadInitialData() {
return loadInitialData;
}
}]]></programlisting>
<note>
<para>
O <emphasis>Demoiselle Framework</emphasis> adiciona automaticamente o ponto entre o prefixo e o nome do
atributo, você não precisa se preocupar com isso.
</para>
</note>
<tip>
<para>
No arquivo xml o prefixo corresponde a uma <emphasis>tag</emphasis> acima das tag que correspondem aos
atributos. O exemplo acima ficaria da seguinte forma em um arquivo xml:
</para>
<programlisting role="XML"><![CDATA[
<info>
<applicationTitle>Demoiselle Application<\applicationTitle>
<loadInitialData>true<\loadInitialData>
</info>
]]></programlisting>
</tip>
</section>
<section>
<title>Especificando os parâmetros</title>
<para>
Atualmente são suportados nativamente pelo <emphasis>Demoiselle Framework</emphasis> parâmetros de sete categorias
diferentes. São eles: tipos primitivos (<emphasis>int, float, boolean, etc</emphasis>), classes <emphasis>wrapper</emphasis> (<emphasis>Integer, Float, Boolean, etc.</emphasis>)
, <emphasis>String</emphasis>, <emphasis>Class</emphasis>, <emphasis>Map</emphasis>, <emphasis>Array</emphasis> e instâncias de <emphasis>Enum</emphasis>.
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.
</para>
<caution>
<para>
A partir da versão 2.4.0 não são mais reconhecidas as convenções de substituição de nomes. Os parâmetros serão procurados exatamente
como foram definidos na classe de configuração.
</para>
</caution>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Primitivos</emphasis>
</entry>
</row>
<row>
<entry>
<para>
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.
</para>
<programlisting role="JAVA"><![CDATA[@Configuration
public class BookmarkConfig {
private int pageSize;
public String getPageSize() {
return pageSize;
}
}]]></programlisting>
<para>
Para essa classe, o arquivo de propriedade correspondente (<emphasis>demoiselle.properties</emphasis>) deveria
apresentar o seguinte conteúdo:
</para>
<programlisting role="JAVA"><![CDATA[
pageSize=10
]]></programlisting>
<para>
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 <emphasis>boolean</emphasis>, cujo valor padrão é <emphasis>false</emphasis>, e
<emphasis>char</emphasis>, cujo valor padrão é o caracter nulo (<emphasis>'\u0000'</emphasis>).
Outro cenário possível é a existência da chave, mas sem valor atribuído (<emphasis>pageSize=</emphasis>). Nesse
caso o valor encontrado no arquivo é equivalente a uma <emphasis>String</emphasis> vazia, e a exceção
<emphasis>ConfigurationException</emphasis>, cuja causa foi uma <emphasis>ConversionException</emphasis>, será
lançada.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Wrappers</emphasis>
</entry>
</row>
<row>
<entry>
<para>
Os atributos do tipo <emphasis>wrapper</emphasis> 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.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Strings</emphasis>
</entry>
</row>
<row>
<entry>
<para>
Por sua vez, as configurações do tipo <emphasis>String</emphasis> 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 <emphasis>String</emphasis> vazia.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Class</emphasis>
</entry>
</row>
<row>
<entry>
<para>
A partir da versão 2.4.0 é possível ter atributos do tipo <emphasis>Class</emphasis> como parâmetro. O atributo
pode ou não ser tipado, e no arquivo o valor atribuído à chave deve corresponder ao nome (<emphasis>
Canonical Name</emphasis>) de uma classe existente. Abaixo temos um exemplo de uma classe de configuração com
dois atributos do tipo <emphasis>Class</emphasis>, um tipado e outro não tipado:
</para>
<programlisting role="JAVA"><![CDATA[
@Configuration
public class BookmarkConfig {
private Class<MyClass> typedClass;
private Class<?> untypedClass;
public Class<MyClass> getTypedClass() {
return typedClass;
}
public Class<?> getUntypedClass() {
return untypedClass;
}
}
]]></programlisting>
<para>O arquivo de propriedades teria o seguinte conteúdo:</para>
<programlisting role="JAVA"><![CDATA[
typedClass=package.MyClass
untypedClass=package.MyOtherClass
]]></programlisting>
<para>
Caso uma chave de uma configuração do tipo <emphasis>Class</emphasis> 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 <emphasis>ConfigurationException</emphasis>, cuja causa é uma
<emphasis>ClassNotFoundException</emphasis>. 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 <emphasis>Class</emphasis>, este será carregado
com valor nulo.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Map</emphasis>
</entry>
</row>
<row>
<entry>
<para>
Para utilizar parâmetros do tipo <emphasis>Map</emphasis>, o arquivo de configurações deve usar a seguinte
estrutura na formação da chave: <emphasis>prefixo+nomedoatributo+chavedomap</emphasis>. Vejamos um exemplo.
Se temos em nossa aplicação uma classe de configuração como a mostrada abaixo:
</para>
<programlisting role="JAVA"><![CDATA[
@Configuration
public class BookmarkConfig {
private Map<String, String> connectionConfiguration;
public Map<String, String> getConnectionConfiguration() {
return connectionConfiguration;
}
}
]]></programlisting>
<para>
O arquivo de configuração deverá ser preenchido no seguinte formato (se for do tipo <emphasis>properties</emphasis>):
</para>
<programlisting role="PROPERTIES"><![CDATA[connectionConfiguration.ip=192.168.0.120
connectionConfiguration.gateway=192.168.0.1
connectionConfiguration.dns1=200.10.128.99
connectionConfiguration.dns2=200.10.128.88]]></programlisting>
<para>
Dessa forma, ao fazer a chamada <emphasis>connectionConfiguration.get("gateway");</emphasis> por exemplo, o valor retornado será
<emphasis>192.168.0.1</emphasis>.
</para>
<tip>
<para>
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 o seu arquivo de propriedades
contiver uma chave:
</para>
<programlisting role="JAVA"><![CDATA[prefix.myMap=Default Value]]></programlisting>
<para>então seu código poderá ter um comando:</para>
<programlisting role="JAVA"><![CDATA[String value = myMap.get("default");]]></programlisting>
<para>e o valor de <emphasis>value</emphasis> será <emphasis>"Default Value"</emphasis>.</para>
</tip>
<para>
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 <emphasis>Map</emphasis>, este será carregado com valor nulo, e estará sujeito às exceções
informadas anteriormente, conforme o tipo de variáveis que ele contenha.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Array</emphasis>
</entry>
</row>
<row>
<entry>
<para>
No caso do <emphasis>Array</emphasis>, 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 <emphasis>Array</emphasis> de inteiros, de nome <emphasis>integerArray</emphasis>
tenha o conteúdo <emphasis>{-1, 0, 1}</emphasis>, você deve criar um arquivo de propriedades que contenha
as seguintes linhas:
</para>
<programlisting role="JAVA"><![CDATA[
integerArray=-1
integerArray=0
integerArray=1
]]></programlisting>
<para>
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.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Enum</emphasis>
</entry>
</row>
<row>
<entry>
<para>
É possível criar uma lista de constantes do tipo <emphasis>Enum</emphasis> e carregar um valor de constante
através de um arquivo de configuração. Por exemplo, caso exista o seguinte <emphasis>Enum</emphasis>
</para>
<programlisting role="JAVA"><![CDATA[public enum ConfigurationType {
PROPERTIES , XML , SYSTEM;
}]]></programlisting>
<para>e ele seja usado no seguinte arquivo de configuração</para>
<programlisting role="JAVA"><![CDATA[@Configuration
public class ConfigurationLoader {
private ConfigurationType loadedConfigurationType;
public ConfigurationType getLoadedConfigurationType(){
return loadedConfigurationType;
}
}]]></programlisting>
<para>O arquivo do tipo <emphasis>properties</emphasis> pode ser criado assim:</para>
<programlisting role="PROPERTIES"><![CDATA[loadedConfigurationType=SYSTEM]]></programlisting>
<note>
<para>
O valor definido no arquivo de configuração para atributos do tipo <emphasis>Enum</emphasis> deve
ser idêntico ao nome da constante definida no <emphasis>Enum</emphasis>, inclusive casando letras maiúsculas e
minúsculas. De fato, o valor da propriedade deve casar com o valor retornado no código:
<emphasis>Enum.name()</emphasis>.
</para>
<para>
Caso o valor definido no arquivo de configuração não case com nenhuma constante definida no <emphasis>Enum</emphasis>,
uma exceção de tipo <emphasis>ConfigurationException</emphasis> de causa <emphasis>ConversionException</emphasis>
será lançada. Já se à propriedade for atribuido um valor vazio, o atributo do tipo <emphasis>Enum</emphasis> receberá
o valor <emphasis>null</emphasis>.
</para>
</note>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
<section>
<title>Mais Recursos</title>
<para>
Além das possibilidades relacionadas acima, existem ainda algumas anotações e recursos extras que o
<emphasis>Demoiselle Framework</emphasis> oferece para o desenvolvedor na utilização das configurações. A seguir
listamos e explicamos como utilizar esses recursos em sua aplicação.
</para>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Ignore</emphasis>
</entry>
</row>
<row>
<entry>
<para>
Por padrão, todos os atributos existentes em uma classe anotada com <literal>@Configuration</literal> 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 <literal>@Ignore</literal>, que o atributo será ignorado (como indica a própria anotação) pelo carregador
de configurações.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Valor Padrão</emphasis>
</entry>
</row>
<row>
<entry>
<para>
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:
</para>
<programlisting role="JAVA"><![CDATA[@Configuration
public class BookmarkConfig {
private String applicationTitle = "My App";
public String getApplicationTitle() {
return applicationTitle;
}
} ]]></programlisting>
<para>
Com essa atribuição, se no arquivo de propriedades não existir uma chave com valor <literal>applicationTitle</literal>
esse parametro será carregado com o valor <literal>My App</literal>.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Bean Validation</emphasis>
</entry>
</row>
<row>
<entry>
<para>
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 <emphasis>Demoiselle</emphasis> 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 (<emphasis>@NotNull</emphasis>), limitar um valor máximo ou mínimo para ele
(<emphasis>@Max</emphasis> e <emphasis>@Min</emphasis>, 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:
<ulink url="http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html">
<literal>http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html</literal></ulink>.
</para>
<para>
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
<ulink url="http://www.hibernate.org/subprojects/validator"><emphasis>Hibernate Validator</emphasis></ulink>.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Name</emphasis>
</entry>
</row>
<row>
<entry>
<para>
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 <emphasis>@Name</emphasis>. 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:
</para>
<programlisting role="JAVA"><![CDATA[@Configuration
public class BookmarkConfig {
@Name("app.title")
private String applicationTitle;
public String getApplicationTitle() {
return applicationTitle;
}
} ]]></programlisting>
<para>
Com essa anotação, ao invés de procurar pela chave <emphasis>applicationTitle</emphasis>, o
<emphasis>Demoiselle</emphasis> irá buscar pela chave <emphasis>app.title</emphasis>.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Escopo</emphasis>
</entry>
</row>
<row>
<entry>
<para>
A partir da versão 2.3.3 do <emphasis>Demoiselle Framework</emphasis> as classes anotadas com
<emphasis>@Configuration</emphasis> estarão por padrão no escopo estático (<emphasis>@StaticScoped</emphasis>).
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<informaltable>
<tgroup cols="1">
<colspec colwidth="100*" />
<tbody>
<row>
<entry>
<emphasis role="bold">Extratores</emphasis>
</entry>
</row>
<row>
<entry>
<para>
Você precisa de parâmetros de um tipo que ainda não é suportado pelo <emphasis>Demoiselle</emphasis>? Você
pode implementar sua própria classe extratora. A partir da versão 2.4.0 as aplicações
podem implementar a interface <emphasis>ConfigurationValueExtractor</emphasis>, e ter um
extrator de configurações para atributos de qualquer tipo. Essa interface obriga a classe
a implementar os métodos: <emphasis>boolean isSupported(Field field)</emphasis>, que retorna <literal>true</literal>
caso a classe seja extratora daquele tipo de campo, e
<emphasis>Object getValue(String prefix, String key, Field field, Configuration configuration)
throws Exception</emphasis> que deve extrair o valor do campo da forma correta.
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
</chapter>