Demoiselle Reference

Embed Size (px)

Citation preview

Framework Demoiselle 2.0

Guia de Referncia

Cleverson Sacramento Marlon Carvalho Rodrigo Hjort Serge Rehem Thiago Mariano Wilson Guimares

Sobre o Guia de Referncia ...................................................................................................... v I. Framework ......................................................................................................................... 1 1. Introduo ................................................................................................................ 3 1.1. O que o Demoiselle? ...................................................................................... 3 1.2. Demoiselle 2.0 ................................................................................................. 3 2. Arquitetura/Estrutura .................................................................................................. 5 2.1. Estruturao do Framework ................................................................................. 5 2.2. Pacote Internal ................................................................................................. 2.3. Arqutipo ........................................................................................................ 2.4. Estrutura sugerida s aplicaes ........................................................................... 3. Controlador .............................................................................................................. 5 5 6 7

3.1. Como criar seu controlador ................................................................................. 7 4. Transao ................................................................................................................ 9 4.1. Mtodos transacionais ........................................................................................ 9 4.2. E se acontecer uma Exception? ........................................................................... 9 4.3. O objeto Transaction ........................................................................................ 10 4.4. Escolha a estratgia adequada ........................................................................... 10 4.5. Estratgia JPA ............................................................................................... 10 4.6. Estratgia JTA ............................................................................................... 11 4.7. Crie a sua estratgia ........................................................................................ 12 5. Excees ............................................................................................................... 15 5.1. Tratadores de exceo ..................................................................................... 15 5.2. Mltiplos tratadores .......................................................................................... 15 5.3. Misturando os dois mundos ............................................................................... 16 5.4. Exceo de aplicao ...................................................................................... 16 5.5. Tratamento padro .......................................................................................... 16 6. Configurao .......................................................................................................... 17 6.1. Configuraes em uma aplicao ........................................................................ 17 6.2. As classes de configurao ............................................................................... 17 6.3. Especificando os parmetros .............................................................................. 18 6.4. Usando a configurao na aplicao .................................................................... 20 6.5. Lendo arquivos XML ........................................................................................ 20 6.6. Lendo variveis de ambiente .............................................................................. 21 7. Inicializao ............................................................................................................ 23 7.1. Introduo ao mecanismo .................................................................................. 23 7.2. Implementao na aplicao .............................................................................. 23 7.3. Um exemplo prtico ......................................................................................... 24 8. Tratamento de Mensagens ......................................................................................... 25 8.1. Mensagens em uma aplicao ............................................................................ 25 8.2. Introduo ao mecanismo .................................................................................. 25 8.3. Parametrizao das mensagens .......................................................................... 27 8.4. Internacionalizao das mensagens ..................................................................... 28 8.5. Exemplos de implementao .............................................................................. 30 9. Resource Bundle ..................................................................................................... 33 9.1. Utilizando Resource Bundle no Demoiselle ............................................................. 33 10. Parmetro ............................................................................................................. 35 10.1. Como passar parmetro no Demoiselle 2.0 ........................................................... 35 10.2. As classes de parmetro ................................................................................. 36 11. Logger ................................................................................................................. 37 12. Templates ............................................................................................................. 39 12.1. Camada de persistncia .................................................................................. 39 12.2. Camada de negcio ....................................................................................... 39 12.3. Camada de apresentao ................................................................................ 40

iii

Framework Demoiselle 2.0

A. Instalao ....................................................................................................................... 41 A.1. Pr-requisitos ......................................................................................................... 41 A.2. Demoiselle Infra ..................................................................................................... 41

iv

Sobre o Guia de RefernciaEste documento tem como objetivo ser um guia de referncia destinado a todos que desejem conhecer melhor o Framework Demoiselle 2.0 e suas funcionalidades.

NotaEsta documentao refere-se release 2.0 do Framework Demoiselle e pode diferir significativamente das verses anteriores.

v

vi

Parte I. Framework

Introduo1.1. O que o Demoiselle?O Demoiselle Framework implementa o conceito de framework integrador. Seu objetivo facilitar a construo de aplicaes minimizando tempo dedicado escolha e integrao de frameworks especialistas, o que resulta no aumento da produtividade e garante a manutenibilidade dos sistemas. Disponibiliza mecanismos reusveis voltados as funcionalidades mais comuns de uma aplicao (arquitetura, segurana, transao, mensagem, configurao, tratamento de excees, etc). O nome Demoiselle uma homenagem srie de aeroplanos construdos por Santos Dummont entre 1907 e 1909. Tambm conhecido como Libellule, as Demoiselles foram os melhores, menores e mais baratos avies da sua poca. Como sua inteno era popularizar a aviao com fabricao em larga escala, o inventor disponibilizava os planos em revistas tcnicas a qualquer um que se interessasse. O Demoiselle Framework usa a mesma filosofia do Pai da Aviao, tendo sido disponibilizado como software livre em abril de 2009, sob a licena livre LGPL version 3. Informaes no portal www.frameworkdemoiselle.gov.br.

