emerson saito marlon carvalho rodrigo hjort serge...

32
Framework Demoiselle 2.0 QuickStart Emerson Saito Marlon Carvalho Rodrigo Hjort Serge Rehem

Upload: dinhhanh

Post on 21-Sep-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

Framework Demoiselle 2.0

QuickStart

Emerson Saito

Marlon Carvalho

Rodrigo Hjort

Serge Rehem

iii

Sobre o QuickStart ................................................................................................................. v

1. Instalação ........................................................................................................................ 1

1.1. Pré-requisitos .......................................................................................................... 1

1.2. Demoiselle Infra ....................................................................................................... 1

2. Criação da aplicação .......................................................................................................... 3

2.1. Nossa primeira aplicação ............................................................................................ 3

2.2. Construindo o projeto usando um arquétipo Maven ............................................................ 3

2.2.1. Linha de comando .......................................................................................... 3

2.2.2. Modo assistido com Eclipse .............................................................................. 3

2.3. Criando a entidade de domínio ..................................................................................... 8

2.4. Implementando a camada de persistência ....................................................................... 9

2.5. Implementando a camada de negócio ........................................................................... 10

2.6. Implementando a camada de apresentação .................................................................... 11

2.7. Executando no servidor ............................................................................................ 14

3. Melhorando a aplicação .................................................................................................... 17

3.1. Implementando funcionalidade de edição ....................................................................... 17

3.2. Exibindo mensagens para o usuário ............................................................................. 22

3.3. Criando regras de validação nos campos ....................................................................... 24

iv

v

Sobre o QuickStart

Este documento é um tutorial do tipo "passo a passo" que visa ilustrar de forma rápida, clara e prática a criação de

uma aplicação simples utilizando o Demoiselle Framework 2.X.

Nota

Apesar de o Demoiselle Framework 2.X ser simples de usar, o desenvolvimento de aplicações

não triviais requer o conhecimento das diversas tecnologias envolvidas na especificação Java

EE, incluindo:

• Linguagem Java

• Servlets, JSP e Tag Libraries

• JavaBeans

• HTML e XML

• Contêineres e Servidores Web

Nota

Esta documentação refere-se à release 2.2.X do Demoiselle Framework e pode diferir

significativamente das versões anteriores.

vi

1

Instalação

1.1. Pré-requisitos

Software Versão Site (Download)

