Beruflich Dokumente
Kultur Dokumente
Guia de Referncia
Cleverson Sacramento Emerson Oliveira Emerson Saito Luciano Borges Marlon Carvalho Rodrigo Hjort Serge Rehem Thiago Mariano Wilson Guimares
Sobre o Guia de Referncia ...................................................................................................... v 1. Introduo ....................................................................................................................... 1 1.1. O que o Demoiselle? .............................................................................................. 1 1.2. Sobre a verso 2 ..................................................................................................... 1 2. Arquitetura ....................................................................................................................... 3 2.1. Estrutura ................................................................................................................ 3 2.2. Pacote Internal ......................................................................................................... 3 2.3. Arquitetura das aplicaes .......................................................................................... 3. Super POM ....................................................................................................................... 3.1. Demoiselle-Minimal-Parent .......................................................................................... 3.2. Demoiselle-SE-Parent ................................................................................................ 4 5 5 5
3.3. Demoiselle-Servlet-Parent ........................................................................................... 5 3.4. Demoiselle-JSF-Parent ............................................................................................... 5 3.5. Demoiselle-Archetype-Parent ....................................................................................... 5 4. Arqutipos ....................................................................................................................... 7 4.1. Mnimo .................................................................................................................. 7 4.2. JSF com JPA .......................................................................................................... 7 4.3. Vaadin com JPA ...................................................................................................... 7 5. Controlador ...................................................................................................................... 9 5.1. Como criar seu controlador ......................................................................................... 9 6. Transao ...................................................................................................................... 11 6.1. Configurando ......................................................................................................... 11 6.2. Mtodos transacionais .............................................................................................. 11 6.3. E se acontecer uma Exception? .................................................................................. 12 6.4. O objeto Transaction ................................................................................................ 12 6.5. Escolha a estratgia adequada ................................................................................... 12 6.6. Estratgia JPA ....................................................................................................... 12 6.7. Estratgia JTA ....................................................................................................... 13 6.8. Crie a sua estratgia ................................................................................................ 14 6.9. Escolhendo estratgias manualmente ........................................................................... 14 7. Excees ....................................................................................................................... 17 7.1. Configurando ......................................................................................................... 17 7.2. Tratadores de exceo ............................................................................................. 17 7.3. Mltiplos tratadores ................................................................................................. 17 7.4. Misturando os dois mundos ....................................................................................... 18 7.5. Exceo de Aplicao .............................................................................................. 18 7.6. Tratamento Padro .................................................................................................. 19 8. Configurao .................................................................................................................. 21 8.1. Configuraes em uma aplicao ................................................................................ 21 8.2. As classes de configurao ....................................................................................... 21 8.3. Especificando os parmetros ...................................................................................... 22 8.4. Usando a configurao na aplicao ............................................................................ 24 8.5. Lendo arquivos XML ................................................................................................ 24 8.6. Lendo variveis de ambiente ...................................................................................... 25 9. Inicializao .................................................................................................................... 27 9.1. Introduo ao mecanismo .......................................................................................... 27 9.2. Implementao na aplicao ...................................................................................... 27 9.3. Um exemplo prtico ................................................................................................. 28 10. Tratamento de Mensagens ............................................................................................... 29 10.1. Mensagens em uma aplicao .................................................................................. 29 10.2. Introduo ao mecanismo ........................................................................................ 29 10.3. Parametrizao das mensagens ................................................................................ 31 10.4. Internacionalizao das mensagens ............................................................................ 32
iii
10.5. Exemplos de implementao .................................................................................... 34 11. Resource Bundle ............................................................................................................ 37 11.1. Utilizando Resource Bundle no Demoiselle ................................................................... 37 12. Parmetro ..................................................................................................................... 39 12.1. Como passar parmetro no Demoiselle 2. .................................................................... 39 12.2. As classes de parmetro ......................................................................................... 40 13. Logger ......................................................................................................................... 41 14. Templates ..................................................................................................................... 14.1. Camada de persistncia .......................................................................................... 14.2. Camada de negcio ............................................................................................... 14.3. Camada de apresentao ........................................................................................ 43 43 43 44
15. Segurana ..................................................................................................................... 45 15.1. Configurando ........................................................................................................ 45 15.2. Autenticao ........................................................................................................ 45 15.3. Autorizao .......................................................................................................... 46 15.4. Criando sua implementao ..................................................................................... 47 16. Paginao ..................................................................................................................... 51 16.1. Introduo ao mecanismo ........................................................................................ 51 16.2. Cdigos de suporte ................................................................................................ 51 16.3. Implementao na aplicao ..................................................................................... 53 17. Demoiselle Properties ..................................................................................................... 55 17.1. Configuraes do Core ........................................................................................... 55 17.2. Configuraes da extenso JSF ................................................................................ 55 17.3. Configuraes da Extenso JPA ................................................................................ 56 A. Instalao ....................................................................................................................... 57 A.1. Pr-requisitos ......................................................................................................... 57 A.2. Demoiselle Infra ..................................................................................................... 57
iv
Nota
Esta documentao refere-se release 2.3.0 do Demoiselle Framework e pode diferir significativamente das verses anteriores.
vi
Introduo
1.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 disponibilizou os planos em revistas tcnicas para qualquer pessoa 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. Mais informaes no portal "www.frameworkdemoiselle.gov.br [http://www.frameworkdemoiselle.gov.br]
Arquitetura
2.1. Estrutura
Visando uma melhor modularizao, o Demoiselle est dividido por funcionalidades. Isto significa que o framework no monoltico, no qual todas as suas 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 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 funcionariam. As Extenses, como o prprio nome sugere, estendem o Core com funcionalidades extras e bem especficas a um domnio ou tecnologia. Neste contexto, caso sua aplicao necessite de persistncia com JPA, o framework fornecer facilidades para voc, contudo, estas funcionalidades no esto no Core. Para este propsito existem as extenses como a demoiselle-jpa, por exemplo. Cabe destacar que as extenses no possuem vida prpria, pois esto diretamente ligadas ao ncleo do framework, inclusive o ciclo de vida das extenses est totalmente acoplado ao do Core. J os Componentes so artefatos separados e que, portanto, no so dependentes diretamente do Core. Alis, os Componentes podem at mesmo existir sem referenciar o Core. Desta forma, o seu ciclo de vida totalmente independente do Core e Extenses. Um componente no precisa, necessariamente, estender o comportamento do Core, mas permitir disponibilizar novas funcionalidades ao usurio. Outra diferena importante que, diferente de Core e Extenses, os Componentes no necessariamente so aderentes a alguma especificao. Um exemplo o demoiselle-validation.
Dica
As classes do pacote internal nunca devem ser referenciadas pela sua aplicao!
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, 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 mudanas. Contudo, tudo que consta no pacote internal pode sofrer mudanas repentinas. Isto significa que sua aplicao pode deixar de funcionar de uma verso para outra caso voc esteja usando diretamente classes internas.
Captulo 2. Arquitetura
Super POM
O Demoiselle faz uso da soluo proposta pelo Apache Maven para diversas fases do desenvolvimento de software. O artefato principal do Maven o POM.XML que o arquivo XML que contm todas as informaes necessrias para a ferramenta gerenciar o projeto, entre as quais est o gerenciamento de dependncias(bibliotecas), build do projeto, etc. Mas muito comum que vrios projetos, vinculados ou no, utilizem muitas configuraes em comum. Para o reaproveitamento dessas configuraes, evitando a cpia de texto, o Maven prov dois tipos de estratgia: -Por herana [http://maven.apache.org/pom.html#Inheritance] pom.html#Aggregation]. ou agregao [http://maven.apache.org/
No Demoiselle 2 a estratgia adota foi tambm o da herana. E o termo usado no Demoiselle para identificar essa estratgia que chamamos de Parent POM. Seguindo esse conceito, foram criados alguns arquivos (pom.xml) e tambm disponibilizados no repositrio Maven do Demoiselle , que facilitam a configurao dos projetos, e inclusive para o desenvolvimento do prprio Demoiselle. Os arquivos gerados foram divididos em perfis, para que o desenvolvedor possa escolher qual usar de acordo com o tipo de aplicao que est desenvolvendo. Assim, a alterao no POM.XML da aplicao ser a minima possvel. Outra vantagem, que as bibliotecas apontadas como dependncias so testadas pela equipe do Demoiselle o que evita eventuais incompatibilidades.
Dica
Para excluir uma dependncia vinda do Parent, mas no necessria utilize a tag Exclusions
3.1. Demoiselle-Minimal-Parent
Configuraes teis para todas as aplicaes que utilizam o framework. O ideal que toda aplicao que utiliza o Demoiselle herde deste POM ou de uma de suas especializaes.
3.2. Demoiselle-SE-Parent
Especializao do POM mnimo, contendo configuraes teis para todas as aplicaes Desktop que utilizam o framework, mas sem definio da camada de apresentao que ser utilizada.
3.3. Demoiselle-Servlet-Parent
Especializao do POM mnimo, contendo profiles para Tomcat 6, Tomcat 7, GAE, Glassfish 3, JBoss 6 e JBoss 7, e outras configuraes teis para todas as aplicaes JEE6/Web que utilizam o Demoiselle, mas sem a definio de qual camada de apresentao utilizar. Entre as dependncias refernciadas por este POM est a extenso Demoiselle-Servlet.
3.4. Demoiselle-JSF-Parent
Especializao do POM demoiselle-servlet-parent, contendo configuraes teis e necessrias para todas as aplicaes que utilizaro a tecnologia JSF2 para camada de apresentao. Entre as dependncias refernciadas por este POM est obviamente a extenso Demoiselle-JSF.
3.5. Demoiselle-Archetype-Parent
Contm configuraes comuns a todos os projetos geradores de arqutipos.
Arqutipos
O projeto Demoiselle recomenda e usa a ferramenta Apache-Maven [http://maven.apache.org/] , para gerenciamento do ciclo de vida do desenvolvimento de projeto. Baseada nesta ferramenta, alm do fornecimento dos POMs Parentes, tambm fornece as estruturas chamadas arqutipos [http://maven.apache.org/archetype/ maven-archetype-plugin/] para facilitar a criao de aplicaes, garantido a estrutura recomendada pelo framework e o conceito de gerenciamento do prprio Maven. Atualmente esto disponveis os seguintes artefatos:
4.1. Mnimo
Fornece um conjunto mnimo de artefatos para criar uma aplicao Java, utiliza o Demoiselle-Minimal-Parent sendo til quando os outros arqutipos disponveis no se enquadram nas caractersticas do projeto a ser criado.
Controlador
No Demoiselle Framework 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.
Neste exemplo foi criado um controlador chamado SeuController que tem a caracterstica de ter um escopo de View. Isto quer dizer que toda classe que seja desse tipo de controlador, tambm ter o escopo de View.
10
Transao
Esta funcionalidade utiliza os recursos do CDI para interceptar e delegar adequadamente o tratamento das transaes. 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.
6.1. Configurando
Para um correto funcionamento do Demoiselle necessrio inserir o interceptador de transao no arquivo src/ main/WEB-INF/beans.xml.
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <interceptors> <class>br.gov.frameworkdemoiselle.internal.interceptor.TransactionalInterceptor</ class> </interceptors> </beans>
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() { }
11
Captulo 6. Transao
Neste exemplo, os mtodos inserir(), alterar() e excluir() da classe Simples participaro do contexto transacional.
@Transactional. Contudo, caso voc a utilize, voc poder escolher entre as estratgias JPA, JTA (ambas fornecidas pelo Framework) e uma estratgia que voc pode criar ou importar para seu projeto.
A forma de selecionar cada uma dessas estratgias descrita abaixo. Caso tente utilizar o controle de transao e no selecione nenhuma estratgia, o framework lanar uma exceo lhe avisando sobre isto!
12
Estratgia JTA
Dica
Caso no esteja utilizando o arqutipo JSF-JPA fornecidos pelo Demoiselle, confira se a dependncia para a extenso est indicada corretamente no arquivo POM.XML.
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="bookmark-ds" transaction-type="JTA"> <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source> <properties> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="false" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" /> </properties> </persistence-unit> </persistence>
13
Captulo 6. Transao
Dica
Caso no esteja utilizando o arqutipo JSF-JPA fornecidos pelo Demoiselle, confira se a dependncia para a extenso est indicada corretamente, no arquivo POM.XML.
package projeto; import br.gov.frameworkdemoiselle.transaction.Transaction; public class MegaTransaction implements Transaction { public void begin() { } public void commit() { } public void rollback() { } public public public public public } void setRollbackOnly() { } int getStatus() { } void setTransactionTimeout(int seconds) { } boolean isActive() { } boolean isMarkedRollback() { }
Pronto, s isso! Agora, os mtodos anotados com @Transactional iro utilizar a estratgia criada em seu projeto de forma automtica, mesmo que as extenses demoiselle-jpa e demoiselle-jta sejam adicionadas ao projeto, pois o framework da prioridade mxima estratgia criada no projeto.
frameworkdemoiselle.transaction.class=projeto.MyTransaction
14
frameworkdemoiselle.transaction.class=br.gov.frameworkdemoiselle.transaction.JTATransaction
frameworkdemoiselle.transaction.class=br.gov.frameworkdemoiselle.transaction.JPATransaction
15
16
Excees
Esta 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.
7.1. Configurando
Para um correto funcionamento do Demoiselle necessrio inserir o interceptador de exceo no arquivo src/ main/WEB-INF/beans.xml.
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <interceptors> <class>br.gov.frameworkdemoiselle.internal.interceptor.ExceptionHandlerInterceptor</ class> </interceptors> </beans>
@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.
@Controller
17
Captulo 7. Excees
public class Simples { @ExceptionHandler public void tratador(NullPointerException cause) { } @ExceptionHandler public void tratador(AbacaxiException cause) { } public void inserir() { } public void alterar() { } public void excluir() { } }
@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() { } }
18
Tratamento Padro
No exemplo citado acima, estamos informando que caso esta exceo seja lanada por um mtodo anotado com @Transactional, este mtodo sofrer um rollback. Ao mesmo tempo, sua camada de exibio apresentar uma mensagem automtica para o usurio, conforme o nvel de severidade. O comportamento padro para o rollback realizar o rollback sempre que a exceo for lanada. O grau de severidade padro informativo (INFO).
@ApplicationException, um rollback realizado de forma automtica. Por ltimo, sem o uso desta anotao, toda exceo vista como tendo nvel de gravidade igual a ERROR.
19
20
Configurao
8.1. Configuraes em uma aplicao
Em 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.
@Configuration(resource = "bookmark") public class BookmarkConfig { private String applicationTitle; private boolean loadInitialData; public String getApplicationTitle() { return applicationTitle; } public boolean isLoadInitialData() { return loadInitialData; } }
21
Captulo 8. 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:
Nota
As 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:
Nota
Recomenda-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.
Dica
Para 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.
Dica
Para 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.
22
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
Dica
A 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:
@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.
23
Captulo 8. Configurao
Neste caso, ser buscado um arquivo de propriedades com o nome bookmark.properties contendo as seguintes chaves:
Dica
Alm 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 e de alguns tipos complexos (i.e., Integer, BigDecimal,
public class BookmarkBC { @Inject private BookmarkConfig config; public void startup() { if (config.isLoadInitialData()) { ... } } }
Nota
O Demoiselle Framework utiliza internamente o mecanismo de configuraes na leitura do arquivo
<configuration> <qtdeInicial>125</qtdeInicial>
24
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<String> papeis; private Integer getQtdeInicial() { return qtdeInicial; } public List<String> getPapeis() { return papeis; } }
@Configuration(type = ConfigType.SYSTEM) public class EscolaConfig { @Name("java.home") private String javaDirectory; public String getJavaDirectory() { return javaDirectory; } }
25
26
Inicializao
9.1. Introduo ao mecanismo
Uma 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.
Dica
O 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 pode ser utilizada em conjunto com a anotao @Priority, que recebe como parametro um nmero inteiro que serve para definir a
prioridade de execuo do respectivo mtodo, na 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 a anotao @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() { ... } }
27
Captulo 9. Inicializao
Dica
Para 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.Priority.
import br.gov.frameworkdemoiselle.lifecycle.Shutdown; import br.gov.frameworkdemoiselle.lifecycle.Startup; import static br.gov.frameworkdemoiselle.annotation.Priority.MAX_PRIORITY; import static br.gov.frameworkdemoiselle.annotation.Priority.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(); } }
28
Tratamento de Mensagens
10.1. Mensagens em uma aplicao
Uma aplicao bem estruturada, seja na plataforma Web ou Desktop, deve exibir mensagens informativas, de aviso, ou de erro para o 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:
MessageContext. Esta interface contm mtodos destinados a incluso, recuperao e limpeza de mensagens
no contexto. Para obter uma instncia do contexto de mensagens, basta injet-lo na classe:
29
A maneira mais simples de se inserir uma mensagem no contexto invocando o mtodo add() de
Dica
Quando 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:
A classe DefaultMessage fornecida pelo Demoiselle Framework 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.
Nota
A unidade bsica de manipulao de mensagens no Demoiselle Framework 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:
30
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.
Nota
A extenso para JavaServer Faces no Demoiselle Framework 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.
Nota
Especificamente 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.
Nota
O 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).
31
Message message = new DefaultMessage("Aluno {0} inserido com sucesso"); messageContext.add(message, aluno.getNome());
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.
Ou seja, ao invs de usar a string literal, passamos o identificador da chave presente no arquivo de propriedades.
Nota
O 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.
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:
32
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
Nota
As 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.
Nota
Internamente 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.
Nota
A seleo de idioma na internacionalizao de uma aplicao consiste na definio de:
33
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.
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,
texto
das
mensagens
ser
recuperado
do
arquivo
de
recursos
BOOKMARK_DELETE_OK = Bookmark exclu\u00EDdo\: {0} BOOKMARK_INSERT_OK = Bookmark inserido: {0} BOOKMARK_UPDATE_OK = Bookmark atualizado: {0}
Dica
Recomenda-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.
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.
34
Exemplos de implementao
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()); } }
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
35
passada como parmetro seja adicionada ao contexto, que ao final exibida para o usurio na camada de apresentao.
36
Resource Bundle
Um 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:
messages_pt.properties:
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. Utilizando Resource Bundle atravs da injeo:
37
@Inject @Name("messages-core") private ResourceBundle bundle; public String metodoQueRetornaOValorDaChavebuttonedit() { return bundle.getString("button.edit"); }
private ResourceBundleFactory bundleFactory = new ResourceBundleFactory(Locale.getDefault()); private ResourceBundle bundle; public String metodoQueRetornaOValorDaChavebuttonedit() { bundle = bundleFactory.create("messages-core"); return bundle.getString("button.edit"); }
38
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
public class Classe { public void metodo() { FacesContext context = FacesContext.getCurrentInstance(); HttpServletRequest req = (HttpServletRequest) context.getExternalContext().getRequest(); String param = req.getParameter("parametro"); } }
http://localhost:8080/aplicacao/pagina.jsf?parametro=1 http://localhost:8080/aplicacao/pagina.jsf?parametroString=valorParametroString
39
public class Classe { @ViewScoped @Inject private Parameter<Long> parametro; public void metodo() { System.out.println("Valor do par#metro: " + parametro.getValue()); } }
40
Logger
Uma 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.X 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:
public class MinhaClasse { @Inject private Logger logger; public void meuMetodo() { logger.debug("logando meu metodo"); logger.warn("mensagem de alerta do meu metodo"); } }
41
42
Templates
O Demoiselle Framework 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.
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<SuaEntidade, Long> { public List<SuaEntidade> findByAlgumCriterioEspecifico(final String criterio) { Query query = getEntityManager().createQuery("select se from SuaEntidade se where se.criterio = :criterio "); query.setParameter("criterio", criterio); return query.getResultList(); } }
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
43
public class SuaEntidadeBC extends DelegateCrud<SuaEntidade, Long, SuaEntidadeDAO> { private void validateInsert(SuaEntidade se) { // valida os atributos da entidade } @Override @Transactional public void insert(SuaEntidade se) { validateInsert(se); super.insert(se); } }
T representa a entidade que ser tratada I representa o tipo do identificador da entidade Estendendo o AbstractListPageBean:
Estendendo o AbstractEditPageBean:
44
Segurana
Neste captulo ser tratada uma questo de grande importncia para a maioria das aplicaes e motivo de infindveis discusses nas equipes de desenvolvimento: controle de acesso. Assim como tudo relacionado ao framework, a implementao de segurana foi projetada de forma simples e flexvel, independente de camada de apresentao ou tecnologia, te deixando livre para implementar sua prpria soluo ou utilizar as extenses prontas, como a que atualmente provemos baseada no Apache Shiro (http://shiro.apache.org). Para utilizar o modelo de segurana proposto basta utilizar o Demoiselle, pois no ncleo do Framework esto as interfaces e anotaes que definem o comportamento bsico da implementao.
15.1. Configurando
Para um correto funcionamento do Demoiselle necessrio inserir os interceptadores de segurana no arquivo
src/main/WEB-INF/beans.xml.
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <interceptors> <class>br.gov.frameworkdemoiselle.internal.interceptor.RequiredPermissionInterceptor</ class> <class>br.gov.frameworkdemoiselle.internal.interceptor.RequiredRoleInterceptor</class> </interceptors> </beans>
15.2. Autenticao
O mecanismo de autenticao busca verificar a identidade do usurio de um sistema. A forma mais conhecida, e comum, para executar essa verificao se d por meio de um formulrio de login, geralmente solicitando um nome de usurio e sua respectiva senha. No entanto, outras formas como reconhecimento biomtrico e autenticao por token, para citar apenas duas, tm ganhado um grande nmero de adeptos. O Demoiselle deixa o desenvolvedor livre para definir qual forma usar, de acordo com a sua convenincia e necessidade. A pea chave para tornar isso possvel o contexto de segurana, representado pela interface SecurityContext. Nessa esto definidos os mtodos responsveis por gerenciar os mecanismos de autenticao como, por exemplo, executar login/logout de usurios e verificar se os mesmos esto ou no autenticados. O contexto de segurana ir direcionar as requisies para a implementao definida pela aplicao. A autenticao ser efetuada por uma classe que implemente a interface Authenticator, cujo mtodo authenticate() responsvel por executar os passos necessrios para validar a identidade de um usurio. Nesta mesma interface sero encontrados, ainda, os mtodos unAuthenticate() e getUser(), responsveis por, respectivamente, desautenticar e retornar o usurio autenticado. Para exemplificar, consideremos a autenticao baseada em nome de usurio e senha. O primeiro passo criar um bean para armazenar essas informaes:
45
Feito isso, podemos implementar a classe na qual se deseja adicionar o mecanismo de segurana:
public class ClasseExemplo { @Inject private Credential credential; @Inject private SecurityContext context; public void metodo1() { credential.setLogin(#usuario1#); credential.setSenha(#123#); context.login(); // codigo do metodo context.logout(); } }
Neste caso, a interface SecurityContext e o bean Credential esto sendo injetados na classe utilizando o CDI. Dentro do mtodo, ao definir o usurio e a senha e invocar context.login(), a implementao de segurana definida ir tratar essa requisio de acordo com os critrios estabelecidos.
15.3. Autorizao
O mecanismo de autorizao responsvel por garantir que apenas usurios autorizados tenham o acesso concedido a determinados recursos de um sistema. No modelo de segurana do Demoiselle 2, a autorizao pode acontecer de duas formas: Permisso por usurio, atravs da anotao @RequiredPermission Permisso por papel, atravs da anotao @RequiredRole Novamente a interface SecurityContext a responsvel pela interao entre as funcionalidades da aplicao e a implementao de segurana. Nela esto definidos os mtodos que verificam se o usurio possui permisso para acessar um recurso ou se o usurio est associado a um papel. A anotao @RequiredPermission pode ser utilizada tanto em classes como em mtodos e possui dois parmetros opcionais: operation e resource. O primeiro define a operao para a qual se deseja permisso e o segundo define em qual recurso essa operao ser realizada. Abaixo sero exemplificadas algumas formas de utilizao:
class ClasseExemplo { @RequiredPermission public void requiredPermissionWithoutDeclaredResourceAndOperation() { } @RequiredPermission(resource = "contact", operation = "insert")
46
Observe o mtodo cuja anotao no possui parmetros. Nesse caso sero considerados como recurso e operao o nome da classe e do mtodo, respectivamente. Uma outra possibilidade seria utilizar a anotao @Name, tanto na classe como no mtodo, de forma a possibilitar uma descrio mais amigvel para o usurio. Assim como na autenticao, o contexto de segurana possui mtodos destinados a delegar as requisies de autorizao para a implementao de segurana. No caso da anotao @RequiredPermission , o mtodo hasPermission(String resource, String operation) executa esta tarefa. Para tanto, deve existir uma classe que implemente a interface Authorizer, cujo mtodo hasPermission(Object resource, String operation) verifica se o usurio logado possui permisso para executar uma determinada operao em um recurso especfico. Ainda na interface Authorizer, pode-se notar a existncia do mtodo hasRole(String role), responsvel por verificar se o usurio logado possui um papel especfico. Este mtodo chamado pelo contexto de segurana, por meio do seu mtodo hasRole(String role), para tratar as requisies que possuam a anotao @RequiredRole. Essa anotao possui um parmetro obrigatrio, no qual podem ser definidos uma simples role ou um array delas.
class ClasseExemplo { @RequiredRole("simpleRoleName") public void requiredRoleWithSingleRole() { } @RequiredRole({ "firstRole", "secondRole", "thirdRole", "fourthRole", "fifthRole" }) public void requiredRoleWithArrayOfRoles() { } }
As restries de segurana pode ser utilizadas, ainda, em pginas web, com o auxlio de Expression Language, como no exemplo abaixo:
Nesse caso, a habilitao de um boto est condicionada existncia de permisso para o usurio autenticado no momento executar a operao insert no recurso contact.
47
@Override public boolean authenticate() { // Escreva aqui seu codigo de autenticacao return true; } @Override public User getUser() { // Escreva aqui seu codigo para retornar o usuario logado return null; } @Override public void unAuthenticate() { // Escreva aqui seu codigo de desautenticacao } }
public class MeuAuthorizer implements Authorizer { @Override public boolean hasRole(String role) { // Escreva aqui seu codigo de verificacao do papel return false; } @Override public boolean hasPermission(Object resource, String operation) { // Escreva aqui seu codigo de verifica##o de permissao return false; } }
Pronto! Sua aplicao j possui uma implementao de segurana definida. Caso sua ela no implemente essas interfaces, no momento em que forem chamadas, o framework lanar uma exceo informando que a aplicao precisa implement-las. Se voc tem mais de uma implementao de Authenticator e/ou Authorizer (o que pode acontecer, por exemplo, quando se necessite de uma implementao na aplicao principal, e outra para os testes), dever definir no arquivo demoiselle.properties qual classe ser a padro:
frameworkdemoiselle.security.authenticator.class=projeto.MeuAuthenticatorPadrao frameworkdemoiselle.security.authorizer.class=projeto.MeuAuthorizerPadrao
Cuidado
O Demoiselle tambm oferece o componente Authorization [http://demoiselle.sourceforge.net/ docs/demoiselle-guide-components/1.2.0/html/authorization-master.html] que facilita o uso de segurana com JAAS. Obviamente, no possvel utiliz-los ao mesmo tempo. H arqutipos
48
Maven que j trazem esse componente como dependncia, por isso sempre confira o arquivo POM.XML e se for o caso retire essa dependncia.
49
50
Paginao
Neste captulo sero considerados os seguintes assuntos: Motivao para o uso de um mecanismo padronizado para paginao; Funcionamento e uso da estrutura Pagination e do contexto de paginao (PaginationContext).
currentPage (pgina atual, selecionada na camada de viso), pageSize (tamanho da pgina, a quantidade de registros que ela comportar) e totalResults (a quantidade de resultados existentes na base de dados);
A classe PaginationContext: contexto usado para armazenar e fornecer estruturas do tipo Pagination; A classe PaginationConfig: armazenador de configuraes referentes paginao. Cdigos internos de suporte no Core:
public class Pagination { private int currentPage; private int pageSize; private Long totalResults; private Integer totalPages; // ...
51
} @SessionScoped public class PaginationContext { private final Map<Class<?>, Pagination> map; public Pagination getPagination(Class<?> clazz) { ... } public Pagination getPagination(Class<?> clazz, boolean create) { ... } } @Configuration public class PaginationConfig { @Name("default_page_size") private int defaultPageSize = 10; @Name("max_page_links") private int maxPageLinks = 5; }
public class JPACrud<T, I> implements Crud<T, I> { @Inject private PaginationContext paginationContext; // ... public List<T> findAll() { final String jpql = "select this from " + getBeanClass().getSimpleName() + " this"; final Query query = getEntityManager().createQuery(jpql); final Pagination pagination = paginationContext.getPagination(getBeanClass()); if (pagination != null) { if (pagination.getTotalPages() == null) { pagination.setTotalResults(this.countAll()); } query.setFirstResult(pagination.getFirstResult()); query.setMaxResults(pagination.getPageSize()); } // ... } }
public abstract class AbstractListPageBean<T, I> extends AbstractPage implements ListPageBean<T, I> { @Inject private PaginationContext paginationContext; @Inject private PaginationConfig paginationConfig;
52
Implementao na aplicao
// ... public Pagination getPagination() { return paginationContext.getPagination(getBeanClass(), true); } public int getPageSize() { return paginationConfig.getDefaultPageSize(); } public int getMaxPageLinks() { return paginationConfig.getMaxPageLinks(); } }
Pagination e ajustar alguns dos seus parmetros para: indicar a partir de qual item a paginao deve iniciar, e o tamanho (quantidade de itens) de cada pgina. Esses dados so usados no mtodo findAll(), da classe JPACrud (extenso JPA), que utiliza o contexto de paginao para pegar os parametros e fazer a consulta no banco buscando apenas os itens que esto dentro da pagina que o parametro first indicar. O resultado passado para a instncia do LazyDataModel, que responsvel por exibir os dados de forma apropriada.
classe BookmarkList devem ser adicionados os seguintes trechos de cdigo:
// ... import java.util.Map; import br.gov.frameworkdemoiselle.pagination.Pagination; // ... public BookmarkListMB() { private LazyDataModel<Bookmark> lazyModel; lazyModel = new LazyDataModel<Bookmark>() { @Override public List<Bookmark> load (int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters){ Pagination pagination = getPagination(); pagination.setPageSize(pageSize); pagination.setFirstResult(first); List<Bookmark> itemsList = bc.findAll();
53
lazyModel.setRowCount(pagination.getTotalResults()); return itemsList; } }; // ... public LazyDataModel<Bookmark> getLazyModel() { return lazyModel; } // ... }
por:
Com essas alteraes simples, a aplicao Bookmarks passa a utilizar o mecanismo de paginao oferecido pelo Demoiselle Framework.
Dica
O mtodo getPagination() do contexto PaginationContext sobrecarregado, podendo aceitar os seguintes argumentos: Class ou Class e boolean.
Nota
A JPA 2.0, atravs da Query API, suporta controle de paginao independente de fornecedor de banco de dados. Para controlar a paginao, a interface Query define os mtodos
54
Demoiselle Properties
Em um projeto com o Demoiselle Framework, algumas propriedades e configuraes do Framework podem ser ajustadas no arquivo demoiselle.properties. A seguir listamos as propriedades e configuraes do Demoiselle Framework que o usurio pode modificar, acompanhados de alguns exemplos ilustrativos.
false, desabilita as
"/
index", configura a pgina "/index" para ser acessada no redirecionamento aps o logout do usurio.
frameworkdemoiselle.security.redirect.enebled - Configura a habilitao do redirecionamento da pgina aps login e logout. Por padro, o valor dessa propriedade true. Exemplo de configurao: frameworkdemoiselle.security.redirect.enebled desabilita os redirecionamentos de pginas aps login e logout.
false,
frameworkdemoiselle.handle.application.exception - Define se a extenso vai capturar ou no alguma exceo lanada pela aplicao. Por padro, essa configurao vem marcada como true, que diz para a extenso capturar a exceo.
55
Exemplo de configurao: frameworkdemoiselle.handle.application.exception = false, desabilita a captura de excees lanadas pela aplicao. frameworkdemoiselle.handle.aplication.exception.page - Configura a pgina para a qual a aplicao ser direcionada em caso de exceo. Por padro, a pgina configurada /application_error. Exemplo de configurao: framework.handle.aplication.exception.page = /exception_x_page, redireciona a aplicao para a pgina /exception_x_page caso ocorra alguma exceo.
database1-ds,
56
Apndice A. Instalao
A.1. Pr-requisitos
Software 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/
Nota
Atualmente so disponibilizados pacotes exclusivamente para a plataforma GNU/Linux e distribuies baseadas no Debian, tal como Ubuntu.
57
58