1.2. Demoiselle 2.0O principal objetivo da verso 2.0 do Demoiselle Framework a completa aderncia especificao JSR 316: Java Platform, Enterprise Edition 6 [http://jcp.org/en/jsr/detail?id=316], ou simplesmente Java EE 6. Para saber mais, recomendamos os links Introducing the Java EE 6 Platform [http://www.oracle.com/technetwork/articles/javaee/ javaee6overview-141808.html] e As novidades da JEE 6 [http://cleversonsacramento.wordpress.com/2010/08/15/ as-novidades-da-jee-6/]. Esta documentao referente s especificaes da verso 2.0 cadastradas no tracker [https://sourceforge.net/ apps/mantisbt/demoiselle/changelog_page.php] do Demoiselle, as quais foram publicamente discutidas no frum demoiselle-proposal [https://sourceforge.net/apps/phpbb/demoiselle/viewtopic.php?f=35&t=63&start=0]. Os captulos a seguir entram em detalhes sobre cada uma das principais funcionalidades do framework.

3

4

Arquitetura/Estrutura2.1. Estruturao do FrameworkVisando uma melhor modularizao, o Demoiselle dividido conforme as funcionalidades disponibilizadas. Isto significa que o framework no um ncleo monoltico, no qual todas as sua funcionalidades esto contidas em um nico pacote. Alis, esta estratgia no a mais indicada, pois projetos com um propsito especfico, que no necessitam de persistncia ou interface Web, por exemplo, teriam dependncias desnecessrias. Assim, o Demoiselle separado em Core, Extenses e Componentes. O core do Demoiselle contm aquelas funcionalidades que so comuns a todas as extenses e aplicaes. O core simples, leve e formado majoritariamente por interfaces e poucas implementaes. O core a base do framework, sem ele, as extenses, e a prpria aplicao, no funcionam. As extenses, como seu prprio nome sugere, estende o Demoiselle com funcionalidades extras e bem especficas a um domnio. Neste contexto, se sua aplicao precisa de persistncia com JPA, o framework fornece facilidades para voc, contudo, estas funcionalidades no esto no core. Alis, mais uma vez, no faz sentido estar no core, pois existem aplicaes que no precisam de persistncia! Para este propsito existe a extenso demoiselle-

jpa. Basta incluir uma dependncia para esta extenso que seu projeto ter disponvel todas as facilidades que oDemoiselle fornece para o JPA. Cabe destacar que as extenses no possuem vida prpria, pois esto diretamente ligadas ao ncleo do framework, estendendo suas funcionalidades e usando aquelas j fornecidas por ele. Inclusive, as extenses possuem seu ciclo de vida totalmente acoplado ao ciclo de vida do core. J os componentes so artefatos separados e que, portanto, no so dependentes diretamente do core do framework. Alis, os componentes podem at mesmo ter vida sem o Demoiselle. Desta forma, o ciclo de vida de um componente totalmente independente do framework, ao contrrio das extenses. Um componente no precisa, necessariamente, estender as funcionalidades j providas pelo core, mas permitir ao usurio incluir uma nova funcionalidade independente da verso que esteja sendo usada no core.

2.2. Pacote InternalAs boas prticas de programao nos alertam para que nunca sejamos dependentes de implementaes, mas sempre de interfaces ou, como alguns costumam dizer, depender de contratos! E as interfaces existem para isto: define um contrato, enquanto as implementaes deste contrato ficam parte, de preferncia, distante do programador da aplicao. E o mecanismo de injeo de dependncia fortalece ainda mais esta ideia. Sua aplicao precisar apenas depender das interfaces que o Demoiselle prov. A implementao especfica ser injetada automaticamente pelo CDI. E qual o motivo de toda esta explicao? Os programadores mais curiosos iro encontrar classes do framework que esto inseridas no pacote internal. Cabe alertar que as classes a contidas no devem ser usadas diretamente pela aplicao, caso contrrio, voc estar acoplando-a com a implementao interna do framework e que pode sofrer mudanas sem aviso prvio. A equipe do Demoiselle possui ateno especial quanto s suas interfaces (contratos) e no ir modific-las sem antes tornar pblicas as possveis mudanas. Contudo, tudo que consta no pacote internal pode sofrer mudanas repentinas. Isto significa que sua aplicao pode deixar de funcionar de uma verso minor para outra do Demoiselle caso voc esteja usando diretamente classes deste pacote. Ento, fica a dica. O pacote internal no deve ser usado diretamente! Lembre-se sempre disto.

2.3. ArqutipoO Demoiselle fornece um arqutipo para facilitar a criao de aplicaes que precisam de uma arquitetura que utilize as tecnologias JSF e JPA. Trata-se do arqutipo demoiselle-jsf-jpa, que j traz uma estrutura padro

5

Captulo 2. Arquitetura/Estrutura

de pacotes e todas as dependncias necessrias para rodar a aplicao. Ao usar este arqutipo, voc j ter uma pequena aplicao de Bookmarks j pronta para rodar. Para isto, basta instal-la em um servidor da sua preferncia! Para mais detalhes sobre esta aplicao de exemplo e em como usar o arqutipo, acesse nosso Quickstart.

2.4. Estrutura sugerida s aplicaes importante reforar que o Demoiselle no fora nenhum tipo de estrutura para as aplicaes que o utilizam. Sua aplicao pode ser constituda de quantas camadas forem necessrias. Contudo, prudente no exagerar. O framework apenas sugere uma possvel estruturao de sua aplicao, de forma a facilitar a manuteno e para uma melhor modularizao de seu projeto. Usualmente, as aplicaes so constitudas de trs camadas, conforme sugere o padro MVC (Model/ View/Controller). Desta forma, comum separar as lgicas de apresentao, negcio e persistncia em camadas prprias. O Demoiselle j fornece esteretipos que visam tornar esta separao mais clara: @BusinessController, @ViewController e @PersistenceController. Portanto, para a sua classe que mantm a lgica de negcio de sua aplicao, sugerida a utilizao da anotao @BusinessController. Para as classes de acesso a dados, pode-se usar a anotao @PersistenceController, enquanto as classes responsveis pela viso so anotadas com @ViewController. Maiores detalhes sobre cada anotao desta sero dados no decorrer desta documentao. Cabe destacar que estamos falando de uma viso arquitetural macro. Cada camada desta pode ser organizada internamente da melhor forma possvel, ou conforme os padres vigentes no mercado. Para uma aplicao Swing, por exemplo, o padro de projeto Presentation Model bastante indicado e pode ser adotado em aplicaes nesta plataforma.

6

ControladorNo Demoiselle Framework 2.0 os controladores ou controllers servem para identificar as camadas da arquitetura de sua aplicao. comum que as aplicaes utilizem apenas trs camadas: viso, negcio e persistncia. Existem aplicaes que utilizam fachadas. Por esse motivo, foram implementados nessa verso do framework quatro controllers:

ViewController FacadeController BusinessController PersistenceController Alm de identificar as camadas, os controllers so pr-requisitos para utilizao da funcionalidade de tratamento de excees, atravs do uso da anotao @ExceptionHandler. Isso quer dizer que para utilizar essa funcionalidade, a classe precisa usar um dos controllers citados acima ou a prpria anotao @Controller ou ainda um controller criado exclusivamente para sua aplicao. Todos os controllers criados no framework so esteretipos e podem ser usados tambm para definio de caractersticas como, por exemplo, o escopo. Isso quer dizer que se um controller tem um determinado escopo, todas as classes desse controller, tambm tero o mesmo escopo. Foi falado que possvel criar um controller para uso exclusivo em sua aplicao, mas como fazer isso? Veja na seo abaixo.

3.1. Como criar seu controlador comum nos depararmos com situaes onde precisamos criar controllers exclusivos com determinadas caractersticas ou que sirvam apenas para determinar algum tipo de funcionalidade. Para criar um novo controller no Demoiselle 2.0, basta que ele esteja anotado com @Controller, como no exemplo abaixo.

@Controller @Stereotype @ViewScoped public @interface SeuController { }

Neste exemplo foi criado um controlador chamado SeuController quem tem a caracterstica de ter um escopo de View. Isto quer dizer que todo classe que seja desse tipo de controlador, tambm ter o escopo de View.

7

8

TransaoEsta funcionalidade utiliza os recursos do CDI para interceptar e delegar o tratamento adequado das transaes para quem de direito. Em outras palavras, no reinventamos a roda. Criamos algumas estratgias de delegao e controle de transao com base no que est sendo mais utilizado no mercado, algumas mais simples de configurar, outras mais completas para utilizar. Alm de plugar e usar as estratgias prontas que fizemos para voc, possvel tambm criar a sua. Vai que voc precise de algo que no pensamos ainda. O importante que voc tenha opes, e uma das opes tambm no utilizar a nossa soluo. Caso voc esteja utilizando o Demoiselle Framework em conjunto com outro framework (tais como o JBoss Seam, Spring ou Google Guice) que oferea o controle de transao, voc pode us-lo tambm. Viva a liberdade de escolha! Neste captulo apresentaremos para voc como usar a nossa soluo de controle de transao, as estratgias prontas que oferecemos e a criao de sua prpria estratgia.

4.1. Mtodos transacionaisVamos comear pelo mais importante: como declarar os mtodos como transacionais? Como informar ao Demoiselle Framework que o mtodo deve participar da sesso transacional? A resposta muito simples, anote seu mtodo com @Transactional.

@Transactional public void inserir() { }

Se voc desejar que todos os mtodos de sua classe sejam transacionais, anote diretamente a classe:

@Transactional public class Simples { public void inserir() { } public void alterar() { } public void excluir() { } }

Neste exemplo, os mtodos inserir(), alterar() e excluir() da classe Simples participaro do contexto transacional.

4.2. E se acontecer uma Exception?Caso ocorra uma exceo na execuo de um mtodo transacional o mecanismo far rollback na transao automaticamente. possvel mudar este comportamento utilizando excees de aplicao.

@ApplicationException(rollback = false) public class AbacaxiException {

9

Captulo 4. Transao

}

4.3. O objeto TransactionPara ter acesso instncia da transao corrente, basta injet-la em sua classe.

public class Simples { @Inject private Transaction transaction; }

4.4. Escolha a estratgia adequadaPara o controle transacional funcionar corretamente preciso escolher a estratgia mais adequada para o seu caso. No existe a bala de prata, voc tem que avaliar o melhor para o seu projeto. Voc pode optar tambm por no utilizar controle de transao. Neste caso voc no precisa definir a estratgia

NoTransaction do pacote br.gov.frameworkdemoiselle.transaction. Contudo, obviamente voc no poder utilizar a anotao @Transactional. Se a utilizar, o Demoiselle lanar uma exceo para que voclembre disto. Defina a alternativa NoTransaction no arquivo de configuraes do CDI, o META-INF/beans.xml.

br.gov.frameworkdemoiselle.transaction.NoTransaction

4.5. Estratgia JPAEsta estratgia, que est disponvel na extenso demoiselle-jpa, delega o controle de transaes para o javax.persistence.EntityManager da especificao JPA. Voc deve escolher esta estratgia quando voc estiver fazendo a persistncia com JPA e utilizando apenas uma base de dados em sua aplicao. Como um EntityManager acessa apenas uma unidade de persistncia, no h como fazer o controle transacional de unidades distintas. A transao JPA simples de configurar e no exige nenhum recurso externo sua aplicao. Basta definir no arquivo META-INF/beans.xml a seguinte configurao:

10

Estratgia JTA

br.gov.frameworkdemoiselle.transaction.JPATransaction

4.6. Estratgia JTAEsta estratgia j vem no ncleo do framework (i.e., demoiselle-core) e responsvel por delegar o controle de transao para o container JEE. Com a JTATransaction possvel incluir vrias unidades de persistncia de uma mesma aplicao no mesmo contexto transacional. Isso mesmo, o famoso Two-Phase Commit (2PC). A estratgia JTA no serve apenas para persistncia em banco de dados, serve tambm para integrar com tecnologias que faam acesso ao contexto JTA, como o caso do EJB. Para ativar esta estratgia defina no arquivo

META-INF/beans.xml a seguinte configurao:

br.gov.frameworkdemoiselle.transaction.JTATransaction

Feito com

isto, o controle transacional o nome UserTransaction.

ser delegado para A estratgia acessa

a transao acessvel via JNDI o objeto da seguinte maneira:

context.lookup("UserTransaction"). Portanto, para voc utilizar esta estratgia, voc precisa de umcontainer JEE ou de um servidor JTA qualquer. preciso tambm informar no arquivo persistence.xml o endereo da conexo JTA gerenciada. Veja um exemplo utilizando o Hibernate como implementao JPA:

java:/DefaultDS

11

Captulo 4. Transao

4.7. Crie a sua estratgiaCaso nenhuma das estratgias oferecidas sirva para voc, crie a sua. Basta escrever uma classe no-final que implemente a interface Transaction do pacote br.gov.frameworkdemoiselle.transaction. Anote a classe com @SessionScoped e @Alternative para que o CDI saiba que se trata de uma estratgia. preciso que sua classe no possua construtores explcitos ou que possua um construtor pblico sem parmetros. possvel fazer injees nesta classe.

package projeto; import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.Alternative; import br.gov.frameworkdemoiselle.transaction.Transaction; @Alternative @SessionScoped public class MegaTransaction implements Transaction { public void begin() { } public void commit() { } public void rollback() { } public void setRollbackOnly() { } public int getStatus() { } public void setTransactionTimeout(int seconds) { } public boolean isActive() { } public boolean isMarkedRollback() { } }

Basta agora definir no arquivo META-INF/beans.xml a sua estratgia:

projeto.MegaTransaction

12

Crie a sua estratgia

13

14

ExceesEsta funcionalidade foi feita para voc que acha muito verboso encher o cdigo de try/catch. E o que dizer de repetir o tratamento de excees em vrios mtodos da mesma classe na base do copiar/colar? Oferecemos voc uma alternativa para resolver estes problemas, mas voc estar livre para us-la: isoladamente, misturando com a forma verbosa ou at mesmo no us-la.

5.1. Tratadores de exceoPara definir um tratador de exceo, basta anotar o mtodo com @ExceptionHandler. O tratamento de excees s possvel em classes anotadas com @Controller ou os derivados desta anotao. (TODO: fazer referncia ao captulo Controladores)

@Controller public class Simples { @ExceptionHandler public void tratador(NullPointerException cause) { } public void inserir() { } public void alterar() { } public void excluir() { } }

Neste exemplo, qualquer exceo do tipo NullPointerException que ocorrer nos mtodos da classe Simples ter o tratamento delegado para o mtodo tratador(). Para as excees no tratadas, o comportamento seguir o padro da linguagem.

5.2. Mltiplos tratadoresNo se limite a apenas um tratador por classe, voc pode ter vrios.

@Controller public class Simples { @ExceptionHandler public void tratador(NullPointerException cause) { } @ExceptionHandler public void tratador(AbacaxiException cause) { } public void inserir() { } public void alterar() { } public void excluir() { }

15

Captulo 5. Excees

}

Caso as excees NullPointerException ou AbacaxiException ocorram nos mtodos da classe Simples, o tratamento ser delegado para o seu tratador.

5.3. Misturando os dois mundos possvel que, em determindas situaes no seu projeto, voc precise misturar o tratamento sofisticado com a tradicional forma verbosa. Como fazer isso? Suponha que no mtodo inserir() voc precise dar um tratamento exclusivo para uma exceo. Para isso, misture as duas abordagens para atingir o seu objetivo.

@Controller public class Simples { @ExceptionHandler public void tratador(NullPointerException cause) { } public void inserir() { try { // tenta algo } catch (AbacaxiException cause ) { // trata o problema } } public void alterar() { } public void excluir() { } }

Neste caso a exceo AbacaxiException s ser tratada no mtodo inserir().

5.4. Exceo de aplicaoTODO: escrever sobre a anotao @ApplicationException

5.5. Tratamento padroTODO: escrever sobre o tratamento automtico das excees de aplicao que chegam camada de apresentao.

16

Configurao6.1. Configuraes em uma aplicaoEm aplicaes no modelo Java EE, as quais so executadas hospedadas em um servidor de aplicaes ou continer Web, existem diversos papis alm do desenvolvedor, tais como assembler e deployer. comum nestas aplicaes que informaes de configurao de ambiente, especialmente por questes de segurana, sejam de conhecimento restrito. Por exemplo, o usurio e senha de um banco de dados ou o nome de uma fila de mensagens so informaes que o desenvolvedor no deve possuir, pelo menos para o ambiente de produo. Alm disso, o profissional responsvel pelo deploy (i.e., a implantao) da aplicao geralmente no pode ser encarregado de recompilar os cdigos fontes para efetivar a alterao desses dados. Para resolver essas questes, faz-se necessrio um mecanismo de configurao para as aplicaes. O desenvolvedor e o assembler constroem inteiramente uma aplicao e entregam o respectivo arquivo para o deployer coloc-la em produo. Paralelamente a isso, o deployer configura arquivos externos e variveis de sistema com as informaes sigilosas e protegidas que sero posteriormente lidas pela aplicao. A aplicao no precisar ser reconstruda caso um dado de configurao precise ser modificado. Frequentemente em Java utilizamos as seguintes abordagens para armazenar as configuraes: arquivo de propriedades: tratam-se de simples arquivos de texto nomeados com a extenso .properties e que internamente so escritos com a sintaxe chave = valor, armazenando uma nica chave por linha; arquivo XML: so arquivos de texto altamente estruturados com a sintaxe de tags e que permitem uma maior validao de seus valores, sendo geralmente nomeados com a extenso .xml; variveis de ambiente: valores definidos a nvel de sistema operacional, independente de plataforma (Windows, Linux, etc) e que podem ser recuperados durante a execuo da aplicao. Na seo a seguir veremos como o Demoiselle Framework apoia o desenvolvimento de aplicaes nas tarefas de carregamento de configuraes. Tal mecanismo comumente utilizado internamente em diversos componentes do framework.

6.2. As classes de configuraoA primeira etapa para a utilizao do mecanismo de configurao em uma aplicao consiste em criar uma classe especfica para armazenar os parmetros desejados e anot-la com @Configuration. Eis um exemplo:

@Configuration(resource = "bookmark") public class BookmarkConfig { private String applicationTitle; private boolean loadInitialData; public String getApplicationTitle() { return applicationTitle; } public boolean isLoadInitialData() { return loadInitialData; }

17

Captulo 6. Configurao

}

Na classe os atributos devem ser tratados como sendo somente de leitura, possuindo apenas seus respectivos mtodos getter. Valores default podem ser especificados com literais na prpria declarao do atributo (ex: boolean loadInitialData = true).

NotaAs classes anotadas com @Configuration so tratadas de forma diferenciada pelo continer. Elas so instanciadas uma nica vez (seguindo o padro de projeto singleton) e podem ser utilizadas em qualquer ponto da aplicao. Seu ciclo de vida gerenciado automaticamente pela implementao CDI. O arquivo de recursos especificado lido apenas na inicializao da aplicao e os atributos da classe so preenchidos automaticamente nessa etapa.

No exemplo em questo, ser buscado um arquivo de propriedades com o nome bookmark.properties contendo as seguintes chaves:

application.title = Ttulo da Aplicao load.initial.data = true

NotaRecomenda-se usar o sufixo Config em uma classe de configurao para indic-la como tal.

O nome do recurso (resource) e o tipo de configurao (type) so argumentos opcionais na anotao @Configuration. Caso no sejam especificados, ser considerado o arquivo de propriedades padro do Demoiselle Framework, o demoiselle.properties.

6.3. Especificando os parmetrosPor padro todos os atributos existentes em uma classe anotada com @Configuration so tratados como parmetros de configurao e sero automaticamente preenchidos durante a leitura do arquivo de recursos.

DicaPara indicar que um determinado atributo da classe no corresponde a um parmetro, utilize a anotao @Ignore nele. Desta forma ele ser desconsiderado no momento de leitura da configurao.

DicaPara forar a existncia de um parmetro de configurao, utilize a anotao @NotNull no respectivo atributo. Caso ele no seja encontrado no recurso, uma exceo ser lanada na inicializao da aplicao.

18

Especificando os parmetros

No arquivo de recursos ser buscada a chave correspondente ao atributo seguindo convenes pr-determinadas. Por exemplo, no caso do atributo loadInitialData, sero buscadas as seguintes verses de chaves no arquivo de recursos:

loadInitialData load.initial.data load_initial_data loadinitialdata

DicaA fim de utilizar uma nomenclatura de chave diferente dos formatos convencionados, utilize a anotao @Name no atributo.

Em determinadas situaes utilizado um prefixo de chave comum a todos os parmetros de uma classe de configurao. Neste caso, possvel especificar tal prefixo na anotao @Configuration. Isso permite, por exemplo, que um mesmo arquivo de recursos (ex: demoiselle.properties) seja compartilhado por diversas classes de configurao. Veja na listagem abaixo um cdigo fonte que ilustra a utilizao das anotaes descritas nesta seo:

@Configuration(resource = "bookmark", prefix = "general") public class BookmarkConfig { @Name("app.title") private String applicationTitle; @NotNull private boolean loadInitialData; @Ignore private int dummy; public String getApplicationTitle() { return applicationTitle; } public boolean isLoadInitialData() { return loadInitialData; } }

Na anotao @Configuration so especificados o arquivo de recursos bookmark.properties e o prefixo general a ser considerado em cada uma das chaves. Ao invs de adotar o padro convencionado, com a anotao @Name ser considerada a chave app.title aps o prefixo. Como o atributo anotado com @NotNull, presume-se que ele sempre estar presente no arquivo de recursos. Caso contrrio, uma exceo ocorrer na inicializao da aplicao. Este atributo, por estar anotado com @Ignore, no ser considerado pelo mecanismo de configuraes.

19

Captulo 6. Configurao

Neste caso, ser buscado um arquivo de propriedades com o nome bookmark.properties contendo as seguintes chaves:

general.app.title = Ttulo da Aplicao general.load.initial.data = true

DicaAlm 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 tambm arrays desses tipos.

6.4. Usando a configurao na aplicaoA fim de utilizar o objeto de configurao previamente instanciado e preenchido pelo continer, basta criar uma varivel numa classe qualquer da aplicao e anot-la com @Inject. Tal varivel ser injetada automaticamente e pode ser usada dentro de um mtodo. Veja na listagem a seguir um exemplo de injeo e uso de uma classe de configurao:

public class BookmarkBC { @Inject private BookmarkConfig config; public void startup() { if (config.isLoadInitialData()) { ... } } }

NotaO Demoiselle Framework utiliza internamente o mecanismo de configuraes na leitura do arquivo demoiselle.properties para outras funcionalidades, tais como transao, persistncia e paginao.

6.5. Lendo arquivos XMLAgora veja como ficaria a abordagem de configurao usando arquivos XML. Eis um arquivo de exemplo, o escola.xml, possuindo um valor numrico e um conjunto de strings:

125

20

Lendo variveis de ambiente

Aluno Professor Administrador

Neste caso, na classe de configurao EscolaConfig a anotao @Configuration precisa apontar para o tipo de recursos XML e usar o respectivo arquivo escola.xml. Eis a implementao necessria para que o referido arquivo XML seja lido e os seus valores carregados automaticamente:

@Configuration(resource = "escola", type = ConfigType.XML) public class EscolaConfig { private Integer qtdeInicial = 50; @Name("papeis.papel") private List papeis; private Integer getQtdeInicial() { return qtdeInicial; } public List getPapeis() { return papeis; } }

6.6. Lendo variveis de ambienteA terceira abordagem na configurao consiste em utilizar as variveis de ambiente do sistema operacional. Estas variveis geralmente so carregadas na inicializao do sistema ou aps a criao da sesso do usurio (i.e., aps o login), mas tambm podem ser modificadas manualmente atravs de comandos como set ou export. O mecanismo de configuraes no Demoiselle Framework faz uso da classe java.lang.System [http:// download.oracle.com/javase/6/docs/api/java/lang/System.html] fornecida pela API do Java para carregar os valores nas propriedades a partir de variveis de ambiente independente do sistema operacional. Veja na listagem abaixo o cdigo necessrio para a leitura de uma varivel de ambiente:

@Configuration(type = ConfigType.SYSTEM) public class EscolaConfig { @Name("java.home") private String javaDirectory; public String getJavaDirectory() { return javaDirectory; } }

21

22

Inicializao7.1. Introduo ao mecanismoUma aplicao qualquer, seja do tipo Web ou desktop, geralmente necessita efetuar determinadas tarefas durante a sua inicializao e ou finalizao. Eis alguns exemplos: abertura de conexo a um servidor de banco de dados, carregamento de parmetros de configurao a partir de arquivos externos e execuo de scripts especficos. Ou seja, normalmente essas aes so definidas como funes estruturais da aplicao. Para que a execuo dessas aes ocorra de forma concisa, faz-se necessrio o uso de um mecanismo padronizado para inicializao do ambiente. O Demoiselle Framework fornece esse mecanismo atravs da especificao CDI introduzindo duas anotaes: @Startup e @Shutdown.

7.2. Implementao na aplicaoA fim de utilizar o mecanismo inerente do Demoiselle Framework, preciso simplesmente anotar os mtodos contendo as instrues desejadas com @Startup, para a inicializao, ou @Shutdown, para a finalizao.

DicaO mecanismo de inicializao do Demoiselle Framework independente da natureza da aplicao Java, isto , visa tanto aplicaes do tipo Web quanto do tipo desktop (ex: Swing).

As instrues contidas em um mtodo anotado com @Startup sero executadas automaticamente quando a aplicao Java for inicializada, seja ela hospedada em um continer Web ou executada atravs de um mtodo

main(). Nenhum outro arquivo ou classe precisa ser definido. A anotao @Startup permite a indicao do argumento priority, um nmero inteiro que serve para definir a prioridade de execuo do respectivo mtodona existncia de mais de um inicializador para a aplicao. De maneira anloga, um mtodo anotado com @Shutdown ser executado no momento de finalizao de uma aplicao, obedecendo tambm ordem de prioridade definida com o argumento priority. Eis um exemplo de implementao de inicializador em uma aplicao:

public class BookmarkInitializer { @Startup(priority = 1) public void initialize() { ... } @Shutdown(priority = 5) public void finalize() { ... } }

23

Captulo 7. Inicializao

DicaPara a definio de prioridade de execuo de um mtodo na inicializao ou finalizao, podem ser utilizadas as constantes MIN_PRIORITY ou MAX_PRIORITY presentes em br.gov.frameworkdemoiselle.annotation.Startup.

7.3. Um exemplo prticoEis um interessante caso de uso de inicializao e finalizao: rodar um servidor de modo standalone em paralelo execuo da aplicao principal. Eis o cdigo referente essa implementao:

import br.gov.frameworkdemoiselle.annotation.Shutdown; import br.gov.frameworkdemoiselle.annotation.Startup; import static br.gov.frameworkdemoiselle.annotation.Startup.MAX_PRIORITY; import static br.gov.frameworkdemoiselle.annotation.Startup.MIN_PRIORITY; public class DatabaseServer { private final org.hsqldb.Server server; public DatabaseServer() { server = new Server(); server.setDatabaseName(0, "db"); server.setDatabasePath(0, "database/db"); server.setPort(9001); server.setSilent(true); } @Startup(priority = MAX_PRIORITY) public void startup() { server.start(); } @Shutdown(priority = MIN_PRIORITY) public void shutdown() { server.stop(); } }

24

Tratamento de Mensagens8.1. Mensagens em uma aplicaoUma aplicao bem estruturada, seja na plataforma Web ou desktop, deve exibir mensagens informativas, de aviso ou de erro ao usurio aps efetuar determinadas tarefas. Por exemplo, aps gravar um registro no banco de dados, aconselhvel que a aplicao exiba uma mensagem informativa. Se alguma exceo ocorreu, preciso exibir uma mensagem de erro. Ou seja, a severidade da mensagem deve ser escolhida de acordo com o resultado da execuo. Veja na tabela a seguir a definio de cada um dos nveis de severidade da mensagem em uma aplicao e um exemplo de texto associado:

Tabela 8.1. Nveis de severidade em mensagensSeveridade Informao Utilizao Usada quando da ocorrncia normal ou esperada no fluxo, com o objetivo de confirmar ao usurio uma situao de sucesso. Aviso Usada quando uma regra de negcio ou validao qualquer da aplicao tenha desviado o fluxo normal de execuo. Erro Reservado para o caso de uma situao anormal, tal como excees provenientes de ambiente (falha de conexo na rede, queda de um servidor de banco de dados, etc) tenha impedido a execuo. Em uma aplicao construda usando-se arquitetura em camadas, as mensagens geralmente so originadas em uma determinada camada e precisam ser transmitidas s demais at chegar ao usurio. Por exemplo, se ocorre um erro de gravao no banco de dados, isto , na camada de persistncia, tal informao precisa ser repassada s camadas subsequentes, ou seja, as camadas de negcio e posteriormente de controle e viso. Este conceito justamente chamado de tratamento de mensagens, o qual, ao lado do tratamento de excees, auxilia o fluxo de execues em uma aplicao bem arquiteturada. Em resumo, preciso programar a troca de mensagens entre as diversas camadas de uma aplicao orientada a objetos. Veremos na seo a seguir como o Demoiselle Framework 2.0 pode ajudar o desenvolvedor na tarefa de troca de mensagens em uma aplicao. A turma selecionada j est lotada. Matrcula do aluno no efetuada. Exemplo de texto Aluno includo com sucesso.

No foi possvel efetuar a modificao do aluno.

8.2. Introduo ao mecanismoOrtogonalmente s camadas verticais da aplicao (i.e., apresentao, negcio e persistncia), a arquitetura proposta pelo Demoiselle Framework fornece os contextos de transao, segurana e mensagem. Este ltimo justamente responsvel pela troca de mensagens entre as camadas. Tecnicamente falando, o contexto de mensagens no Demoiselle Framework representado pela interface

MessageContext. Esta interface contm mtodos destinados a incluso, recuperao e limpeza de mensagensno contexto. Para obter uma instncia do contexto de mensagens, basta injet-lo na classe:

25

Captulo 8. Tratamento de Men...

@Inject private MessageContext messageContext;

A maneira mais simples de se inserir uma mensagem no contexto invocando o mtodo add() de

MessageContext passando como argumento o texto literal da mensagem:

messageContext.add("Aluno inserido com sucesso.");

Opcionalmente, pode-se indicar a severidade da mensagem:

messageContext.add("Deseja realmente excluir o aluno?", SeverityType.WARN);

DicaQuando a severidade no informada (argumento de tipo SeverityType), ser considerado o nvel informativo, isto , INFO.

Para a transmisso das mensagens no contexto tambm fornecida a interface Message, a qual permite com que os textos sejam obtidos de catlogos especializados, tais como arquivos de propriedades ou banco de dados. Essa interface precisa ser implementada em uma classe customizada pelo desenvolvedor. Sua estrutura bem simples:

public interface Message { String getText(); SeverityType getSeverity(); }

A classe DefaultMessage fornecida pelo Demoiselle Framework 2.0 uma implementao da interface

Message que faz uso dos arquivos de recurso da aplicao para obteno das descries das mensagens. Especificamente utiliza o arquivo messages.properties.

NotaA unidade bsica de manipulao de mensagens no Demoiselle Framework 2.0 a interface Message. Basta que ela seja implementada na aplicao para que o contexto de mensagens possa manipul-la. A classe DefaultMessage oferecida como implementao padro dessa interface.

Para incluir uma mensagem no contexto usando o tipo Message preciso invocar o mtodo add() de MessageContext passando o objeto como argumento. Eis um exemplo disso utilizando a classe

DefaultMessage:

26

Parametrizao das mensagens

Message message = new DefaultMessage("Ocorreu um erro ao excluir o aluno!", SeverityType.ERROR); messageContext.add(message);

Uma vez inseridas no contexto em determinada camada da aplicao, as mensagens podem ser posteriormente recuperadas. Para tal, preciso invocar o mtodo getMessages() da interface MessageContext, o qual retornar uma coleo de objetos do tipo Message.

NotaA extenso para JavaServer Faces no Demoiselle Framework 2.0 transfere automaticamente as mensagens includas no MessageContext para a apresentao durante a renderizao da pgina pelo JSF.

Para remover todas as mensagens existentes no contexto, basta invocar o mtodo clear() da interface MessageContext.

NotaEspecificamente para aplicaes Java Web, o contexto de mensagens automaticamente reinicializado a cada requisio HTTP. Ou seja, as mensagens includas no contexto por uma determinada sesso de usurio no interferem nas demais sesses existentes no servidor de aplicaes. Alm disso, ao final da requisio as mensagens existentes so automaticamente excludas do contexto.

O contexto de mensagens MessageContext tem o seu ciclo de vida gerenciado pelo CDI e pertence ao escopo de sesso (i.e., @SessionScoped). Ou seja, mensagens includas na requisio de um determinado usurio no sero exibidas para um outro usurio, pois cada um possuir a sua sesso.

NotaO contexto de mensagens, representado pela interface MessageContext, capaz de armazenar diversas mensagens em uma mesma requisio. Ele no restrito aplicaes do tipo Web, isto , pode ser usado tambm para aplicaes do tipo desktop (i.e., Swing).

8.3. Parametrizao das mensagensUm recurso importante no tratamento de mensagens de uma aplicao consiste na parametrizao dos textos que elas carregam. Isso extremamente til para indicar com detalhes uma situao especfica, com o objetivo de melhor informar o usurio. Por exemplo, ao invs de simplesmente exibir Excluso de disciplina no permitida prefervel mostrar o seguinte texto mais explicativo Excluso no permitida: disciplina est sendo usada pela turma 301. Para efetuar essa parametrizao, preciso usar a formatao de textos padronizada pela classe java.text.MessageFormat [http://download.oracle.com/javase/6/docs/api/java/text/MessageFormat.html] da API do Java, que basicamente considera a notao de chaves para os argumentos. O Demoiselle Framework usa a MessageFormat para efetuar a parametrizao e formatao dos valores. Para usar essa funcionalidade, basta incluir as chaves na string da mensagem e ao inseri-la no contexto especificar os parmetros:

27

Captulo 8. Tratamento de Men...

Message message = new DefaultMessage("Aluno {0} inserido com sucesso"); messageContext.add(message, aluno.getNome());

Eis um exemplo mais avanado do uso de parametrizaes em mensagens:

Message message = new DefaultMessage( "As {1,time} do dia {1,date,short} houve {2} na turma {0}"); messageContext.add(message, new Integer(502), new Date(), "falta de professor");

O resultado da execuo deste cdigo seria um texto como: s 13:45:05 do dia 03/01/11 houve falta do professor na turma 502. Ou seja, os argumentos {0}, {1} e {2} so substitudos por seus respectivos elementos na ordem em que so passados no mtodo add(), sendo que ainda podemos formatar esses valores.

Dica possvel passar mais de um parmetro nas mensagens adicionadas no contexto, usando para isso a sintaxe de formatao da classe java.text.MessageFormat. A ordem dos argumentos passados no mtodo add() reflete nos elementos substitudos na string.

8.4. Internacionalizao das mensagensA DefaultMessage oferece a funcionalidade de internacionalizao da aplicao, ou seja, a disponibilizao dos textos em diversos idiomas. Numa aplicao do tipo Web, o mecanismo de internacionalizao faz com que as mensagens e textos sejam exibidos de acordo com o idioma selecionado pelo usurio na configurao do navegador. Como j foi citado anteriormente, a implementao DefaultMessage busca os textos das mensagens no arquivo de recursos messages.properties, o qual possui entradas no conhecido formato chave = valor. Todavia, para fazer uso desses textos, preciso passar a chave da mensagem desejada como argumento na invocao do construtor da classe. Este identificador precisa estar entre sinais de chaves, tal como no exemplo a seguir:

Message message = new DefaultMessage("{ALUNO_INSERIR_OK}"); messageContext.add(message, aluno.getNome());

Ou seja, ao invs de usar a string literal, passamos o identificador da chave presente no arquivo de propriedades.

NotaO smbolo de chaves {} na string do construtor da classe DefaultMessage indica se o texto da mensagem ser recuperado de um arquivo de recursos ou considerado o texto literal.

28

Internacionalizao das mensagens

Eis um exemplo de contedo do arquivo messages.properties destinado a manter por padro os textos no idioma portugus brasileiro (i.e., pt-BR). Veja que ele contm a chave ALUNO_INSERIR_OK usada no exemplo anterior:

ALUNO_INSERIR_OK = Aluno {0} inserido com sucesso ALUNO_ALTERAR_OK = Aluno {0} alterado com sucesso ALUNO_EXCLUIR_OK = Aluno {0} excludo com sucesso

A fim de prover internacionalizao para o idioma ingls americano (i.e., en-US) no exemplo em questo, eis o contedo do arquivo messages_en_US.properties:

ALUNO_INSERIR_OK = Student {0} was successfully added ALUNO_ALTERAR_OK = Student {0} was successfully modified ALUNO_EXCLUIR_OK = Student {0} was successfully removed

Similarmente, o arquivo messages_fr.properties se destina a prover as mensagens no idioma francs (independente do pas), contendo as linhas a seguir:

ALUNO_INSERIR_OK = L'tudiant {0} a t ajout avec succs ALUNO_ALTERAR_OK = L'tudiant {0} a t modifi avec succs ALUNO_EXCLUIR_OK = L'tudiant {0} a t supprim avec succs

NotaAs chaves das mensagens (ex: ALUNO_INSERIR_OK) devem ser as mesmas em todos os arquivos de propriedades. So elas que identificam unicamente uma mensagem, que ao final do processo tem o seu texto automaticamente traduzido para o idioma preferido do usurio.

Dica possvel ainda configurar de modo genrico o idioma, especificando apenas a lngua. Por exemplo, ao invs de ingls britnico (en_GB) e ingls americano (en_US), podemos simplesmente definir o idioma ingls (en). Neste caso, o arquivo dever ser o messages_en.properties.

NotaInternamente o Demoiselle Framework usa a classe java.util.Locale [http://download.oracle.com/ javase/6/docs/api/java/util/Locale.html] presente na API do Java para manipular os textos das mensages durante a internacionalizao.

29

Captulo 8. Tratamento de Men...

NotaA seleo de idioma na internacionalizao de uma aplicao consiste na definio de:

lngua: cdigos formados por duas letras em minsculo listados na ISO-639 (ISO Language Code) - exemplos: pt, en, fr, es, de; pas: cdigos formados por duas letras em maisculo listados na ISO-3166 (ISO Country Code) - exemplos: BR, PT, US, GB.

8.5. Exemplos de implementaoA fim de auxiliar a manuteno das descries das mensagens em uma aplicao diversas solues podem ser escolhidas pelos arquitetos e empregadas pelos desenvolvedores. Nesta seo sero mostradas duas sugestes para essa questo, usando interfaces e enumeradores. A vantagem em se utilizar ambas as solues que diversas mensagens relacionadas podem ser agrupadas, reduzindo assim a quantidade de arquivos a serem mantidos e centralizando a configurao das mensagens. Sendo assim, uma possvel soluo criar uma interface destinada a armazenar todos os modelos de mensagens de uma determinada severidade a ser usada na aplicao. Nesta interface so declarados campos do tipo Message com o modificador final (implicitamente tambm ser public e static). Veja o exemplo de cdigo para a interface InfoMessages:

public interface InfoMessages { final Message BOOKMARK_DELETE_OK = new DefaultMessage("{BOOKMARK_DELETE_OK}"); final Message BOOKMARK_INSERT_OK = new DefaultMessage("{BOOKMARK_INSERT_OK}"); final Message BOOKMARK_UPDATE_OK = new DefaultMessage("{BOOKMARK_UPDATE_OK}"); }

No

exemplo

em

questo,

o

texto

das

mensagens

ser

recuperado

do

arquivo

de

recursos

messages.properties presente no diretrio /src/main/resources/. Eis o contedo desse arquivo:

BOOKMARK_DELETE_OK = Bookmark exclu\u00EDdo\: {0} BOOKMARK_INSERT_OK = Bookmark inserido: {0} BOOKMARK_UPDATE_OK = Bookmark atualizado: {0}

DicaRecomenda-se criar uma interface para cada tipo de severidade (ex: InfoMessages, WarningMessages, ErrorMessages e FatalMessages), agrupando nestas as mensagens usadas exclusivamente para o mesmo fim.

30

Exemplos de implementao

J a segunda abordagem consiste no uso de enumeraes para centralizar os modelos de mensagem. utilizado o mesmo arquivo de recursos messages.properties ilustrado na abordagem anterior. Porm, neste caso cada enumerador da enumerao corresponder a uma chave no arquivo de propriedades.

public enum InfoMessages implements Message { BOOKMARK_DELETE_OK, BOOKMARK_INSERT_OK, BOOKMARK_UPDATE_OK; private final DefaultMessage msg; private InfoMessages() { msg = new DefaultMessage("{" + this.name() + "}"); } @Override public String getText() { return msg.getText(); } @Override public SeverityType getSeverity() { return msg.getSeverity(); } }

A fim de adicionar mensagens ao contexto, eis um exemplo de cdigo que faz uso do artefato InfoMessages, que funciona no importa qual abordagem escolhida (interface ou enumerao):

@BusinessController public class BookmarkBC { @Inject private MessageContext messageContext; public void insert(Bookmark bookmark) { ... messageContext.add(InfoMessages.BOOKMARK_INSERT_OK, bookmark.getDescription()); } public void update(Bookmark bookmark) { ... messageContext.add(InfoMessages.BOOKMARK_UPDATE_OK, bookmark.getDescription()); } public void delete(Bookmark bookmark) { ... messageContext.add(InfoMessages.BOOKMARK_DELETE_OK, bookmark.getDescription()); }

31

Captulo 8. Tratamento de Men...

}

No ponto contendo @Inject ser injetado via CDI o contexto de mensagens presente na aplicao, ou seja, uma instncia da interface MessageContext que poder ser utilizada em qualquer mtodo nessa classe. Aqui os mtodos insert(), update() e delete() na classe BookmarkBC manipulam o contexto de mensagens em cada invocao destes. O mtodo add() de MessageContext faz com que a mensagem passada como parmetro seja adicionada ao contexto, que ao final exibida para o usurio na camada de apresentao.

32

Resource BundleUm dos requisitos para se construir uma aplicao nos dias de hoje, o de que seja utilizada por pessoas em vrios lugares no mundo e em diferentes lnguas. Portanto, preciso que as aplicaes sejam facilmente internacionalizveis. Para isso, existe um recurso no java chamado de Resource Bundle, que nada mais do que um esquema de arquivos properties, onde cada arquivo representa uma lngua e cada um desses arquivos possui um conjunto de chaves e valores, sendo que os valores so os textos que sero exibidos na aplicao e esto na lngua correspondente lngua que o arquivo representa. O arquivo properties que ser utilizado para montar a aplicao escolhido pelo prprio usurio, seja atravs da lngua definida no browser ou no prprio sistema operacional. Caso o usurio escolha uma lngua que no est disponvel na aplicao, uma lngua default ser utilizada. Por exemplo: vamos imaginar que em uma aplicao existem dois arquivos properties, um em portugus e outro em ingls, e que o arquivo default o ingls. Vamos imaginar tambm que a aplicao Web, portanto a lngua escolhida est definida no prprio browser. Caso esteja configurado no browser do usurio a lngua alem e como no existe nenhum arquivo de properties para alemo, a aplicao ser exibida na lngua inglesa, que a lngua configurada como default. Todos os arquivos so criados praticamente com o mesmo nome. O que diferencia um arquivo do outro o acrscimo da sigla que representa a lngua daquele arquivo. O arquivo que representa a lngua default no tem essa sigla ao fim do nome. Seguindo o exemplo citado acima e imaginando que o nome dos nossos arquivos messages, ficaria da seguinte forma: messages.properties seria o arquivo default que representaria a lngua inglesa e messages_pt.properties seria o arquivo da lngua portuguesa. Veja abaixo um exemplo com esses dois arquivos.

messages.properties:

button.edit=Edit button.new=New button.save=Save

messages_pt.properties:

button.edit=Editar button.new=Novo button.save=Salvar

9.1. Utilizando Resource Bundle no DemoiselleNa verso 2.0 do Demoiselle Framework, existe uma fbrica de Resource Bundle que fica no Core e permite seu uso atravs da injeo ou atravs de uma instanciao normal. O grande detalhe que nessa fbrica injetado um objeto do tipo Locale, isso quer dizer que necessrio criar tambm uma fabrica de Locale. Como a definio de Locale varia de acordo com a camada de apresentao, essas fbricas foram criadas nas extenses de apresentao: demoiselle-jsf, demoiselle-se e demoiselle-vaadin. Na extenso demoiselle-

se a definio do Locale dada atravs do Locale definido na mquina do usurio, enquanto que nas extenses demoiselle-jsf e demoiselle-vaadin essa definio acontece atravs do Locale do browser do usurio,por se tratarem de extenses para camada de apresentao Web. Por default, a fbrica de Resource Bundle vai injetar um bundle apontando para o arquivo messages, mas isso pode ser facilmente alterado atravs da anotao @Name. Veja abaixo como utilizar o Resource Bundle no Demoiselle 2.0. Utilizando Resource Bundle atravs da injeo:

33

Captulo 9. Resource Bundle

@Inject @Name("messages-core") private ResourceBundle bundle; public String metodoQueRetornaOValorDaChavebuttonedit() { return bundle.getString("button.edit"); }

Utilizando Resource Bundle sem uso de injeo:

private ResourceBundleFactory bundleFactory = new ResourceBundleFactory(Locale.getDefault()); private ResourceBundle bundle; public String metodoQueRetornaOValorDaChavebuttonedit() { bundle = bundleFactory.create("messages-core"); return bundle.getString("button.edit"); }

34

Parmetro muito comum em uma aplicao web haver a necessidade de passar parmetros atravs da URL. A passagem de parmetros at que algo fcil e tranquilo de fazer. O chato a captura do parmetro dentro do Page Bean, pois toda vez que quisermos faz-lo, temos que acessar o FacesContext, para a partir da pegar o

HttpServletRequest e depois recuperar o valor passado. Veja abaixo como ficaria o cdigo.Passagem do parmetro:

http://localhost:8080/aplicacao/pagina.jsf?parametro=valorParametro

Captura do parmetro pelo Page Bean

public class Classe { public void metodo() { FacesContext context = FacesContext.getCurrentInstance(); HttpServletRequest req = (HttpServletRequest) context.getExternalContext().getRequest(); String param = req.getParameter("parametro"); } }

10.1. Como passar parmetro no Demoiselle 2.0Visando facilitar essa recuperao do parmetro passado atravs da URL, foi disponibilizada na verso 2.0 do Demoiselle Framework uma funcionalidade atravs da interface Parameter e de sua implementao

ParameterImpl, que permite capturar esse valor atravs do uso de injeo. Para isso, basta criar no seu Page Bean um objeto do tipo br.gov.frameworkdemoiselle.util.Parameter e anot-lo com @Inject. Onome desse objeto o nome que ser usado para buscar o valor do parmetro. Caso o usurio queira dar um nome diferente ao objeto, ele pode anot-lo com @Name e no valor dessa anotao, colocar o nome do parmetro. Por default o objeto criado tem o escopo de request, mas possvel usar o escopo de sesso ou de viso, bastando anotar o objeto com @SessionScoped ou @ViewScoped, respectivamente. Veja abaixo como ficaria essa passagem de parmetros na verso 2.0 do Demoiselle. Passagem do parmetro

http://localhost:8080/aplicacao/pagina.jsf?parametro=1 http://localhost:8080/aplicacao/pagina.jsf?parametroString=valorParametroString

Captura do parmetro pelo Page Bean

public class Classe { @ViewScoped @Inject private Parameter parametro;

35

Captulo 10. Parmetro

@Name("parametroString") @SessionScoped @Inject private Parameter objetoComNomeDiferenteDoParametro; }

10.2. As classes de parmetroA interface Parameter e sua implementao ParameterImpl disponibilizam alguns mtodos, como setValue(T value), getKey(), getValue() e getConverter(), que servem respectivamente para atribuir o valor do objeto, capturar o nome do parmetro passado na URL, recuperar o valor passado para aquele parmetro e capturar o conversor de tipo utilizado. Logo, para usar o valor daquele objeto, basta utilizar o mtodo getValue(), tal como mostrado a seguir:

public class Classe { @ViewScoped @Inject private Parameter parametro; public void metodo() { System.out.println("Valor do par#metro: " + parametro.getValue()); } }

36

LoggerUma API de logging um recurso interessante para informar o usurio e o desenvolvedor sobre os erros, alertas, resultados de operaes, os recursos acessados e outras informaes a respeito do sistema. Por esse motivo foi implementada na verso 2.0 do Demoiselle Framework uma fbrica de logger que fica no core e visa permitir a injeo desse recurso baseado na classe org.slf4j.Logger. Veja abaixo como usar o logger no Demoiselle 2.0:

public class MinhaClasse { @Inject private Logger logger; public void meuMetodo() { logger.debug("logando meu metodo"); logger.warn("mensagem de alerta do meu metodo"); } }

37

38

TemplatesO Demoiselle Framework 2.0 prov abstraes de classes para as camadas de apresentao, negcio e persistncia. Tais classes podem ser encontradas no pacote br.gov.frameworkdemoiselle.template e auxiliam o desenvolvedor ao disponibilizar mtodos comuns maioria das aplicaes. seguir iremos exemplificar o uso de cada uma delas.

12.1. Camada de persistnciaA classe abstrata JPACrud implementa as operaes bsicas de incluso, remoo, atualizao e recuperao de registros no banco de dados. Sendo assim, possibilita que o desenvolvedor concentre-se na criao de mtodos especficos para atender as regras de negcio da sua aplicao. Esta classe recebe dois parmetros em notao de genricos: T representa a entidade que ser tratada I representa o tipo do identificador da entidade No exemplo abaixo demonstra-se a utilizao da JPACrud, onde o desenvolvedor precisou implementar apenas um mtodo especfico.

@PersistenceController public class SuaEntidadeDAO extends JPACrud { public List findByAlgumCriterioEspecifico(final String criterio) { Query query = getEntityManager().createQuery("select se from SuaEntidade se where se.criterio = :criterio "); query.setParameter("criterio", criterio); return query.getResultList(); } }

12.2. Camada de negcioDe forma semelhante classe JPACrud, a classe DelegateCrud foi criada com o intuito de dispensar o desenvolvedor de implementar mtodos que sero comuns maioria das entidades. Alm disso, esta classe implementa a injeo de dependncia entre as camadas de negcio e persistncia. Para utiliz-la, trs parmetros devem ser passados em notao de genricos: T representa a entidade I representa o tipo do identificador da entidade C representa uma classe que implemente a interface CRUD Segue abaixo um exemplo da utilizao do DelegateCrud. Neste caso, foi implementado um mtodo para validar a entidade antes de proceder com a incluso no banco de dados. Para isso, o mtodo insert() fornecido pela classe foi sobreescrito.

@BusinessController

39

Captulo 12. Templates

public class SuaEntidadeBC extends DelegateCrud { private void validateInsert(SuaEntidade se) { // valida os atributos da entidade } @Override @Transactional public void insert(SuaEntidade se) { validateInsert(se); super.insert(se); } }

12.3. Camada de apresentaoPara a camada de apresentao, existem duas classes que implementam os comportamentos bsicos de navegao para pginas de listagem e edio. Estas classes so AbstractListPageBean e

AbstractEditPageBean, respectivamente. De forma semelhante DelegateCrud, estas classes realizama injeo de dependncia da camada de negcio dentro do artefato da camada de apresentao. Ambas recebem dois parmetros em notao de genricos:

T representa a entidade que ser tratada I representa o tipo do identificador da entidade Estendendo o AbstractListPageBean:

@ViewController public class SuaEntidadeListMB extends AbstractListPageBean { }

Estendendo o AbstractEditPageBean:

@ViewController public class SuaEntidadeEditMB extends AbstractEditPageBean { }

40

Apndice A. InstalaoA.1. Pr-requisitosSoftware Java Development Kit (JDK) Apache Maven Eclipse IDE m2eclipse plugin JBoss Application Server Verso 6.0 2.2 3.6 0.10 6.0 Site http://openjdk.org/ http://maven.apache.org/ http://www.eclipse.org/ http://m2eclipse.sonatype.org/ http://www.jboss.org/

A.2. Demoiselle InfraPara auxiliar no preparo do ambiente integrado de desenvolvimento utilizado na presente documentao, recomenda-se a utilizao dos pacotes de software fornecidos pelo projeto Demoiselle Infra [http:// demoiselle.sourceforge.net/infra/].

NotaAtualmente so disponibilizados pacotes exclusivamente para a plataforma GNU/Linux e distribuies baseadas no Debian, tal como Ubuntu.

41

42