Java Development Kit (JDK) 6.0 openjdk.org [http://openjdk.org/]

Apache Maven 2.2 maven.apache.org [http://

maven.apache.org/docs/2.2.1/release-

notes.html]

Eclipse IDE 3.7 www.eclipse.org [http://www.eclipse.org/

downloads/packages/release/indigo/r]

m2eclipse plugin 0.12 m2eclipse.sonatype.org [http://

m2eclipse.sonatype.org/installing-

m2eclipse.html]

JBoss Application Server 6.0 www.jboss.org [http://sourceforge.net/

projects/jboss/files/JBoss/

JBoss-6.0.0.Final/jboss-as-

distribution-6.0.0.Final.zip/download]

1.2. Demoiselle Infra

Para auxiliar no preparo do ambiente integrado de desenvolvimento utilizado na presente documentação,

recomenda-se a utilização dos pacotes de software fornecidos pelo projeto Demoiselle Infra [http://

demoiselle.sourceforge.net/infra/]. Neste link você encontrará as orientações necessárias para a sua configuração.

Nota

Atualmente são disponibilizados pacotes exclusivamente para a plataforma GNU/Linux e

distribuições baseadas no Debian, tal como Ubuntu.

Se você não utiliza nenhum dos sistemas operacionais citados, terá que baixar e instalar todos os

softwares listados acima. Para auxiliar um pouco o processo, disponibilizamos alguns vídeos aqui [http://

www.frameworkdemoiselle.gov.br/documentacaodoprojeto/tutoriais/videos/] de demonstração de algumas fases.

2

3

Criação da aplicação

2.1. Nossa primeira aplicação

Para iniciar o uso do Demoiselle Framework 2.X, criaremos uma aplicação Java do tipo Web utilizando o Apache

Maven [http://maven.apache.org/], através do plugin para IDE Eclipse (M2Eclipse) para gerenciar todo o clico de

vida do Projeto, desde a criação até o deploy.

Essa aplicação consistirá em um cadastro simples de bookmarks (links “Favoritos”) e será gerada com o auxílio de

um arquétipo do Maven disponibilizado pelo projeto Demoiselle. Ela será preparada para utilizar as tecnologias de

persistência JPA e de apresentação JSF nas versões mais recentes conforme a especificação Java EE 6.

2.2. Construindo o projeto usando um arquétipo Maven

Importante

O procedimento a seguir pode ser comumente executado de forma visual com o auxílio de um

assistente (i.e., wizard) de dentro da IDE Eclipse, como será demonstrado logo após o modo linha

de comando.

2.2.1. Linha de comando

Para criar a aplicação usando o arquétipo em linha de comando, abra um terminal e execute o comando mvn do

Maven com os argumentos ilustrados a seguir:

mvn archetype:generate \

-DarchetypeGroupId=br.gov.frameworkdemoiselle.archetypes \

-DarchetypeArtifactId=demoiselle-jsf-jpa \

-DarchetypeVersion=2.2.0 \

-DarchetypeRepository=http://demoiselle.sourceforge.net/repository/release/ \

-DgroupId=br.gov.frameworkdemoiselle.sample \

-DartifactId=bookmark \

-Dversion=1.0.0-SNAPSHOT \

-DinteractiveMode=false

2.2.2. Modo assistido com Eclipse

Para criar esse projeto utilizando a IDE Eclipse, acesse o menu File, New, Other... digite e selecione Maven Project:

conforme mostrado na figura abaixo:

Capítulo 2. Criação da aplicação

4

Na tela seguinte, recomenda-se manter os valores "default":

Na tela abaixo, no combo-box chamado Catalog, selecione o item com o nome “Demoiselle” e no campo Filter

digite “JSF” e em seguida selecione o item “demoiselle-jsf-jpa”:

Modo assistido com Eclipse

5

Cuidado

Se as opções anteriores não aparecem, é porque será necessário incluir o catálogo remoto de

arquétipos Maven do Demoiselle. Caso contrário pule o subitem Incluindo catálogo remoto e siga

as demais instruções.

Cuidado

A versão do arquétipo irá variar conforme surjam novas versões do Demoiselle. A imagem deste

guia apresenta a versão 2.0.0, contudo, fique sempre atento para as novas versões do Demoiselle

em nosso site e sempre utilize a versão do arquétipo mais recente.

2.2.2.1. Incluindo catálogo remoto

Ainda na tela criação do novo projeto, clique no botão Configure à direita do combo-box Catalog, para que

apareça a tela de configuração de arquétipos Maven no Eclipse.

Capítulo 2. Criação da aplicação

6

Clique no botão Add Remote Catalog...:

Na campo Catalog File coloque este conteúdo: http://demoiselle.sourceforge.net/

repository/archetype-catalog.xml. No campo Description informe: “Demoiselle”. Em seguida,

clique no botão Verify... para certificar-se que o conteúdo está correto. Retorne então ao item anterior e siga as

instruções.

Na próxima tela preencha os campos conforme ilustrado a seguir e clique em Finish:

Modo assistido com Eclipse

7

Ao término do processo será criado o projeto bookmark gerenciado pelo Maven e com a seguinte estrutura de

diretórios:

bookmark/

|-- pom.xml

`-- src

|-- main

| |-- java

| | `-- br

| | `-- gov

| | `-- frameworkdemoiselle

| | `-- sample

| | |-- business

| | |-- constant

| | |-- domain

| | |-- exception

| | |-- message

| | |-- persistence

| | |-- util

| | `-- view

| |-- resources

| | |-- demoiselle.properties

| | |-- log4j.properties

| | |-- messages.properties

| | |-- META-INF

| | | |-- beans.xml

| | | `-- persistence.xml

| | `-- ValidationMessages.properties

| `-- webapp

| |-- home.xhtml

| |-- images

| | `-- logo.png

| |-- index.html

| |-- menu.xhtml

| |-- template

Capítulo 2. Criação da aplicação

8

| | `-- main.xhtml

| `-- WEB-INF

| |-- faces-config.xml

| `-- web.xml

`-- test

|-- java

| `-- br

| `-- gov

| `-- frameworkdemoiselle

| `-- sample

`-- resources

2.3. Criando a entidade de domínio

Dentro do pacote br.gov.frameworkdemoiselle.sample.domain crie a classe Bookmark, a qual será

responsável por representar um objeto de bookmark a ser persistido no banco de dados usando JPA:

@Entity

public class Bookmark {

@Id

@GeneratedValue

private Long id;

@Column

private String description;

@Column

private String link;

public Bookmark() {

super();

}

public Bookmark(String description, String link) {

this.description = description;

this.link = link;

}

}

Nota

Lembre-se de criar os respectivos métodos getter e setter para as propriedades dessa classe.

Os dois construtores da classe Bookmark serão utilizados posteriormente na aplicação. As anotações @Entity,

@Id, @GeneratedValue e @Column são fornecidas pela especificação JPA.

Implementando a camada de persistência

9

2.4. Implementando a camada de persistência

Dentro do pacote br.gov.frameworkdemoiselle.sample.persistence crie a classe BookmarkDAO,

a qual será responsável por manipular os dados:

@PersistenceController

public class BookmarkDAO extends JPACrud<Bookmark, Long> {

private static final long serialVersionUID = 1L;

}

Dica

A anotação @PersistenceController trata-se de um estereótipo fornecido pelo Demoiselle

Framework 2.X para indicar que uma classe será tratada como controlador da camada de

persistência na aplicação.

A classe abstrata JPACrud faz parte do código de suporte fornecido pelo Demoiselle Framework 2.X

(especificamente na extensão JPA). Ao utilizá-la, o desenvolvedor não precisará implementar métodos de

manipulação de uma entidade, tais como busca, listagem, inclusão, alteração e exclusão de registros. Dessa forma,

apenas métodos específicos do caso de uso necessitam ser criados manualmente.

Nota

Recomenda-se usar o sufixo “DAO” nessa classe para indicar que se trata de um objeto de acesso

a dados (i.e., um DAO - Data Access Object).

No diretório /src/main/resources/META-INF/, altere o arquivo persistence.xml com o conteúdo

seguinte:

<?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">

<jta-data-source>java:/DefaultDS</jta-data-source>

<class>br.gov.frameworkdemoiselle.sample.domain.Bookmark</class>

<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.factory_class"

value="org.hibernate.transaction.JTATransactionFactory" />

<property name="jta.UserTransaction" value="UserTransaction" />

</properties>

</persistence-unit>

Capítulo 2. Criação da aplicação

10

</persistence>

Este arquivo armazenará as configurações de acesso ao banco de dados via JPA. Neste caso, o gerenciamento

das conexões ficará a cargo do servidor de aplicações (ex: JBoss AS). Será usada a fonte de dados java:/

DefaultDS.

No diretório /src/main/resources/, altere o arquivo demoiselle.properties com o conteúdo seguinte:

frameworkdemoiselle.persistence.unit.name=bookmark-ds

No diretório /src/main/resources/META-INF/, altere o arquivo beans.xml com o conteúdo seguinte:

<?xml version="1.0"?>

<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_1.xsd">

<alternatives>

<class>br.gov.frameworkdemoiselle.transaction.JTATransaction</class>

</alternatives>

</beans>

2.5. Implementando a camada de negócioDentro do pacote br.gov.frameworkdemoiselle.sample.business crie a classe BookmarkBC, a qual

será responsável por gerenciar as regras de negócio referentes aos bookmarks:

@BusinessController

public class BookmarkBC extends DelegateCrud<Bookmark, Long, BookmarkDAO> {

private static final long serialVersionUID = 1L;

@Startup

@Transactional

public void startup() {

if (findAll().isEmpty()) {

insert(new Bookmark("Demoiselle Portal", "http://www.frameworkdemoiselle.gov.br"));

insert(new Bookmark("Demoiselle SourceForge", "http://sf.net/projects/demoiselle"));

insert(new Bookmark("Twitter", "http://twitter.frameworkdemoiselle.gov.br"));

insert(new Bookmark("Blog", "http://blog.frameworkdemoiselle.gov.br"));

insert(new Bookmark("Wiki", "http://wiki.frameworkdemoiselle.gov.br"));

insert(new Bookmark("Bug Tracking", "http://tracker.frameworkdemoiselle.gov.br"));

insert(new Bookmark("Forum", "http://forum.frameworkdemoiselle.gov.br"));

insert(new Bookmark("SVN", "http://svn.frameworkdemoiselle.gov.br"));

insert(new Bookmark("Maven", "http://repository.frameworkdemoiselle.gov.br"));

insert(new Bookmark("Downloads", "http://download.frameworkdemoiselle.gov.br"));

}

}

Implementando a camada de apresentação

11

}

O método startup() nessa classe será invocado automaticamente durante a inicialização da aplicação e fará

com que a tabela seja populada com dados iniciais de bookmarks.

Dica

A anotação @BusinessController trata-se de um estereótipo fornecido pelo Demoiselle

Framework 2.X para indicar que uma classe será tratada como controlador da camada de negócio

na aplicação.

A classe DelegateCrud faz parte do código de suporte fornecido pelo Demoiselle Framework 2.0. Ao utilizá-la,

o desenvolvedor não precisará implementar métodos de negócio triviais de uma entidade e tampouco programar a

injeção de dependência entre as camadas de negócio e persistência. Tal injeção será realizada de forma implícita.

Nota

Recomenda-se usar o sufixo “BC” nessa classe para indicar que se trata de um controlador de

negócio (i.e., um BC - Business Controller).

2.6. Implementando a camada de apresentação

Dentro do pacote br.gov.frameworkdemoiselle.sample.view crie a classe BookmarkListMB, a qual

será responsável por exibir as informações sobre os bookmarks para o usuário:

@ViewController

public class BookmarkListMB extends AbstractListPageBean<Bookmark, Long> {

private static final long serialVersionUID = 1L;

@Inject

private BookmarkBC bc;

@Override

protected List<Bookmark> handleResultList() {

return bc.findAll();

}

}

Dica

A anotação @ViewController trata-se de um estereótipo fornecido pelo Demoiselle

Framework para indicar que uma classe será tratada como controlador da camada de

apresentação (i.e., visão) na aplicação.

Capítulo 2. Criação da aplicação

12

A classe AbstractListPageBean faz parte do código de suporte fornecido pelo Demoiselle Framework

(especificamente na extensão JSF). Ao utilizá-la, o desenvolvedor não precisará implementar métodos específicos

de navegação para uma tela de cadastro (i.e., do tipo CRUD).

A anotação @Inject é fornecida pela especificação CDI. Ela realiza a injeção de dependência da camada de

negócio dentro do artefato da camada de apresentação.

Nota

Recomenda-se usar o sufixo “MB” nessa classe para indicar que se trata de um bean gerenciado

do JSF (i.e., um MB - Managed Bean).

No diretório /src/main/webapp/, crie o arquivo bookmark_list.xhtml com o conteúdo seguinte:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"

xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"

xmlns:ui="http://java.sun.com/jsf/facelets" template="/template/main.xhtml">

<ui:define name="body">

<h:form>

<p:dataTable id="list" var="bean" value="#{bookmarkListMB.resultList}">

<f:facet name="header">#{messages['bookmark.list.table.title']}</f:facet>

<p:column style="width:1%;">

<h:selectBooleanCheckbox value="#{bookmarkListMB.selection[bean.id]}" />

</p:column>

<p:column style="width:5%;" sortBy="#{bean.id}">

<f:facet name="header">#{messages['bookmark.label.id']}</f:facet>

<h:outputText value="#{bean.id}" />

</p:column>

<p:column sortBy="#{bean.description}">

<f:facet name="header">#{messages['bookmark.label.description']}</f:facet>

<h:commandLink action="#{bookmarkListMB.getNextView}"

actionListener="#{bookmarkListMB.clear}">

<h:outputText value="#{bean.description}" />

<f:param name="id" value="#{bean.id}" />

</h:commandLink>

</p:column>

<p:column sortBy="#{bean.link}">

<f:facet name="header">#{messages['bookmark.label.link']}</f:facet>

<h:commandLink action="#{bookmarkListMB.getNextView}"

actionListener="#{bookmarkListMB.clear}">

<h:outputText value="#{bean.link}" />

<f:param name="id" value="#{bean.id}" />

</h:commandLink>

</p:column>

</p:dataTable>

</h:form>

</ui:define>

</ui:composition>

Implementando a camada de apresentação

13

Dica

Nos arquivos XHTML listados neste exemplo foi empregado o framework PrimeFaces [http://

www.primefaces.org/], o qual foi um dos primeiros a oferecer suporte completo à especificação

JSF 2.0.

No diretório /src/main/webapp/, altere o arquivo menu.xhtml com o conteúdo seguinte:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"

xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"

xmlns:ui="http://java.sun.com/jsf/facelets">

<h:form>

<p:menubar>

<p:submenu label="#{messages['menu.bookmark']}">

<p:menuitem value="#{messages['menu.menuitem.list']}"

url="/bookmark_list.jsf" />

</p:submenu>

<p:submenu>

<f:facet name="label">

<p:menuitem value="#{messages['menu.menuitem.quit']}"

url="http://www.frameworkdemoiselle.gov.br/" />

</f:facet>

</p:submenu>

</p:menubar>

</h:form>

</ui:composition>

No diretório /src/main/resources/, altere o arquivo messages.properties incluindo as linhas a seguir:

bookmark.list.table.title=Lista de Links

bookmark.label.id=ID

bookmark.label.link=Link

bookmark.label.description=Descri\u00E7\u00E3o

bookmark.label=Bookmark

bookmark.alt.id=ID

bookmark.alt.link=Link

bookmark.alt.description=Descri\u00E7\u00E3o

menu.bookmark=Bookmarks

Nota

O arquivo de recursos messages.properties armazenará textos no idioma default da

aplicação (neste caso, em Português do Brasil).

Capítulo 2. Criação da aplicação

14

Dica

Ao invés de manter fixas as descrições em rótulos, links, botões e mensagens em uma aplicação,

recomenda-se parametrizar esses textos em arquivos de recursos. Além de ser considerada boa

prática, essa medida facilita uma posterior internacionalização da aplicação para diversos idiomas.

2.7. Executando no servidor

A última etapa consiste na construção da aplicação Java Web e no respectivo deploy em um servidor de aplicações.

Utilizando a IDE Eclipse, basta clicar com o botão direito no projeto bookmark e acessar o menu Run As, Run

on Server. Em seguida, escolha um servidor compatível com Java EE 6 (ex: JBoss AS 6) e aguarde a inicialização

deste.

Na visão Console você verá as mensagens decorrentes do servidor de aplicações e da inicialização da aplicação

bookmark agora hospedada nele.

Dica

Para executar em modo de depuração, na visão Servers, clique com o botão direito no servidor

desejado e selecione a opção Debug.

Nota

Também é possível efetuar esses passos em linha de comando. Para isso, execute o comando

mvn package, copie o arquivo bookmark.war resultante para a pasta de deploy do servidor

Executando no servidor

15

(ex: JBOSS_HOME/server/default/deploy) e inicie este último através de seu comando

próprio (ex: JBOSS_HOME/bin/run.sh).

Em seguida, abra o navegador Web de sua preferência e acesse o endereço http://localhost:8080/bookmark. Esta

é a página que deverá ser exibida com a aplicação bookmark em funcionamento:

Figura 2.1. Página principal da aplicação Bookmark

16

17

Melhorando a aplicação

3.1. Implementando funcionalidade de edição

Agora que a aplicação inicial já está rodando, iremos aumentar sua complexidade adicionando a funcionalidade de

edição dos registros de bookmark.

Dentro do pacote br.gov.frameworkdemoiselle.sample.view crie a classe BookmarkEditMB, a qual

será responsável por controlar as modificações sobre os bookmarks efetuadas pelo usuário:

@ViewController

@PreviousView("/bookmark_list.xhtml")

public class BookmarkEditMB extends AbstractEditPageBean<Bookmark, Long> {

private static final long serialVersionUID = 1L;

@Inject

private BookmarkBC bc;

@Override

@Transactional

public String delete() {

bc.delete(getId());

return getPreviousView();

}

@Override

@Transactional

public String insert() {

bc.insert(getBean());

return getPreviousView();

}

@Override

@Transactional

public String update() {

bc.update(getBean());

return getPreviousView();

}

@Override

protected void handleLoad() {

setBean(bc.load(getId()));

}

}

Capítulo 3. Melhorando a apli...

18

Dica

A anotação @Transactional trata-se de uma anotação fornecida pelo Demoiselle Framework

para indicar que o método em questão será incluído na sessão transacional. Caso essa anotação

esteja vinculada na classe, todos os seus métodos serão considerados transacionais.

A classe AbstractEditPageBean faz parte do código de suporte fornecido pelo Demoiselle Framework

(especificamente na extensão JSF). Ao utilizá-la, o desenvolvedor não precisará implementar métodos específicos

de navegação para uma tela de cadastro (i.e., do tipo CRUD).

Ainda no pacote br.gov.frameworkdemoiselle.sample.view altere a classe BookmarkListMB:

@ViewController

@NextView("/bookmark_edit.xhtml")

@PreviousView("/bookmark_list.xhtml")

public class BookmarkListMB extends AbstractListPageBean<Bookmark, Long> {

private static final long serialVersionUID = 1L;

@Inject

private BookmarkBC bc;

@Override

protected List<Bookmark> handleResultList() {

return bc.findAll();

}

@Transactional

public String deleteSelection() {

boolean delete = false;

Iterator<Long> iter = getSelection().keySet().iterator();

while (iter.hasNext()) {

Long id = iter.next();

delete = getSelection().get(id);

if (delete) {

bc.delete(id);

iter.remove();

}

}

return getPreviousView();

}

}

A anotação @NextView serve para definir a próxima visão a ser direcionado o fluxo de navegação JSF. De

forma semelhante, a anotação @PreviousView define a visão anterior de um fluxo.

O novo método deleteSelection() servirá para permitir a funcionalidade de exclusão de múltiplas linhas

da tabela. A anotação @Transactional nele faz com que o método seja considerado como transacional,

incluindo-o na respectiva sessão.

No diretório /src/main/webapp/, crie o arquivo bookmark_edit.xhtml com o conteúdo seguinte:

Implementando funcionalidade de edição

19

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"

xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"

xmlns:ui="http://java.sun.com/jsf/facelets" template="/template/main.xhtml">

<ui:define name="body">

<h:form prependId="false">

<p:toolbar>

<p:toolbarGroup align="left">

<p:commandButton value="#{messages['button.save']}"

action="#{bookmarkEditMB.insert}"

rendered="#{!bookmarkEditMB.updateMode}" ajax="false" />

<p:commandButton value="#{messages['button.save']}"

action="#{bookmarkEditMB.update}"

rendered="#{bookmarkEditMB.updateMode}" ajax="false" />

<p:commandButton value="#{messages['button.delete']}"

onclick="confirmation.show()" rendered="#{bookmarkEditMB.updateMode}"

type="button" immediate="true" ajax="false" />

<p:confirmDialog message="#{messages['label.confirm.delete']}"

showEffect="bounce" hideEffect="explode"

header="#{messages['label.dialog.delete']}"

severity="alert" widgetVar="confirmation">

<h:commandButton value="#{messages['button.dialog.yes']}"

action="#{bookmarkEditMB.delete}" immediate="true" ajax="false" />

<h:commandButton value="#{messages['button.dialog.no']}"

onclick="confirmation.hide()" type="button" />

</p:confirmDialog>

</p:toolbarGroup>

</p:toolbar>

<br />

<p:fieldset legend="#{messages['bookmark.label']}" toggleable="true"

toggleSpeed="500">

<h:panelGrid id="fields" columns="3">

<h:outputLabel value="#{messages['bookmark.label.id']}: "

for="id" styleClass="text-input" />

<h:outputText id="id" value="#{bookmarkEditMB.bean.id}" />

<p:message for="id" />

<h:outputLabel value="#{messages['bookmark.label.description']}: "

for="description" styleClass="text-input" />

<h:inputText id="description" value="#{bookmarkEditMB.bean.description}"

title="#{messages['bookmark.alt.description']}" />

<p:message for="description" />

<h:outputLabel value="#{messages['bookmark.label.link']}: "

for="link" styleClass="text-input" />

<h:inputText id="link" value="#{bookmarkEditMB.bean.link}"

title="#{messages['bookmark.alt.link']}" />

<p:message for="link" />

</h:panelGrid>

</p:fieldset>

</h:form>

</ui:define>

</ui:composition>

Ainda no diretório /src/main/webapp/, modifique o arquivo bookmark_list.xhtml com o conteúdo

seguinte:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"

Capítulo 3. Melhorando a apli...

20

xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"

xmlns:ui="http://java.sun.com/jsf/facelets" template="/template/main.xhtml">

<ui:define name="body">

<h:form>

<p:toolbar>

<p:toolbarGroup align="left">

<p:commandButton title="#{messages['button.new']}"

image="ui-icon-document" action="#{bookmarkListMB.getNextView}"

actionListener="#{bookmarkListMB.clear}" ajax="false" />

<p:commandButton title="#{messages['button.delete']}"

image="ui-icon-trash" onclick="confirmation.show()" type="button"

immediate="true" ajax="false" />

<p:confirmDialog message="#{messages['label.confirm.delete']}"

showEffect="bounce" hideEffect="explode"

header="#{messages['label.dialog.alert']}!"

severity="alert" widgetVar="confirmation">

<h:commandButton value="#{messages['button.dialog.yes']}"

action="#{bookmarkListMB.deleteSelection}"

actionListener="#{bookmarkListMB.clear}" />

<h:commandButton value="#{messages['button.dialog.no']}"

onclick="confirmation.hide()" type="button" />

</p:confirmDialog>

</p:toolbarGroup>

</p:toolbar>

<p:dataTable id="list" var="bean" value="#{bookmarkListMB.resultList}">

<f:facet name="header">#{messages['bookmark.list.table.title']}</f:facet>

<p:column style="width:1%;">

<h:selectBooleanCheckbox value="#{bookmarkListMB.selection[bean.id]}" />

</p:column>

<p:column style="width:5%;" sortBy="#{bean.id}">

<f:facet name="header">#{messages['bookmark.label.id']}</f:facet>

<h:outputText value="#{bean.id}" />

</p:column>

<p:column sortBy="#{bean.description}">

<f:facet name="header">#{messages['bookmark.label.description']}</f:facet>

<h:commandLink action="#{bookmarkListMB.getNextView}"

actionListener="#{bookmarkListMB.clear}">

<h:outputText value="#{bean.description}" />

<f:param name="id" value="#{bean.id}" />

</h:commandLink>

</p:column>

<p:column sortBy="#{bean.link}">

<f:facet name="header">#{messages['bookmark.label.link']}</f:facet>

<h:commandLink action="#{bookmarkListMB.getNextView}"

actionListener="#{bookmarkListMB.clear}">

<h:outputText value="#{bean.link}" />

<f:param name="id" value="#{bean.id}" />

</h:commandLink>

</p:column>

</p:dataTable>

</h:form>

</ui:define>

</ui:composition>

No diretório /src/main/webapp/, altere o arquivo menu.xhtml conforme o conteúdo seguinte:

Implementando funcionalidade de edição

21

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"

xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html"

xmlns:ui="http://java.sun.com/jsf/facelets">

<h:form>

<p:menubar>

<p:submenu label="#{messages['menu.bookmark']}">

<p:menuitem value="#{messages['menu.menuitem.new']}"

url="/bookmark_edit.jsf" />

<p:menuitem value="#{messages['menu.menuitem.list']}"

url="/bookmark_list.jsf" />

</p:submenu>

<p:submenu>

<f:facet name="label">

<p:menuitem value="#{messages['menu.menuitem.quit']}"

url="http://www.frameworkdemoiselle.gov.br/" />

</f:facet>

</p:submenu>

</p:menubar>

</h:form>

</ui:composition>

Tendo feito todas essas alterações, reconstrua o projeto Java e faça novo deploy no servidor de aplicações.

Ao acessar a aplicação bookmark pelo browser, verá que agora existe uma opção nova no menu principal:

Bookmarks, Novo. Executando-a, será exibida a página a seguir:

Figura 3.1. Edição dos dados na aplicação Bookmark

Capítulo 3. Melhorando a apli...

22

3.2. Exibindo mensagens para o usuário

Uma vez que o objetivo principal da aplicação foi concluído (i.e., listagem e edição de bookmarks), veremos algumas

funcionalidades adicionais fornecidas pelo Demoiselle Framework, iniciando pelo tratamento de mensagens.

Dentro do pacote br.gov.frameworkdemoiselle.sample.message crie a interface InfoMessages, a

qual servirá para armazenar mensagens informativas a serem exibidas ao usuário:

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}");

}

Nota

A unidade básica de manipulação de mensagens no Demoiselle Framework é a interface

Message. Ou seja, basta que esta última seja implementada na aplicação para que o contexto de

mensagens possa manipulá-la. A classe DefaultMessage é oferecida como implementação

padrão dessa interface.

No exemplo em questão, o texto das mensagens será recuperado do arquivo de recursos

messages.properties previamente criado no diretório /src/main/resources/. Para isso, adicione as

seguintes linhas nesse arquivo:

bookmark-delete-ok=Bookmark exclu\u00EDdo\: {0}

bookmark-insert-ok=Bookmark inserido: {0}

bookmark-update-ok=Bookmark atualizado: {0}

Dentro do pacote br.gov.frameworkdemoiselle.sample.business altere a classe BookmarkBC

incluindo os trechos de código indicados a seguir:

@BusinessController

public class BookmarkBC extends DelegateCrud<Bookmark, Long, BookmarkDAO> {

@Inject

private MessageContext messageContext;

...

@Override

public void insert(Bookmark bookmark) {

super.insert(bookmark);

messageContext.add(InfoMessages.BOOKMARK_INSERT_OK,

bookmark.getDescription());

}

Exibindo mensagens para o usuário

23

@Override

public void update(Bookmark bookmark) {

super.update(bookmark);

messageContext.add(InfoMessages.BOOKMARK_UPDATE_OK,

bookmark.getDescription());

}

@Override

public void delete(Long id) {

super.delete(id);

messageContext.add(InfoMessages.BOOKMARK_DELETE_OK, id);

}

}

No ponto contendo @Inject será injetado via CDI o contexto de mensagens presente na aplicação, ou seja,

uma instância da interface MessageContext que poderá ser utilizada em qualquer método nessa classe.

Aqui os métodos insert(), update() e delete() da classe DelegateCrud são sobrescritos para

permitir com que o contexto de mensagens seja manipulado em cada invocação destes. O método add() de

MessageContext faz com que a mensagem passada como parâmetro seja adicionada ao contexto, que ao

final será exibida para o usuário na camada de apresentação.

Nota

O contexto de mensagens, representado pela interface MessageContext, é capaz de

armazenar diversas mensagens em uma mesma requisição. Ele não é restrito à aplicações do

tipo Web, isto é, pode ser usado também para aplicações do tipo desktop (i.e., Swing).

Ao término das modificações propostas até aqui, reconstrua o projeto Java e faça novo deploy no servidor de

aplicações. Acesse a aplicação bookmark e efetue inclusões, modificações e exclusões de bookmarks. As

mensagens informativas devem aparecer em caixas de mensagens na tela, tal como ilustrado a seguir:

Capítulo 3. Melhorando a apli...

24

Figura 3.2. Exibição de mensagens na aplicação Bookmark

3.3. Criando regras de validação nos camposSendo aderente à especificação Java EE 6, o Demoiselle Framework recomenda e faz uso do mecanismo de

validação provido pela especificação JSR-303 (Bean Validation) [http://jcp.org/en/jsr/detail?id=303].

A fim de testarmos mais essa funcionalidade, utilizaremos a implementação de validação Hibernate Validator. Para

tal, abra o arquivo pom.xml do projeto bookmark e inclua nele a seguinte dependência:

<dependencies>

...

<dependency>

<groupId>org.hibernate</groupId>

<artifactId>hibernate-validator</artifactId>

<version>4.1.0.Final</version>

</dependency>

</dependencies>

Nota

O objetivo dessa abordagem de validação é auxiliar na criação de restrições diretamente nas

entidades de domínio. Tais restrições serão utilizadas de forma conjunta nas camadas de

persistência e apresentação da aplicação. A vantagem é que elas são facilmente configuráveis,

Criando regras de validação nos campos

25

bastando apenas incluir certas anotações (ex: @NotNull, @Size) nos campos da classe a ser

validada.

No pacote br.gov.frameworkdemoiselle.sample.domain altere a entidade de domínio Bookmark

incluindo as anotações de validação nos campos description e link conforme ilustrado a seguir:

@Entity

public class Bookmark {

@Id

@GeneratedValue

private Long id;

@Column

@NotNull

@Size(min = 1, max = 20)

private String description;

@Column

@NotNull

@NotBlank

@Size(max = 255)

@URL

private String link;

...

}

No campo description, a anotação @NotNull serve para impedir que o valor nulo seja atribuído a ele.

Já a anotação @Size restringe a quantidade mínima e máxima de caracteres no campo.

No campo link mais restrições são aplicadas. Além de não permitir o valor nulo (com @NotNull) e estipular

o comprimento máximo de 255 caracteres (com @Size), o campo não pode ficar vazio (com @NotBlank) e

seu conteúdo deve ser um endereço de Internet válido (com @URL).

Dica

Validações de campos específicos para a comunidade brasileira são oferecidos pelo componente

Demoiselle Validation. Com ele, as seguintes anotações podem ser aplicadas nas classes de

domínio: @Cep, @Cnpj, @Cpf, @InscricaoEstadual e @PisPasep.

Assim que você efetuar as modificações, reconstrua o projeto Java e faça novo deploy no servidor de aplicações.

Acesse a aplicação bookmark e, na tela de edição de bookmarks, deixe vazios os campos no formulário e clique

em Salvar. Tente também preencher um endereço de Internet inválido no campo Link. Caixas de erro com as

mensagens referentes as validações devem aparecer ao lado de cada campo, tal como ilustrado:

Capítulo 3. Melhorando a apli...

26

Figura 3.3. Validação de campos na aplicação Bookmark

Dica

As mensagens exibidas na tela durante a validação estão contidas no arquivo de recursos

ValidationMessages.properties presente no diretório /src/main/resources/.