Commit ef1222f9d5c4a2b344d5b53490531c0668780566
1 parent
047ee503
Exists in
master
FWK-221: Remoção das documentações reference e quickstart
Task-Url: https://demoiselle.atlassian.net/browse/FWK-221
Showing
48 changed files
with
0 additions
and
5612 deletions
Show diff stats
documentation/quickstart/.gitignore
documentation/quickstart/pt-BR/authorgroup.xml
... | ... | @@ -1,29 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | - <authorgroup> | |
5 | - <author> | |
6 | - <firstname>Emerson</firstname> | |
7 | - <surname>Oliveira</surname> | |
8 | - </author> | |
9 | - <author> | |
10 | - <firstname>Emerson</firstname> | |
11 | - <surname>Saito</surname> | |
12 | - </author> | |
13 | - <author> | |
14 | - <firstname>Luciano</firstname> | |
15 | - <surname>Borges</surname> | |
16 | - </author> | |
17 | - <author> | |
18 | - <firstname>Marlon</firstname> | |
19 | - <surname>Carvalho</surname> | |
20 | - </author> | |
21 | - <author> | |
22 | - <firstname>Rodrigo</firstname> | |
23 | - <surname>Hjort</surname> | |
24 | - </author> | |
25 | - <author> | |
26 | - <firstname>Serge</firstname> | |
27 | - <surname>Rehem</surname> | |
28 | - </author> | |
29 | - </authorgroup> | |
30 | 0 | \ No newline at end of file |
documentation/quickstart/pt-BR/avancado.xml
... | ... | @@ -1,117 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="avancado"> | |
5 | - <title>Utilizando opções avançadas</title> | |
6 | - <section> | |
7 | - <title>Implementando paginação dos dados</title> | |
8 | - <para>... introduzir mecanismo e <emphasis>lazy | |
9 | - loading</emphasis></para> | |
10 | - <note> | |
11 | - <para>explicar interface <literal>Pagination</literal> (unidade | |
12 | - básica de paginação) e contexto de paginação <literal> | |
13 | - PaginationContext</literal>, disponível através de injeção</para> | |
14 | - </note> | |
15 | - <note> | |
16 | - <para>o exemplo em questão é específico para o PrimeFaces se for | |
17 | - utilizar outra implementação, tal como RichFaces, ... código será | |
18 | - semelhante</para> | |
19 | - </note> | |
20 | - <para>No pacote <literal> | |
21 | - br.gov.frameworkdemoiselle.sample.view</literal> altere a classe | |
22 | - <literal>BookmarkListMB</literal> incluindo nela as linhas de | |
23 | - código a seguir:</para> | |
24 | - <programlisting role="JAVA"> private DataModel<Bookmark> dataModel; | |
25 | - | |
26 | - @Override | |
27 | - @SuppressWarnings("unchecked") | |
28 | - public DataModel<Bookmark> getDataModel() { | |
29 | - if (dataModel == null) { | |
30 | - dataModel = new LazyDataModelImpl(); | |
31 | - } | |
32 | - return dataModel; | |
33 | - } | |
34 | - | |
35 | - private class LazyDataModelImpl extends LazyDataModel<Bookmark> { | |
36 | - | |
37 | - private static final long serialVersionUID = 1L; | |
38 | - | |
39 | - private boolean loaded = false; | |
40 | - | |
41 | - @Override | |
42 | - public int getRowCount() { | |
43 | - if (!loaded) { | |
44 | - getPagination(); | |
45 | - handleResultList(); | |
46 | - loaded = true; | |
47 | - } | |
48 | - return getPagination().getTotalResults(); | |
49 | - } | |
50 | - | |
51 | - @Override | |
52 | - public List<Bookmark> load(int first, int pageSize, String sortField, | |
53 | - boolean sortOrder, Map<String, String> filters) { | |
54 | - | |
55 | - Pagination pagination = getPagination(); | |
56 | - pagination.setPageSize(pageSize); | |
57 | - pagination.setFirstResult(first); | |
58 | - | |
59 | - return handleResultList(); | |
60 | - } | |
61 | - | |
62 | - }</programlisting> | |
63 | - <para>A interface <literal>DataModel</literal> pertence à | |
64 | - especificação JSF, enquanto que a classe abstrata <literal> | |
65 | - LazyDataModel</literal> é uma implementação da primeira fornecida | |
66 | - pelo framework <emphasis>PrimeFaces</emphasis>.</para> | |
67 | - <para>No diretório <filename>/src/main/webapp/</filename>, altere o | |
68 | - arquivo <filename>bookmark_list.xhtml</filename> substituindo | |
69 | - apenas a tag <literal>p:dataTable</literal> com o conteúdo | |
70 | - seguinte:</para> | |
71 | - <programlisting role="XML"><p:dataTable id="list" height="300" var="bean" value="#{bookmarkListMB.dataModel}" | |
72 | - lazy="true" paginator="true" rows="#{bookmarkListMB.pageSize}" | |
73 | - pageLinks="#{bookmarkListMB.maxPageLinks}"></programlisting> | |
74 | - <para>...</para> | |
75 | - <para>No diretório <filename>/src/main/resources/</filename>, | |
76 | - altere o arquivo <filename>demoiselle.properties</filename> | |
77 | - incluindo as linhas a seguir:</para> | |
78 | - <programlisting>frameworkdemoiselle.pagination.default.page.size = 5 | |
79 | -frameworkdemoiselle.pagination.max.page.links = 3</programlisting> | |
80 | - <para>...</para> | |
81 | - <figure> | |
82 | - <title>Paginação de dados na aplicação Bookmark</title> | |
83 | - <mediaobject><imageobject role="fo"><imagedata align="center" | |
84 | - fileref="images/apppage.png" scalefit="1"/></imageobject> | |
85 | - <imageobject role="html"><imagedata align="center" | |
86 | - fileref="images/apppage.png"/></imageobject><textobject><phrase>Aplicação | |
87 | - Bookmark em funcionamento</phrase></textobject></mediaobject> | |
88 | - </figure> | |
89 | - <para>...</para> | |
90 | - <programlisting>INFO [STDOUT] Hibernate: select top ? count(bookmark0_.id) as col_0_0_ from Bookmark bookmark0_ | |
91 | -INFO [STDOUT] Hibernate: select top ? bookmark0_.id as id4_, bookmark0_.description as descript2_4_, bookmark0_.link as link4_ from Bookmark bookmark0_ | |
92 | -INFO [STDOUT] Hibernate: select limit ? ? bookmark0_.id as id4_, bookmark0_.description as descript2_4_, bookmark0_.link as link4_ from Bookmark bookmark0_</programlisting> | |
93 | - <tip> | |
94 | - <para>// todo: explicar superficialmente como implementar no | |
95 | - RF...</para> | |
96 | - <programlisting role="JAVA"> | |
97 | -import org.richfaces.component.UIDatascroller; | |
98 | -import org.richfaces.event.DataScrollerEvent; | |
99 | - | |
100 | - // evento específico do RichFaces | |
101 | - public void updatePage(DataScrollerEvent e) { | |
102 | - int index = ((UIDatascroller) e.getComponent()).getPage(); | |
103 | - Page pagina = new Page(getRows(), index); | |
104 | - recarregarLista(pagina); | |
105 | - } | |
106 | - </programlisting> | |
107 | - <programlisting role="XML"> | |
108 | - <rich:datascroller for="table" | |
109 | - maxPages="#{bookmarkListMB.maxPages}" page="#{bookmarkListMB.currentPage}" | |
110 | - reRender="table" scrollerListener="#{bookmarkListMB.updatePage}" /> | |
111 | - <rich:dataTable width="100%" value="#{bookmarkListMB.lazyModel}" | |
112 | - rows="#{bookmarkListMB.pageSize}" | |
113 | - var="element" rowKeyVar="row" id="table"> | |
114 | - </programlisting> | |
115 | - </tip> | |
116 | - </section> | |
117 | -</chapter> | |
118 | 0 | \ No newline at end of file |
documentation/quickstart/pt-BR/bookinfo.xml
... | ... | @@ -1,8 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<bookinfo> | |
5 | - <title>Framework Demoiselle</title> | |
6 | - <subtitle>QuickStart</subtitle> | |
7 | - <xi:include href="authorgroup.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
8 | -</bookinfo> |
documentation/quickstart/pt-BR/criacao.xml
... | ... | @@ -1,600 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | - | |
5 | -<chapter id="criacao"> | |
6 | - <title>Criação da aplicação</title> | |
7 | - <section> | |
8 | - <title>Nossa primeira aplicação</title> | |
9 | - <para> | |
10 | - Para iniciar o uso do <emphasis>Demoiselle Framework</emphasis>, criaremos uma aplicação | |
11 | - Java do tipo Web utilizando o <ulink url="http://maven.apache.org/"><citetitle>Apache Maven</citetitle></ulink>, | |
12 | - através do plugin para IDE Eclipse (M2Eclipse) para gerenciar todo o clico de vida do Projeto, | |
13 | - desde a criação até o <emphasis>deploy</emphasis>. | |
14 | - </para> | |
15 | - <para> | |
16 | - Essa aplicação consistirá em um cadastro simples de bookmarks (links <quote>Favoritos</quote>) e | |
17 | - será gerada com o auxílio de um arquétipo do Maven disponibilizado pelo projeto Demoiselle. | |
18 | - Ela será preparada para utilizar as tecnologias de persistência JPA e de apresentação JSF nas | |
19 | - versões mais recentes conforme a especificação Java EE 6. | |
20 | - </para> | |
21 | - </section> | |
22 | - | |
23 | - <section> | |
24 | - <title>Construindo o projeto usando um arquétipo Maven</title> | |
25 | - <para> | |
26 | - Para criar esse projeto utilizando a IDE Eclipse, acesse o menu <guimenu>File</guimenu>, | |
27 | - <guimenu>New</guimenu>, <guimenu>Other...</guimenu> digite e selecione <guimenu>Maven Project</guimenu>: | |
28 | - conforme mostrado na figura abaixo: | |
29 | - <mediaobject> | |
30 | - <imageobject role="fo"> | |
31 | - <imagedata fileref="images/newwiz.png" align="center" scalefit="1" width="75%"/> | |
32 | - </imageobject> | |
33 | - <imageobject role="html"> | |
34 | - <imagedata fileref="images/newwiz.png" align="center"/> | |
35 | - </imageobject> | |
36 | - </mediaobject> | |
37 | - </para> | |
38 | - <para> | |
39 | - Na tela seguinte, recomenda-se manter os valores padrões: | |
40 | - <mediaobject> | |
41 | - <imageobject role="fo"> | |
42 | - <imagedata fileref="images/new-maven-project01.png" align="center" scalefit="1" width="75%"/> | |
43 | - </imageobject> | |
44 | - <imageobject role="html"> | |
45 | - <imagedata fileref="images/new-maven-project01.png" align="center"/> | |
46 | - </imageobject> | |
47 | - </mediaobject> | |
48 | - </para> | |
49 | - <para> | |
50 | - Na tela abaixo, no combo-box chamado <literal>Catalog</literal>, selecione o item com o nome <quote>Demoiselle</quote> e | |
51 | - no campo <literal>Filter</literal> digite <quote>JSF</quote> e em seguida selecione o item <quote>demoiselle-jsf-jpa</quote>: | |
52 | - <mediaobject> | |
53 | - <imageobject role="fo"> | |
54 | - <imagedata fileref="images/new-maven-project02.png" align="center" scalefit="1" width="75%"/> | |
55 | - </imageobject> | |
56 | - <imageobject role="html"> | |
57 | - <imagedata fileref="images/new-maven-project02.png" align="center"/> | |
58 | - </imageobject> | |
59 | - </mediaobject> | |
60 | - </para> | |
61 | - <caution> | |
62 | - <para> | |
63 | - Se as opções anteriores não aparecem, é porque será necessário incluir o catálogo remoto de arquétipos Maven do Demoiselle. | |
64 | - Caso contrário pule o subitem <emphasis>Incluindo catálogo remoto</emphasis> e siga as demais instruções. | |
65 | - </para> | |
66 | - </caution> | |
67 | - <caution> | |
68 | - <para> | |
69 | - A versão do arquétipo irá variar conforme surjam novas versões do Demoiselle. A imagem deste guia apresenta a versão &version;, contudo, | |
70 | - fique sempre atento para as novas versões do Demoiselle em nosso site e sempre utilize a versão do arquétipo mais recente. | |
71 | - </para> | |
72 | - </caution> | |
73 | - <section> | |
74 | - <title>Incluindo catálogo remoto</title> | |
75 | - <para> | |
76 | - Ainda na tela criação do novo projeto, clique no botão <guibutton>Configure</guibutton> à direita do combo-box | |
77 | - <literal>Catalog</literal>, para que apareça a tela de configuração de arquétipos Maven no Eclipse. | |
78 | - </para> | |
79 | - <mediaobject> | |
80 | - <imageobject role="fo"> | |
81 | - <imagedata fileref="images/addRemoteArchetypeCatalog01.png" align="center" scalefit="1" width="75%"/> | |
82 | - </imageobject> | |
83 | - <imageobject role="html"> | |
84 | - <imagedata fileref="images/addRemoteArchetypeCatalog01.png" align="center"/> | |
85 | - </imageobject> | |
86 | - </mediaobject> | |
87 | - <para> | |
88 | - Clique no botão <guibutton>Add Remote Catalog...</guibutton>: | |
89 | - </para> | |
90 | - <mediaobject> | |
91 | - <imageobject role="fo"> | |
92 | - <imagedata fileref="images/addRemoteArchetypeCatalog02.png" align="center" scalefit="1" width="75%"/> | |
93 | - </imageobject> | |
94 | - <imageobject role="html"> | |
95 | - <imagedata fileref="images/addRemoteArchetypeCatalog02.png" align="center"/> | |
96 | - </imageobject> | |
97 | - </mediaobject> | |
98 | - <para> | |
99 | - Na campo <literal>Catalog File</literal> coloque este conteúdo: | |
100 | - <literal>https://oss.sonatype.org/content/repositories/releases</literal>. | |
101 | - No campo <literal>Description</literal> informe: <quote>Nexus</quote>. Em seguida, clique no botão | |
102 | - <guibutton>Verify...</guibutton> para certificar-se que o conteúdo está correto. | |
103 | - Retorne então ao item anterior e siga as instruções. | |
104 | - </para> | |
105 | - </section> | |
106 | - <para> | |
107 | - Na próxima tela preencha os campos conforme ilustrado a seguir e clique em <guibutton>Finish</guibutton>: | |
108 | - </para> | |
109 | - <mediaobject> | |
110 | - <imageobject role="fo"> | |
111 | - <imagedata fileref="images/newproj.png" align="center" scalefit="1" width="75%"/> | |
112 | - </imageobject> | |
113 | - <imageobject role="html"> | |
114 | - <imagedata fileref="images/newproj.png" align="center"/> | |
115 | - </imageobject> | |
116 | - </mediaobject> | |
117 | - </section> | |
118 | - <para> | |
119 | - Ao término do processo será criado o projeto <literal>bookmark</literal> gerenciado pelo Maven e com a seguinte estrutura de diretórios: | |
120 | - </para> | |
121 | - <programlisting> | |
122 | -<![CDATA[bookmark/ | |
123 | -|-- pom.xml | |
124 | -|-- src | |
125 | -| |-- main | |
126 | -| | |-- java | |
127 | -| | | |-- br | |
128 | -| | | |-- gov | |
129 | -| | | |-- frameworkdemoiselle | |
130 | -| | | |-- sample | |
131 | -| | | |-- bookmark | |
132 | -| | | |-- business | |
133 | -| | | | |-- BookmarkBC.java | |
134 | -| | | |-- constant | |
135 | -| | | | |-- readme.txt | |
136 | -| | | |-- domain | |
137 | -| | | | |-- Bookmark.java | |
138 | -| | | |-- exception | |
139 | -| | | | |-- readme.txt | |
140 | -| | | |-- message | |
141 | -| | | | |-- readme.txt | |
142 | -| | | |-- persistence | |
143 | -| | | | |-- BookmarkDAO.java | |
144 | -| | | |-- util | |
145 | -| | | | |-- readme.txt | |
146 | -| | | |-- view | |
147 | -| | | |-- BookmarkEditMB.java | |
148 | -| | | |-- BookmarkListMB.java | |
149 | -| | |-- resources | |
150 | -| | | |-- demoiselle.properties | |
151 | -| | | |-- log4j.properties | |
152 | -| | | |-- messages.properties | |
153 | -| | | |-- META-INF | |
154 | -| | | | |-- beans.xml | |
155 | -| | | | |-- persistence.xml | |
156 | -| | | |-- ValidationMessages.properties | |
157 | -| | |-- webapp | |
158 | -| | |-- bookmark_edit.xhtml | |
159 | -| | |-- bookmark_list.xhtml | |
160 | -| | |-- images | |
161 | -| | | |-- logo.png | |
162 | -| | |-- index.html | |
163 | -| | |-- index.xhtml | |
164 | -| | |-- menu.xhtml | |
165 | -| | |-- template | |
166 | -| | | |-- main.xhtml | |
167 | -| | |-- WEB-INF | |
168 | -| | |-- beans.xml | |
169 | -| | |-- faces-config.xml | |
170 | -| | |-- lib | |
171 | -| | |-- web.xml | |
172 | -| |-- test | |
173 | -| |-- java | |
174 | -| | |-- br | |
175 | -| | |-- gov | |
176 | -| | |-- frameworkdemoiselle | |
177 | -| | |-- sample | |
178 | -| | |-- bookmark | |
179 | -| | |-- business | |
180 | -| | |-- BookmarkBCTest.java | |
181 | -| |-- resources | |
182 | -| |-- demoiselle.properties | |
183 | -| |-- META-INF | |
184 | -| |-- beans.xml | |
185 | -| |-- persistence.xml]]> | |
186 | - </programlisting> | |
187 | - <section> | |
188 | - <title>Entidade de domínio</title> | |
189 | - <para> | |
190 | - Dentro do pacote <literal>br.gov.frameworkdemoiselle.sample.bookmark.domain</literal> foi criada a classe | |
191 | - <literal>Bookmark</literal>, a qual será responsável por representar um objeto de bookmark | |
192 | - a ser persistido no banco de dados usando JPA: | |
193 | - </para> | |
194 | - <programlisting role="JAVA"> | |
195 | -<![CDATA[@Entity | |
196 | -public class Bookmark implements Serializable { | |
197 | - | |
198 | - private static final long serialVersionUID = 1L; | |
199 | - | |
200 | - /* If you are using Glassfish then remove the strategy attribute */ | |
201 | - @Id | |
202 | - @GeneratedValue(strategy = SEQUENCE) | |
203 | - private Long id; | |
204 | - | |
205 | - @Column | |
206 | - private String description; | |
207 | - | |
208 | - @Column | |
209 | - private String link; | |
210 | - | |
211 | - public Bookmark() { | |
212 | - super(); | |
213 | - } | |
214 | - | |
215 | - public Bookmark(String description, String link) { | |
216 | - this.description = description; | |
217 | - this.link = link; | |
218 | - } | |
219 | - | |
220 | - public Long getId() { | |
221 | - return id; | |
222 | - } | |
223 | - | |
224 | - public void setId(Long id) { | |
225 | - this.id = id; | |
226 | - } | |
227 | - | |
228 | - public String getDescription() { | |
229 | - return description; | |
230 | - } | |
231 | - | |
232 | - public void setDescription(String description) { | |
233 | - this.description = description; | |
234 | - } | |
235 | - | |
236 | - public String getLink() { | |
237 | - return link; | |
238 | - } | |
239 | - | |
240 | - public void setLink(String link) { | |
241 | - this.link = link; | |
242 | - } | |
243 | -}]]> | |
244 | - </programlisting> | |
245 | - <para> | |
246 | - Os dois construtores da classe <literal>Bookmark</literal> serão utilizados posteriormente na aplicação. | |
247 | - As anotações <literal>@Entity</literal>, <literal>@Id</literal>, <literal>@GeneratedValue</literal> e | |
248 | - <literal>@Column</literal> são fornecidas pela especificação JPA. | |
249 | - </para> | |
250 | - </section> | |
251 | - | |
252 | - <section> | |
253 | - <title>Camada de persistência</title> | |
254 | - <para> | |
255 | - Dentro do pacote <literal>br.gov.frameworkdemoiselle.sample.bookmark.persistence</literal> foi criada a classe | |
256 | - <literal>BookmarkDAO</literal>, a qual será responsável por manipular os dados: | |
257 | - </para> | |
258 | - <programlisting role="JAVA"> | |
259 | -<![CDATA[@PersistenceController | |
260 | -public class BookmarkDAO extends JPACrud<Bookmark, Long> { | |
261 | - | |
262 | - private static final long serialVersionUID = 1L; | |
263 | - | |
264 | -}]]> | |
265 | - </programlisting> | |
266 | - <note> | |
267 | - <para> | |
268 | - A anotação <literal>@PersistenceController</literal> trata-se de um estereótipo fornecido | |
269 | - pelo <emphasis>Demoiselle Framework</emphasis> para indicar que uma classe será tratada | |
270 | - como controlador da camada de persistência na aplicação. | |
271 | - </para> | |
272 | - </note> | |
273 | - <para> | |
274 | - A classe abstrata <literal>JPACrud</literal> faz parte do código de suporte fornecido pelo | |
275 | - <emphasis>Demoiselle Framework</emphasis> (especificamente na extensão JPA). Ao utilizá-la, | |
276 | - o desenvolvedor não precisará implementar métodos de manipulação de uma entidade, tais como busca, | |
277 | - listagem, inclusão, alteração e exclusão de registros. Dessa forma, apenas métodos específicos do | |
278 | - caso de uso necessitam ser criados manualmente. | |
279 | - </para> | |
280 | - <tip> | |
281 | - <para> | |
282 | - Recomenda-se usar o sufixo <quote>DAO</quote> nessa classe para indicar que se trata de | |
283 | - um objeto de acesso a dados (i.e., um <emphasis>DAO - Data Access Object</emphasis>). | |
284 | - </para> | |
285 | - </tip> | |
286 | - <para> | |
287 | - No diretório <filename>/src/main/resources/META-INF/</filename> foi criado o arquivo <filename>persistence.xml</filename> | |
288 | - utilizado para armazenar as configurações de acesso ao banco de dados via JPA (conexões controladas por um <literal>JPA Provider</literal>, ex: Hibernate) | |
289 | - ou JTA (conexões controladas pelo <literal>Application Server</literal>, ex: JBossAS) e, como pode ser observado, o <emphasis>Demoiselle Framework</emphasis> | |
290 | - já traz neste arquivo vários exemplos de configurações para os mais distintos <literal>Application Servers</literal>, como: | |
291 | - JBoss AS7, JBoss AS6, GlassFish 3, Tomcat 6 e Tomcat7. | |
292 | - </para> | |
293 | - <para> | |
294 | - O projeto criado pelo arquétipo <quote>demoiselle-jsf-jpa</quote> já vem configurado para usar conexão JPA com o HSQLDB, conforme código abaixo: | |
295 | - </para> | |
296 | - <programlisting role="XML"> | |
297 | -<![CDATA[<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" | |
298 | -xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
299 | -xsi:schemaLocation="http://java.sun.com/xml/ns/persistence | |
300 | -http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> | |
301 | - | |
302 | - <persistence-unit name="bookmark-ds" transaction-type="RESOURCE_LOCAL"> | |
303 | - | |
304 | - <non-jta-data-source>java:jboss/datasources/ExampleDS</non-jta-data-source> | |
305 | - | |
306 | - <class>br.gov.frameworkdemoiselle.sample.bookmark.domain.Bookmark</class> | |
307 | - | |
308 | - <properties> | |
309 | - <property name="hibernate.show_sql" value="true" /> | |
310 | - <property name="hibernate.format_sql" value="false" /> | |
311 | - <property name="hibernate.hbm2ddl.auto" value="create-drop" /> | |
312 | - </properties> | |
313 | - | |
314 | - </persistence-unit> | |
315 | - | |
316 | -</persistence>]]> | |
317 | - </programlisting> | |
318 | - </section> | |
319 | - | |
320 | - <section> | |
321 | - <title>Camada de negócio</title> | |
322 | - <para> | |
323 | - Dentro do pacote <literal>br.gov.frameworkdemoiselle.sample.bookmark.business</literal> foi criada a classe | |
324 | - <literal>BookmarkBC</literal>, a qual será responsável por gerenciar as regras de negócio referentes aos bookmarks: | |
325 | - </para> | |
326 | - <programlisting role="JAVA"> | |
327 | -<![CDATA[@BusinessController | |
328 | -public class BookmarkBC extends DelegateCrud<Bookmark, Long, BookmarkDAO> { | |
329 | - | |
330 | - private static final long serialVersionUID = 1L; | |
331 | - | |
332 | - @Startup | |
333 | - @Transactional | |
334 | - public void load() { | |
335 | - if (findAll().isEmpty()) { | |
336 | - insert(new Bookmark("Demoiselle Portal", "http://www.frameworkdemoiselle.gov.br")); | |
337 | - insert(new Bookmark("Demoiselle SourceForge", "http://sf.net/projects/demoiselle")); | |
338 | - insert(new Bookmark("Twitter", "http://twitter.frameworkdemoiselle.gov.br")); | |
339 | - insert(new Bookmark("Blog", "http://blog.frameworkdemoiselle.gov.br")); | |
340 | - insert(new Bookmark("Wiki", "http://wiki.frameworkdemoiselle.gov.br")); | |
341 | - insert(new Bookmark("Bug Tracking", "http://tracker.frameworkdemoiselle.gov.br")); | |
342 | - insert(new Bookmark("Forum", "http://forum.frameworkdemoiselle.gov.br")); | |
343 | - insert(new Bookmark("Github", "https://github.com/demoiselle")); | |
344 | - insert(new Bookmark("SVN", "http://svn.frameworkdemoiselle.gov.br")); | |
345 | - insert(new Bookmark("Maven", "http://repository.frameworkdemoiselle.gov.br")); | |
346 | - insert(new Bookmark("Downloads", "http://download.frameworkdemoiselle.gov.br")); | |
347 | - } | |
348 | - } | |
349 | -}]]> | |
350 | - </programlisting> | |
351 | - <para> | |
352 | - O método com a anotação <literal>@startup</literal> nessa classe será invocado automaticamente durante a | |
353 | - inicialização da aplicação e fará com que a tabela seja populada com dados iniciais de bookmarks. | |
354 | - </para> | |
355 | - <note> | |
356 | - <para> | |
357 | - A anotação <literal>@BusinessController</literal> trata-se de um estereótipo fornecido | |
358 | - pelo <emphasis>Demoiselle Framework</emphasis> para indicar que uma classe será tratada | |
359 | - como controlador da camada de negócio na aplicação. | |
360 | - </para> | |
361 | - </note> | |
362 | - <para> | |
363 | - A classe <literal>DelegateCrud</literal> faz parte do código de suporte fornecido pelo | |
364 | - <emphasis>Demoiselle Framework</emphasis>. Ao utilizá-la, o desenvolvedor não precisará | |
365 | - implementar métodos de negócio triviais de uma entidade e tampouco programar a injeção de dependência | |
366 | - entre as camadas de negócio e persistência. Tal injeção será realizada de forma implícita. | |
367 | - </para> | |
368 | - <tip> | |
369 | - <para> | |
370 | - Recomenda-se usar o sufixo <quote>BC</quote> nessa classe para indicar que se trata de | |
371 | - um controlador de negócio (i.e., um <emphasis>BC - Business Controller</emphasis>). | |
372 | - </para> | |
373 | - </tip> | |
374 | - </section> | |
375 | - | |
376 | - <section> | |
377 | - <title>Camada de apresentação</title> | |
378 | - <para> | |
379 | - Dentro do pacote <literal>package br.gov.frameworkdemoiselle.sample.bookmark.view</literal> foram criadas as | |
380 | - classes <literal>BookmarkEditMB</literal> e <literal>BookmarkListMB</literal>, onde a primeira é responsável | |
381 | - por controlar as modificações sobre os bookmarks efetuadas pelo usuário e a segunda é responsável por | |
382 | - exibir as informações sobre os bookmarks. | |
383 | - </para> | |
384 | - | |
385 | - <programlisting role="JAVA"> | |
386 | -<![CDATA[@ViewController | |
387 | -@PreviousView("/bookmark_list.xhtml") | |
388 | -public class BookmarkEditMB extends AbstractEditPageBean<Bookmark, Long> { | |
389 | - | |
390 | - private static final long serialVersionUID = 1L; | |
391 | - | |
392 | - @Inject | |
393 | - private BookmarkBC bookmarkBC; | |
394 | - | |
395 | - @Override | |
396 | - @Transactional | |
397 | - public String delete() { | |
398 | - this.bookmarkBC.delete(getId()); | |
399 | - return getPreviousView(); | |
400 | - } | |
401 | - | |
402 | - @Override | |
403 | - @Transactional | |
404 | - public String insert() { | |
405 | - this.bookmarkBC.insert(getBean()); | |
406 | - return getPreviousView(); | |
407 | - } | |
408 | - | |
409 | - @Override | |
410 | - @Transactional | |
411 | - public String update() { | |
412 | - this.bookmarkBC.update(getBean()); | |
413 | - return getPreviousView(); | |
414 | - } | |
415 | - | |
416 | - @Override | |
417 | - protected Bookmark handleLoad(Long id) { | |
418 | - return this.bookmarkBC.load(id); | |
419 | - } | |
420 | -}]]> | |
421 | - </programlisting> | |
422 | - <programlisting role="JAVA"> | |
423 | -<![CDATA[@ViewController | |
424 | -@NextView("/bookmark_edit.xhtml") | |
425 | -@PreviousView("/bookmark_list.xhtml") | |
426 | -public class BookmarkListMB extends AbstractListPageBean<Bookmark, Long> { | |
427 | - | |
428 | - private static final long serialVersionUID = 1L; | |
429 | - | |
430 | - @Inject | |
431 | - private BookmarkBC bc; | |
432 | - | |
433 | - @Override | |
434 | - protected List<Bookmark> handleResultList() { | |
435 | - return this.bc.findAll(); | |
436 | - } | |
437 | - | |
438 | - @Transactional | |
439 | - public String deleteSelection() { | |
440 | - boolean delete; | |
441 | - for (Iterator<Long> iter = getSelection().keySet().iterator(); iter.hasNext();) { | |
442 | - Long id = iter.next(); | |
443 | - delete = getSelection().get(id); | |
444 | - | |
445 | - if (delete) { | |
446 | - bc.delete(id); | |
447 | - iter.remove(); | |
448 | - } | |
449 | - } | |
450 | - return getPreviousView(); | |
451 | - } | |
452 | -}]]> | |
453 | - </programlisting> | |
454 | - | |
455 | - <para> | |
456 | - A anotação <literal>@ViewController</literal> trata-se de um estereótipo fornecido | |
457 | - pelo <emphasis>Demoiselle Framework</emphasis> para indicar que uma classe será tratada | |
458 | - como controlador da camada de apresentação (i.e., visão) na aplicação. | |
459 | - </para> | |
460 | - <para> | |
461 | - A anotação <literal>@NextView</literal> serve para definir a próxima | |
462 | - visão a ser direcionado o fluxo de navegação JSF. De forma semelhante, | |
463 | - a anotação <literal>@PreviousView</literal> define a visão anterior | |
464 | - de um fluxo. | |
465 | - </para> | |
466 | - <para> | |
467 | - A anotação <literal>@Inject</literal> é fornecida pela especificação CDI. Ela realiza a injeção | |
468 | - de dependência da camada de negócio dentro do artefato da camada de apresentação. | |
469 | - </para> | |
470 | - <para> | |
471 | - A anotação <literal>@Transactional</literal> trata-se de uma anotação fornecida pelo | |
472 | - <emphasis>Demoiselle Framework</emphasis> para indicar que o método em questão | |
473 | - será incluído na sessão transacional. Caso essa anotação esteja vinculada na classe, | |
474 | - todos os seus métodos serão considerados transacionais. | |
475 | - </para> | |
476 | - <para> | |
477 | - As classes <literal>AbstractEditPageBean</literal> e <literal>AbstractListPageBean</literal> fazem parte | |
478 | - do código de suporte fornecido pelo <emphasis>Demoiselle Framework</emphasis> (especificamente na extensão JSF). | |
479 | - Ao utilizá-las, o desenvolvedor não precisará implementar métodos específicos de navegação para uma tela de | |
480 | - cadastro (i.e., do tipo <emphasis>CRUD</emphasis>). | |
481 | - </para> | |
482 | - <tip> | |
483 | - <para> | |
484 | - Recomenda-se usar o sufixo <quote>MB</quote> nessa classe para indicar que se trata de | |
485 | - um bean gerenciado do JSF (i.e., um <emphasis>MB - Managed Bean</emphasis>). | |
486 | - </para> | |
487 | - </tip> | |
488 | - <para> | |
489 | - No diretório <filename>/src/main/webapp/</filename> foram criados os arquivos: | |
490 | - <itemizedlist> | |
491 | - <listitem><emphasis>bookmark_edit.xhtml</emphasis> - página JSF de cadastro e edição de bookmark;</listitem> | |
492 | - <listitem><emphasis>bookmark_list.xhtml</emphasis> - página JSF de cadastro e edição de bookmark;</listitem> | |
493 | - <listitem><emphasis>index.html</emphasis> - página HTML que redireciona para a página jsf;</listitem> | |
494 | - <listitem><emphasis>index.xhtml</emphasis> - página JSF inicial do sistema;</listitem> | |
495 | - <listitem><emphasis>menu.xhtml</emphasis> - página JSF que monta o menu de navegação.</listitem> | |
496 | - </itemizedlist> | |
497 | - </para> | |
498 | - <para> | |
499 | - No diretório <filename>/src/main/webapp/template</filename> foi criado o arquivo: | |
500 | - <itemizedlist> | |
501 | - <listitem><emphasis>main.xhtml</emphasis> - página JSF que serve de template referenciada na demais páginas JSF.</listitem> | |
502 | - </itemizedlist> | |
503 | - </para> | |
504 | - <note> | |
505 | - <para> | |
506 | - Nos arquivos XHTML listados neste exemplo foi empregado o framework | |
507 | - <ulink url="http://www.primefaces.org/">PrimeFaces</ulink>, o qual foi um dos primeiros a | |
508 | - oferecer suporte completo à especificação JSF 2.0. | |
509 | - </para> | |
510 | - </note> | |
511 | - <para> | |
512 | - No diretório <filename>/src/main/resources/</filename> podemos observar que foi criado o arquivo de recursos | |
513 | - <filename>messages.properties</filename>. Ao invés de manter fixas as descrições em rótulos, links, botões e | |
514 | - mensagens em uma aplicação, recomenda-se parametrizar esses textos em arquivos de recursos. Além de ser considerada | |
515 | - boa prática, essa medida facilita uma posterior internacionalização da aplicação para diversos idiomas. | |
516 | - </para> | |
517 | - <note> | |
518 | - <para> | |
519 | - O arquivo de recursos <filename>messages.properties</filename> armazenará textos | |
520 | - no idioma default da aplicação (neste caso, em Português do Brasil). | |
521 | - </para> | |
522 | - </note> | |
523 | - </section> | |
524 | - | |
525 | - <section> | |
526 | - <title>Executando no servidor</title> | |
527 | - <para> | |
528 | - A última etapa consiste em fazer o deploy da Java Web em um servidor de aplicações. | |
529 | - </para> | |
530 | - <para> | |
531 | - Utilizando a IDE Eclipse, basta clicar com o botão direito no projeto <literal>bookmark</literal> e | |
532 | - acessar o menu <guimenu>Run As</guimenu>, <guimenu>Run on Server</guimenu>. Em seguida, escolha um | |
533 | - servidor compatível com Java EE 6 (ex: JBoss AS 7) e aguarde a inicialização deste. | |
534 | - </para> | |
535 | - <mediaobject> | |
536 | - <imageobject role="fo"> | |
537 | - <imagedata fileref="images/viewproj.png" align="center" scalefit="1" width="50%" /> | |
538 | - </imageobject> | |
539 | - <imageobject role="html"> | |
540 | - <imagedata fileref="images/viewproj.png" align="center"/> | |
541 | - </imageobject> | |
542 | - </mediaobject> | |
543 | - <mediaobject> | |
544 | - <imageobject role="fo"> | |
545 | - <imagedata fileref="images/viewserver.png" align="center" scalefit="1" width="50%" /> | |
546 | - </imageobject> | |
547 | - <imageobject role="html"> | |
548 | - <imagedata fileref="images/viewserver.png" align="center"/> | |
549 | - </imageobject> | |
550 | - </mediaobject> | |
551 | - <para> | |
552 | - Na visão <literal>Console</literal> você verá as mensagens decorrentes do servidor de aplicações | |
553 | - e da inicialização da aplicação <literal>bookmark</literal> agora hospedada nele. | |
554 | - </para> | |
555 | - <tip> | |
556 | - <para> | |
557 | - Para executar em modo de depuração, na visão <literal>Servers</literal>, clique com o botão | |
558 | - direito no servidor desejado e selecione a opção <guimenu>Debug</guimenu>. | |
559 | - </para> | |
560 | - </tip> | |
561 | - <para> | |
562 | - Em seguida, abra o navegador Web de sua preferência e acesse o endereço | |
563 | - <ulink url="http://localhost:8080/bookmark">http://localhost:8080/bookmark</ulink>. Esta é a | |
564 | - página que deverá ser exibida com a aplicação <literal>bookmark</literal> em funcionamento: | |
565 | - </para> | |
566 | - <figure> | |
567 | - <title>Página principal da aplicação Bookmark</title> | |
568 | - <mediaobject> | |
569 | - <imageobject role="fo"> | |
570 | - <imagedata fileref="images/apphome.png" align="center" scalefit="1" /> | |
571 | - </imageobject> | |
572 | - <imageobject role="html"> | |
573 | - <imagedata fileref="images/apphome.png" align="center" /> | |
574 | - </imageobject> | |
575 | - <textobject> | |
576 | - <phrase>Aplicação Bookmark em funcionamento</phrase> | |
577 | - </textobject> | |
578 | - </mediaobject> | |
579 | - </figure> | |
580 | - <para> | |
581 | - Para cadastrar um novo bookmark basta ir no menu principal: <guimenu>Bookmarks</guimenu>, | |
582 | - <guimenu>Novo</guimenu>. Executando-a, será exibida a página a seguir: | |
583 | - </para> | |
584 | - <figure> | |
585 | - <title>Tela de cadastro e edição dos dados na aplicação Bookmark</title> | |
586 | - <mediaobject> | |
587 | - <imageobject role="fo"> | |
588 | - <imagedata fileref="images/appedit.png" align="center" scalefit="1" /> | |
589 | - </imageobject> | |
590 | - <imageobject role="html"> | |
591 | - <imagedata fileref="images/appedit.png" align="center" /> | |
592 | - </imageobject> | |
593 | - <textobject> | |
594 | - <phrase>Aplicação Bookmark em funcionamento</phrase> | |
595 | - </textobject> | |
596 | - </mediaobject> | |
597 | - </figure> | |
598 | - </section> | |
599 | - | |
600 | -</chapter> |
documentation/quickstart/pt-BR/images/addRemoteArchetypeCatalog01.png
52.1 KB
documentation/quickstart/pt-BR/images/addRemoteArchetypeCatalog02.png
21 KB
documentation/quickstart/pt-BR/images/appedit.png
32.4 KB
documentation/quickstart/pt-BR/images/apphome.png
33.3 KB
documentation/quickstart/pt-BR/images/appmsg.png
87.4 KB
documentation/quickstart/pt-BR/images/apppage.png
68.1 KB
documentation/quickstart/pt-BR/images/appvalid.png
39.4 KB
documentation/quickstart/pt-BR/images/demoiselle-logo.png
96.8 KB
documentation/quickstart/pt-BR/images/new-maven-project.png
43.9 KB
documentation/quickstart/pt-BR/images/new-maven-project01.png
32.2 KB
documentation/quickstart/pt-BR/images/new-maven-project02.png
45.5 KB
documentation/quickstart/pt-BR/images/newproj.png
45.4 KB
documentation/quickstart/pt-BR/images/newwiz.png
32.9 KB
documentation/quickstart/pt-BR/images/viewproj.png
12.1 KB
documentation/quickstart/pt-BR/images/viewserver.png
32.7 KB
documentation/quickstart/pt-BR/instalacao.xml
... | ... | @@ -1,95 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | - <chapter id="instalacao"> | |
5 | - <title>Instalação</title> | |
6 | - <section> | |
7 | - <title>Ambiente recomendado</title> | |
8 | - <informaltable> | |
9 | - <tgroup cols="3"> | |
10 | - <colspec colwidth="50*" /> | |
11 | - <colspec colwidth="10*" /> | |
12 | - <colspec colwidth="40*" /> | |
13 | - <tbody> | |
14 | - <row> | |
15 | - <entry> | |
16 | - <emphasis role="bold">Software</emphasis> | |
17 | - </entry> | |
18 | - <entry> | |
19 | - <emphasis role="bold">Versão</emphasis> | |
20 | - </entry> | |
21 | - <entry> | |
22 | - <emphasis role="bold">Site (Download)</emphasis> | |
23 | - </entry> | |
24 | - </row> | |
25 | - <row> | |
26 | - <entry>Java Development Kit (JDK)</entry> | |
27 | - <entry>6.0</entry> | |
28 | - <entry> | |
29 | - <ulink url="http://openjdk.org/"> | |
30 | - <citetitle>openjdk.org</citetitle> | |
31 | - </ulink> | |
32 | - </entry> | |
33 | - </row> | |
34 | - <row> | |
35 | - <entry>Apache Maven</entry> | |
36 | - <entry>2.2</entry> | |
37 | - <entry> | |
38 | - <ulink url="http://maven.apache.org/docs/2.2.1/release-notes.html"> | |
39 | - <citetitle>maven.apache.org</citetitle> | |
40 | - </ulink> | |
41 | - </entry> | |
42 | - </row> | |
43 | - <row> | |
44 | - <entry>Eclipse IDE</entry> | |
45 | - <entry>3.7</entry> | |
46 | - <entry> | |
47 | - <ulink url="http://www.eclipse.org/downloads/packages/release/indigo/r"> | |
48 | - <citetitle>www.eclipse.org</citetitle> | |
49 | - </ulink> | |
50 | - </entry> | |
51 | - </row> | |
52 | - <row> | |
53 | - <entry>m2eclipse plugin</entry> | |
54 | - <entry>0.12</entry> | |
55 | - <entry> | |
56 | - <ulink url="http://m2eclipse.sonatype.org/installing-m2eclipse.html"> | |
57 | - <citetitle>m2eclipse.sonatype.org</citetitle> | |
58 | - </ulink> | |
59 | - </entry> | |
60 | - </row> | |
61 | - <row> | |
62 | - <entry>JBoss Application Server</entry> | |
63 | - <entry>7.1.1</entry> | |
64 | - <entry> | |
65 | - <ulink url="http://download.jboss.org/jbossas/7.1/jboss-as-7.1.1.Final/jboss-as-7.1.1.Final.zip"> | |
66 | - <citetitle>www.jboss.org</citetitle> | |
67 | - </ulink> | |
68 | - </entry> | |
69 | - </row> | |
70 | - </tbody> | |
71 | - </tgroup> | |
72 | - </informaltable> | |
73 | - </section> | |
74 | - <section> | |
75 | - <title>Demoiselle Infra</title> | |
76 | - <para> | |
77 | - Para auxiliar no preparo do ambiente integrado de desenvolvimento utilizado na presente | |
78 | - documentação, recomenda-se a utilização dos pacotes de software fornecidos pelo projeto | |
79 | - <ulink url="http://demoiselle.sourceforge.net/infra/"><citetitle>Demoiselle Infra</citetitle></ulink>. | |
80 | - Neste link você encontrará as orientações necessárias para a sua configuração. | |
81 | - </para> | |
82 | - <note> | |
83 | - <para> | |
84 | - Atualmente são disponibilizados pacotes exclusivamente para a plataforma <emphasis>GNU/Linux</emphasis> | |
85 | - e distribuições baseadas no <emphasis>Debian</emphasis>, tal como <emphasis>Ubuntu</emphasis>. | |
86 | - </para> | |
87 | - </note> | |
88 | - <para> | |
89 | - Se você não utiliza nenhum dos sistemas operacionais citados, terá que baixar e instalar | |
90 | - todos os softwares listados acima. Para auxiliar um pouco o processo, disponibilizamos alguns | |
91 | - vídeos <ulink url="http://www.frameworkdemoiselle.gov.br/documentacaodoprojeto/manuais-e-tutoriais/tutoriais-da-versao-2/"> | |
92 | - <citetitle>aqui</citetitle></ulink> de demonstração de algumas fases. | |
93 | - </para> | |
94 | - </section> | |
95 | - </chapter> |
documentation/quickstart/pt-BR/master.xml
... | ... | @@ -1,38 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<book lang="pt"> | |
5 | - <xi:include href="bookinfo.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
6 | - | |
7 | - <preface> | |
8 | - <title>Sobre o QuickStart - versão &version;</title> | |
9 | - <para> | |
10 | - Este documento é um tutorial do tipo "passo a passo" que visa ilustrar de forma rápida, clara e prática a criação | |
11 | - de uma aplicação simples utilizando o <emphasis>Demoiselle Framework &version;</emphasis>. | |
12 | - </para> | |
13 | - <note> | |
14 | - <para> | |
15 | - Apesar de o <emphasis>Demoiselle Framework &version;</emphasis> ser simples de usar, o desenvolvimento de aplicações | |
16 | - não triviais requer o conhecimento das diversas tecnologias envolvidas na especificação | |
17 | - <emphasis>Java EE</emphasis>, incluindo: | |
18 | - <itemizedlist> | |
19 | - <listitem>Linguagem Java</listitem> | |
20 | - <listitem>Servlets, JSP e Tag Libraries</listitem> | |
21 | - <listitem>JavaBeans</listitem> | |
22 | - <listitem>HTML e XML</listitem> | |
23 | - <listitem>Contêineres e Servidores Web</listitem> | |
24 | - </itemizedlist> | |
25 | - </para> | |
26 | - </note> | |
27 | - <note> | |
28 | - <para> | |
29 | - Esta documentação refere-se à versão &version; do <emphasis>Demoiselle Framework</emphasis> e pode diferir | |
30 | - significativamente das versões anteriores. | |
31 | - </para> | |
32 | - </note> | |
33 | - </preface> | |
34 | - | |
35 | - <xi:include href="instalacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
36 | - <xi:include href="criacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
37 | - <xi:include href="melhoria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
38 | - </book> | |
39 | 0 | \ No newline at end of file |
documentation/quickstart/pt-BR/melhoria.xml
... | ... | @@ -1,254 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="melhoria"> | |
5 | - | |
6 | - <title>Melhorando a aplicação</title> | |
7 | - | |
8 | - <section> | |
9 | - <title>Exibindo mensagens para o usuário</title> | |
10 | - <para> | |
11 | - Uma vez que o objetivo principal da aplicação foi concluído (i.e., listagem e edição de bookmarks), | |
12 | - veremos algumas funcionalidades adicionais fornecidas pelo <emphasis>Demoiselle Framework</emphasis>, | |
13 | - iniciando pelo tratamento de mensagens. | |
14 | - </para> | |
15 | - <para> | |
16 | - Dentro do pacote <literal>br.gov.frameworkdemoiselle.sample.bookmark.message</literal> crie a interface | |
17 | - <literal>InfoMessages</literal>, a qual servirá para armazenar mensagens informativas a serem | |
18 | - exibidas ao usuário: | |
19 | - </para> | |
20 | - <programlisting role="JAVA"> | |
21 | -<![CDATA[public interface InfoMessages { | |
22 | - final Message BOOKMARK_DELETE_OK = new DefaultMessage("{bookmark-delete-ok}"); | |
23 | - final Message BOOKMARK_INSERT_OK = new DefaultMessage("{bookmark-insert-ok}"); | |
24 | - final Message BOOKMARK_UPDATE_OK = new DefaultMessage("{bookmark-update-ok}"); | |
25 | -}]]> | |
26 | - </programlisting> | |
27 | - <note> | |
28 | - <para> | |
29 | - A unidade básica de manipulação de mensagens no <emphasis>Demoiselle Framework</emphasis> | |
30 | - é a interface <literal>Message</literal>. Ou seja, basta que esta última seja implementada na | |
31 | - aplicação para que o contexto de mensagens possa manipulá-la. | |
32 | - A classe <literal>DefaultMessage</literal> é oferecida como implementação padrão dessa interface. | |
33 | - </para> | |
34 | - </note> | |
35 | - <para> | |
36 | - No exemplo em questão, o texto das mensagens será recuperado do arquivo de recursos | |
37 | - <filename>messages.properties</filename> previamente criado no diretório | |
38 | - <filename>/src/main/resources/</filename>. Para isso, adicione as seguintes linhas nesse arquivo: | |
39 | - </para> | |
40 | - <programlisting role="XML"> | |
41 | -<![CDATA[bookmark-delete-ok=Bookmark exclu\u00EDdo\: {0} | |
42 | -bookmark-insert-ok=Bookmark inserido: {0} | |
43 | -bookmark-update-ok=Bookmark atualizado: {0}]]> | |
44 | - </programlisting> | |
45 | - <para> | |
46 | - Dentro do pacote <literal>br.gov.frameworkdemoiselle.sample.bookmark.business</literal> altere a classe | |
47 | - <literal>BookmarkBC</literal> incluindo os trechos de código indicados a seguir: | |
48 | - </para> | |
49 | - <programlistingco> | |
50 | - <areaspec> | |
51 | - <area id="inject-context" coords="5"/> | |
52 | - <areaset id="add-msg-context" coords=""> | |
53 | - <area id="" coords="10"/> | |
54 | - <area id="" coords="17"/> | |
55 | - <area id="" coords="23"/> | |
56 | - </areaset> | |
57 | - </areaspec> | |
58 | - <programlisting role="JAVA"> | |
59 | -<![CDATA[@BusinessController | |
60 | -public class BookmarkBC extends DelegateCrud<Bookmark, Long, BookmarkDAO> { | |
61 | - | |
62 | -@Inject | |
63 | -private MessageContext messageContext; | |
64 | - | |
65 | -... | |
66 | - | |
67 | -@Override | |
68 | -public void insert(Bookmark bookmark) { | |
69 | - super.insert(bookmark); | |
70 | - messageContext.add(InfoMessages.BOOKMARK_INSERT_OK, bookmark.getDescription()); | |
71 | -} | |
72 | - | |
73 | -@Override | |
74 | -public void update(Bookmark bookmark) { | |
75 | - super.update(bookmark); | |
76 | - messageContext.add(InfoMessages.BOOKMARK_UPDATE_OK, bookmark.getDescription()); | |
77 | -} | |
78 | - | |
79 | -@Override | |
80 | -public void delete(Long id) { | |
81 | - super.delete(id); | |
82 | - messageContext.add(InfoMessages.BOOKMARK_DELETE_OK, id); | |
83 | -} | |
84 | -}]]></programlisting> | |
85 | - <calloutlist> | |
86 | - <callout arearefs="inject-context"> | |
87 | - <para> | |
88 | - No ponto contendo <literal>@Inject</literal> será injetado via CDI o contexto de mensagens | |
89 | - presente na aplicação, ou seja, uma instância da interface <literal>MessageContext</literal> | |
90 | - que poderá ser utilizada em qualquer método nessa classe. | |
91 | - </para> | |
92 | - </callout> | |
93 | - <callout arearefs="add-msg-context"> | |
94 | - <para> | |
95 | - Aqui os métodos <function>insert()</function>, <function>update()</function> e | |
96 | - <function>delete()</function> da classe <literal>DelegateCrud</literal> são sobrescritos | |
97 | - para permitir com que o contexto de mensagens seja manipulado em cada invocação destes. | |
98 | - O método <function>add()</function> de <literal>MessageContext</literal> faz com que a | |
99 | - mensagem passada como parâmetro seja adicionada ao contexto, que ao final será exibida | |
100 | - para o usuário na camada de apresentação. | |
101 | - </para> | |
102 | - </callout> | |
103 | - </calloutlist> | |
104 | - </programlistingco> | |
105 | - <note> | |
106 | - <para> | |
107 | - O contexto de mensagens, representado pela interface <literal>MessageContext</literal>, é capaz de | |
108 | - armazenar diversas mensagens em uma mesma requisição. Ele não é restrito à aplicações do tipo Web, | |
109 | - isto é, pode ser usado também para aplicações do tipo desktop (i.e., Swing). | |
110 | - </para> | |
111 | - </note> | |
112 | - <para> | |
113 | - Ao término das modificações propostas até aqui, reconstrua o projeto Java e faça novo deploy | |
114 | - no servidor de aplicações. Acesse a aplicação <literal>bookmark</literal> e efetue inclusões, | |
115 | - modificações e exclusões de bookmarks. As mensagens informativas devem aparecer em caixas de | |
116 | - mensagens na tela, tal como ilustrado a seguir: | |
117 | - </para> | |
118 | - <figure> | |
119 | - <title>Exibição de mensagens na aplicação Bookmark</title> | |
120 | - <mediaobject> | |
121 | - <imageobject role="fo"> | |
122 | - <imagedata fileref="images/appmsg.png" align="center" scalefit="1" /> | |
123 | - </imageobject> | |
124 | - <imageobject role="html"> | |
125 | - <imagedata fileref="images/appmsg.png" align="center" /> | |
126 | - </imageobject> | |
127 | - <textobject> | |
128 | - <phrase>Aplicação Bookmark em funcionamento</phrase> | |
129 | - </textobject> | |
130 | - </mediaobject> | |
131 | - </figure> | |
132 | - </section> | |
133 | - | |
134 | - <section> | |
135 | - <title>Criando regras de validação nos campos</title> | |
136 | - <para> | |
137 | - Sendo aderente à especificação Java EE 6, o <emphasis>Demoiselle Framework</emphasis> | |
138 | - recomenda e faz uso do mecanismo de validação provido pela especificação | |
139 | - <ulink url="http://jcp.org/en/jsr/detail?id=303">JSR-303 (Bean Validation)</ulink>. | |
140 | - </para> | |
141 | - <para> | |
142 | - A fim de testarmos mais essa funcionalidade, utilizaremos a implementação de validação | |
143 | - <emphasis>Hibernate Validator</emphasis>. Para tal, abra o arquivo <filename>pom.xml</filename> | |
144 | - do projeto <literal>bookmark</literal> e inclua nele a seguinte dependência: | |
145 | - </para> | |
146 | - <programlisting role="XML"> | |
147 | -<![CDATA[<dependencies> | |
148 | - ... | |
149 | - <dependency> | |
150 | - <groupId>org.hibernate</groupId> | |
151 | - <artifactId>hibernate-validator</artifactId> | |
152 | - <version>4.3.0.Final</version> | |
153 | - </dependency> | |
154 | -</dependencies>]]> | |
155 | - </programlisting> | |
156 | - <note> | |
157 | - <para> | |
158 | - O objetivo dessa abordagem de validação é auxiliar na criação de restrições diretamente nas | |
159 | - entidades de domínio. Tais restrições serão utilizadas de forma conjunta nas camadas de | |
160 | - persistência e apresentação da aplicação. A vantagem é que elas são facilmente configuráveis, | |
161 | - bastando apenas incluir certas anotações (ex: <literal>@NotNull</literal>, <literal>@Size</literal>) | |
162 | - nos campos da classe a ser validada. | |
163 | - </para> | |
164 | - </note> | |
165 | - <para> | |
166 | - No pacote <literal>br.gov.frameworkdemoiselle.sample.bookmark.domain</literal> altere a entidade de domínio | |
167 | - <literal>Bookmark</literal> incluindo as anotações de validação nos campos <literal>description</literal> | |
168 | - e <literal>link</literal> conforme ilustrado a seguir: | |
169 | - </para> | |
170 | - <programlistingco> | |
171 | - <areaspec> | |
172 | - <area id="valid-desc" coords="9"/> | |
173 | - <area id="valid-link" coords="14"/> | |
174 | - </areaspec> | |
175 | - <programlisting role="JAVA"> | |
176 | -<![CDATA[@Entity | |
177 | -public class Bookmark { | |
178 | - | |
179 | - @Id | |
180 | - @GeneratedValue | |
181 | - private Long id; | |
182 | - | |
183 | - @Column | |
184 | - @NotNull | |
185 | - @Size(min = 1, max = 30) | |
186 | - private String description; | |
187 | - | |
188 | - @Column | |
189 | - @NotNull | |
190 | - @NotBlank | |
191 | - @Size(max = 255) | |
192 | - @URL | |
193 | - private String link; | |
194 | - | |
195 | - ... | |
196 | -}]]> | |
197 | - </programlisting> | |
198 | - <calloutlist> | |
199 | - <callout arearefs="valid-desc"> | |
200 | - <para> | |
201 | - No campo <literal>description</literal>, a anotação <literal>@NotNull</literal> serve | |
202 | - para impedir que o valor nulo seja atribuído a ele. Já a anotação <literal>@Size</literal> | |
203 | - restringe a quantidade mínima e máxima de caracteres no campo. | |
204 | - </para> | |
205 | - </callout> | |
206 | - <callout arearefs="valid-link"> | |
207 | - <para> | |
208 | - No campo <literal>link</literal> mais restrições são aplicadas. Além de não permitir o valor | |
209 | - nulo (com <literal>@NotNull</literal>) e estipular o comprimento máximo de 255 caracteres | |
210 | - (com <literal>@Size</literal>), o campo não pode ficar vazio (com <literal>@NotBlank</literal>) | |
211 | - e seu conteúdo deve ser um endereço de Internet válido (com <literal>@URL</literal>). | |
212 | - </para> | |
213 | - </callout> | |
214 | - </calloutlist> | |
215 | - </programlistingco> | |
216 | - <tip> | |
217 | - <para> | |
218 | - Validações de campos específicos para a comunidade brasileira são oferecidos pelo componente | |
219 | - <emphasis>Demoiselle Validation</emphasis>. Com ele, as seguintes anotações podem ser aplicadas nas | |
220 | - classes de domínio: <literal>@Cep</literal>, <literal>@Cnpj</literal>, <literal>@Cpf</literal>, | |
221 | - <literal>@InscricaoEstadual</literal> e <literal>@PisPasep</literal>. | |
222 | - </para> | |
223 | - </tip> | |
224 | - <para> | |
225 | - Assim que você efetuar as modificações, reconstrua o projeto Java e faça novo deploy no servidor de | |
226 | - aplicações. Acesse a aplicação <literal>bookmark</literal> e, na tela de edição de bookmarks, deixe | |
227 | - vazios os campos no formulário e clique em <guibutton>Salvar</guibutton>. Tente também preencher um | |
228 | - endereço de Internet inválido no campo <literal>Link</literal>. Caixas de erro com as mensagens | |
229 | - referentes as validações devem aparecer ao lado de cada campo, tal como ilustrado: | |
230 | - </para> | |
231 | - <figure> | |
232 | - <title>Validação de campos na aplicação Bookmark</title> | |
233 | - <mediaobject> | |
234 | - <imageobject role="fo"> | |
235 | - <imagedata fileref="images/appvalid.png" align="center" scalefit="1" /> | |
236 | - </imageobject> | |
237 | - <imageobject role="html"> | |
238 | - <imagedata fileref="images/appvalid.png" align="center" /> | |
239 | - </imageobject> | |
240 | - <textobject> | |
241 | - <phrase>Aplicação Bookmark em funcionamento</phrase> | |
242 | - </textobject> | |
243 | - </mediaobject> | |
244 | - </figure> | |
245 | - <tip> | |
246 | - <para> | |
247 | - As mensagens exibidas na tela durante a validação estão contidas no arquivo de | |
248 | - recursos <filename>ValidationMessages.properties</filename> presente no diretório | |
249 | - <filename>/src/main/resources/</filename>. | |
250 | - </para> | |
251 | - </tip> | |
252 | - </section> | |
253 | - | |
254 | -</chapter> | |
255 | 0 | \ No newline at end of file |
documentation/quickstart/pt-BR/revhistory.xml
... | ... | @@ -1,35 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE revhistory PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<revhistory> | |
5 | - <revision> | |
6 | - <revnumber>2.0.4</revnumber> | |
7 | - <date>17/11/2011</date> | |
8 | - <authorinitials>mc</authorinitials> | |
9 | - <revremark>Atualizações de acordo com a versão 2.2.0 do Framework Demoiselle .</revremark> | |
10 | - </revision> | |
11 | - <revision> | |
12 | - <revnumber>2.0.3</revnumber> | |
13 | - <date>26/04/2011</date> | |
14 | - <authorinitials>rh</authorinitials> | |
15 | - <revremark>Correções ortográficas e de formatação.</revremark> | |
16 | - </revision> | |
17 | - <revision> | |
18 | - <revnumber>2.0.2</revnumber> | |
19 | - <date>04/02/2011</date> | |
20 | - <authorinitials>es</authorinitials> | |
21 | - <revremark>Melhoria no procedimento de criação da aplicação.</revremark> | |
22 | - </revision> | |
23 | - <revision> | |
24 | - <revnumber>2.0.1</revnumber> | |
25 | - <date>03/01/2011</date> | |
26 | - <authorinitials>rh</authorinitials> | |
27 | - <revremark>Códigos em fonte monoespaçada.</revremark> | |
28 | - </revision> | |
29 | - <revision> | |
30 | - <revnumber>2.0.0</revnumber> | |
31 | - <date>27/12/2010</date> | |
32 | - <authorinitials>rh</authorinitials> | |
33 | - <revremark>Primeira release da documentação.</revremark> | |
34 | - </revision> | |
35 | -</revhistory> | |
36 | 0 | \ No newline at end of file |
documentation/reference/.gitignore
documentation/reference/pt-BR/arquetipo.xml
... | ... | @@ -1,37 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="estrutura"> | |
5 | - | |
6 | - <title>Arquétipos</title> | |
7 | - | |
8 | - <para> | |
9 | - O projeto Demoiselle recomenda e usa a ferramenta <ulink url="http://maven.apache.org/">Apache-Maven</ulink>, para gerenciamento do ciclo de vida do desenvolvimento | |
10 | - de projeto. Baseada nesta ferramenta, além do fornecimento dos POMs Parentes, também fornece as estruturas chamadas <ulink url="http://maven.apache.org/archetype/maven-archetype-plugin/">arquétipos</ulink> | |
11 | - para facilitar a criação de aplicações, garantido a estrutura recomendada pelo framework e o conceito de gerenciamento do próprio Maven. | |
12 | - Atualmente estão disponíveis os seguintes artefatos: | |
13 | - </para> | |
14 | - | |
15 | - <section> | |
16 | - <title>demoiselle-minimal</title> | |
17 | - <para> | |
18 | - Fornece um conjunto mínimo de artefatos para criar uma aplicação Java, utiliza o Demoiselle-Minimal-Parent, | |
19 | - sendo útil quando os outros arquétipos disponíveis não se enquadram nas características do projeto a ser criado. | |
20 | - </para> | |
21 | - </section> | |
22 | - | |
23 | - <section> | |
24 | - <title>demoiselle-jsf-jpa</title> | |
25 | - <para> | |
26 | - Útil para os projetos que precisam de uma arquitetura que utilize as tecnologias JSF e JPA, | |
27 | - é baseado no <emphasis>demoiselle-jsf-parent</emphasis> | |
28 | - e já traz uma estrutura padrão de pacotes e todas | |
29 | - as dependências necessárias para rodar a aplicação. Ao usar este | |
30 | - arquétipo, você terá uma pequena aplicação de | |
31 | - Bookmarks já pronta para rodar. Para isto, basta instalá-la em um | |
32 | - servidor da sua preferência! Para mais detalhes | |
33 | - sobre esta aplicação de exemplo e em como usar o arquétipo, acesse | |
34 | - a sessão de documentação chamada <ulink url="http://demoiselle.sourceforge.net/docs/quickstart/">QuickStart</ulink>. | |
35 | - </para> | |
36 | - </section> | |
37 | -</chapter> |
documentation/reference/pt-BR/arquitetura.xml
... | ... | @@ -1,89 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="arquetipo"> | |
5 | - | |
6 | - <title>Arquitetura</title> | |
7 | - | |
8 | - <section> | |
9 | - <title>Estrutura</title> | |
10 | - <para> | |
11 | - Visando uma melhor modularização, o Demoiselle está dividido por funcionalidades. Isto significa que o framework | |
12 | - não é monolítico, no qual todas as suas funcionalidades estão contidas em um único pacote. Aliás, esta estratégia não é | |
13 | - a mais indicada, pois projetos com um propósito específico, que não necessitam de persistência ou interface Web, por | |
14 | - exemplo, teriam dependências desnecessárias. Assim, o Demoiselle é separado em Core, Extensões e Componentes. | |
15 | - </para> | |
16 | - <!-- TODO: incluir um diagrama ilustrando a estrutura do framework --> | |
17 | - <para> | |
18 | - O Core do Demoiselle contém aquelas funcionalidades comuns a todas as extensões e aplicações. O core é simples, | |
19 | - leve e formado majoritariamente por interfaces e poucas implementações. O Core é a base do framework, sem ele, as | |
20 | - extensões e a própria aplicação não funcionariam.</para> | |
21 | - <para> | |
22 | - As Extensões, como o próprio nome sugere, estendem o Core com funcionalidades extras e bem específicas a um domínio ou | |
23 | - tecnologia. Neste contexto, caso sua aplicação necessite de persistência com JPA, o framework fornecerá facilidades | |
24 | - para você; contudo, estas funcionalidades não estão no Core. Para este propósito existem as extensões como a | |
25 | - <literal>demoiselle-jpa</literal>, por exemplo. Cabe destacar que as extensões não possuem vida própria, | |
26 | - pois estão diretamente ligadas ao núcleo do framework, inclusive o ciclo de vida das extensões está | |
27 | - totalmente acoplado ao do Core. | |
28 | - </para> | |
29 | - <para> | |
30 | - Já os Componentes são artefatos separados e que, portanto, não são dependentes diretamente do Core. Aliás, os | |
31 | - Componentes podem até mesmo existir sem referenciar o Core. Desta forma, o seu ciclo de vida é totalmente | |
32 | - independente do Core e Extensões. Um componente não precisa, necessariamente, estender o comportamento do Core, mas | |
33 | - permitir disponibilizar novas funcionalidades ao usuário. Outra diferença importante é que, diferente de Core e | |
34 | - Extensões, os Componentes não necessariamente são aderentes a alguma especificação. Um exemplo é o | |
35 | - <literal>demoiselle-validation</literal>. | |
36 | - </para> | |
37 | - </section> | |
38 | - | |
39 | - <section> | |
40 | - <title>Pacote Internal</title> | |
41 | - <para> | |
42 | - As boas práticas de programação nos alertam para que nunca sejamos dependentes de implementações, mas sempre de | |
43 | - interfaces ou, como alguns costumam dizer, <quote>depender de contratos</quote>. | |
44 | - Portanto a sua aplicação precisará apenas depender das interfaces que o Demoiselle provê. As implementações específicas | |
45 | - e internas do Framework serão injetadas automaticamente pelo CDI. | |
46 | - </para> | |
47 | - <tip> | |
48 | - <para> | |
49 | - As classes do pacote <literal>internal</literal> nunca devem ser referenciadas pela sua aplicação! | |
50 | - </para> | |
51 | - </tip> | |
52 | - <para> | |
53 | - Qual o motivo de toda esta explicação? Os programadores mais curiosos irão encontrar classes do framework que estão | |
54 | - inseridas no pacote <literal>br.gov.frameworkdemoiselle.internal</literal>. | |
55 | - As classes deste pacote não devem ser usadas diretamente pela sua aplicação, caso contrário você | |
56 | - estará acoplando-a com a implementação interna do Framework. A equipe do | |
57 | - Demoiselle possui atenção especial quanto às suas interfaces (contratos) e não irá modificá-las sem antes tornar | |
58 | - públicas as mudanças. Contudo, tudo que consta no pacote <literal>br.gov.frameworkdemoiselle.internal</literal> | |
59 | - pode sofrer mudanças repentinas. Se você referenciar tais classes internas, a sua aplicação pode deixar | |
60 | - de funcionar ao atualizar a versão do Demoiselle. | |
61 | - </para> | |
62 | - </section> | |
63 | - | |
64 | - <section> | |
65 | - <title>Arquitetura das aplicações</title> | |
66 | - <para> | |
67 | - É importante reforçar que o Demoiselle não obriga nenhum tipo de arquitetura para as aplicações, que podem ser | |
68 | - constituídas por quantas camadas forem necessárias. Contudo, é prudente não exagerar! Para quem não sabe por onde | |
69 | - começar, sugerimos uma arquitetura e padrões largamente utilizados pelo mercado, de forma a facilitar a manutenção e | |
70 | - para melhor modularização de seu projeto. | |
71 | - </para> | |
72 | - <para> | |
73 | - Usualmente, as aplicações são constituídas por pelo menos três camadas, desta forma é comum separar as lógicas de | |
74 | - apresentação, regras de negócio e persistência. O Demoiselle já fornece estereótipos que visam tornar esta | |
75 | - separação mais clara, respectivamente: | |
76 | - <literal>@ViewController</literal>, <literal>@BusinessController</literal> e <literal>@PersistenceController</literal>. | |
77 | - Maiores detalhes sobre cada anotação serão dados no decorrer desta documentação. | |
78 | - </para> | |
79 | - <!-- TODO: explicar melhor cada um dos estereótipos, se possível exemplificando com códigos --> | |
80 | - <para> | |
81 | - Cabe destacar que estamos falando de uma macro-visão arquitetural. Cada camada pode ser organizada | |
82 | - internamente da melhor forma possível, ou conforme os padrões vigentes no mercado. Para uma aplicação Swing, por | |
83 | - exemplo, o padrão de projeto <emphasis>Presentation Model</emphasis> | |
84 | - é bastante indicado. Para aplicações Web, os frameworks | |
85 | - especialistas geralmente aplicam o padrão MVC (Model/View/Controller). | |
86 | - </para> | |
87 | - </section> | |
88 | - | |
89 | -</chapter> |
documentation/reference/pt-BR/authorgroup.xml
... | ... | @@ -1,49 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE authorgroup PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<authorgroup> | |
5 | - <author> | |
6 | - <firstname>Cleverson</firstname> | |
7 | - <surname>Sacramento</surname> | |
8 | - </author> | |
9 | - <author> | |
10 | - <firstname>Danilo</firstname> | |
11 | - <surname>Viana</surname> | |
12 | - </author> | |
13 | - <author> | |
14 | - <firstname>Emerson</firstname> | |
15 | - <surname>Oliveira</surname> | |
16 | - </author> | |
17 | - <author> | |
18 | - <firstname>Emerson</firstname> | |
19 | - <surname>Saito</surname> | |
20 | - </author> | |
21 | - <author> | |
22 | - <firstname>Luciano</firstname> | |
23 | - <surname>Borges</surname> | |
24 | - </author> | |
25 | - <author> | |
26 | - <firstname>Marlon</firstname> | |
27 | - <surname>Carvalho</surname> | |
28 | - </author> | |
29 | - <!-- <author> --> | |
30 | - <!-- <firstname>Robson</firstname> --> | |
31 | - <!-- <surname>Ximenes</surname> --> | |
32 | - <!-- </author> --> | |
33 | - <author> | |
34 | - <firstname>Rodrigo</firstname> | |
35 | - <surname>Hjort</surname> | |
36 | - </author> | |
37 | - <author> | |
38 | - <firstname>Serge</firstname> | |
39 | - <surname>Rehem</surname> | |
40 | - </author> | |
41 | - <author> | |
42 | - <firstname>Thiago</firstname> | |
43 | - <surname>Mariano</surname> | |
44 | - </author> | |
45 | - <author> | |
46 | - <firstname>Wilson</firstname> | |
47 | - <surname>Guimarães</surname> | |
48 | - </author> | |
49 | -</authorgroup> |
documentation/reference/pt-BR/bookinfo.xml
... | ... | @@ -1,8 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<bookinfo> | |
5 | - <title>Framework Demoiselle</title> | |
6 | - <subtitle>Guia de Referência</subtitle> | |
7 | - <xi:include href="authorgroup.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
8 | -</bookinfo> |
documentation/reference/pt-BR/bundle.xml
... | ... | @@ -1,86 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="bundle"> | |
5 | - | |
6 | - <title>Resource Bundle</title> | |
7 | - | |
8 | - <para> | |
9 | - Um dos requisitos para se construir uma aplicação nos dias de hoje é o de que seja utilizada por pessoas | |
10 | - em vários lugares no mundo e em diferentes línguas. Portanto, é preciso que as aplicações sejam facilmente | |
11 | - internacionalizáveis. Para isso, existe um recurso no java chamado de <emphasis>Resource Bundle</emphasis>, | |
12 | - que nada mais é do que um esquema de arquivos <filename>properties</filename>, onde cada arquivo representa | |
13 | - uma língua e cada um desses arquivos possui um conjunto de chaves e valores, sendo que os valores são os textos | |
14 | - que serão exibidos na aplicação e estão na língua correspondente à língua que o arquivo representa. | |
15 | - </para> | |
16 | - <para> | |
17 | - O arquivo <filename>properties</filename> que será utilizado para montar a aplicação é escolhido pelo próprio | |
18 | - usuário, seja através da língua definida no browser ou no próprio sistema operacional. Caso o usuário escolha | |
19 | - uma língua que não está disponível na aplicação, uma língua default será utilizada. Por exemplo: vamos imaginar | |
20 | - que em uma aplicação existem dois arquivos <filename>properties</filename>, um em português e outro em inglês, e | |
21 | - que o arquivo default é o inglês. Vamos imaginar também que a aplicação é Web, portanto a língua escolhida está | |
22 | - definida no próprio browser. Caso esteja configurado no browser do usuário a língua alemã e como não existe nenhum | |
23 | - arquivo de properties para alemão, a aplicação será exibida na língua inglesa, que é a língua configurada como | |
24 | - default. | |
25 | - </para> | |
26 | - <para> | |
27 | - Todos os arquivos são criados praticamente com o mesmo nome. O que diferencia um arquivo do outro é o acréscimo | |
28 | - da sigla que representa a língua daquele arquivo. O arquivo que representa a língua default não tem essa sigla | |
29 | - ao fim do nome. Seguindo o exemplo citado acima e imaginando que o nome dos nossos arquivos é messages, ficaria | |
30 | - da seguinte forma: <filename>messages.properties</filename> seria o arquivo default que representaria a língua | |
31 | - inglesa e <filename>messages_pt.properties</filename> seria o arquivo da língua portuguesa. Veja abaixo um | |
32 | - exemplo com esses dois arquivos. | |
33 | - </para> | |
34 | - <para> | |
35 | - <filename>messages.properties</filename>: | |
36 | - </para> | |
37 | - <programlisting><![CDATA[button.edit=Edit | |
38 | -button.new=New | |
39 | -button.save=Save]]></programlisting> | |
40 | - <para> | |
41 | - <filename>messages_pt.properties</filename>: | |
42 | - </para> | |
43 | - <programlisting><![CDATA[button.edit=Editar | |
44 | -button.new=Novo | |
45 | -button.save=Salvar]]></programlisting> | |
46 | - | |
47 | - <section> | |
48 | - <title>Utilizando Resource Bundle no Demoiselle</title> | |
49 | - <para> | |
50 | - Na versão 2 do <emphasis>Demoiselle Framework</emphasis>, existe uma fábrica de Resource Bundle que fica no | |
51 | - Core e permite seu uso através da injeção ou através de uma instanciação normal. O grande detalhe é que nessa | |
52 | - fábrica é injetado um objeto do tipo <literal>Locale</literal>, isso quer dizer que é necessário criar também | |
53 | - uma fábrica de <literal>Locale</literal>. Como a definição de <literal>Locale</literal> varia de acordo com a | |
54 | - camada de apresentação, essas fábricas foram criadas nas extensões de apresentação: | |
55 | - <literal>demoiselle-servlet</literal>, <literal>demoiselle-jsf</literal> e <literal>demoiselle-se</literal>. | |
56 | - Na extensão <literal>demoiselle-se</literal> a definição do <literal>Locale</literal> é dada através do | |
57 | - <literal>Locale</literal> definido na máquina do usuário, enquanto que nas extensões | |
58 | - <literal>demoiselle-servlet</literal> e <literal>demoiselle-jsf</literal> essa definição | |
59 | - acontece através do <literal>Locale</literal> do browser do usuário, por se tratarem de extensões para camada | |
60 | - de apresentação Web. Por default, a fábrica de Resource Bundle vai injetar um bundle apontando para o arquivo | |
61 | - <filename>messages</filename>, mas isso pode ser facilmente alterado através da anotação | |
62 | - <literal>@Name</literal>. Veja abaixo como utilizar o Resource Bundle no Demoiselle. | |
63 | - </para> | |
64 | - <para> | |
65 | - Utilizando Resource Bundle através da injeção: | |
66 | - </para> | |
67 | - <programlisting role="JAVA"><![CDATA[@Inject | |
68 | -@Name("messages-core") | |
69 | -private ResourceBundle bundle; | |
70 | - | |
71 | -public String metodoQueRetornaOValorDaChavebuttonedit() { | |
72 | - return bundle.getString("button.edit"); | |
73 | -}]]></programlisting> | |
74 | - <para> | |
75 | - Utilizando Resource Bundle sem uso de injeção: | |
76 | - </para> | |
77 | - <programlisting role="JAVA"><![CDATA[private ResourceBundleFactory bundleFactory = new ResourceBundleFactory(Locale.getDefault()); | |
78 | -private ResourceBundle bundle; | |
79 | - | |
80 | -public String metodoQueRetornaOValorDaChavebuttonedit() { | |
81 | - bundle = bundleFactory.create("messages-core"); | |
82 | - return bundle.getString("button.edit"); | |
83 | -}]]></programlisting> | |
84 | - </section> | |
85 | - | |
86 | -</chapter> |
documentation/reference/pt-BR/configuracao.xml
... | ... | @@ -1,662 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="configuracao"> | |
5 | - | |
6 | - <title>Configuração</title> | |
7 | - | |
8 | - <section> | |
9 | - <title>Configurações em uma aplicação</title> | |
10 | - <para> | |
11 | - Muitas vezes, por motivos diversos, é necessário parametrizar a aplicação à partir de algum mecanismo de | |
12 | - configuração. E em java é comum se utilizar as seguintes abordagens para armazenas as configurações: | |
13 | - <itemizedlist> | |
14 | - <listitem> | |
15 | - <para> | |
16 | - <emphasis>arquivo de propriedades</emphasis>: tratam-se de simples arquivos de texto nomeados com a | |
17 | - extensão <filename>.properties</filename>, os quais são escritos com a sintaxe <literal>chave=valor</literal>, | |
18 | - armazenando uma única chave por linha; | |
19 | - </para> | |
20 | - </listitem> | |
21 | - <listitem> | |
22 | - <para> | |
23 | - <emphasis>arquivo XML</emphasis>: são arquivos de texto altamente estruturados com a sintaxe de tags e | |
24 | - que permitem uma maior validação dos seus valores, sendo geralmente nomeados com a extensão<filename>.xml</filename>; | |
25 | - </para> | |
26 | - </listitem> | |
27 | - <listitem> | |
28 | - <para> | |
29 | - <emphasis>variáveis de ambiente</emphasis>: valores definidos no sistema operacional, independente de | |
30 | - plataforma (Windows, Linux, Mac OS, etc) e que podem ser recuperados durante a execução da aplicação. | |
31 | - </para> | |
32 | - </listitem> | |
33 | - </itemizedlist> | |
34 | - </para> | |
35 | - <para> | |
36 | - Esse capítulo mostra de que maneira o <emphasis>Demoiselle Framework</emphasis> pode facilitar a utilização dessas | |
37 | - formas de configuração, oferencendo vários recursos interessantes para a sua aplicação. | |
38 | - </para> | |
39 | - | |
40 | - </section> | |
41 | - <section> | |
42 | - <title>As classes de configuração</title> | |
43 | - <para> | |
44 | - O primeiro passo para a utilização do mecanismo de configuração em uma aplicação consiste em criar uma classe | |
45 | - específica para armazenar os parâmetros desejados e anotá-la com <literal>@Configuration</literal>. O código | |
46 | - abaixo mostra um exemplo de classe de configuração: | |
47 | - </para> | |
48 | - <programlisting role="JAVA"><![CDATA[@Configuration | |
49 | -public class BookmarkConfig { | |
50 | - | |
51 | - private String applicationTitle; | |
52 | - | |
53 | - private boolean loadInitialData; | |
54 | - | |
55 | - public String getApplicationTitle() { | |
56 | - return applicationTitle; | |
57 | - } | |
58 | - | |
59 | - public boolean isLoadInitialData() { | |
60 | - return loadInitialData; | |
61 | - } | |
62 | -}]]></programlisting> | |
63 | - <note> | |
64 | - <para> | |
65 | - As classes anotadas com <literal>@Configuration</literal> são instanciadas uma única vez (seguindo o padrão | |
66 | - de projeto <emphasis>singleton</emphasis>) e podem ser injetadas em qualquer ponto da aplicação. Seu ciclo | |
67 | - de vida é gerenciado automaticamente pelo CDI. Os recursos (arquivo ou variável de ambiente) são lidos no | |
68 | - primeiro acesso à respectiva classe de configuração, quando os seus atributos são preenchidos automaticamente. | |
69 | - </para> | |
70 | - </note> | |
71 | - <note> | |
72 | - <para> | |
73 | - Recomenda-se usar o sufixo <quote>Config</quote> nas classes de configuração, e que sejam criados | |
74 | - apenas os acessores para leitura (<emphasis>getters</emphasis>). | |
75 | - </para> | |
76 | - </note> | |
77 | - | |
78 | - | |
79 | - <para> | |
80 | - Esse é um exemplo bastante simples, no qual não são especificados nem nome nem tipo do arquivo de configuração. Nessa | |
81 | - situação os parâmetros de nome <emphasis>applicationTitle</emphasis> e <emphasis>loadInitialData</emphasis> serão | |
82 | - procurados em um arquivo de propriedades de nome <emphasis>demoiselle.properties</emphasis>. Ou seja, quando não | |
83 | - especificados nome e tipo do arquivo, assume-se que o arquivo é do tipo <emphasis>propriedades</emphasis> | |
84 | - e seu nome é <emphasis>demoiselle</emphasis>. Mas como fazer para não utilizar o valor padrão e definir | |
85 | - nome e tipo do arquivo? Bastante simples. Basta adicionar esses parâmetros à anotação @Configuration, como mostra o | |
86 | - exemplo a seguir: | |
87 | - </para> | |
88 | - <programlisting role="JAVA"><![CDATA[@Configuration(resource="my-property-file", type=ConfigType.XML) | |
89 | -public class BookmarkConfig { | |
90 | - | |
91 | - private String applicationTitle; | |
92 | - | |
93 | - private boolean loadInitialData; | |
94 | - | |
95 | - public String getApplicationTitle() { | |
96 | - return applicationTitle; | |
97 | - } | |
98 | - | |
99 | - public boolean isLoadInitialData() { | |
100 | - return loadInitialData; | |
101 | - } | |
102 | -}]]></programlisting> | |
103 | - | |
104 | - <para> | |
105 | - Devemos atribuir o nome do arquivo de configuração ao parâmetro <emphasis>resource</emphasis>, sem a extensão. | |
106 | - Ao parâmetro <emphasis>type</emphasis> pode ser atribuída uma das três possibilidades: | |
107 | - <emphasis>ConfigType.PROPERTIES</emphasis>, que é o valor padrão e indica que as configurações daquela classe | |
108 | - estão em um arquivo do tipo <emphasis>properties</emphasis>; <emphasis>ConfigType.XML</emphasis>, que indica que | |
109 | - as configurações daquela classe estão em um arquivo do tipo <emphasis>xml</emphasis>; e <emphasis> | |
110 | - ConfigType.SYSTEM</emphasis>, que indica que as configurações daquela classe são valores definidos pelo Sistema | |
111 | - Operacional. Nesse exemplo, ao definir <emphasis>resource</emphasis> e <emphasis>type</emphasis> os parâmetros de | |
112 | - nome <emphasis>applicationTitle</emphasis> e <emphasis>loadInitialData</emphasis> serão procurados em um arquivo | |
113 | - xml de nome <emphasis>my-property-file</emphasis> (my-property-file.xml). | |
114 | - </para> | |
115 | - <para> | |
116 | - Outro parâmetro que você pode ajustar nessa anotação é o prefixo. Ao definir um valor de prefixo você informa que | |
117 | - o nome das propriedades definidas naquela classe devem ser concatenados com o prefixo, de forma que o nome dos | |
118 | - atributos procurados no arquivo seja <emphasis>prefixo.nomeatributo</emphasis>. O exemplo abaixo mostra a | |
119 | - utilização desse parâmetro. Nesse caso, os parâmetros de nome <emphasis>info.applicationTitle</emphasis> e | |
120 | - <emphasis>info.loadInitialData</emphasis> serão procurados em um arquivo de propriedade de nome | |
121 | - <emphasis>my-property-file</emphasis> (<emphasis>my-property-file.properties</emphasis>). | |
122 | - </para> | |
123 | - <programlisting role="JAVA"><![CDATA[@Configuration(prefix="info", resource="my-property-file") | |
124 | -public class BookmarkConfig { | |
125 | - | |
126 | - private String applicationTitle; | |
127 | - | |
128 | - private boolean loadInitialData; | |
129 | - | |
130 | - public String getApplicationTitle() { | |
131 | - return applicationTitle; | |
132 | - } | |
133 | - | |
134 | - public boolean isLoadInitialData() { | |
135 | - return loadInitialData; | |
136 | - } | |
137 | -}]]></programlisting> | |
138 | - <note> | |
139 | - <para> | |
140 | - O <emphasis>Demoiselle Framework</emphasis> adiciona automaticamente o ponto entre o prefixo e o nome do | |
141 | - atributo, você não precisa se preocupar com isso. | |
142 | - </para> | |
143 | - </note> | |
144 | - <tip> | |
145 | - <para> | |
146 | - No arquivo xml o prefixo corresponde a uma <emphasis>tag</emphasis> acima das tag que correspondem aos | |
147 | - atributos. O exemplo acima ficaria da seguinte forma em um arquivo xml: | |
148 | - </para> | |
149 | - <programlisting role="XML"><![CDATA[ | |
150 | -<info> | |
151 | - <applicationTitle>Demoiselle Application<\applicationTitle> | |
152 | - <loadInitialData>true<\loadInitialData> | |
153 | -</info> | |
154 | - | |
155 | -]]></programlisting> | |
156 | - | |
157 | - </tip> | |
158 | - </section> | |
159 | - | |
160 | - <section> | |
161 | - <title>Especificando os parâmetros</title> | |
162 | - <para> | |
163 | - Atualmente são suportados nativamente pelo <emphasis>Demoiselle Framework</emphasis> parâmetros de sete categorias | |
164 | - diferentes. São eles: tipos primitivos (<emphasis>int, float, boolean, etc</emphasis>), classes <emphasis>wrapper</emphasis> (<emphasis>Integer, Float, Boolean, etc.</emphasis>) | |
165 | - , <emphasis>String</emphasis>, <emphasis>Class</emphasis>, <emphasis>Map</emphasis>, <emphasis>Array</emphasis> e instâncias de <emphasis>Enum</emphasis>. | |
166 | - A seguir vamos explicar e exemplificar como utilizar cada um desses | |
167 | - tipos, e alertar para as possíveis exceções que poderão ser lançadas para sua aplicação. | |
168 | - </para> | |
169 | - <caution> | |
170 | - <para> | |
171 | - A partir da versão 2.4.0 não são mais reconhecidas as convenções de substituição de nomes. Os parâmetros serão procurados exatamente | |
172 | - como foram definidos na classe de configuração. | |
173 | - </para> | |
174 | - </caution> | |
175 | - <informaltable> | |
176 | - <tgroup cols="1"> | |
177 | - <colspec colwidth="100*" /> | |
178 | - <tbody> | |
179 | - <row> | |
180 | - <entry> | |
181 | - <emphasis role="bold">Primitivos</emphasis> | |
182 | - </entry> | |
183 | - </row> | |
184 | - <row> | |
185 | - <entry> | |
186 | - <para> | |
187 | - A utilização dos tipos primitivos é bastante simples. Veja no exemplo abaixo uma classe de configuração um arquivo | |
188 | - de configurações, que ilustram como é o procedimento para adicionar parâmetros do tipo primitivo. | |
189 | - </para> | |
190 | - <programlisting role="JAVA"><![CDATA[@Configuration | |
191 | - public class BookmarkConfig { | |
192 | - | |
193 | - private int pageSize; | |
194 | - | |
195 | - public String getPageSize() { | |
196 | - return pageSize; | |
197 | - } | |
198 | -}]]></programlisting> | |
199 | - | |
200 | - <para> | |
201 | - Para essa classe, o arquivo de propriedade correspondente (<emphasis>demoiselle.properties</emphasis>) deveria | |
202 | - apresentar o seguinte conteúdo: | |
203 | - </para> | |
204 | - <programlisting role="JAVA"><![CDATA[ | |
205 | -pageSize=10 | |
206 | -]]></programlisting> | |
207 | - <para> | |
208 | - Bastante simples, não? Mesmo assim, é bom ficarmos atentos, pois alguns cenários diferentes podem | |
209 | - acontecer. Vamos supor por exemplo que, por um motivo qualquer, a classe de configuração não esteja associada a um arquivo que contenha a chave de um de | |
210 | - seus parâmetros. Nesse caso será atribuido o valor padrão da linguagem ao atributo, que para os tipos primitivos | |
211 | - é 0, exceto para os tipos <emphasis>boolean</emphasis>, cujo valor padrão é <emphasis>false</emphasis>, e | |
212 | - <emphasis>char</emphasis>, cujo valor padrão é o caracter nulo (<emphasis>'\u0000'</emphasis>). | |
213 | - Outro cenário possível é a existência da chave, mas sem valor atribuído (<emphasis>pageSize=</emphasis>). Nesse | |
214 | - caso o valor encontrado no arquivo é equivalente a uma <emphasis>String</emphasis> vazia, e a exceção | |
215 | - <emphasis>ConfigurationException</emphasis>, cuja causa foi uma <emphasis>ConversionException</emphasis>, será | |
216 | - lançada. | |
217 | - </para> | |
218 | - </entry> | |
219 | - </row> | |
220 | - </tbody> | |
221 | - </tgroup> | |
222 | - </informaltable> | |
223 | - | |
224 | - <informaltable> | |
225 | - <tgroup cols="1"> | |
226 | - <colspec colwidth="100*" /> | |
227 | - <tbody> | |
228 | - <row> | |
229 | - <entry> | |
230 | - <emphasis role="bold">Wrappers</emphasis> | |
231 | - </entry> | |
232 | - </row> | |
233 | - <row> | |
234 | - <entry> | |
235 | - <para> | |
236 | - Os atributos do tipo <emphasis>wrapper</emphasis> devem ser utilizados da mesma forma que os atributos do tipo | |
237 | - primitivo. A única diferença entre eles é que o valor padrão atribuído a um parâmetro, no caso da classe de | |
238 | - configuração não estar associada a um arquivo que contenha sua chave, é nulo. | |
239 | - </para> | |
240 | - </entry> | |
241 | - </row> | |
242 | - </tbody> | |
243 | - </tgroup> | |
244 | - </informaltable> | |
245 | - | |
246 | - <informaltable> | |
247 | - <tgroup cols="1"> | |
248 | - <colspec colwidth="100*" /> | |
249 | - <tbody> | |
250 | - <row> | |
251 | - <entry> | |
252 | - <emphasis role="bold">Strings</emphasis> | |
253 | - </entry> | |
254 | - </row> | |
255 | - <row> | |
256 | - <entry> | |
257 | - <para> | |
258 | - Por sua vez, as configurações do tipo <emphasis>String</emphasis> tem funcionalidade bastante similar às | |
259 | - configurações do tipo Wrapper. A diferença fica por conta de que, ao deixar a chave sem valor atribuído, para | |
260 | - atributo desse tipo, não será lançada exceção, pois que não haverá o problema de conversão, e à configuração | |
261 | - será atribuido o valor de uma <emphasis>String</emphasis> vazia. | |
262 | - </para> | |
263 | - </entry> | |
264 | - </row> | |
265 | - </tbody> | |
266 | - </tgroup> | |
267 | - </informaltable> | |
268 | - | |
269 | - <informaltable> | |
270 | - <tgroup cols="1"> | |
271 | - <colspec colwidth="100*" /> | |
272 | - <tbody> | |
273 | - <row> | |
274 | - <entry> | |
275 | - <emphasis role="bold">Class</emphasis> | |
276 | - </entry> | |
277 | - </row> | |
278 | - <row> | |
279 | - <entry> | |
280 | - <para> | |
281 | - A partir da versão 2.4.0 é possível ter atributos do tipo <emphasis>Class</emphasis> como parâmetro. O atributo | |
282 | - pode ou não ser tipado, e no arquivo o valor atribuído à chave deve corresponder ao nome (<emphasis> | |
283 | - Canonical Name</emphasis>) de uma classe existente. Abaixo temos um exemplo de uma classe de configuração com | |
284 | - dois atributos do tipo <emphasis>Class</emphasis>, um tipado e outro não tipado: | |
285 | - </para> | |
286 | - <programlisting role="JAVA"><![CDATA[ | |
287 | -@Configuration | |
288 | -public class BookmarkConfig { | |
289 | - | |
290 | - private Class<MyClass> typedClass; | |
291 | - | |
292 | - private Class<?> untypedClass; | |
293 | - | |
294 | - public Class<MyClass> getTypedClass() { | |
295 | - return typedClass; | |
296 | - } | |
297 | - | |
298 | - public Class<?> getUntypedClass() { | |
299 | - return untypedClass; | |
300 | - } | |
301 | -} | |
302 | - ]]></programlisting> | |
303 | - <para>O arquivo de propriedades teria o seguinte conteúdo:</para> | |
304 | - <programlisting role="JAVA"><![CDATA[ | |
305 | -typedClass=package.MyClass | |
306 | -untypedClass=package.MyOtherClass | |
307 | - ]]></programlisting> | |
308 | - <para> | |
309 | - Caso uma chave de uma configuração do tipo <emphasis>Class</emphasis> não tenha valor atribuído ou seja | |
310 | - atribuído um nome de classe que não existe (ou não possa ser encontrada pela aplicação), no momento do | |
311 | - seu carregamento sera lançada uma exceção do tipo <emphasis>ConfigurationException</emphasis>, cuja causa é uma | |
312 | - <emphasis>ClassNotFoundException</emphasis>. Caso a classe de configuração não esteja associada a um | |
313 | - arquivo que contenha a chave de um de seus parâmetros do tipo <emphasis>Class</emphasis>, este será carregado | |
314 | - com valor nulo. | |
315 | - </para> | |
316 | - </entry> | |
317 | - </row> | |
318 | - </tbody> | |
319 | - </tgroup> | |
320 | - </informaltable> | |
321 | - | |
322 | - <informaltable> | |
323 | - <tgroup cols="1"> | |
324 | - <colspec colwidth="100*" /> | |
325 | - <tbody> | |
326 | - <row> | |
327 | - <entry> | |
328 | - <emphasis role="bold">Map</emphasis> | |
329 | - </entry> | |
330 | - </row> | |
331 | - <row> | |
332 | - <entry> | |
333 | - <para> | |
334 | - Para utilizar parâmetros do tipo <emphasis>Map</emphasis>, o arquivo de configurações deve usar a seguinte | |
335 | - estrutura na formação da chave: <emphasis>prefixo+nomedoatributo+chavedomap</emphasis>. Vejamos um exemplo. | |
336 | - Se temos em nossa aplicação uma classe de configuração como a mostrada abaixo: | |
337 | - </para> | |
338 | - <programlisting role="JAVA"><![CDATA[ | |
339 | -@Configuration | |
340 | -public class BookmarkConfig { | |
341 | - | |
342 | - private Map<String, String> connectionConfiguration; | |
343 | - | |
344 | - public Map<String, String> getConnectionConfiguration() { | |
345 | - return connectionConfiguration; | |
346 | - } | |
347 | -} | |
348 | - ]]></programlisting> | |
349 | - <para> | |
350 | - O arquivo de configuração deverá ser preenchido no seguinte formato (se for do tipo <emphasis>properties</emphasis>): | |
351 | - </para> | |
352 | - <programlisting role="PROPERTIES"><![CDATA[connectionConfiguration.ip=192.168.0.120 | |
353 | -connectionConfiguration.gateway=192.168.0.1 | |
354 | -connectionConfiguration.dns1=200.10.128.99 | |
355 | -connectionConfiguration.dns2=200.10.128.88]]></programlisting> | |
356 | - <para> | |
357 | - Dessa forma, ao fazer a chamada <emphasis>connectionConfiguration.get("gateway");</emphasis> por exemplo, o valor retornado será | |
358 | - <emphasis>192.168.0.1</emphasis>. | |
359 | - </para> | |
360 | - | |
361 | - <tip> | |
362 | - <para> | |
363 | - Você pode utilizar a chave do Map com nome "default" para indicar que, no arquivo de configuração, a chave é formada | |
364 | - apenas pela junção do prefixo com o atributo, sem utilizar a própria chave do Map. Por exemplo, se o seu arquivo de propriedades | |
365 | - contiver uma chave: | |
366 | - </para> | |
367 | - <programlisting role="JAVA"><![CDATA[prefix.myMap=Default Value]]></programlisting> | |
368 | - <para>então seu código poderá ter um comando:</para> | |
369 | - <programlisting role="JAVA"><![CDATA[String value = myMap.get("default");]]></programlisting> | |
370 | - <para>e o valor de <emphasis>value</emphasis> será <emphasis>"Default Value"</emphasis>.</para> | |
371 | - </tip> | |
372 | - <para> | |
373 | - Caso a classe de configuração não esteja associada a um arquivo que contenha a chave de um de seus parâmetros | |
374 | - do tipo <emphasis>Map</emphasis>, este será carregado com valor nulo, e estará sujeito às exceções | |
375 | - informadas anteriormente, conforme o tipo de variáveis que ele contenha. | |
376 | - </para> | |
377 | - </entry> | |
378 | - </row> | |
379 | - </tbody> | |
380 | - </tgroup> | |
381 | - </informaltable> | |
382 | - | |
383 | - <informaltable> | |
384 | - <tgroup cols="1"> | |
385 | - <colspec colwidth="100*" /> | |
386 | - <tbody> | |
387 | - <row> | |
388 | - <entry> | |
389 | - <emphasis role="bold">Array</emphasis> | |
390 | - </entry> | |
391 | - </row> | |
392 | - <row> | |
393 | - <entry> | |
394 | - <para> | |
395 | - No caso do <emphasis>Array</emphasis>, a principal diferença em relação às demais formas de declarar | |
396 | - configurações é a maneira de atribuir valores aos seus respectivos elementos no arquivo de configuração. | |
397 | - Por exemplo, para que um <emphasis>Array</emphasis> de inteiros, de nome <emphasis>integerArray</emphasis> | |
398 | - tenha o conteúdo <emphasis>{-1, 0, 1}</emphasis>, você deve criar um arquivo de propriedades que contenha | |
399 | - as seguintes linhas: | |
400 | - </para> | |
401 | - <programlisting role="JAVA"><![CDATA[ | |
402 | -integerArray=-1 | |
403 | -integerArray=0 | |
404 | -integerArray=1 | |
405 | - ]]></programlisting> | |
406 | - <para> | |
407 | - Exceto a forma de atribuir os valores às configurações, se comporta de acordo com o tipo de variável que ele | |
408 | - contém, conforme o espeficifcado para cada um. | |
409 | - </para> | |
410 | - </entry> | |
411 | - </row> | |
412 | - </tbody> | |
413 | - </tgroup> | |
414 | - </informaltable> | |
415 | - | |
416 | - <informaltable> | |
417 | - <tgroup cols="1"> | |
418 | - <colspec colwidth="100*" /> | |
419 | - <tbody> | |
420 | - <row> | |
421 | - <entry> | |
422 | - <emphasis role="bold">Enum</emphasis> | |
423 | - </entry> | |
424 | - </row> | |
425 | - <row> | |
426 | - <entry> | |
427 | - <para> | |
428 | - É possível criar uma lista de constantes do tipo <emphasis>Enum</emphasis> e carregar um valor de constante | |
429 | - através de um arquivo de configuração. Por exemplo, caso exista o seguinte <emphasis>Enum</emphasis> | |
430 | - </para> | |
431 | - | |
432 | - <programlisting role="JAVA"><![CDATA[public enum ConfigurationType { | |
433 | - | |
434 | - PROPERTIES , XML , SYSTEM; | |
435 | - | |
436 | -}]]></programlisting> | |
437 | - | |
438 | - <para>e ele seja usado no seguinte arquivo de configuração</para> | |
439 | - | |
440 | - <programlisting role="JAVA"><![CDATA[@Configuration | |
441 | -public class ConfigurationLoader { | |
442 | - | |
443 | - private ConfigurationType loadedConfigurationType; | |
444 | - | |
445 | - public ConfigurationType getLoadedConfigurationType(){ | |
446 | - return loadedConfigurationType; | |
447 | - } | |
448 | -}]]></programlisting> | |
449 | - | |
450 | - <para>O arquivo do tipo <emphasis>properties</emphasis> pode ser criado assim:</para> | |
451 | - | |
452 | - <programlisting role="PROPERTIES"><![CDATA[loadedConfigurationType=SYSTEM]]></programlisting> | |
453 | - | |
454 | - <note> | |
455 | - <para> | |
456 | - O valor definido no arquivo de configuração para atributos do tipo <emphasis>Enum</emphasis> deve | |
457 | - ser idêntico ao nome da constante definida no <emphasis>Enum</emphasis>, inclusive casando letras maiúsculas e | |
458 | - minúsculas. De fato, o valor da propriedade deve casar com o valor retornado no código: | |
459 | - <emphasis>Enum.name()</emphasis>. | |
460 | - </para> | |
461 | - | |
462 | - <para> | |
463 | - Caso o valor definido no arquivo de configuração não case com nenhuma constante definida no <emphasis>Enum</emphasis>, | |
464 | - uma exceção de tipo <emphasis>ConfigurationException</emphasis> de causa <emphasis>ConversionException</emphasis> | |
465 | - será lançada. Já se à propriedade for atribuido um valor vazio, o atributo do tipo <emphasis>Enum</emphasis> receberá | |
466 | - o valor <emphasis>null</emphasis>. | |
467 | - </para> | |
468 | - </note> | |
469 | - </entry> | |
470 | - </row> | |
471 | - </tbody> | |
472 | - </tgroup> | |
473 | - </informaltable> | |
474 | - | |
475 | - </section> | |
476 | - | |
477 | - <section> | |
478 | - <title>Mais Recursos</title> | |
479 | - <para> | |
480 | - Além das possibilidades relacionadas acima, existem ainda algumas anotações e recursos extras que o | |
481 | - <emphasis>Demoiselle Framework</emphasis> oferece para o desenvolvedor na utilização das configurações. A seguir | |
482 | - listamos e explicamos como utilizar esses recursos em sua aplicação. | |
483 | - </para> | |
484 | - | |
485 | - <informaltable> | |
486 | - <tgroup cols="1"> | |
487 | - <colspec colwidth="100*" /> | |
488 | - <tbody> | |
489 | - <row> | |
490 | - <entry> | |
491 | - <emphasis role="bold">Ignore</emphasis> | |
492 | - </entry> | |
493 | - </row> | |
494 | - <row> | |
495 | - <entry> | |
496 | - <para> | |
497 | - Por padrão, todos os atributos existentes em uma classe anotada com <literal>@Configuration</literal> são tratados | |
498 | - como parâmetros de configuração e serão automaticamente preenchidos durante a leitura do recurso. Porém, caso você | |
499 | - não queira que determinado atributo seja tratado como parâmetro dentro desse tipo de classe, basta anotá-lo com | |
500 | - a anotação <literal>@Ignore</literal>, que o atributo será ignorado (como indica a própria anotação) pelo carregador | |
501 | - de configurações. | |
502 | - </para> | |
503 | - </entry> | |
504 | - </row> | |
505 | - </tbody> | |
506 | - </tgroup> | |
507 | - </informaltable> | |
508 | - | |
509 | - <informaltable> | |
510 | - <tgroup cols="1"> | |
511 | - <colspec colwidth="100*" /> | |
512 | - <tbody> | |
513 | - <row> | |
514 | - <entry> | |
515 | - <emphasis role="bold">Valor Padrão</emphasis> | |
516 | - </entry> | |
517 | - </row> | |
518 | - <row> | |
519 | - <entry> | |
520 | - <para> | |
521 | - Muitas vezes é interessante que especifiquemos um valor padrão para o parâmetro, para o caso dele não estar | |
522 | - presente no arquivo de configuração. Para isso, basta atribuir o valor desejado no momento da declaração do | |
523 | - atributo, como exemplificado abaixo: | |
524 | - </para> | |
525 | - <programlisting role="JAVA"><![CDATA[@Configuration | |
526 | -public class BookmarkConfig { | |
527 | - | |
528 | - private String applicationTitle = "My App"; | |
529 | - | |
530 | - public String getApplicationTitle() { | |
531 | - return applicationTitle; | |
532 | - } | |
533 | -} ]]></programlisting> | |
534 | - <para> | |
535 | - Com essa atribuição, se no arquivo de propriedades não existir uma chave com valor <literal>applicationTitle</literal> | |
536 | - esse parametro será carregado com o valor <literal>My App</literal>. | |
537 | - </para> | |
538 | - </entry> | |
539 | - </row> | |
540 | - </tbody> | |
541 | - </tgroup> | |
542 | - </informaltable> | |
543 | - | |
544 | - <informaltable> | |
545 | - <tgroup cols="1"> | |
546 | - <colspec colwidth="100*" /> | |
547 | - <tbody> | |
548 | - <row> | |
549 | - <entry> | |
550 | - <emphasis role="bold">Bean Validation</emphasis> | |
551 | - </entry> | |
552 | - </row> | |
553 | - <row> | |
554 | - <entry> | |
555 | - <para> | |
556 | - Fazer validação mantém a integridade dos dados e pode ser fator importante na lógica da aplicação. A partir da | |
557 | - versão 2.4.0 o <emphasis>Demoiselle</emphasis> permite que os atributos das classes de configuração sejam | |
558 | - anotados com todas as anotações definidas pela JSR 303 (Bean Validation). Com esse recurso você pode exigir que | |
559 | - determinado parâmetro não seja nulo (<emphasis>@NotNull</emphasis>), limitar um valor máximo ou mínimo para ele | |
560 | - (<emphasis>@Max</emphasis> e <emphasis>@Min</emphasis>, respectivamente), dentre outras restrições (que podem | |
561 | - ser feitas simultâneamente). A lista completa das restrições que podem ser aplicadas nos atributos das classes | |
562 | - de configuração pode ser conferida aqui: | |
563 | - <ulink url="http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html"> | |
564 | - <literal>http://docs.oracle.com/javaee/6/tutorial/doc/gircz.html</literal></ulink>. | |
565 | - </para> | |
566 | - <para> | |
567 | - Para utilizar esse recurso você deve ter como dependência de seu projeto alguma implementação da especificação | |
568 | - Bean Validation. A implementação de referência é o | |
569 | - <ulink url="http://www.hibernate.org/subprojects/validator"><emphasis>Hibernate Validator</emphasis></ulink>. | |
570 | - </para> | |
571 | - </entry> | |
572 | - </row> | |
573 | - </tbody> | |
574 | - </tgroup> | |
575 | - </informaltable> | |
576 | - | |
577 | - <informaltable> | |
578 | - <tgroup cols="1"> | |
579 | - <colspec colwidth="100*" /> | |
580 | - <tbody> | |
581 | - <row> | |
582 | - <entry> | |
583 | - <emphasis role="bold">Name</emphasis> | |
584 | - </entry> | |
585 | - </row> | |
586 | - <row> | |
587 | - <entry> | |
588 | - <para> | |
589 | - Em alguns casos você pode querer que um determinado parâmetro tenha nomes diferentes na classe de configuração e | |
590 | - no arquivo de propriedades. Para isso você pode utilizar a anotação <emphasis>@Name</emphasis>. Basta anotar | |
591 | - o atributo passando como parâmetro o nome pelo qual você deseja que ele seja procurado no arquivo de propriedades, | |
592 | - como mostra o exemplo abaixo: | |
593 | - </para> | |
594 | - <programlisting role="JAVA"><![CDATA[@Configuration | |
595 | -public class BookmarkConfig { | |
596 | - | |
597 | - @Name("app.title") | |
598 | - private String applicationTitle; | |
599 | - | |
600 | - public String getApplicationTitle() { | |
601 | - return applicationTitle; | |
602 | - } | |
603 | -} ]]></programlisting> | |
604 | - <para> | |
605 | - Com essa anotação, ao invés de procurar pela chave <emphasis>applicationTitle</emphasis>, o | |
606 | - <emphasis>Demoiselle</emphasis> irá buscar pela chave <emphasis>app.title</emphasis>. | |
607 | - </para> | |
608 | - </entry> | |
609 | - </row> | |
610 | - </tbody> | |
611 | - </tgroup> | |
612 | - </informaltable> | |
613 | - | |
614 | - <informaltable> | |
615 | - <tgroup cols="1"> | |
616 | - <colspec colwidth="100*" /> | |
617 | - <tbody> | |
618 | - <row> | |
619 | - <entry> | |
620 | - <emphasis role="bold">Escopo</emphasis> | |
621 | - </entry> | |
622 | - </row> | |
623 | - <row> | |
624 | - <entry> | |
625 | - <para> | |
626 | - A partir da versão 2.3.3 do <emphasis>Demoiselle Framework</emphasis> as classes anotadas com | |
627 | - <emphasis>@Configuration</emphasis> estarão por padrão no escopo estático (<emphasis>@StaticScoped</emphasis>). | |
628 | - </para> | |
629 | - </entry> | |
630 | - </row> | |
631 | - </tbody> | |
632 | - </tgroup> | |
633 | - </informaltable> | |
634 | - | |
635 | - <informaltable> | |
636 | - <tgroup cols="1"> | |
637 | - <colspec colwidth="100*" /> | |
638 | - <tbody> | |
639 | - <row> | |
640 | - <entry> | |
641 | - <emphasis role="bold">Extratores</emphasis> | |
642 | - </entry> | |
643 | - </row> | |
644 | - <row> | |
645 | - <entry> | |
646 | - <para> | |
647 | - Você precisa de parâmetros de um tipo que ainda não é suportado pelo <emphasis>Demoiselle</emphasis>? Você | |
648 | - pode implementar sua própria classe extratora. A partir da versão 2.4.0 as aplicações | |
649 | - podem implementar a interface <emphasis>ConfigurationValueExtractor</emphasis>, e ter um | |
650 | - extrator de configurações para atributos de qualquer tipo. Essa interface obriga a classe | |
651 | - a implementar os métodos: <emphasis>boolean isSupported(Field field)</emphasis>, que retorna <literal>true</literal> | |
652 | - caso a classe seja extratora daquele tipo de campo, e | |
653 | - <emphasis>Object getValue(String prefix, String key, Field field, Configuration configuration) | |
654 | - throws Exception</emphasis> que deve extrair o valor do campo da forma correta. | |
655 | - </para> | |
656 | - </entry> | |
657 | - </row> | |
658 | - </tbody> | |
659 | - </tgroup> | |
660 | - </informaltable> | |
661 | - </section> | |
662 | -</chapter> |
documentation/reference/pt-BR/controlador.xml
... | ... | @@ -1,52 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ ]> | |
4 | -<chapter id="controlador"> | |
5 | - | |
6 | - <title>Controlador</title> | |
7 | - | |
8 | - <para> | |
9 | - No <emphasis>Demoiselle Framework</emphasis> os controladores ou controllers servem para identificar as camadas da | |
10 | - arquitetura de sua aplicação. É comum que as aplicações utilizem apenas três camadas: visão, negócio e persistência. | |
11 | - Existem aplicações que utilizam fachadas. Por esse motivo, foram implementados nessa versão do framework cinco controllers: | |
12 | - <itemizedlist> | |
13 | - <listitem><para><literal>ViewController</literal></para></listitem> | |
14 | - <listitem><para><literal>FacadeController</literal></para></listitem> | |
15 | - <listitem><para><literal>BusinessController</literal></para></listitem> | |
16 | - <listitem><para><literal>PersistenceController</literal></para></listitem> | |
17 | - <listitem><para><literal>ManagementController</literal></para></listitem> | |
18 | - </itemizedlist> | |
19 | - </para> | |
20 | - <!-- TODO: incluir exemplos de códigos usando os controladores citados acima --> | |
21 | - | |
22 | - <para> | |
23 | - Além de identificar as camadas, os controllers são pré-requisitos para utilização da funcionalidade de tratamento de exceções, | |
24 | - através do uso da anotação <literal>@ExceptionHandler</literal>. Isso quer dizer que para utilizar essa funcionalidade, a classe | |
25 | - precisa usar um dos controllers citados acima ou a própria anotação <literal>@Controller</literal>, ou ainda um controller criado | |
26 | - exclusivamente para sua aplicação. Todos os controllers criados no framework são estereótipos e podem ser usados também para | |
27 | - definição de características como, por exemplo, o escopo. Isso quer dizer que se um controller tem um determinado escopo, todas | |
28 | - as classes desse controller também terão o mesmo escopo. Foi falado que é possível criar um controller para uso exclusivo em sua | |
29 | - aplicação, mas como fazer isso? Veja na seção abaixo. | |
30 | - </para> | |
31 | - <!-- TODO: explicar o que é um "estereótipo" e qual o seu uso na aplicação --> | |
32 | - | |
33 | - <section> | |
34 | - <title>Como criar seu controlador</title> | |
35 | - <para> | |
36 | - É comum nos depararmos com situações onde precisamos criar controllers exclusivos com determinadas características ou | |
37 | - que sirvam apenas para determinar algum tipo de funcionalidade. Para criar um novo controller no Demoiselle, basta que ele | |
38 | - esteja anotado com <literal>@Controller</literal>, como no exemplo abaixo. | |
39 | - </para> | |
40 | - <programlisting role="JAVA"><![CDATA[@Controller | |
41 | -@Stereotype | |
42 | -@ViewScoped | |
43 | -public @interface SeuController { | |
44 | -}]]></programlisting> | |
45 | - <para> | |
46 | - Neste exemplo foi criado um controlador chamado <literal>SeuController</literal> que tem a característica de ter um escopo de | |
47 | - View. Isto quer dizer que toda classe que seja desse tipo de controlador também terá o escopo de View. | |
48 | - </para> | |
49 | - <!-- TODO: qual a vantagem em se criar um controlador customizado? incluir um exemplo possível e prático de utilização disso --> | |
50 | - </section> | |
51 | - | |
52 | -</chapter> |
documentation/reference/pt-BR/excecao.xml
... | ... | @@ -1,139 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="excecao"> | |
5 | - | |
6 | - <title>Exceções</title> | |
7 | - | |
8 | - <para> | |
9 | - Esta funcionalidade foi feita para você que acha muito verboso encher o código de <literal>try/catch</literal>. | |
10 | - E o que dizer de repetir o tratamento de exceções em vários métodos da mesma classe na base do copiar/colar? | |
11 | - Oferecemos a você uma alternativa para resolver estes problemas, mas você estará livre para usá-la: isoladamente, | |
12 | - misturando com a forma verbosa ou até mesmo não usá-la. | |
13 | - </para> | |
14 | - | |
15 | - <section> | |
16 | - <title>Configurando</title> | |
17 | - <para> | |
18 | - Para um correto funcionamento do Demoiselle é necessário inserir o interceptador de exceção no arquivo <filename>src/main/WEB-INF/beans.xml</filename>. | |
19 | - </para> | |
20 | - <programlisting role="XML"><![CDATA[<beans xmlns="http://java.sun.com/xml/ns/javaee" | |
21 | -xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
22 | -xsi:schemaLocation="http://java.sun.com/xml/ns/javaee | |
23 | - http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> | |
24 | - <interceptors> | |
25 | - <class>br.gov.frameworkdemoiselle.exception.ExceptionHandlerInterceptor</class> | |
26 | - </interceptors> | |
27 | -</beans>]]></programlisting> | |
28 | - </section> | |
29 | - | |
30 | - <section> | |
31 | - <title>Tratadores de exceção</title> | |
32 | - <para> | |
33 | - Para definir um tratador de exceção, basta anotar o método com <literal>@ExceptionHandler</literal>. | |
34 | - O tratamento de exceções só é possível em classes anotadas com <literal>@Controller</literal> ou os derivados | |
35 | - desta anotação. Para ver mais detalhes sobre controladores no Demoiselle, leia o capítulo <link linkend="controlador">Controladores</link>. | |
36 | - </para> | |
37 | - <programlisting role="JAVA"><![CDATA[@Controller | |
38 | -public class Simples { | |
39 | - | |
40 | - @ExceptionHandler | |
41 | - public void tratador(NullPointerException cause) { } | |
42 | - public void inserir() { } | |
43 | - public void alterar() { } | |
44 | - public void excluir() { } | |
45 | -}]]></programlisting> | |
46 | - <para> | |
47 | - Neste exemplo, qualquer exceção do tipo <literal>NullPointerException</literal> que ocorrer nos métodos | |
48 | - da classe <literal>Simples</literal> terá o tratamento delegado para o método <literal>tratador()</literal>. | |
49 | - Para as exceções não tratadas, o comportamento seguirá o padrão da linguagem. | |
50 | - </para> | |
51 | - </section> | |
52 | - | |
53 | - <section> | |
54 | - <title>Múltiplos tratadores</title> | |
55 | - <para> | |
56 | - Não se limite a apenas um tratador por classe, você pode ter vários. | |
57 | - </para> | |
58 | - <programlisting role="JAVA"><![CDATA[@Controller | |
59 | -public class Simples { | |
60 | - | |
61 | - @ExceptionHandler | |
62 | - public void tratador(NullPointerException cause) { } | |
63 | - @ExceptionHandler | |
64 | - public void tratador(AbacaxiException cause) { } | |
65 | - public void inserir() { } | |
66 | - public void alterar() { } | |
67 | - public void excluir() { } | |
68 | -}]]></programlisting> | |
69 | - <para> | |
70 | - Caso as exceções <literal>NullPointerException</literal> ou <literal>AbacaxiException</literal> ocorram | |
71 | - nos métodos da classe <literal>Simples</literal>, o tratamento será delegado para o seu tratador. | |
72 | - </para> | |
73 | - </section> | |
74 | - | |
75 | - <section> | |
76 | - <title>Misturando os dois mundos</title> | |
77 | - <para> | |
78 | - É possível que, em determindas situações no seu projeto, você precise misturar o tratamento sofisticado com a | |
79 | - tradicional forma verbosa. Como fazer isso? | |
80 | - </para> | |
81 | - <para> | |
82 | - Suponha que no método <literal>inserir()</literal> você precise dar um tratamento exclusivo para uma exceção. | |
83 | - Para isso, misture as duas abordagens para atingir o seu objetivo. | |
84 | - </para> | |
85 | - <programlisting role="JAVA"><![CDATA[@Controller | |
86 | -public class Simples { | |
87 | - | |
88 | - @ExceptionHandler | |
89 | - public void tratador(NullPointerException cause) { } | |
90 | - public void inserir() { | |
91 | - try { | |
92 | - // tenta algo | |
93 | - } catch (AbacaxiException cause ) { | |
94 | - // trata o problema | |
95 | - } | |
96 | - } | |
97 | - public void alterar() { } | |
98 | - public void excluir() { } | |
99 | -}]]></programlisting> | |
100 | - <para> | |
101 | - Neste caso a exceção <literal>AbacaxiException</literal> só será tratada no método <literal>inserir()</literal>. | |
102 | - </para> | |
103 | - </section> | |
104 | - | |
105 | - <section> | |
106 | - <title>Exceção de Aplicação</title> | |
107 | - <para> | |
108 | - Imagine que você precise informar que, caso um determinado tipo de exceção seja lançado através do seu método, a transação atual sofrerá um | |
109 | - <emphasis>rollback</emphasis>. Ou, então, que haja necessidade de informar o grau de severidade da exceção, de forma que uma camada de apresentação | |
110 | - específica a trate de forma diferenciada. Estas duas opções são possíveis através do uso da anotação <literal>@ApplicationException</literal>. | |
111 | - Utilize-a em suas exceções e informe os atributos <literal>rollback</literal> e <literal>severity</literal> para alcançar os objetivos acima. | |
112 | - </para> | |
113 | - <programlisting role="JAVA"><![CDATA[@ApplicationException(rollback=true, severity=SeverityType.INFO) | |
114 | -public class MinhaException extends Exception { | |
115 | -}]]></programlisting> | |
116 | - <para> | |
117 | - No exemplo citado acima, estamos informando que caso esta exceção seja lançada por um método anotado com <literal>@Transactional</literal>, este | |
118 | - método sofrerá um rollback. Ao mesmo tempo, sua camada de exibição apresentará uma mensagem automática para o usuário, conforme o nível de severidade. | |
119 | - O comportamento padrão para o <literal>rollback</literal> é realizar o rollback sempre que a exceção for lançada. | |
120 | - O grau de severidade padrão é informativo (<literal>INFO</literal>). | |
121 | - </para> | |
122 | - </section> | |
123 | - | |
124 | - <section> | |
125 | - <title>Tratamento Padrão</title> | |
126 | - <para> | |
127 | - As exceções lançadas a partir da camada de negócio, ou de persistência, não causam a interrupção de sua aplicação, muito menos apresentam a tela | |
128 | - padrão de erro do JSF ou de outra tecnologia de visão. Qualquer exceção lançada que chega até a camada de apresentação recebe um tratamento | |
129 | - especial. Inicialmente, ela é encapsulada de forma que possa ser exibida de forma elegante para o usuário. No caso do JSF, é utilizado o mecanismo | |
130 | - de Messages próprio desta tecnologia. | |
131 | - </para> | |
132 | - <para> | |
133 | - No caso do Vaadin, o tratamento é bem semelhante, contudo a exceção é tratada de forma que possa ser exibida adotando os mecanismos próprios da | |
134 | - tecnologia. No caso de exceções que não usam a anotação <literal>@ApplicationException</literal>, um <emphasis>rollback</emphasis> é realizado | |
135 | - de forma automática. Por último, sem o uso desta anotação, toda exceção é vista como tendo nível de gravidade igual a <literal>ERROR</literal>. | |
136 | - </para> | |
137 | - </section> | |
138 | - | |
139 | -</chapter> |
documentation/reference/pt-BR/gerenciamento.xml
... | ... | @@ -1,305 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="gerenciamento"> | |
5 | - | |
6 | - <title>Monitoração e Gerenciamento de Recursos</title> | |
7 | - | |
8 | - <section> | |
9 | - <title>Por que monitorar e gerenciar aplicações</title> | |
10 | - | |
11 | - <para>Ao implantar um sistema para produção, muitas vezes é necessário monitorar aspectos sobre o funcionamento desse sistema. Quanta memória | |
12 | - ele está utilizando? Qual o pico de MIPS utilizados? Quantas sessões estão autenticadas no momento?</para> | |
13 | - | |
14 | - <para>Além de monitorar um sistema, as vezes é necessário gerenciá-lo alterando aspectos de seu comportamento. Se o sistema está implantado em um | |
15 | - servidor alugado, talvez seja necessário ajustar o uso de MIPS para reduzir custos ou talvez deseje-se solicitar que o sistema limpe dados de sessão | |
16 | - de autenticação abandonados por usuários que desligaram suas estações sem efetuar "logoff".</para> | |
17 | - | |
18 | - <para>Para esse fim existem diversas tecnologias que permitem ao desenvolvedor expor aspectos monitoráveis e gerenciáves de seu sistema | |
19 | - para clientes de gerenciamento. Exemplos dessas tecnologias incluem o <emphasis>Simple Network Management Protocol</emphasis> (SNMP) e o | |
20 | - <emphasis>Java Management Extension</emphasis> (JMX).</para> | |
21 | - | |
22 | - <para>O <emphasis>Demoiselle Framework</emphasis> dispõe de uma série de ferramentas para nivelar | |
23 | - o conhecimento do desenvolvedor e facilitar o uso e integraçao de várias tecnologias de gerenciamento e | |
24 | - monitoração. Através de seu uso o desenvolvedor pode facilmente integrar tais tecnologias, despreocupando-se | |
25 | - com detalhes de implementação de cada uma delas.</para> | |
26 | - </section> | |
27 | - | |
28 | - <section> | |
29 | - <title>Introdução ao mecanismo</title> | |
30 | - | |
31 | - <para>Para expor aspectos monitoráveis da sua aplicação, o primeiro passo é criar uma interface contendo os atributos monitoráveis e as operações | |
32 | - de gerenciamento que serão expostas para clientes de gerenciamento. Isso é feito através de uma simples classe Java (<emphasis>ou POJO</emphasis>) | |
33 | - anotada com o estereótipo <code>@ManagementController</code>.</para> | |
34 | - | |
35 | - <programlisting role="JAVA"><![CDATA[ | |
36 | -@ManagementController | |
37 | -public class GerenciadorUsuarios]]></programlisting> | |
38 | - | |
39 | - <para>Essa anotação é suficiente para o mecanismo de gerenciamento descobrir sua classe e disponibilizá-la para ser monitorada e gerenciada.</para> | |
40 | - | |
41 | - <para>Contudo, a simples anotação acima não informa ao mecanismo quais aspectos da classe serão expostos. Por padrão, um <emphasis>Management Controller</emphasis> | |
42 | - não expõe nenhum aspecto seu. Para selecionar quais aspectos serão expostos usamos as anotações | |
43 | - <emphasis>@ManagedProperty</emphasis> e <emphasis>@ManagedOperation</emphasis>. Além disso outras anotações podem ser usadas para personalizar o funcionamento | |
44 | - de classes anotadas com <code>@ManagementController</code>.</para> | |
45 | - | |
46 | - <informaltable> | |
47 | - <tgroup cols="3" rowsep="1" colsep="1"> | |
48 | - <thead> | |
49 | - <row> | |
50 | - <entry>Anotação</entry> | |
51 | - <entry>Descrição</entry> | |
52 | - <entry>Atributos</entry> | |
53 | - </row> | |
54 | - </thead> | |
55 | - | |
56 | - <tbody> | |
57 | - <row valign="top"> | |
58 | - <entry> | |
59 | - <emphasis role="BOLD">@ManagedProperty</emphasis> | |
60 | - </entry> | |
61 | - | |
62 | - <entry> | |
63 | - <para>Marca um atributo na classe como uma propriedade gerenciada, significando que clientes externos podem ler e/ou escrever valores nesses atributos.</para> | |
64 | - <para>Um atributo marcado pode estar disponível para leitura e/ou escrita. Por padrão, o que determina a visibilidade de um atributo | |
65 | - marcado é a presença dos métodos <emphasis>getAtributo</emphasis> e <emphasis>setAtributo</emphasis>, respectivamente disponibilizando o atributo | |
66 | - para leitura e escrita.</para> | |
67 | - <para>Para sobrescrever esse comportamento existe na anotação <emphasis role="BOLD">@ManagedProperty</emphasis> o atributo <emphasis>accessLevel</emphasis>. | |
68 | - Com ele é possível criar um atributo apenas para leitura, mas que contenha um método <emphasis>set</emphasis>. O contrário também é possível.</para> | |
69 | - </entry> | |
70 | - | |
71 | - <entry> | |
72 | - <itemizedlist> | |
73 | - <listitem><emphasis role="BOLD">description</emphasis>: Um texto descritivo documentando o propósito da propriedade.</listitem> | |
74 | - <listitem><emphasis role="BOLD">accessLevel</emphasis>: Sobrescreve o nível padrão de acesso de uma propriedade. Os valores possíveis são | |
75 | - READ_ONLY, WRITE_ONLY e DEFAULT, que significa que a presença de métodos <emphasis>get</emphasis> e <emphasis>set</emphasis> vai determinar o nível de acesso.</listitem> | |
76 | - </itemizedlist> | |
77 | - </entry> | |
78 | - </row> | |
79 | - | |
80 | - <row valign="top"> | |
81 | - <entry> | |
82 | - <emphasis role="BOLD">@ManagedOperation</emphasis> | |
83 | - </entry> | |
84 | - | |
85 | - <entry> | |
86 | - <para>Marca um método da classe gerenciada como uma operação, o que significa que clientes externos podem invocar esse método remotamente.</para> | |
87 | - <para>Operações gerenciadas normalmente são criadas para executar intervenções em um sistema já em execução. Por exemplo, é possível criar uma | |
88 | - operação que, ao ser invocada, destrua todas as seções abertas no servidor e não utilizadas nos últimos 30 minutos.</para> | |
89 | - </entry> | |
90 | - | |
91 | - <entry> | |
92 | - <itemizedlist> | |
93 | - <listitem><emphasis role="BOLD">description</emphasis>: Um texto descritivo documentando o propósito da operação.</listitem> | |
94 | - <listitem><emphasis role="BOLD">type</emphasis>: Documenta o propósito da operação. <emphasis>ACTION</emphasis> informa que a operação modificará | |
95 | - o sistema de alguma forma. <emphasis>INFO</emphasis> diz que a operação coletará e retornará informações sobre o sistema. <emphasis>ACTION_INFO</emphasis> | |
96 | - informa que a operação modificará o sistema de alguma forma e retornará informações sobre o resultado. <emphasis>UNKNOWN</emphasis> é o padrão | |
97 | - e significa que o resultado da execução da operação é desconhecido.</listitem> | |
98 | - </itemizedlist> | |
99 | - </entry> | |
100 | - </row> | |
101 | - | |
102 | - <row valign="top"> | |
103 | - <entry> | |
104 | - <emphasis role="BOLD">@OperationParameter</emphasis> | |
105 | - </entry> | |
106 | - | |
107 | - <entry> | |
108 | - <para>Esta anotação opcional pode ser usada para cada parâmetro de um método anotado com <emphasis role="BOLD">@ManagedOperation</emphasis>.</para> | |
109 | - | |
110 | - <para>Ele permite detalhar melhor parâmetros em uma operação gerenciada. O efeito desta anotação é dependente da | |
111 | - tecnologia utilizada para comunicação entre cliente e servidor. Na maioria das tecnologias, essa anotação meramente permite ao cliente | |
112 | - exibir informações sobre cada parâmetro: nome, tipo e descrição.</para> | |
113 | - </entry> | |
114 | - | |
115 | - <entry> | |
116 | - <itemizedlist> | |
117 | - <listitem><emphasis role="BOLD">name</emphasis>: O nome do parâmetro quando exibido para clientes.</listitem> | |
118 | - <listitem><emphasis role="BOLD">description</emphasis>: Um texto descritivo documentando o propósito do parâmetro.</listitem> | |
119 | - </itemizedlist> | |
120 | - </entry> | |
121 | - </row> | |
122 | - </tbody> | |
123 | - </tgroup> | |
124 | - </informaltable> | |
125 | - | |
126 | - </section> | |
127 | - | |
128 | - | |
129 | - | |
130 | - <section> | |
131 | - <title>Expondo aspectos de sua aplicação para monitoração</title> | |
132 | - | |
133 | - <para>Uma vez que uma classe esteja anotada com <emphasis>@ManagementController</emphasis> e seus atributos e operações estejam expostos, a classe está pronta para | |
134 | - ser monitorada.</para> | |
135 | - | |
136 | - <para>Suponha que a aplicação deseje expor o número de usuários que efetuaram login. A operação de <emphasis>login</emphasis> será processada em | |
137 | - uma classe de negócio <emphasis>ControleAcesso</emphasis>. Vamos supor também que existe uma classe chamada <emphasis>MonitorLogin</emphasis> responsável | |
138 | - por expor o número de usuários que efetuaram login no sistema.</para> | |
139 | - | |
140 | - <programlisting role="JAVA"><![CDATA[ | |
141 | -@BusinessController | |
142 | -public class ControleAcesso{ | |
143 | - | |
144 | - @Inject | |
145 | - private MonitorLogin monitorLogin; | |
146 | - | |
147 | - public boolean efetuarLogin(String usuario , String senha){ | |
148 | - // codigo de login | |
149 | - monitorLogin.setContadorLogin( monitorLogin.getContadorLogin() + 1 ); | |
150 | - } | |
151 | -}]]></programlisting> | |
152 | - | |
153 | - <programlisting role="JAVA"><![CDATA[ | |
154 | -@ManagementController | |
155 | -public class MonitorLogin{ | |
156 | - | |
157 | - @ManagedProperty | |
158 | - private int contadorLogin; | |
159 | - | |
160 | - @ManagedOperation | |
161 | - public void setContadorLogin(int qtdUsuarioLogados){ | |
162 | - contadorLogin = qtdUsuarioLogados; | |
163 | - } | |
164 | - | |
165 | - @ManagedOperation | |
166 | - public int getContatorLogin(){ | |
167 | - return contadorLogin; | |
168 | - } | |
169 | -}]]></programlisting> | |
170 | - | |
171 | - <para>Como é possível ver, classes anotadas com <emphasis>@ManagementController</emphasis> podem ser injetadas em qualquer ponto do código. Valores definidos | |
172 | - para seus atributos retêm seu estado, então um cliente que acesse remotamente o sistema e monitore o valor do atributo <emphasis>contadorLogin</emphasis> verá | |
173 | - a quantidade de logins efetuados no momento da consulta.</para> | |
174 | - | |
175 | - <section> | |
176 | - <title>Enviando notificações da aplicação</title> | |
177 | - | |
178 | - <para> | |
179 | - É comum que aplicações monitoradas permaneçam em estado de espera - é função do cliente de monitoração acessar a aplicação e obter | |
180 | - as informações necessárias. No entanto existem casos onde é necessário que a aplicação comunique clientes de eventos ocorridos no sistema. Um exemplo é um monitor | |
181 | - de espaço em disco que envia um alerta quando esse espaço for menor que 20% do total. | |
182 | - </para> | |
183 | - | |
184 | - <para> | |
185 | - Para essa funcionalidade o <emphasis>Demoiselle Framework</emphasis> disponibiliza o utilitário <emphasis>NotificationManager</emphasis>, que | |
186 | - pode ser injetado em sua aplicação a qualquer momento para notificar clientes externos de eventos importantes. | |
187 | - </para> | |
188 | - | |
189 | - <para>Considere o exemplo abaixo:</para> | |
190 | - | |
191 | - <programlisting role="JAVA"><![CDATA[ | |
192 | -public class DiskWritter{ | |
193 | - | |
194 | - @Inject | |
195 | - private NotificationManager notificationManager; | |
196 | - | |
197 | - public void writeFile(byte[] data , File fileToWrite){ | |
198 | - // ... implementação da escrita de arquivo | |
199 | - | |
200 | - if (fileToWrite.getUsableSpace() / (float)fileToWrite.getTotalSpace() <= 0.2f){ | |
201 | - Notification notification = new DefaultNotification("O espaço disponível no disco é inferior a 20% do total"); | |
202 | - notificationManager.sendNotification( notification ); | |
203 | - } | |
204 | - } | |
205 | -}]]></programlisting> | |
206 | - | |
207 | - <para> | |
208 | - Como é possível ver no exemplo, o utilitário <emphasis>NotificationManager</emphasis> é usado para enviar notificações em decorrência | |
209 | - de eventos ocorridos na sua aplicação. O uso mais comum é notificar avisos ou problemas para que ações sejam tomadas, mas é possível também | |
210 | - usar essa técnica para tomar ações preventivas ou informativas - uma notificação que o backup noturno foi feito com sucesso por exemplo. | |
211 | - </para> | |
212 | - | |
213 | - <para> | |
214 | - A interface <emphasis>Notification</emphasis> é a base das notificações enviadas e possui apenas um método: | |
215 | - <emphasis>Object getMessage()</emphasis>. A API de monitoração não força o tipo específico da mensagem e usualmente essa mensagem | |
216 | - será uma <emphasis>String</emphasis> (como no exemplo acima), mas algumas extensões podem utilizar tipos específicos de mensagem | |
217 | - capazes de carregar mais informações. | |
218 | - </para> | |
219 | - | |
220 | - <para> | |
221 | - O <emphasis>demoiselle-core</emphasis> disponibiliza por padrão o tipo concreto de notificação <emphasis>DefaultNotification</emphasis> - uma | |
222 | - implementação direta da interface <emphasis>Notification</emphasis> que permite definir a mensagem a ser retornada por <emphasis>getMessage()</emphasis>. | |
223 | - Além disso o <emphasis>demoiselle-core</emphasis> disponibiliza o tipo especial de mensagem <emphasis>AttributeChangeMessage</emphasis>, que permite | |
224 | - especificar além do texto da mensagem enviada, dados sobre a mudança de valor de um atributo, como o nome do atributo alterado, o valor antigo e o novo. | |
225 | - </para> | |
226 | - <para> | |
227 | - Notificações contendo mensagens do tipo <emphasis>AttributeChangeMessage</emphasis> são automaticamente enviadas por padrão pelo framework quando um | |
228 | - agente de monitoração altera o valor de uma propriedade anotada com <emphasis>@ManagedProperty</emphasis>, mas você também pode enviar mensagens desse tipo | |
229 | - quando propriedades de sua aplicação são alteradas. Extensões e componentes compatíveis com a API de monitoração do <emphasis>Demoiselle Framework</emphasis> | |
230 | - (por exemplo, a extensão <emphasis>demoiselle-jmx</emphasis>) podem fornecer implementações específicas da interface <emphasis>Notification</emphasis> e | |
231 | - tipos especializados de mensagem. Consulte a documentação desses componentes para aprender sobre seus usos. | |
232 | - </para> | |
233 | - </section> | |
234 | - | |
235 | - </section> | |
236 | - | |
237 | - <section> | |
238 | - <title>Conectando um cliente de monitoração</title> | |
239 | - | |
240 | - <para>O <emphasis>demoiselle-core</emphasis> contém as funcionalidades necessárias para marcar aspectos monitoráveis de sua aplicação, | |
241 | - mas não conta com nenhum mecanismo para estabelecer uma conexão com um cliente de monitoração. Para isso utiliza-se extensões do framework.</para> | |
242 | - | |
243 | - <para>A extensão padrão do framework <emphasis>Demoiselle</emphasis> responsável pela tecnologia de monitoração é a <emphasis>demoiselle-jmx</emphasis>. | |
244 | - Essa extensão utiliza a especificação JMX (JSR 3) e permite registrar as classes marcadas para monitoração como <emphasis>MBeans</emphasis>. | |
245 | - Uma vez que as classes sejam registradas como <emphasis>MBeans</emphasis>, seus atributos e operações expostos para monitoração podem ser | |
246 | - acessados via JMX por um cliente adequado, como o <emphasis>JConsole</emphasis> que acompanha por padrão o JDK da Oracle.</para> | |
247 | - | |
248 | - <tip> | |
249 | - <para>Para acrescentar a extensão <emphasis>demoiselle-jmx</emphasis> em um projeto Maven, adicione a dependência abaixo no arquivo <emphasis>pom.xml</emphasis>.</para> | |
250 | - | |
251 | - <programlisting role="XML"><![CDATA[ | |
252 | -<dependency> | |
253 | - <groupId>br.gov.frameworkdemoiselle</groupId> | |
254 | - <artifactId>demoiselle-jmx</artifactId> | |
255 | - <scope>compile</scope> | |
256 | -</dependency>]]></programlisting> | |
257 | - </tip> | |
258 | - | |
259 | - <tip> | |
260 | - <para>A API de monitoração é compatível com o uso de múltiplas extensões simultãneas. Adicione em seu projeto a dependência às extensões desejadas e configure-as | |
261 | - individualmente, as classes monitoradas serão então expostas para todas as extensões escolhidas.</para> | |
262 | - </tip> | |
263 | - | |
264 | - <para>A figura <xref linkend="exemplo_jconsole" /> mostra como uma classe monitorada é exibida no <emphasis>JConsole</emphasis>.</para> | |
265 | - | |
266 | - <programlisting role="JAVA"><![CDATA[@ManagementController | |
267 | -public class HelloWorldManager { | |
268 | - | |
269 | - @Inject | |
270 | - private HelloWorld helloWorld; | |
271 | - | |
272 | - @ManagedOperation(type=OperationType.ACTION) | |
273 | - public void saySomething(String whatToSay){ | |
274 | - helloWorld.say(whatToSay); | |
275 | - } | |
276 | - | |
277 | -}]]></programlisting> | |
278 | - | |
279 | - <figure id="exemplo_jconsole"><title>JConsole acessando uma aplicação monitorada</title> | |
280 | - <mediaobject> | |
281 | - <imageobject> | |
282 | - <imagedata fileref="images/jmx-jconsole-example.png" width="90%" /> | |
283 | - </imageobject> | |
284 | - <textobject><phrase>JConsole acessando a aplicação <emphasis>Bookmark</emphasis></phrase></textobject> | |
285 | - </mediaobject> | |
286 | - </figure> | |
287 | - | |
288 | - <para> | |
289 | - É possível perceber os seguintes elementos nessa imagem: | |
290 | - <itemizedlist> | |
291 | - <listitem>Uma classe gerenciada <emphasis>HelloWorldManager</emphasis> com uma operação chamada <emphasis>saySomething</emphasis></listitem> | |
292 | - <listitem>Uma classe geradora de notificações <emphasis>NotificationBroadcaster</emphasis> responsável por converter as notificações para a API JMX</listitem> | |
293 | - </itemizedlist> | |
294 | - </para> | |
295 | - | |
296 | - <para> | |
297 | - Através do <emphasis>JConsole</emphasis> é possível invocar comandos e acessar atributos em todas as classes anotadas com <emphasis>@ManagementController</emphasis> | |
298 | - em aplicações que usam o <emphasis>demoiselle-jmx</emphasis>. Também é possível inscrever-se às notificações enviadas por <emphasis>NotificationBroadcaster</emphasis> | |
299 | - e receber todas as notificações enviadas pela aplicação. | |
300 | - </para> | |
301 | - | |
302 | - </section> | |
303 | - | |
304 | - | |
305 | -</chapter> | |
306 | 0 | \ No newline at end of file |
documentation/reference/pt-BR/images/jmx-jconsole-example.png
50.9 KB
documentation/reference/pt-BR/inicializacao.xml
... | ... | @@ -1,111 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="inicializacao"> | |
5 | - | |
6 | - <title>Inicialização</title> | |
7 | - | |
8 | - <section> | |
9 | - <title>Introdução ao mecanismo</title> | |
10 | - <para> | |
11 | - Uma aplicação qualquer, seja do tipo Web ou desktop, geralmente necessita efetuar determinadas tarefas durante a sua | |
12 | - inicialização e ou finalização. Eis alguns exemplos: abertura de conexão a um servidor de banco de dados, carregamento de | |
13 | - parâmetros de configuração a partir de arquivos externos e execução de scripts específicos. Ou seja, normalmente essas ações | |
14 | - são definidas como funções estruturais da aplicação. | |
15 | - </para> | |
16 | - <para> | |
17 | - Para que a execução dessas ações ocorra de forma concisa, faz-se necessário o uso de um mecanismo padronizado para inicialização | |
18 | - do ambiente. O <emphasis>Demoiselle Framework</emphasis> fornece esse mecanismo através da especificação CDI introduzindo duas | |
19 | - anotações: <literal>@Startup</literal> e <literal>@Shutdown</literal>. | |
20 | - </para> | |
21 | - </section> | |
22 | - | |
23 | - <section> | |
24 | - <title>Implementação na aplicação</title> | |
25 | - <para> | |
26 | - A fim de utilizar o mecanismo inerente do <emphasis>Demoiselle Framework</emphasis>, é preciso simplesmente anotar os métodos | |
27 | - contendo as instruções desejadas com <literal>@Startup</literal>, para a <emphasis>inicialização</emphasis>, ou | |
28 | - <literal>@Shutdown</literal>, para a <emphasis>finalização</emphasis>. | |
29 | - </para> | |
30 | - <tip> | |
31 | - <para> | |
32 | - O mecanismo de inicialização do <emphasis>Demoiselle Framework</emphasis> é independente da natureza da aplicação Java, isto é, | |
33 | - visa tanto aplicações do tipo Web quanto do tipo desktop (ex: Swing). | |
34 | - </para> | |
35 | - </tip> | |
36 | - <para> | |
37 | - As instruções contidas em um método anotado com <literal>@Startup</literal> serão executadas automaticamente quando a aplicação | |
38 | - Java for inicializada, seja ela hospedada em um contêiner Web ou executada através de um método <literal>main()</literal>. | |
39 | - Nenhum outro arquivo ou classe precisa ser definido. A anotação <literal>@Startup</literal> pode ser utilizada em conjunto com a anotação | |
40 | - <literal>@Priority</literal>, que recebe como parâmetro um número inteiro que serve para definir a prioridade de execução do respectivo | |
41 | - método, na existência de mais de um inicializador para a aplicação. | |
42 | - </para> | |
43 | - <para> | |
44 | - De maneira análoga, um método anotado com <literal>@Shutdown</literal> será executado no momento de finalização de uma aplicação, | |
45 | - obedecendo também à ordem de prioridade definida com a anotação <literal>@Priority</literal>. | |
46 | - </para> | |
47 | - <para> | |
48 | - Eis um exemplo de implementação de inicializador em uma aplicação: | |
49 | - </para> | |
50 | - <programlisting role="JAVA"><![CDATA[public class BookmarkInitializer { | |
51 | - | |
52 | - @Startup | |
53 | - @Priority(1) | |
54 | - public void initialize() { | |
55 | - ... | |
56 | - } | |
57 | - | |
58 | - @Shutdown | |
59 | - @Priority(5) | |
60 | - public void finalize() { | |
61 | - ... | |
62 | - } | |
63 | -}]]></programlisting> | |
64 | - <tip> | |
65 | - <para> | |
66 | - Para a definição de prioridade de execução de um método na inicialização ou finalização, podem ser | |
67 | - utilizadas as constantes <literal>MIN_PRIORITY</literal> ou <literal>MAX_PRIORITY</literal> presentes em | |
68 | - <literal>br.gov.frameworkdemoiselle.annotation.Priority</literal>. | |
69 | - </para> | |
70 | - </tip> | |
71 | - </section> | |
72 | - | |
73 | - <section> | |
74 | - <title>Um exemplo prático</title> | |
75 | - <para> | |
76 | - Eis um interessante caso de uso de inicialização e finalização: rodar um servidor de modo standalone em paralelo à | |
77 | - execução da aplicação principal. Eis o código referente a essa implementação: | |
78 | - </para> | |
79 | - <programlisting role="JAVA"><![CDATA[import br.gov.frameworkdemoiselle.lifecycle.Shutdown; | |
80 | -import br.gov.frameworkdemoiselle.lifecycle.Startup; | |
81 | - | |
82 | -import static br.gov.frameworkdemoiselle.annotation.Priority.MAX_PRIORITY; | |
83 | -import static br.gov.frameworkdemoiselle.annotation.Priority.MIN_PRIORITY; | |
84 | - | |
85 | -public class DatabaseServer { | |
86 | - | |
87 | - private final org.hsqldb.Server server; | |
88 | - | |
89 | - public DatabaseServer() { | |
90 | - server = new Server(); | |
91 | - server.setDatabaseName(0, "db"); | |
92 | - server.setDatabasePath(0, "database/db"); | |
93 | - server.setPort(9001); | |
94 | - server.setSilent(true); | |
95 | - } | |
96 | - | |
97 | - @Startup | |
98 | - @Priority(MAX_PRIORITY) | |
99 | - public void startup() { | |
100 | - server.start(); | |
101 | - } | |
102 | - | |
103 | - @Shutdown | |
104 | - @Priority (MIN_PRIORITY) | |
105 | - public void shutdown() { | |
106 | - server.stop(); | |
107 | - } | |
108 | -}]]></programlisting> | |
109 | - </section> | |
110 | - | |
111 | -</chapter> |
documentation/reference/pt-BR/instalacao.xml
... | ... | @@ -1,72 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE appendix PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<appendix id="instalacao"> | |
5 | - | |
6 | - <title>Instalação</title> | |
7 | - | |
8 | - <section> | |
9 | - <title>Pré-requisitos</title> | |
10 | - <informaltable> | |
11 | - <tgroup cols="3"> | |
12 | - <colspec colwidth="50*" /> | |
13 | - <colspec colwidth="10*" /> | |
14 | - <colspec colwidth="40*" /> | |
15 | - <tbody> | |
16 | - <row> | |
17 | - <entry> | |
18 | - <emphasis role="bold">Software</emphasis> | |
19 | - </entry> | |
20 | - <entry> | |
21 | - <emphasis role="bold">Versão</emphasis> | |
22 | - </entry> | |
23 | - <entry> | |
24 | - <emphasis role="bold">Site</emphasis> | |
25 | - </entry> | |
26 | - </row> | |
27 | - <row> | |
28 | - <entry>Java Development Kit (JDK)</entry> | |
29 | - <entry>6.0</entry> | |
30 | - <entry>http://openjdk.org/</entry> | |
31 | - </row> | |
32 | - <row> | |
33 | - <entry>Apache Maven</entry> | |
34 | - <entry>2.2</entry> | |
35 | - <entry>http://maven.apache.org/</entry> | |
36 | - </row> | |
37 | - <row> | |
38 | - <entry>Eclipse IDE</entry> | |
39 | - <entry>3.6</entry> | |
40 | - <entry>http://www.eclipse.org/</entry> | |
41 | - </row> | |
42 | - <row> | |
43 | - <entry>m2eclipse plugin</entry> | |
44 | - <entry>0.10</entry> | |
45 | - <entry>http://m2eclipse.sonatype.org/</entry> | |
46 | - </row> | |
47 | - <row> | |
48 | - <entry>JBoss Application Server</entry> | |
49 | - <entry>6.0</entry> | |
50 | - <entry>http://www.jboss.org/</entry> | |
51 | - </row> | |
52 | - </tbody> | |
53 | - </tgroup> | |
54 | - </informaltable> | |
55 | - </section> | |
56 | - | |
57 | - <section> | |
58 | - <title>Demoiselle Infra</title> | |
59 | - <para> | |
60 | - Para auxiliar no preparo do ambiente integrado de desenvolvimento utilizado na presente | |
61 | - documentação, recomenda-se a utilização dos pacotes de software fornecidos pelo projeto | |
62 | - <ulink url="http://demoiselle.sourceforge.net/infra/">Demoiselle Infra</ulink>. | |
63 | - </para> | |
64 | - <note> | |
65 | - <para> | |
66 | - Atualmente são disponibilizados pacotes exclusivamente para a plataforma <emphasis>GNU/Linux</emphasis> | |
67 | - e distribuições baseadas no <emphasis>Debian</emphasis>, tal como <emphasis>Ubuntu</emphasis>. | |
68 | - </para> | |
69 | - </note> | |
70 | - </section> | |
71 | - | |
72 | -</appendix> |
documentation/reference/pt-BR/intro.xml
... | ... | @@ -1,56 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="intro"> | |
5 | - | |
6 | - <title>Introdução</title> | |
7 | - | |
8 | - <section> | |
9 | - <title>O que é o Demoiselle?</title> | |
10 | - <para> | |
11 | - O <emphasis>Demoiselle Framework</emphasis> implementa o conceito de | |
12 | - <emphasis>framework integrador</emphasis>. | |
13 | - Seu objetivo é facilitar a construção de aplicações minimizando tempo dedicado à escolha e integração de frameworks | |
14 | - especialistas, o que resulta no aumento da produtividade e garante a manutenibilidade dos sistemas. Disponibiliza | |
15 | - mecanismos reusáveis voltados as funcionalidades mais comuns de uma aplicação (arquitetura, segurança, transação, | |
16 | - mensagem, configuração, tratamento de exceções, etc). | |
17 | - </para> | |
18 | - <para> | |
19 | - O nome <emphasis>Demoiselle</emphasis> | |
20 | - é uma homenagem à série de aeroplanos construídos por Santos Dummont entre 1907 e 1909. Também conhecido como | |
21 | - <emphasis>Libellule</emphasis>, as Demoiselles foram os melhores, menores e mais baratos aviões da sua época. Como | |
22 | - sua intenção era popularizar a aviação com fabricação em larga escala, o inventor disponibilizou os planos em revistas | |
23 | - técnicas para qualquer pessoa que se interessasse. | |
24 | - </para> | |
25 | - <para> | |
26 | - O <emphasis>Demoiselle Framework</emphasis> usa a mesma filosofia do <quote>Pai da Aviação</quote>, tendo sido | |
27 | - disponibilizado como software livre em abril de 2009, sob a licença livre LGPL version 3. Mais informações no portal | |
28 | - <ulink url="http://www.frameworkdemoiselle.gov.br">"www.frameworkdemoiselle.gov.br</ulink> | |
29 | - </para> | |
30 | - </section> | |
31 | - | |
32 | - <section> | |
33 | - <title>Sobre a versão 2</title> | |
34 | - <para> | |
35 | - O principal objetivo da versão 2 do | |
36 | - <emphasis>Demoiselle Framework</emphasis> | |
37 | - é a completa aderência à especificação | |
38 | - <ulink url="http://jcp.org/en/jsr/detail?id=316">JSR 316: Java Platform, Enterprise Edition 6</ulink>, ou simplesmente | |
39 | - <emphasis>Java EE 6</emphasis>. Para saber mais, recomendamos os links | |
40 | - <ulink url="http://www.oracle.com/technetwork/articles/javaee/javaee6overview-141808.html">Introducing the Java EE 6 Platform</ulink> | |
41 | - e | |
42 | - <ulink url="http://cleversonsacramento.wordpress.com/2010/08/15/as-novidades-da-jee-6/">As novidades da JEE 6</ulink>. | |
43 | - </para> | |
44 | - <para> | |
45 | - Esta documentação é referente às especificações da versão 2 cadastradas no | |
46 | - <ulink url="https://sourceforge.net/apps/mantisbt/demoiselle/changelog_page.php">tracker</ulink> | |
47 | - do Demoiselle, as quais foram publicamente discutidas no fórum | |
48 | - <ulink url="https://sourceforge.net/apps/phpbb/demoiselle/viewtopic.php?f=35&t=63&start=0">demoiselle-proposal</ulink>. | |
49 | - </para> | |
50 | - <para> | |
51 | - Os capítulos a seguir entram em detalhes sobre cada uma das principais funcionalidades do framework. Tenha uma | |
52 | - boa leitura! | |
53 | - </para> | |
54 | - </section> | |
55 | - | |
56 | -</chapter> |
documentation/reference/pt-BR/logger.xml
... | ... | @@ -1,27 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="logger"> | |
5 | - | |
6 | - <title>Logger</title> | |
7 | - | |
8 | - <para> | |
9 | - Uma API de logging é um recurso interessante para informar o usuário e o desenvolvedor sobre os erros, alertas, | |
10 | - resultados de operações, os recursos acessados e outras informações a respeito do sistema. Por esse motivo foi | |
11 | - implementada na versão 2.X do <emphasis>Demoiselle Framework</emphasis> uma fábrica de logger que fica no core | |
12 | - e visa permitir a injeção desse recurso baseado na classe <literal>org.slf4j.Logger</literal>. Veja abaixo como | |
13 | - usar o logger no <emphasis>Demoiselle</emphasis>: | |
14 | - </para> | |
15 | - | |
16 | - <programlisting role="JAVA"><![CDATA[public class MinhaClasse { | |
17 | - | |
18 | - @Inject | |
19 | - private Logger logger; | |
20 | - | |
21 | - public void meuMetodo() { | |
22 | - logger.debug("logando meu metodo"); | |
23 | - logger.warn("mensagem de alerta do meu metodo"); | |
24 | - } | |
25 | -}]]></programlisting> | |
26 | - | |
27 | -</chapter> |
documentation/reference/pt-BR/master.xml
... | ... | @@ -1,81 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<book lang="pt"> | |
5 | - | |
6 | - <xi:include href="bookinfo.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
7 | - | |
8 | - <preface> | |
9 | - <title>Sobre o Guia de Referência - versão &version;</title> | |
10 | - <para> | |
11 | - Este documento tem como objetivo ser um guia de referência destinado a todos | |
12 | - que desejem conhecer melhor o <emphasis>Framework Demoiselle &version;</emphasis> e | |
13 | - suas funcionalidades. | |
14 | - </para> | |
15 | - <note> | |
16 | - <para> | |
17 | - Esta documentação refere-se à versão &version; do <emphasis>Demoiselle Framework</emphasis> | |
18 | - e pode diferir significativamente das versões anteriores. | |
19 | - </para> | |
20 | - </note> | |
21 | - </preface> | |
22 | - | |
23 | - <toc /> | |
24 | - | |
25 | - <xi:include href="intro.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
26 | - <xi:include href="arquitetura.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
27 | - <xi:include href="parentsPom.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
28 | - <xi:include href="arquetipo.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
29 | - <xi:include href="controlador.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
30 | - <xi:include href="persistencia.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
31 | - <xi:include href="transacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
32 | - <xi:include href="excecao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
33 | - <xi:include href="configuracao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
34 | - <xi:include href="inicializacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
35 | - <xi:include href="mensagem.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
36 | - <xi:include href="bundle.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
37 | - <xi:include href="parametro.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
38 | - <xi:include href="logger.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
39 | - <xi:include href="templates.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
40 | - <xi:include href="security.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
41 | - <xi:include href="paginacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
42 | - <xi:include href="gerenciamento.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
43 | - <!-- | |
44 | - <xi:include href="properties.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> --> | |
45 | - | |
46 | - <!-- parte 1 --> | |
47 | - <!-- TODO: dividir melhor os capítulos em seções --> | |
48 | -<!-- | |
49 | - <part id="1"> | |
50 | - <title>Framework</title> | |
51 | - <xi:include href="intro.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
52 | - <xi:include href="arquitetura.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
53 | - <xi:include href="parentsPom.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
54 | - <xi:include href="arquetipo.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
55 | - <xi:include href="controlador.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
56 | - <xi:include href="transacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
57 | - <xi:include href="excecao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
58 | - <xi:include href="configuracao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
59 | - <xi:include href="inicializacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
60 | - <xi:include href="mensagem.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
61 | - <xi:include href="bundle.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
62 | - <xi:include href="parametro.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
63 | - <xi:include href="logger.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
64 | - <xi:include href="templates.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
65 | - <xi:include href="security.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
66 | - <xi:include href="paginacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
67 | - <xi:include href="properties.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
68 | - </part> | |
69 | ---> | |
70 | - | |
71 | - <!-- parte 2 --> | |
72 | -<!-- <part id="2">--> | |
73 | -<!-- <title>Componentes</title>--> | |
74 | -<!-- <xi:include href="validacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />--> | |
75 | -<!-- </part>--> | |
76 | - | |
77 | - <!-- apêndices --> | |
78 | - <xi:include href="instalacao.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
79 | - <xi:include href="properties.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> | |
80 | - | |
81 | -</book> |
documentation/reference/pt-BR/mensagem.xml
... | ... | @@ -1,439 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="mensagem"> | |
5 | - | |
6 | - <title>Tratamento de Mensagens</title> | |
7 | - | |
8 | - <section> | |
9 | - <title>Mensagens em uma aplicação</title> | |
10 | - <para> | |
11 | - Uma aplicação bem estruturada, seja na plataforma Web ou Desktop, deve exibir mensagens informativas, | |
12 | - de aviso, ou de erro para o usuário após efetuar determinadas tarefas. Por exemplo, após gravar um registro | |
13 | - no banco de dados, é aconselhável que a aplicação exiba uma mensagem informativa. Se alguma exceção | |
14 | - ocorreu, é preciso exibir uma mensagem de erro. Ou seja, a severidade da mensagem deve ser escolhida de | |
15 | - acordo com o resultado da execução. | |
16 | - </para> | |
17 | - <para> | |
18 | - Veja na tabela a seguir a definição de cada um dos níveis de severidade da mensagem em uma aplicação e | |
19 | - um exemplo de texto associado: | |
20 | - </para> | |
21 | - <table> | |
22 | - <title>Níveis de severidade em mensagens</title> | |
23 | - <tgroup cols="3"> | |
24 | - <colspec colwidth="15*"/> | |
25 | - <colspec colwidth="45*"/> | |
26 | - <colspec colwidth="40*"/> | |
27 | - <thead> | |
28 | - <row> | |
29 | - <entry><emphasis role="bold">Severidade</emphasis></entry> | |
30 | - <entry><emphasis role="bold">Utilização</emphasis></entry> | |
31 | - <entry><emphasis role="bold">Exemplo de texto</emphasis></entry> | |
32 | - </row> | |
33 | - </thead> | |
34 | - <tbody> | |
35 | - <row> | |
36 | - <entry>Informação</entry> | |
37 | - <entry> | |
38 | - <para> | |
39 | - Usada quando da ocorrência normal ou esperada no fluxo, com o objetivo de confirmar ao | |
40 | - usuário uma situação de sucesso. | |
41 | - </para> | |
42 | - </entry> | |
43 | - <entry><quote>Aluno incluído com sucesso.</quote></entry> | |
44 | - </row> | |
45 | - <row> | |
46 | - <entry>Aviso</entry> | |
47 | - <entry> | |
48 | - <para> | |
49 | - Usada quando uma regra de negócio ou validação qualquer da aplicação tenha desviado o | |
50 | - fluxo normal de execução. | |
51 | - </para> | |
52 | - </entry> | |
53 | - <entry><quote>A turma selecionada já está lotada. Matrícula do aluno não efetuada.</quote></entry> | |
54 | - </row> | |
55 | - <row> | |
56 | - <entry>Erro</entry> | |
57 | - <entry> | |
58 | - <para> | |
59 | - Reservado para o caso de uma situação anormal, tal como exceções provenientes de | |
60 | - ambiente (falha de conexão na rede, queda de um servidor de banco de dados, etc) | |
61 | - tenha impedido a execução. | |
62 | - </para> | |
63 | - </entry> | |
64 | - <entry><quote>Não foi possível efetuar a modificação do aluno.</quote></entry> | |
65 | - </row> | |
66 | - </tbody> | |
67 | - </tgroup> | |
68 | - </table> | |
69 | - <para> | |
70 | - Em uma aplicação construída usando-se arquitetura em camadas, as mensagens geralmente são originadas em | |
71 | - uma determinada camada e precisam ser transmitidas às demais até chegar ao usuário. Por exemplo, se ocorre | |
72 | - um erro de gravação no banco de dados, isto é, na camada de persistência, tal informação precisa ser | |
73 | - repassada às camadas subsequentes, ou seja, as camadas de negócio e posteriormente de controle e visão. | |
74 | - Este conceito é justamente chamado de <emphasis>tratamento de mensagens</emphasis>, o qual, ao lado do | |
75 | - tratamento de exceções, auxilia o fluxo de execuções em uma aplicação bem arquiteturada. Em resumo, é | |
76 | - preciso programar a troca de mensagens entre as diversas camadas de uma aplicação orientada a objetos. | |
77 | - </para> | |
78 | - <para> | |
79 | - Veremos na seção a seguir como o <emphasis>Demoiselle Framework</emphasis> pode ajudar o | |
80 | - desenvolvedor na tarefa de troca de mensagens em uma aplicação. | |
81 | - </para> | |
82 | - </section> | |
83 | - | |
84 | - <section> | |
85 | - <title>Introdução ao mecanismo</title> | |
86 | - <para> | |
87 | - Ortogonalmente às camadas verticais da aplicação (i.e., apresentação, negócio e persistência), a arquitetura | |
88 | - proposta pelo <emphasis>Demoiselle Framework</emphasis> fornece os contextos de transação, segurança e mensagem. | |
89 | - Este último é justamente responsável pela troca de mensagens entre as camadas. | |
90 | - </para> | |
91 | - <para> | |
92 | - Tecnicamente falando, o contexto de mensagens no <emphasis>Demoiselle Framework</emphasis> é representado pela | |
93 | - interface <literal>MessageContext</literal>. Esta interface contém métodos destinados a inclusão, recuperação e | |
94 | - limpeza de mensagens no contexto. | |
95 | - </para> | |
96 | - <para> | |
97 | - Para obter uma instância do contexto de mensagens, basta injetá-lo na classe: | |
98 | - </para> | |
99 | - <programlisting role="JAVA"><![CDATA[@Inject | |
100 | -private MessageContext messageContext;]]></programlisting> | |
101 | - <para> | |
102 | - A maneira mais simples de se inserir uma mensagem no contexto é invocando o método <function>add()</function> de | |
103 | - <literal>MessageContext</literal> passando como argumento o texto literal da mensagem: | |
104 | - </para> | |
105 | - <programlisting role="JAVA"><![CDATA[messageContext.add("Aluno inserido com sucesso.");]]></programlisting> | |
106 | - <para> | |
107 | - Opcionalmente, pode-se indicar a severidade da mensagem: | |
108 | - </para> | |
109 | - <programlisting role="JAVA"><![CDATA[messageContext.add("Deseja realmente excluir o aluno?", SeverityType.WARN);]]></programlisting> | |
110 | - <tip> | |
111 | - <para> | |
112 | - Quando a severidade não é informada (argumento de tipo <literal>SeverityType</literal>), será considerado | |
113 | - o nível informativo, isto é, <literal>INFO</literal>. | |
114 | - </para> | |
115 | - </tip> | |
116 | - <para> | |
117 | - Para a transmissão das mensagens no contexto é também fornecida a interface <literal>Message</literal>, a qual | |
118 | - permite com que os textos sejam obtidos de catálogos especializados, tais como arquivos de propriedades ou banco | |
119 | - de dados. Essa interface precisa ser implementada em uma classe customizada pelo desenvolvedor. | |
120 | - Sua estrutura é bem simples: | |
121 | - </para> | |
122 | - <programlisting role="JAVA"><![CDATA[public interface Message { | |
123 | - | |
124 | - String getText(); | |
125 | - SeverityType getSeverity(); | |
126 | -}]]></programlisting> | |
127 | - <para> | |
128 | - A classe <literal>DefaultMessage</literal> fornecida pelo <emphasis>Demoiselle Framework</emphasis> | |
129 | - é uma implementação da interface <literal>Message</literal> que faz uso dos arquivos de recurso da aplicação | |
130 | - para obtenção das descrições das mensagens. Especificamente utiliza o arquivo <filename>messages.properties</filename>. | |
131 | - </para> | |
132 | - <note> | |
133 | - <para> | |
134 | - A unidade básica de manipulação de mensagens no <emphasis>Demoiselle Framework</emphasis> | |
135 | - é a interface <literal>Message</literal>. Basta que ela seja implementada na aplicação para que o | |
136 | - contexto de mensagens possa manipulá-la. A classe <literal>DefaultMessage</literal> é oferecida | |
137 | - como implementação padrão dessa interface. | |
138 | - </para> | |
139 | - </note> | |
140 | - <para> | |
141 | - Para incluir uma mensagem no contexto usando o tipo <literal>Message</literal> é preciso invocar o método | |
142 | - <function>add()</function> de <literal>MessageContext</literal> passando o objeto como argumento. Eis um | |
143 | - exemplo disso utilizando a classe <literal>DefaultMessage</literal>: | |
144 | - </para> | |
145 | - <programlisting role="JAVA"><![CDATA[Message message = new DefaultMessage("Ocorreu um erro ao excluir o aluno!", SeverityType.ERROR); | |
146 | -messageContext.add(message);]]></programlisting> | |
147 | - <para> | |
148 | - A extensão para <emphasis>demoiselle-jsf</emphasis> | |
149 | - transfere automaticamente as mensagens incluídas no <literal>MessageContext</literal> | |
150 | - para o <literal>FacesContext</literal>. | |
151 | - </para> | |
152 | - <para> | |
153 | - O contexto de mensagens, representado pela interface <literal>MessageContext</literal>, é capaz de | |
154 | - armazenar diversas mensagens em uma mesma requisição. Ele não é restrito a aplicações do tipo Web, | |
155 | - isto é, pode ser usado também para aplicações do tipo desktop (i.e., Swing). | |
156 | - </para> | |
157 | - </section> | |
158 | - | |
159 | - <section> | |
160 | - <title>Parametrização das mensagens</title> | |
161 | - <para> | |
162 | - Um recurso importante no tratamento de mensagens de uma aplicação consiste na parametrização dos textos que | |
163 | - elas carregam. Isso é extremamente útil para indicar com detalhes uma situação específica, com o objetivo de | |
164 | - melhor informar o usuário. Por exemplo, ao invés de simplesmente exibir | |
165 | - <quote>Exclusão de disciplina não permitida</quote> é preferível mostrar o seguinte texto mais explicativo | |
166 | - <quote>Exclusão não permitida: disciplina está sendo usada pela turma 301</quote>. | |
167 | - Para efetuar essa parametrização, é preciso usar a formatação de textos padronizada pela classe | |
168 | - <ulink url="http://download.oracle.com/javase/6/docs/api/java/text/MessageFormat.html"> | |
169 | - <literal>java.text.MessageFormat</literal></ulink> da API do Java, que basicamente considera a notação de | |
170 | - chaves para os argumentos. | |
171 | - </para> | |
172 | - <para> | |
173 | - O <emphasis>Demoiselle Framework</emphasis> usa a <literal>MessageFormat</literal> para efetuar a | |
174 | - parametrização e formatação dos valores. Para usar essa funcionalidade, basta incluir as chaves na string | |
175 | - da mensagem e ao inseri-la no contexto especificar os parâmetros: | |
176 | - </para> | |
177 | - <programlisting role="JAVA"><![CDATA[Message message = new DefaultMessage("Aluno {0} inserido com sucesso"); | |
178 | -messageContext.add(message, aluno.getNome());]]></programlisting> | |
179 | - <para> | |
180 | - Eis um exemplo mais avançado do uso de parametrizações em mensagens: | |
181 | - </para> | |
182 | - <programlisting role="JAVA"><![CDATA[Message message = new DefaultMessage("As {1,time} do dia {1,date,short} houve {2} na turma {0}"); | |
183 | -messageContext.add(message, new Integer(502), new Date(), "falta de professor");]]></programlisting> | |
184 | - <para> | |
185 | - O resultado da execução deste código seria um texto como: | |
186 | - <quote>Às 13:45:05 do dia 03/01/11 houve falta do professor na turma 502</quote>. | |
187 | - Ou seja, os argumentos <literal>{0}</literal>, <literal>{1}</literal> e <literal>{2}</literal> | |
188 | - são substituídos por seus respectivos elementos na ordem em que são passados no método | |
189 | - <function>add()</function>, sendo que ainda podemos formatar esses valores. | |
190 | - </para> | |
191 | - <tip> | |
192 | - <para> | |
193 | - É possível passar mais de um parâmetro nas mensagens adicionadas no contexto, usando para isso a | |
194 | - sintaxe de formatação da classe <literal>java.text.MessageFormat</literal>. A ordem dos argumentos | |
195 | - passados no método <function>add()</function> reflete nos elementos substituídos na string. | |
196 | - </para> | |
197 | - </tip> | |
198 | - </section> | |
199 | - | |
200 | - <section> | |
201 | - <title>Internacionalização das mensagens</title> | |
202 | - <para> | |
203 | - A <literal>DefaultMessage</literal> oferece a funcionalidade de internacionalização da aplicação, ou seja, | |
204 | - a disponibilização dos textos em diversos idiomas. Numa aplicação do tipo Web, o mecanismo de internacionalização | |
205 | - faz com que as mensagens e textos sejam exibidos de acordo com o idioma selecionado pelo usuário na configuração | |
206 | - do navegador. | |
207 | - </para> | |
208 | - <para> | |
209 | - Como já foi citado anteriormente, a implementação <literal>DefaultMessage</literal> busca os textos das mensagens | |
210 | - no arquivo de recursos <filename>messages.properties</filename>, o qual possui entradas no conhecido formato | |
211 | - <literal>chave=valor</literal>. Todavia, para fazer uso desses textos, é preciso passar a chave da mensagem | |
212 | - desejada como argumento na invocação do construtor da classe. Este identificador precisa estar entre sinais de | |
213 | - chaves, tal como no exemplo a seguir: | |
214 | - </para> | |
215 | - <programlisting role="JAVA"><![CDATA[Message message = new DefaultMessage("{ALUNO_INSERIR_OK}"); | |
216 | -messageContext.add(message, aluno.getNome());]]></programlisting> | |
217 | - <para> | |
218 | - Ou seja, ao invés de usar a string literal, passamos o identificador da chave presente no arquivo de propriedades. | |
219 | - </para> | |
220 | - <note> | |
221 | - <para> | |
222 | - O símbolo de chaves <literal>{}</literal> na string do construtor da classe <literal>DefaultMessage</literal> | |
223 | - indica se o texto da mensagem será recuperado de um arquivo de recursos ou considerado o texto literal. | |
224 | - </para> | |
225 | - </note> | |
226 | - <para> | |
227 | - Eis um exemplo de conteúdo do arquivo <filename>messages.properties</filename> destinado a manter por padrão os | |
228 | - textos no idioma português brasileiro (i.e., <literal>pt-BR</literal>). Veja que ele contém a chave | |
229 | - <literal>ALUNO_INSERIR_OK</literal> usada no exemplo anterior: | |
230 | - </para> | |
231 | - <programlisting><![CDATA[ALUNO_INSERIR_OK=Aluno {0} inserido com sucesso | |
232 | -ALUNO_ALTERAR_OK=Aluno {0} alterado com sucesso | |
233 | -ALUNO_EXCLUIR_OK=Aluno {0} excluído com sucesso]]></programlisting> | |
234 | - <para> | |
235 | - A fim de prover internacionalização para o idioma inglês americano (i.e., <literal>en-US</literal>) no exemplo | |
236 | - em questão, eis o conteúdo do arquivo <filename>messages_en_US.properties</filename>: | |
237 | - </para> | |
238 | - <programlisting><![CDATA[ALUNO_INSERIR_OK=Student {0} was successfully added | |
239 | -ALUNO_ALTERAR_OK=Student {0} was successfully modified | |
240 | -ALUNO_EXCLUIR_OK=Student {0} was successfully removed]]></programlisting> | |
241 | - <para> | |
242 | - Similarmente, o arquivo <filename>messages_fr.properties</filename> se destina a prover as mensagens no idioma | |
243 | - francês (independente do país), contendo as linhas a seguir: | |
244 | - </para> | |
245 | - <programlisting><![CDATA[ALUNO_INSERIR_OK=L'étudiant {0} a été ajouté avec succès | |
246 | -ALUNO_ALTERAR_OK=L'étudiant {0} a été modifié avec succès | |
247 | -ALUNO_EXCLUIR_OK=L'étudiant {0} a été supprimé avec succès]]></programlisting> | |
248 | - <note> | |
249 | - <para> | |
250 | - As chaves das mensagens (ex: <literal>ALUNO_INSERIR_OK</literal>) devem ser as mesmas em todos os arquivos de | |
251 | - propriedades. São elas que identificam unicamente uma mensagem, que ao final do processo tem o seu texto | |
252 | - automaticamente traduzido para o idioma preferido do usuário. | |
253 | - </para> | |
254 | - </note> | |
255 | - <tip> | |
256 | - <para> | |
257 | - É possível ainda configurar de modo genérico o idioma, especificando apenas a língua. Por exemplo, ao invés de | |
258 | - inglês britânico (<literal>en_GB</literal>) e inglês americano (<literal>en_US</literal>), podemos simplesmente | |
259 | - definir o idioma inglês (<literal>en</literal>). Neste caso, o arquivo deverá ser o | |
260 | - <filename>messages_en.properties</filename>. | |
261 | - </para> | |
262 | - </tip> | |
263 | - <note> | |
264 | - <para> | |
265 | - Internamente o <emphasis>Demoiselle Framework</emphasis> usa a classe | |
266 | - <ulink url="http://download.oracle.com/javase/6/docs/api/java/util/Locale.html">java.util.Locale</ulink> | |
267 | - presente na API do Java para manipular os textos das mensages durante a internacionalização. | |
268 | - </para> | |
269 | - </note> | |
270 | - <note> | |
271 | - <para> | |
272 | - A seleção de idioma na internacionalização de uma aplicação consiste na definição de: | |
273 | - <itemizedlist> | |
274 | - <listitem>língua: códigos formados por duas letras em minúsculo listados na ISO-639 (ISO Language Code) - exemplos: pt, en, fr, es, de;</listitem> | |
275 | - <listitem>país: códigos formados por duas letras em maiúsculo listados na ISO-3166 (ISO Country Code) - exemplos: BR, PT, US, GB.</listitem> | |
276 | - </itemizedlist> | |
277 | - </para> | |
278 | - </note> | |
279 | - </section> | |
280 | - | |
281 | - <section> | |
282 | - <title>Destino das mensagens</title> | |
283 | - | |
284 | - <para> | |
285 | - O Framework Demoiselle permite configurar o destino das mensagens enviadas. Por padrão, mensagens enviadas em um ambiente SE (Swing por exemplo) | |
286 | - são exibidas como registros de log no console, já mensagens enviadas em um ambiente WEB usando JSF 2.0 são redirecionadas para a classe | |
287 | - <code>FacesContext</code>. Caso esse comportamento padrão não seja suficiente para você, é possível personalizar o mecanismo de redirecionamento | |
288 | - de mensagens, fazendo-o enviar as mensagens para um local de seu interesse. | |
289 | - </para> | |
290 | - | |
291 | - <para> | |
292 | - Para isso existe a interface <code>MessageAppender</code>. Para toda mensagem enviada, o Framework Demoiselle vai determinar a implementação | |
293 | - mais adequada de <code>MessageAppender</code> a utilizar e vai redirecionar qualquer mensagem para essa implementação. | |
294 | - </para> | |
295 | - | |
296 | - <programlisting role="JAVA">public interface MessageAppender extends Serializable { | |
297 | - | |
298 | - /** | |
299 | - * Method that must hold message in an appropriate way and in an appropriate local. | |
300 | - * Demoiselle holds a message in a Logger or in a FacesContext, depending on the project. | |
301 | - * | |
302 | - * @param message | |
303 | - * message to be stored. | |
304 | - */ | |
305 | - void append(Message message); | |
306 | -}</programlisting> | |
307 | - | |
308 | - <para> | |
309 | - Para criar seu próprio <code>MessageAppender</code>, implemente essa interface e anote-a com a anotação <code>@Priority</code> - o Framework | |
310 | - Demoiselle irá selecionar a implementação adequada paseada na maior prioridade. Não é necessário configurar mais nada, o Framework Demoiselle | |
311 | - selecionará a implementação automaticamente. Cabe-lhe então a tarefa de implementar o método <code>append(Message message)</code> para tratar | |
312 | - a mensagem da forma que melhor se adequar a seu projeto. | |
313 | - </para> | |
314 | - </section> | |
315 | - | |
316 | - <section> | |
317 | - <title>Exemplos de implementação</title> | |
318 | - <para> | |
319 | - A fim de auxiliar a manutenção das descrições das mensagens em uma aplicação diversas soluções podem ser escolhidas | |
320 | - pelos arquitetos e empregadas pelos desenvolvedores. Nesta seção serão mostradas duas sugestões para essa questão, | |
321 | - usando interfaces e enumeradores. | |
322 | - </para> | |
323 | - <para> | |
324 | - A vantagem em se utilizar ambas as soluções é que diversas mensagens relacionadas podem ser agrupadas, reduzindo assim | |
325 | - a quantidade de arquivos a serem mantidos e centralizando a configuração das mensagens. | |
326 | - </para> | |
327 | - <para> | |
328 | - Sendo assim, uma possível solução é criar uma interface destinada a armazenar todos os modelos de mensagens de | |
329 | - uma determinada severidade a ser usada na aplicação. Nesta interface são declarados campos do tipo <literal>Message</literal> | |
330 | - com o modificador <literal>final</literal> (implicitamente também será <literal>public</literal> e <literal>static</literal>). | |
331 | - Veja o exemplo de código para a interface <literal>InfoMessages</literal>: | |
332 | - </para> | |
333 | - <programlisting role="JAVA"><![CDATA[public interface InfoMessages { | |
334 | - | |
335 | - final Message BOOKMARK_DELETE_OK = new DefaultMessage("{BOOKMARK_DELETE_OK}"); | |
336 | - final Message BOOKMARK_INSERT_OK = new DefaultMessage("{BOOKMARK_INSERT_OK}"); | |
337 | - final Message BOOKMARK_UPDATE_OK = new DefaultMessage("{BOOKMARK_UPDATE_OK}"); | |
338 | -}]]></programlisting> | |
339 | - <para> | |
340 | - No exemplo em questão, o texto das mensagens será recuperado do arquivo de recursos <filename>messages.properties</filename> | |
341 | - presente no diretório <filename>/src/main/resources/</filename>. Eis o conteúdo desse arquivo: | |
342 | - </para> | |
343 | - <programlisting><![CDATA[BOOKMARK_DELETE_OK=Bookmark exclu\u00EDdo\: {0} | |
344 | -BOOKMARK_INSERT_OK=Bookmark inserido: {0} | |
345 | -BOOKMARK_UPDATE_OK=Bookmark atualizado: {0}]]></programlisting> | |
346 | - <tip> | |
347 | - <para> | |
348 | - Recomenda-se criar uma interface para cada tipo de severidade (ex: <literal>InfoMessages</literal>, | |
349 | - <literal>WarningMessages</literal>, <literal>ErrorMessages</literal> e <literal>FatalMessages</literal>), | |
350 | - agrupando nestas as mensagens usadas exclusivamente para o mesmo fim. | |
351 | - </para> | |
352 | - </tip> | |
353 | - <para> | |
354 | - Já a segunda abordagem consiste no uso de enumerações para centralizar os modelos de mensagem. | |
355 | - É utilizado o mesmo arquivo de recursos <filename>messages.properties</filename> ilustrado na abordagem anterior. | |
356 | - Porém, neste caso cada enumerador da enumeração corresponderá a uma chave no arquivo de propriedades. | |
357 | - </para> | |
358 | - <programlisting role="JAVA"><![CDATA[public enum InfoMessages implements Message { | |
359 | - | |
360 | - BOOKMARK_DELETE_OK, | |
361 | - BOOKMARK_INSERT_OK, | |
362 | - BOOKMARK_UPDATE_OK; | |
363 | - | |
364 | - private final DefaultMessage msg; | |
365 | - | |
366 | - private InfoMessages() { | |
367 | - msg = new DefaultMessage("{" + this.name() + "}"); | |
368 | - } | |
369 | - | |
370 | - @Override | |
371 | - public String getText() { | |
372 | - return msg.getText(); | |
373 | - } | |
374 | - | |
375 | - @Override | |
376 | - public SeverityType getSeverity() { | |
377 | - return msg.getSeverity(); | |
378 | - } | |
379 | -}]]></programlisting> | |
380 | - <para> | |
381 | - A fim de adicionar mensagens ao contexto, eis um exemplo de código que faz uso do artefato <literal>InfoMessages</literal>, | |
382 | - que funciona não importa qual abordagem escolhida (interface ou enumeração): | |
383 | - </para> | |
384 | - <programlistingco> | |
385 | - <areaspec> | |
386 | - <area id="inject-context" coords="5"/> | |
387 | - <areaset id="add-msg-context" coords=""> | |
388 | - <area id="" coords="9"/> | |
389 | - <area id="" coords="15"/> | |
390 | - <area id="" coords="21"/> | |
391 | - </areaset> | |
392 | - </areaspec> | |
393 | - <programlisting role="JAVA"><![CDATA[@BusinessController | |
394 | -public class BookmarkBC { | |
395 | - | |
396 | - @Inject | |
397 | - private MessageContext messageContext; | |
398 | - | |
399 | - public void insert(Bookmark bookmark) { | |
400 | - ... | |
401 | - messageContext.add(InfoMessages.BOOKMARK_INSERT_OK, | |
402 | - bookmark.getDescription()); | |
403 | - } | |
404 | - | |
405 | - public void update(Bookmark bookmark) { | |
406 | - ... | |
407 | - messageContext.add(InfoMessages.BOOKMARK_UPDATE_OK, | |
408 | - bookmark.getDescription()); | |
409 | - } | |
410 | - | |
411 | - public void delete(Bookmark bookmark) { | |
412 | - ... | |
413 | - messageContext.add(InfoMessages.BOOKMARK_DELETE_OK, | |
414 | - bookmark.getDescription()); | |
415 | - } | |
416 | -}]]></programlisting> | |
417 | - <calloutlist> | |
418 | - <callout arearefs="inject-context"> | |
419 | - <para> | |
420 | - No ponto contendo <literal>@Inject</literal> será injetado via CDI o contexto de mensagens | |
421 | - presente na aplicação, ou seja, uma instância da interface <literal>MessageContext</literal> | |
422 | - que poderá ser utilizada em qualquer método nessa classe. | |
423 | - </para> | |
424 | - </callout> | |
425 | - <callout arearefs="add-msg-context"> | |
426 | - <para> | |
427 | - Aqui os métodos <function>insert()</function>, <function>update()</function> e | |
428 | - <function>delete()</function> na classe <literal>BookmarkBC</literal> manipulam o | |
429 | - contexto de mensagens em cada invocação destes. | |
430 | - O método <function>add()</function> de <literal>MessageContext</literal> faz com que a | |
431 | - mensagem passada como parâmetro seja adicionada ao contexto, que ao final é exibida | |
432 | - para o usuário na camada de apresentação. | |
433 | - </para> | |
434 | - </callout> | |
435 | - </calloutlist> | |
436 | - </programlistingco> | |
437 | - </section> | |
438 | - | |
439 | -</chapter> |
documentation/reference/pt-BR/paginacao.xml
... | ... | @@ -1,319 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="paginacao"> | |
5 | - | |
6 | - <title>Paginação</title> | |
7 | - | |
8 | - <para> | |
9 | - Neste capítulo serão considerados os seguintes assuntos: | |
10 | - <itemizedlist> | |
11 | - <listitem><para>Motivação para o uso de um mecanismo padronizado para <emphasis>paginação</emphasis>;</para></listitem> | |
12 | - <listitem><para>Funcionamento e uso da estrutura <literal>Pagination</literal> e do contexto de paginação | |
13 | - (<literal>PaginationContext</literal>).</para></listitem> | |
14 | - </itemizedlist> | |
15 | - </para> | |
16 | - | |
17 | - <section> | |
18 | - <title>Introdução ao mecanismo</title> | |
19 | - <para> | |
20 | - A apresentação de conjuntos de registros de médio a grande porte em formato de tabelas em aplicações Web geralmente requer um | |
21 | - <emphasis>mecanismo de paginação</emphasis>, o qual permite ao cliente ver apenas um pedaço do resultado final, podendo este | |
22 | - navegar para frente e para trás através dos registros. A menos que o conjunto de registros seja garantidamente pequeno, qualquer | |
23 | - aplicação do tipo Web com funcionalidades de busca e/ou listagem de registros, precisa ser dotada de paginação. | |
24 | - </para> | |
25 | - <para> | |
26 | - O mecanismo de paginação para as aplicações fornecido pelo <emphasis>Demoiselle Framework</emphasis> consiste em um algoritmo | |
27 | - direcionado ao banco de dados (i.e., Database-Driven Pagination). Essa abordagem, apesar de requerer instruções SQL específicas | |
28 | - para obter porções determinadas de registros, é a mais utilizada por ser mais eficiente e produzir menos redundância de dados, | |
29 | - diminuindo assim tráfego de rede, consumo de memória e reduzindo o tempo de resposta. | |
30 | - </para> | |
31 | - <para> | |
32 | - É fornecido em tempo de execução um <emphasis>contexto de paginação</emphasis>, o qual tem escopo de sessão e armazena a informação | |
33 | - de paginação de cada entidade (i.e., bean) que necessite de tal mecanismo. Esse contexto é compartilhado entre as diversas camadas | |
34 | - da aplicação, especificamente entre as camadas de visão e persistência. Dessa maneira, a paginação dos dados é transparente para a | |
35 | - camada intermediária (i.e., negócio) e não interfere na modelagem das classes de um projeto. | |
36 | - </para> | |
37 | - </section> | |
38 | - | |
39 | - <section> | |
40 | - <title>Códigos de suporte</title> | |
41 | - <!-- | |
42 | - <para> | |
43 | - // TODO: explicar Pagination e PaginationContext | |
44 | - </para> | |
45 | - --> | |
46 | - <para> | |
47 | - O <emphasis>mecanismo de paginação</emphasis> do <emphasis>Demoiselle Framework</emphasis> permite que os parâmetros para a consulta | |
48 | - no banco sejam configurados de forma bastante prática. Por outro lado, a consulta paginada ao banco já é feita pela extensão | |
49 | - <literal>demoiselle-jpa</literal>. Dessa forma, basta ajustar os parâmetros da paginação, e pedir as consultas normalmente. | |
50 | - O resultado da consulta é então passado para algum componente de iteração de dados com suporte ao mecanismo conhecido como <emphasis>Lazy | |
51 | - Load</emphasis> (ou <emphasis>Lazy Loading</emphasis>). | |
52 | - </para> | |
53 | - <para> | |
54 | - Farão parte do código de suporte para paginação: | |
55 | - <itemizedlist> | |
56 | - <listitem> | |
57 | - <para> | |
58 | - A classe <literal>Pagination</literal>: usada para manipular a paginação dos dados resultantes, contendo os campos <literal>currentPage</literal> | |
59 | - (página atual, selecionada na camada de visão), <literal>pageSize</literal> (tamanho da página, a quantidade de registros que ela comportará) | |
60 | - e <literal>totalResults</literal> (a quantidade de resultados existentes na base de dados); | |
61 | - </para> | |
62 | - </listitem> | |
63 | - <listitem> | |
64 | - <para> | |
65 | - A classe <literal>PaginationContext</literal>: contexto usado para armazenar e fornecer estruturas do tipo <literal>Pagination</literal>; | |
66 | - </para> | |
67 | - </listitem> | |
68 | - <listitem> | |
69 | - <para> | |
70 | - A classe <literal>PaginationConfig</literal>: armazenador de configurações referentes à paginação. | |
71 | - </para> | |
72 | - </listitem> | |
73 | - </itemizedlist> | |
74 | - </para> | |
75 | - | |
76 | - <para>Códigos internos de suporte no Core:</para><programlisting role="JAVA"><![CDATA[public class Pagination { | |
77 | - | |
78 | - private int currentPage; | |
79 | - private int pageSize; | |
80 | - private Long totalResults; | |
81 | - private Integer totalPages; | |
82 | - // ... | |
83 | -} | |
84 | - | |
85 | -@SessionScoped | |
86 | -public class PaginationContext { | |
87 | - | |
88 | - private final Map<Class<?>, Pagination> map; | |
89 | - public Pagination getPagination(Class<?> clazz) { ... } | |
90 | - public Pagination getPagination(Class<?> clazz, boolean create) { ... } | |
91 | -} | |
92 | - | |
93 | -@Configuration | |
94 | -public class PaginationConfig { | |
95 | - | |
96 | - @Name("default_page_size") | |
97 | - private int defaultPageSize = 10; | |
98 | - | |
99 | - @Name("max_page_links") | |
100 | - private int maxPageLinks = 5; | |
101 | -}]]></programlisting> | |
102 | - | |
103 | - <para>Códigos internos de suporte em JPA:</para><programlisting role="JAVA"><![CDATA[public class JPACrud<T, I> implements Crud<T, I> { | |
104 | - | |
105 | - @Inject | |
106 | - private PaginationContext paginationContext; | |
107 | - // ... | |
108 | - | |
109 | - public List<T> findAll() { | |
110 | - | |
111 | - final String jpql = "select this from " + getBeanClass().getSimpleName() + " this"; | |
112 | - final Query query = getEntityManager().createQuery(jpql); | |
113 | - final Pagination pagination = paginationContext.getPagination(getBeanClass()); | |
114 | - | |
115 | - if (pagination != null) { | |
116 | - if (pagination.getTotalPages() == null) { | |
117 | - pagination.setTotalResults(this.countAll()); | |
118 | - } | |
119 | - query.setFirstResult(pagination.getFirstResult()); | |
120 | - query.setMaxResults(pagination.getPageSize()); | |
121 | - } | |
122 | - // ... | |
123 | - } | |
124 | -}]]></programlisting> | |
125 | - | |
126 | - <para>Códigos internos de suporte em JSF:</para><programlisting role="JAVA"><![CDATA[public abstract class AbstractListPageBean<T, I> extends AbstractPage implements ListPageBean<T, I> { | |
127 | - | |
128 | - @Inject | |
129 | - private PaginationContext paginationContext; | |
130 | - | |
131 | - @Inject | |
132 | - private PaginationConfig paginationConfig; | |
133 | - // ... | |
134 | - | |
135 | - public Pagination getPagination() { | |
136 | - return paginationContext.getPagination(getBeanClass(), true); | |
137 | - } | |
138 | - | |
139 | - public int getPageSize() { | |
140 | - return paginationConfig.getDefaultPageSize(); | |
141 | - } | |
142 | - | |
143 | - public int getMaxPageLinks() { | |
144 | - return paginationConfig.getMaxPageLinks(); | |
145 | - } | |
146 | -}]]></programlisting> | |
147 | - </section> | |
148 | - | |
149 | - <section> | |
150 | - <title>Implementação na aplicação</title> | |
151 | - <para> | |
152 | - Veremos nessa seção como implementar a paginação em uma aplicação Java. Para esse exmplo tomamos como base a aplicação de Bookmarks | |
153 | - fornecida pelo arquétipo <emphasis>JSF com JPA</emphasis> do <emphasis>Demoiselle Framework</emphasis> (para maiores detalhes | |
154 | - ver <link linkend="estrutura">Arquétipos</link>). Iremos utilizar o componente <literal>DataTable</literal> do <emphasis>PrimeFaces</emphasis>, | |
155 | - que oferece o mecanismo de <emphasis>Lazy Loading</emphasis> conhecido como <literal>LazyDataModel</literal>, muito útil para paginação | |
156 | - e classificação de dados. | |
157 | - </para> | |
158 | - <para> | |
159 | - Primeiro é preciso configurar um objeto <literal>LazyDataModel</literal> no construtor do <emphasis>Managed Bean</emphasis> | |
160 | - (<emphasis>BookmarkList</emphasis> nesse exemplo): instancia-lo e sobrescrever o método abstrado <literal>load</literal>, que recebe | |
161 | - vários argumentos. Esses argumentos são recuperados na página <literal>jsf</literal> que carrega a instância do objeto <literal>LazyDataModel</literal>. | |
162 | - </para> | |
163 | - <para> | |
164 | - Dentro do método <literal>load</literal> iremos pegar do contexto de paginação uma instância da implementação da interface <literal>Pagination</literal> | |
165 | - e ajustar alguns dos seus parâmetros para: indicar a partir de qual item a paginação deve iniciar, e o tamanho (quantidade de itens) de cada página. | |
166 | - Esses dados são usados no método <literal>findAll()</literal>, da classe <literal>JPACrud</literal> (extensão JPA), que utiliza o contexto de | |
167 | - paginação para pegar os parâmetros e fazer a consulta no banco buscando apenas os itens que estão dentro da página que o parâmetro | |
168 | - <literal>first</literal> indicar. O resultado é passado para a instancia do <literal>LazyDataModel</literal>, que é responsável por exibir | |
169 | - os dados de forma apropriada. | |
170 | - </para> | |
171 | - <para> | |
172 | - À classe <emphasis>BookmarkList</emphasis> devem ser adicionados os seguintes trechos de código: | |
173 | - </para><programlisting role="JAVA"><![CDATA[// ... | |
174 | -import java.util.Map; | |
175 | -import br.gov.frameworkdemoiselle.pagination.Pagination; | |
176 | -// ... | |
177 | - | |
178 | -public BookmarkListMB() { | |
179 | - | |
180 | - private LazyDataModel<Bookmark> lazyModel; | |
181 | - lazyModel = new LazyDataModel<Bookmark>() { | |
182 | - | |
183 | - @Override | |
184 | - public List<Bookmark> load (int first, int pageSize, String sortField, | |
185 | - SortOrder sortOrder, Map<String, String> filters){ | |
186 | - | |
187 | - Pagination pagination = getPagination(); | |
188 | - pagination.setPageSize(pageSize); | |
189 | - pagination.setFirstResult(first); | |
190 | - | |
191 | - List<Bookmark> itemsList = bc.findAll(); | |
192 | - | |
193 | - lazyModel.setRowCount(pagination.getTotalResults()); | |
194 | - | |
195 | - return itemsList; | |
196 | - } | |
197 | - }; | |
198 | - // ... | |
199 | - public LazyDataModel<Bookmark> getLazyModel() { | |
200 | - return lazyModel; | |
201 | - } | |
202 | - // ... | |
203 | -}]]></programlisting> | |
204 | - | |
205 | - <para> | |
206 | - No arquivo <literal>messages.properties</literal> adicione as linhas: | |
207 | - </para><programlisting role="JAVA"><![CDATA[page.first=0 | |
208 | -page.rows=4 | |
209 | -page.max.links=3]]></programlisting> | |
210 | - <para> | |
211 | - Na página JSF <literal>bookmark_list.xhtml</literal>, substitua a linha: | |
212 | - </para> | |
213 | - <programlisting role="JAVA"><![CDATA[<p:dataTable id="list" var="bean" value="#{bookmarkListMB.resultList}">]]></programlisting> | |
214 | - | |
215 | - <para> | |
216 | - por: | |
217 | - </para><programlisting role="JAVA"><![CDATA[<p:dataTable id="list" var="bean" | |
218 | -value="#{bookmarkListMB.lazyModel}" lazy="true" paginator="true" | |
219 | -first="#{messages['page.first']}" rows="#{messages['page.rows']}" | |
220 | -pageLinks="#{messages['page.max.links']}">]]></programlisting> | |
221 | - | |
222 | - <para> | |
223 | - Com essas alterações simples, a aplicação Bookmarks passa a utilizar o mecanismo de paginação oferecido pelo <emphasis>Demoiselle Framework</emphasis>. | |
224 | - </para> | |
225 | - | |
226 | - <tip> | |
227 | - <para> | |
228 | - O método <literal>getPagination()</literal> do contexto <literal>PaginationContext</literal> é sobrecarregado, podendo aceitar | |
229 | - os seguintes argumentos: <literal>Class</literal> ou <literal>Class</literal> e <literal>boolean</literal>. | |
230 | - </para> | |
231 | - </tip> | |
232 | - <note> | |
233 | - <para> | |
234 | - A JPA 2.0, através da Query API, suporta controle de paginação independente de fornecedor de banco de dados. | |
235 | - Para controlar a paginação, a interface <literal>Query</literal> define os métodos <literal>setFirstResult()</literal> e | |
236 | - <literal>setMaxResults()</literal> para especificar o primeiro resultado a ser recebido e o número máximo de resultados a | |
237 | - serem retornados em relação àquele ponto. Internamente, são usadas instruções específicas do SGBD (ex: LIMIT e OFFSET no | |
238 | - PostgreSQL). | |
239 | - </para> | |
240 | - </note> | |
241 | - </section> | |
242 | - | |
243 | -</chapter> | |
244 | - | |
245 | -<!--<section> | |
246 | - <title>Um exemplo usando PrimeFaces</title> | |
247 | - <para> | |
248 | - Eis um interessante caso de uso de paginação: ????. | |
249 | - A seguir o código referente a essa implementação: | |
250 | -// camada de persistência | |
251 | - </para> | |
252 | - <programlisting role="JAVA"><![CDATA[@PersistenceController | |
253 | -public class AuditDAO extends JPACrud<Audit, Long> { | |
254 | -} | |
255 | -]]></programlisting> | |
256 | - <para> | |
257 | - ... | |
258 | -// camada de negócio | |
259 | - </para> | |
260 | - <programlisting role="JAVA"><![CDATA[@BusinessController | |
261 | -public class AuditBC extends DelegateCrud<Audit, Long, AuditDAO> { | |
262 | -} | |
263 | -]]></programlisting> | |
264 | - <para> | |
265 | - ... | |
266 | -// camada de visão | |
267 | - </para> | |
268 | - <programlisting role="JAVA"><![CDATA[import org.primefaces.model.LazyDataModel; | |
269 | -... | |
270 | - | |
271 | -@ViewController | |
272 | -public class AuditMB extends AbstractListPageBean<Audit, Long> { | |
273 | - | |
274 | - @Inject | |
275 | - private IAuditBC bc; | |
276 | - | |
277 | - private LazyDataModel<Audit> lazyModel; | |
278 | - | |
279 | - public AuditMB() { | |
280 | - lazyModel = new LazyDataModel<Audit>() { | |
281 | - | |
282 | - public List<Audit> load(int first, int pageSize, String sortField, | |
283 | - boolean sortOrder, Map<String, String> filters) { | |
284 | - | |
285 | - Pagination pagination = getPagination(); | |
286 | - pagination.setFirstResult(first); | |
287 | - pagination.setPageSize(pageSize); | |
288 | - | |
289 | - return bc.findAll(); | |
290 | - } | |
291 | - }; | |
292 | - } | |
293 | - | |
294 | - public LazyDataModel<Audit> getLazyModel() { | |
295 | - return lazyModel; | |
296 | - } | |
297 | - | |
298 | -}]]></programlisting> | |
299 | - <para> | |
300 | - ??? exemplo de uso de paginação em tabela com a implementação PrimeFaces: | |
301 | - </para> | |
302 | - <programlisting role="XML"><![CDATA[<p:dataTable id="list" height="300" var="bean" | |
303 | - value="#{auditMB.lazyModel}" lazy="true" paginator="true" | |
304 | - rows="#{auditMB.pageSize}" pageLinks="#{auditMB.maxPageLinks}">]]></programlisting> | |
305 | - </section> | |
306 | - --> | |
307 | -<!-- | |
308 | - <section> | |
309 | - <title>Referências</title> | |
310 | - <itemizedlist> | |
311 | - <listitem>JPA 2.0 [JSR-317] (http://jcp.org/en/jsr/detail?id=317)</listitem> | |
312 | - <listitem>Implementing Search Result Pagination in a Web Application (http://www.developer.com/java/other/article.php/3696226/)</listitem> | |
313 | - <listitem>A Pagination Technique Using Spring (http://www.developer.com/java/web/article.php/10935_3830886_1/)</listitem> | |
314 | - <listitem>Spring JDBC Pagination Tutorial (http://www.codefutures.com/tutorials/spring-pagination/)</listitem> | |
315 | - <listitem>PrimeFaces DataTable - Lazy Loading (http://www.primefaces.org/showcase/ui/datatableLazy.jsf)</listitem> | |
316 | - </itemizedlist> | |
317 | - </section> | |
318 | - --> | |
319 | - |
documentation/reference/pt-BR/parametro.xml
... | ... | @@ -1,90 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="parametro"> | |
5 | - | |
6 | - <title>Parâmetro</title> | |
7 | - | |
8 | - <para> | |
9 | - É muito comum em uma aplicação web haver a necessidade de passar parâmetros através da URL. A passagem de | |
10 | - parâmetros até que é algo fácil e tranquilo de fazer. O chato é a captura do parâmetro dentro do Page Bean, | |
11 | - pois toda vez que quisermos fazê-lo, temos que acessar o <literal>FacesContext</literal>, para a partir daí | |
12 | - pegar o <literal>HttpServletRequest</literal> e depois recuperar o valor passado. | |
13 | - Veja abaixo como ficaria o código. | |
14 | - </para> | |
15 | - <para> | |
16 | - Passagem do parâmetro: | |
17 | - </para> | |
18 | - <programlisting><![CDATA[http://localhost:8080/aplicacao/pagina.jsf?parametro=valorParametro]]></programlisting> | |
19 | - <para> | |
20 | - Captura do parâmetro pelo Page Bean | |
21 | - </para> | |
22 | - <programlisting role="JAVA"><![CDATA[public class Classe { | |
23 | - | |
24 | - public void metodo() { | |
25 | - FacesContext context = FacesContext.getCurrentInstance(); | |
26 | - HttpServletRequest req = (HttpServletRequest) context.getExternalContext().getRequest(); | |
27 | - String param = req.getParameter("parametro"); | |
28 | - } | |
29 | -}]]></programlisting> | |
30 | - | |
31 | - <section> | |
32 | - <title> | |
33 | - Passagem de parâmetros | |
34 | - </title> | |
35 | - <para> | |
36 | - Visando facilitar essa recuperação do parâmetro passado através da URL, foi disponibilizada na versão 2.X do | |
37 | - <emphasis>Demoiselle Framework</emphasis> uma funcionalidade através da interface <literal>Parameter</literal> | |
38 | - e de sua implementação <literal>ParameterImpl</literal>, que permite capturar esse valor através do uso de | |
39 | - injeção. Para isso, basta criar no seu Page Bean um objeto do tipo | |
40 | - <literal>br.gov.frameworkdemoiselle.util.Parameter</literal> e anotá-lo com <literal>@Inject</literal>. | |
41 | - O nome desse objeto é o nome que será usado para buscar o valor do parâmetro. Caso o usuário queira dar um | |
42 | - nome diferente ao objeto, ele pode anotá-lo com <literal>@Name</literal> e no valor dessa anotação, colocar o | |
43 | - nome do parâmetro. Por default o objeto criado tem o escopo de request, mas é possível usar o escopo de sessão | |
44 | - ou de visão, bastando anotar o objeto com <literal>@SessionScoped</literal> ou <literal>@ViewScoped</literal>, | |
45 | - respectivamente. Veja abaixo como ficaria essa passagem de parâmetros na versão 2.X do Demoiselle. | |
46 | - </para> | |
47 | - <para> | |
48 | - Passagem do parâmetro: | |
49 | - </para> | |
50 | - <programlisting><![CDATA[http://localhost:8080/aplicacao/pagina.jsf?parametro=1 | |
51 | -http://localhost:8080/aplicacao/pagina.jsf?parametroString=valorParametroString]]></programlisting> | |
52 | - <para> | |
53 | - Captura do parâmetro pelo Page Bean: | |
54 | - </para> | |
55 | - <programlisting role="JAVA"><![CDATA[public class Classe { | |
56 | - | |
57 | - @ViewScoped | |
58 | - @Inject | |
59 | - private Parameter<Long> parametro; | |
60 | - | |
61 | - @Name("parametroString") | |
62 | - @SessionScoped | |
63 | - @Inject | |
64 | - private Parameter<String> objetoComNomeDiferenteDoParametro; | |
65 | -}]]></programlisting> | |
66 | - </section> | |
67 | - | |
68 | - <section> | |
69 | - <title>As classes de parâmetro</title> | |
70 | - <para> | |
71 | - A interface <literal>Parameter</literal> e sua implementação <literal>ParameterImpl</literal> disponibilizam | |
72 | - alguns métodos, como <function>setValue(T value)</function>, <function>getKey()</function>, | |
73 | - <function>getValue()</function> e <function>getConverter()</function>, que servem respectivamente para atribuir o | |
74 | - valor do objeto, capturar o nome do parâmetro passado na URL, recuperar o valor passado para aquele parâmetro | |
75 | - e capturar o conversor de tipo utilizado. Logo, para usar o valor daquele objeto, basta utilizar o método | |
76 | - <function>getValue()</function>, tal como mostrado a seguir: | |
77 | - </para> | |
78 | - <programlisting role="JAVA"><![CDATA[public class Classe { | |
79 | - | |
80 | - @ViewScoped | |
81 | - @Inject | |
82 | - private Parameter<Long> parametro; | |
83 | - | |
84 | - public void metodo() { | |
85 | - System.out.println("Valor do parametro: " + parametro.getValue()); | |
86 | - } | |
87 | -}]]></programlisting> | |
88 | - </section> | |
89 | - | |
90 | -</chapter> |
documentation/reference/pt-BR/persistencia.xml
... | ... | @@ -1,430 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="persistencia"> | |
5 | - | |
6 | - <title>Persistência</title> | |
7 | - | |
8 | - <para> | |
9 | - Persistência é um dos aspectos mais importantes de sistemas corporativos - grande parte desses sistemas devem | |
10 | - em algum ponto persistir informações em um sistema gerenciador de banco de dados. A tecnologia Java conta | |
11 | - hoje com algumas formas de facilitar o acesso a SGBD's - algumas são especificações Java como o JDBC | |
12 | - e o JPA, outras são tecnologias desenvolvidas por terceiros como o Hibernate. | |
13 | - </para> | |
14 | - | |
15 | - <para> | |
16 | - O Framework Demoiselle facilita o acesso e a configuração a algumas dessas tecnologias fornecendo produtores | |
17 | - padrão para seus pontos de entrada e centralizando a configuração. Tudo que o desenvolvedor deve fazer | |
18 | - é apenas injetar o recurso adequado em seu código e o Framework Demoiselle se encarregará de | |
19 | - produzi-lo e configurá-lo. | |
20 | - </para> | |
21 | - | |
22 | - <section> | |
23 | - <title>JPA</title> | |
24 | - | |
25 | - <para> | |
26 | - O Framework Demoiselle fornece um produtor padrão para contextos de persistência da JPA. Esse produtor lê o arquivo | |
27 | - de configuração <code>persistence.xml</code> de seu projeto e toma as providências necessárias para fabricar uma instância | |
28 | - da classe <code>EntityManager</code> que pode ser usada para gerenciar as entidades de sua aplicação. Além disso, instâncias | |
29 | - de <code>EntityManager</code> produzidas pelo Framework Demoiselle participam automaticamente de transações abertas através da | |
30 | - anotação <code>@Transactional</code>, conforme apresentado no capítulo sobre <link linkend="transacao">Transações</link>. | |
31 | - </para> | |
32 | - | |
33 | - <tip> | |
34 | - <para> | |
35 | - Para acrescentar a dependência à extensão <literal>demoiselle-jpa</literal>, adicione esse código | |
36 | - em seu arquivo <literal>pom.xml</literal>, na seção <literal>dependencies</literal>. | |
37 | - </para> | |
38 | - | |
39 | - <programlisting role="XML"><![CDATA[<dependency> | |
40 | - <groupId>br.gov.frameworkdemoiselle</groupId> | |
41 | - <artifactId>demoiselle-jpa</artifactId> | |
42 | - <scope>compile</scope> | |
43 | -</dependency>]]></programlisting> | |
44 | - </tip> | |
45 | - | |
46 | - <section> | |
47 | - <title>Introdução ao mecanismo</title> | |
48 | - | |
49 | - <para> | |
50 | - Para injetar uma instância de <code>EntityManager</code> em sua aplicação, basta usar a anotação <code>@Inject</code>. | |
51 | - </para> | |
52 | - | |
53 | - <programlisting role="JAVA">@PersistenceController | |
54 | -public class BookmarkDAO extends JPACrud<Bookmark, Long> { | |
55 | - | |
56 | - private static final long serialVersionUID = 1L; | |
57 | - | |
58 | - @Inject | |
59 | - private EntityManager entityManager; | |
60 | - | |
61 | - public void persistBookmark(Bookmark bookmark){ | |
62 | - entityManager.persist(bookmark); | |
63 | - } | |
64 | - | |
65 | -}</programlisting> | |
66 | - | |
67 | - <para> | |
68 | - O produtor padrão injetará o <code>EntityManager</code> configurado no arquivo <code>persistence.xml</code>. Se houver | |
69 | - mais de um contexto de persistência configurado em <code>persistence.xml</code>, será necessário especificar qual será | |
70 | - injetado no ponto de injeção. Para isso use a anotação <code>@Name</code>. | |
71 | - </para> | |
72 | - | |
73 | - <programlisting role="JAVA">@PersistenceController | |
74 | -public class BookmarkDAO extends JPACrud<Bookmark, Long> { | |
75 | - | |
76 | - private static final long serialVersionUID = 1L; | |
77 | - | |
78 | - @Inject | |
79 | - @Name("persistence_unit_1") | |
80 | - private EntityManager entityManager; | |
81 | - | |
82 | - public void persistBookmark(Bookmark bookmark){ | |
83 | - entityManager.persist(bookmark); | |
84 | - } | |
85 | - | |
86 | -}</programlisting> | |
87 | - | |
88 | - <para> | |
89 | - É possível invocar o utilitário <code>Beans</code> para injetar instâncias de <code>EntityManager</code> programaticamente. | |
90 | - </para> | |
91 | - | |
92 | - <programlisting role="JAVA">@PersistenceController | |
93 | -public class BookmarkDAO extends JPACrud<Bookmark, Long> { | |
94 | - | |
95 | - private static final long serialVersionUID = 1L; | |
96 | - | |
97 | - public void persistBookmark(Bookmark bookmark){ | |
98 | - EntityManager entityManager = Beans.getReference(EntityManager.class); | |
99 | - entityManager.persist(bookmark); | |
100 | - } | |
101 | - | |
102 | - public void persistBookmarkInHistory(Bookmark bookmark){ | |
103 | - EntityManager entityManager = Beans.getReference(EntityManager.class , new NameQualifier("history_persistence_unit")); | |
104 | - entityManager.persist(bookmark); | |
105 | - } | |
106 | - | |
107 | -}</programlisting> | |
108 | - </section> | |
109 | - | |
110 | - <section> | |
111 | - <title>Configuração</title> | |
112 | - | |
113 | - <para> | |
114 | - Alguns comportamentos do produtor podem ser configurados através das propriedades abaixo, que devem ser configuradas | |
115 | - no arquivo <code>demoiselle.properties</code>. | |
116 | - </para> | |
117 | - | |
118 | - <informaltable width="100%"> | |
119 | - <tgroup cols="3"> | |
120 | - <colspec align="left"/> | |
121 | - <colspec align="left"/> | |
122 | - <colspec align="right"/> | |
123 | - | |
124 | - <thead> | |
125 | - <row valign="top"> | |
126 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
127 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
128 | - <entry><emphasis role="bold">Padrão</emphasis></entry> | |
129 | - </row> | |
130 | - </thead> | |
131 | - | |
132 | - <tbody> | |
133 | - <row valign="top"> | |
134 | - <entry>frameworkdemoiselle.​persistence.​default.​unit.​name</entry> | |
135 | - <entry> | |
136 | - <para> | |
137 | - Define o nome da unidade de persistência padrão (configurada em <code>persistence.xml</code>) que será injetada | |
138 | - caso a anotação <code>@Name</code> não seja usada. Não é necessário se apenas uma unidade de persistência for configurada. | |
139 | - </para> | |
140 | - </entry> | |
141 | - <entry></entry> | |
142 | - </row> | |
143 | - | |
144 | - <row valign="top"> | |
145 | - <entry>frameworkdemoiselle.​persistence.​entitymanager.​scope</entry> | |
146 | - <entry> | |
147 | - <para> | |
148 | - Permite determinar o escopo de unidades de persistência injetadas. Dentro do escopo determinado, todos os pontos | |
149 | - de injeção receberão a mesma instância de <code>EntityManager</code>. | |
150 | - </para> | |
151 | - <para> | |
152 | - Os valores possíveis são: | |
153 | - <simplelist type="inline"> | |
154 | - <member>request</member> | |
155 | - <member>session</member> | |
156 | - <member>view</member> | |
157 | - <member>conversation</member> | |
158 | - <member>application</member> | |
159 | - <member>noscope</member> | |
160 | - </simplelist> | |
161 | - </para> | |
162 | - </entry> | |
163 | - <entry>request</entry> | |
164 | - </row> | |
165 | - </tbody> | |
166 | - </tgroup> | |
167 | - </informaltable> | |
168 | - | |
169 | - <tip> | |
170 | - <para> | |
171 | - O escopo especial <emphasis>noscope</emphasis> desliga o gerenciamento de escopo de instâncias de <code>EntityManager</code> | |
172 | - produzidas pelo Framework Demoiselle. Isso permite ao desenvolvedor controlar totalmente o ciclo de vida de um | |
173 | - <code>EntityManager</code> injetado e ainda reter o recurso do produtor padrão. | |
174 | - </para> | |
175 | - <para> | |
176 | - Note que ao usar a opção <emphasis>noscope</emphasis>, o desenvolvedor é o responsável por controlar o ciclo de vida do gerenciador | |
177 | - de persistência. Ele não participará de transações JPA abertas através da anotação <code>@Transactional</code> (transações JTA funcionam normalmente) | |
178 | - e multiplos pontos de injeção durante uma requisição receberão múltiplas instâncias de <code>EntityManager</code>. | |
179 | - </para> | |
180 | - </tip> | |
181 | - | |
182 | - <caution> | |
183 | - <para> | |
184 | - Deve-se usar cautela ao alterar o escopo padrão das instâncias de <code>EntityManager</code>. Na grande maioria dos casos o escopo | |
185 | - padrão <emphasis>request</emphasis> é o suficiente e alterar esse padrão deve ser feito apenas após extensa análise dos prós e contras | |
186 | - de cada escopo. | |
187 | - </para> | |
188 | - <para> | |
189 | - Dê especial atenção aos escopos que podem ser serializados pelo servidor de aplicação (<emphasis>session</emphasis>, <emphasis>view</emphasis> | |
190 | - e <emphasis>conversation</emphasis>) pois a especificação não define o comportamento de instâncias de <code>EntityManager</code> que são | |
191 | - serializadas. | |
192 | - </para> | |
193 | - </caution> | |
194 | - </section> | |
195 | - </section> | |
196 | - | |
197 | - <section> | |
198 | - | |
199 | - <title>JDBC</title> | |
200 | - | |
201 | - <para> | |
202 | - O Framework Demoiselle fornece um produtor padrão para conexões JDBC puras. Esse produtor possui suporte | |
203 | - ao acesso direto utilizando uma URL e ao acesso via <code>DataSource</code>, acessando a conexão através | |
204 | - de um nome <code>JNDI</code> configurado em um servidor de aplicação. | |
205 | - </para> | |
206 | - | |
207 | - <para> | |
208 | - A persistência de dados usando JDBC está disponível na extensão <literal>demoiselle-jdbc</literal>. Para ter acesso | |
209 | - a essa extensão em um projeto Maven declare sua dependência no arquivo <literal>pom.xml</literal> de seu projeto. | |
210 | - </para> | |
211 | - | |
212 | - <tip> | |
213 | - <para> | |
214 | - Para acrescentar a dependência à extensão <literal>demoiselle-jdbc</literal>, adicione esse código | |
215 | - em seu arquivo <literal>pom.xml</literal>, na seção <literal>dependencies</literal>. | |
216 | - </para> | |
217 | - | |
218 | - <programlisting role="XML"><![CDATA[<dependency> | |
219 | - <groupId>br.gov.frameworkdemoiselle</groupId> | |
220 | - <artifactId>demoiselle-jdbc</artifactId> | |
221 | - <scope>compile</scope> | |
222 | -</dependency>]]></programlisting> | |
223 | - </tip> | |
224 | - | |
225 | - <section> | |
226 | - <title>Configuração</title> | |
227 | - | |
228 | - <para> | |
229 | - A conexão será criada pela fábrica do Demoiselle de acordo com as configurações no arquivo de propriedade (<emphasis>demoiselle.properties</emphasis>). | |
230 | - Para configurar uma conexão diretamente através de uma URL utilize as propriedades abaixo: | |
231 | - </para> | |
232 | - | |
233 | - <informaltable width="100%"> | |
234 | - <tgroup cols="2"> | |
235 | - <colspec align="left"/> | |
236 | - <colspec align="left"/> | |
237 | - | |
238 | - <thead> | |
239 | - <row valign="top"> | |
240 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
241 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
242 | - </row> | |
243 | - </thead> | |
244 | - | |
245 | - <tbody> | |
246 | - <row valign="top"> | |
247 | - <entry>frameworkdemoiselle.​persistence.​driver.​class</entry> | |
248 | - <entry> | |
249 | - <para> | |
250 | - Implementação da interface <code>java.sql.Driver</code> que dá acesso | |
251 | - ao SGBD utilizado pela aplicação. | |
252 | - </para> | |
253 | - </entry> | |
254 | - </row> | |
255 | - | |
256 | - <row valign="top"> | |
257 | - <entry>frameworkdemoiselle.​persistence.​url</entry> | |
258 | - <entry> | |
259 | - <para> | |
260 | - URL de conexão no formato <code>jdbc:vendor:database-properties</code>. | |
261 | - </para> | |
262 | - </entry> | |
263 | - </row> | |
264 | - | |
265 | - <row valign="top"> | |
266 | - <entry>frameworkdemoiselle.​persistence.​username</entry> | |
267 | - <entry> | |
268 | - <para> | |
269 | - Login de acesso ao SGBD. | |
270 | - </para> | |
271 | - </entry> | |
272 | - </row> | |
273 | - | |
274 | - <row valign="top"> | |
275 | - <entry>frameworkdemoiselle.​persistence.​password</entry> | |
276 | - <entry> | |
277 | - <para> | |
278 | - Senha de acesso ao SGBD. | |
279 | - </para> | |
280 | - </entry> | |
281 | - </row> | |
282 | - </tbody> | |
283 | - </tgroup> | |
284 | - </informaltable> | |
285 | - | |
286 | - <para> | |
287 | - Também é possível configurar o acesso indicando um nome <code>JNDI</code> que esteja | |
288 | - configurado no servidor de aplicação. | |
289 | - </para> | |
290 | - | |
291 | - <informaltable width="100%"> | |
292 | - <tgroup cols="2"> | |
293 | - <colspec align="left"/> | |
294 | - <colspec align="left"/> | |
295 | - | |
296 | - <thead> | |
297 | - <row valign="top"> | |
298 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
299 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
300 | - </row> | |
301 | - </thead> | |
302 | - | |
303 | - <tbody> | |
304 | - <row valign="top"> | |
305 | - <entry>frameworkdemoiselle.​persistence.​jndi.​name</entry> | |
306 | - <entry> | |
307 | - <para> | |
308 | - Nome <code>JNDI</code> criado no servidor de aplicação para dar acesso | |
309 | - à conexão ao banco de dados. | |
310 | - </para> | |
311 | - </entry> | |
312 | - </row> | |
313 | - </tbody> | |
314 | - </tgroup> | |
315 | - </informaltable> | |
316 | - | |
317 | - <para> | |
318 | - É possível configurar mais de uma conexão JDBC. Para isso acrescente nas propriedades nomes | |
319 | - separados para cada conexão como no exemplo abaixo: | |
320 | - </para> | |
321 | - | |
322 | - <example> | |
323 | - <title>Criando múltiplas conexões</title> | |
324 | - | |
325 | - <programlisting>frameworkdemoiselle.​persistence.​<emphasis role="bold">conn1</emphasis>.​driver.​class=MinhaClasse | |
326 | -frameworkdemoiselle.​persistence.​<emphasis role="bold">conn1</emphasis>.​url=MinhaURL | |
327 | -frameworkdemoiselle.​persistence.​<emphasis role="bold">conn1</emphasis>.​username=MeuLogin | |
328 | -frameworkdemoiselle.​persistence.​<emphasis role="bold">conn1</emphasis>.​password=MinhaSenha | |
329 | - | |
330 | -frameworkdemoiselle.​persistence.​<emphasis role="bold">conn2</emphasis>.​driver.​class=MinhaClasse | |
331 | -frameworkdemoiselle.​persistence.​<emphasis role="bold">conn2</emphasis>.​url=MinhaURL | |
332 | -frameworkdemoiselle.​persistence.​<emphasis role="bold">conn2</emphasis>.​username=MeuLogin | |
333 | -frameworkdemoiselle.​persistence.​<emphasis role="bold">conn2</emphasis>.​password=MinhaSenha</programlisting> | |
334 | - | |
335 | - <programlisting>frameworkdemoiselle.​persistence.​<emphasis role="bold">conn1</emphasis>.​jndi.​name=MeuJndiName1 | |
336 | -frameworkdemoiselle.​persistence.​<emphasis role="bold">conn2</emphasis>.​jndi.​name=MeuJndiName2</programlisting> | |
337 | - </example> | |
338 | - | |
339 | - <para> | |
340 | - Caso várias conexões sejam configuradas, é possível determinal a conexão padrão - aquela | |
341 | - que será utilizada quando o desenvolvedor não especificar qual deseja utilizar. | |
342 | - </para> | |
343 | - | |
344 | - <informaltable width="100%"> | |
345 | - <tgroup cols="2"> | |
346 | - <colspec align="left"/> | |
347 | - <colspec align="left"/> | |
348 | - | |
349 | - <thead> | |
350 | - <row valign="top"> | |
351 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
352 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
353 | - </row> | |
354 | - </thead> | |
355 | - | |
356 | - <tbody> | |
357 | - <row valign="top"> | |
358 | - <entry>frameworkdemoiselle.​persistence.​default.​datasource.​name</entry> | |
359 | - <entry> | |
360 | - <para> | |
361 | - Caso múltiplas conexões sejam criadas, define a conexão padrão | |
362 | - quando uma <code>Connection</code> é injetada no código sem utilizar | |
363 | - a anotação <code>@Name</code>. | |
364 | - </para> | |
365 | - </entry> | |
366 | - </row> | |
367 | - </tbody> | |
368 | - </tgroup> | |
369 | - </informaltable> | |
370 | - </section> | |
371 | - | |
372 | - <section> | |
373 | - <title>Utilização</title> | |
374 | - | |
375 | - <para> | |
376 | - Para utilizar uma conexão JDBC em seu código, basta injetá-la. O Demoiselle se encarregará de produzir | |
377 | - o tipo adequado de conexão. | |
378 | - </para> | |
379 | - | |
380 | - <programlisting role="JAVA"><![CDATA[public class ClasseDAO { | |
381 | - | |
382 | - @Inject | |
383 | - private Connection conn1; | |
384 | - | |
385 | - @Transactional | |
386 | - public void metodoPersistir(){ | |
387 | - conn1.prepareStatement("INSERT INTO TAB_1 VALUES (1,'JDBC')").execute(); | |
388 | - } | |
389 | -}]]></programlisting> | |
390 | - | |
391 | - <para> | |
392 | - Caso multiplas conexões tenham sido definidas, é possível utilizar a anotação <code>@Name</code> para injetar | |
393 | - uma conexão específica. | |
394 | - </para> | |
395 | - | |
396 | - <programlisting role="JAVA"><![CDATA[public class ClasseDAO { | |
397 | - | |
398 | - @Inject | |
399 | - @Name("conn1") | |
400 | - private Connection conn1; | |
401 | - | |
402 | - @Inject | |
403 | - @Name("conn2") | |
404 | - private Connection conn2; | |
405 | - | |
406 | - @Transactional | |
407 | - public void metodoPersistirEmConn1(){ | |
408 | - conn1.prepareStatement("INSERT INTO TAB_1 VALUES (1,'JDBC')").execute(); | |
409 | - } | |
410 | - | |
411 | - @Transactional | |
412 | - public void metodoPersistirEmConn2(){ | |
413 | - conn2.prepareStatement("INSERT INTO TAB_2 VALUES (1,'JDBC')").execute(); | |
414 | - } | |
415 | -}]]></programlisting> | |
416 | - | |
417 | - <caution> | |
418 | - <para> | |
419 | - Caso a propriedade <code>frameworkdemoiselle.persistence.default.datasource.name</code> seja utilizada para | |
420 | - especificar uma conexão padrão, a anotação <code>@Name</code> só é necessária para utilizar conexões diferentes | |
421 | - da padrão. Caso essa propriedade não seja utilizada e existam múltiplas conexões configuradas, torna-se obrigatório | |
422 | - o uso da anotação <code>@Name</code> em todos os pontos de injeção. | |
423 | - </para> | |
424 | - </caution> | |
425 | - | |
426 | - </section> | |
427 | - | |
428 | - </section> | |
429 | - | |
430 | -</chapter> |
documentation/reference/pt-BR/properties.xml
... | ... | @@ -1,365 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ ]> | |
4 | -<appendix id="propriedades"> | |
5 | - | |
6 | - <title>Atributos do demoiselle.properties</title> | |
7 | - | |
8 | - <para> | |
9 | - Em um projeto com o <emphasis>Demoiselle Framework</emphasis>, algumas propriedades e configurações | |
10 | - do <emphasis>Framework</emphasis> podem ser ajustadas no arquivo <literal>demoiselle.properties</literal>. | |
11 | - A seguir listamos as propriedades e configurações do <emphasis>Demoiselle Framework</emphasis> que o usuário pode modificar, | |
12 | - acompanhados de alguns exemplos ilustrativos. | |
13 | - | |
14 | - </para> | |
15 | - | |
16 | - <para> | |
17 | - <table width="100%"> | |
18 | - <title>Configurações do Core</title> | |
19 | - <tgroup cols="3"> | |
20 | - <colspec align="left" colwidth="0.4*"/> | |
21 | - <colspec align="left" colwidth="0.4*"/> | |
22 | - <colspec align="right" colwidth="0.2*"/> | |
23 | - | |
24 | - <thead> | |
25 | - <row valign="top"> | |
26 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
27 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
28 | - <entry><emphasis role="bold">Valor padrão</emphasis></entry> | |
29 | - </row> | |
30 | - </thead> | |
31 | - <tbody> | |
32 | - <row valign="top"> | |
33 | - <entry>frameworkdemoiselle.​security.​enabled</entry> | |
34 | - <entry> | |
35 | - <para> | |
36 | - Habilita o mecanismo de segurança. | |
37 | - </para> | |
38 | - </entry> | |
39 | - <entry>true</entry> | |
40 | - </row> | |
41 | - <row valign="top"> | |
42 | - <entry>frameworkdemoiselle.​security.​authenticator.​class</entry> | |
43 | - <entry> | |
44 | - <para> | |
45 | - Define a classe que implementa a estratégia de autenticação. | |
46 | - </para> | |
47 | - </entry> | |
48 | - <entry></entry> | |
49 | - </row> | |
50 | - <row valign="top"> | |
51 | - <entry>frameworkdemoiselle.​security.​authorizer.​class</entry> | |
52 | - <entry> | |
53 | - <para> | |
54 | - Define a classe que implementa a estratégia de autorização. | |
55 | - </para> | |
56 | - </entry> | |
57 | - <entry></entry> | |
58 | - </row> | |
59 | - <row valign="top"> | |
60 | - <entry>frameworkdemoiselle.​transaction.​class</entry> | |
61 | - <entry> | |
62 | - <para> | |
63 | - Define a classe que implementa a estratégia de controle transacional. | |
64 | - </para> | |
65 | - </entry> | |
66 | - <entry></entry> | |
67 | - </row> | |
68 | - <row valign="top"> | |
69 | - <entry>frameworkdemoiselle.​pagination.​page.​size</entry> | |
70 | - <entry> | |
71 | - <para> | |
72 | - Define o tamanho da página padrão do mecanismo de paginação. | |
73 | - </para> | |
74 | - </entry> | |
75 | - <entry>10</entry> | |
76 | - </row> | |
77 | - </tbody> | |
78 | - </tgroup> | |
79 | - </table> | |
80 | - <table width="100%"> | |
81 | - <title>Configurações da extensão JSF</title> | |
82 | - <tgroup cols="3"> | |
83 | - <colspec align="left" colwidth="0.4*"/> | |
84 | - <colspec align="left" colwidth="0.4*"/> | |
85 | - <colspec align="right" colwidth="0.2*"/> | |
86 | - | |
87 | - <thead> | |
88 | - <row valign="top"> | |
89 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
90 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
91 | - <entry><emphasis role="bold">Valor padrão</emphasis></entry> | |
92 | - </row> | |
93 | - </thead> | |
94 | - <tbody> | |
95 | - <row valign="top"> | |
96 | - <entry>frameworkdemoiselle.​security.​login.​page</entry> | |
97 | - <entry> | |
98 | - <para> | |
99 | - Define a página de login da aplicação. | |
100 | - </para> | |
101 | - </entry> | |
102 | - <entry>"/login"</entry> | |
103 | - </row> | |
104 | - <row valign="top"> | |
105 | - <entry>frameworkdemoiselle.​security.​redirect.​after.​login</entry> | |
106 | - <entry> | |
107 | - <para> | |
108 | - Define a tela para qual o usuário será redirecionado após o processo de <emphasis>login</emphasis> bem sucedido. | |
109 | - </para> | |
110 | - </entry> | |
111 | - <entry>"/index"</entry> | |
112 | - </row> | |
113 | - <row valign="top"> | |
114 | - <entry>frameworkdemoiselle.​security.​redirect.​after.​logout</entry> | |
115 | - <entry> | |
116 | - <para> | |
117 | - Define a tela para qual o usuário será redirecionado após o processo de <emphasis>logout</emphasis> bem sucedido. | |
118 | - </para> | |
119 | - </entry> | |
120 | - <entry>"/login"</entry> | |
121 | - </row> | |
122 | - <row valign="top"> | |
123 | - <entry>frameworkdemoiselle.​security.​redirect.​enabled</entry> | |
124 | - <entry> | |
125 | - <para> | |
126 | - Habilita os redirecionamentos relacionados aos processos de login e logout. | |
127 | - </para> | |
128 | - </entry> | |
129 | - <entry>true</entry> | |
130 | - </row> | |
131 | - <row valign="top"> | |
132 | - <entry>frameworkdemoiselle.​exception.​application.​handle</entry> | |
133 | - <entry> | |
134 | - <para> | |
135 | - Habilita o tratamento automático das exceções da aplicação anotadas com @ApplicationException. | |
136 | - </para> | |
137 | - </entry> | |
138 | - <entry>true</entry> | |
139 | - </row> | |
140 | - <row valign="top"> | |
141 | - <entry>frameworkdemoiselle.​exception.​default.​redirect.​page</entry> | |
142 | - <entry> | |
143 | - <para> | |
144 | - Define o redirecionamento das exceções da aplicação anotadas com @ApplicationException ocorridas | |
145 | - durante a fase de renderização da página (PhaseId.RENDER_RESPONSE). | |
146 | - </para> | |
147 | - </entry> | |
148 | - <entry>"/application_error"</entry> | |
149 | - </row> | |
150 | - <row valign="top"> | |
151 | - <entry>frameworkdemoiselle.​pagination.​max.​page.​links</entry> | |
152 | - <entry> | |
153 | - <para> | |
154 | - Configura a quantidade de links que será exibido em uma página. | |
155 | - </para> | |
156 | - </entry> | |
157 | - <entry>5</entry> | |
158 | - </row> | |
159 | - </tbody> | |
160 | - </tgroup> | |
161 | - </table> | |
162 | - <table width="100%"> | |
163 | - <title>Configurações da extensão JDBC</title> | |
164 | - <tgroup cols="3"> | |
165 | - <colspec align="left" colwidth="0.4*"/> | |
166 | - <colspec align="left" colwidth="0.4*"/> | |
167 | - <colspec align="right" colwidth="0.2*"/> | |
168 | - | |
169 | - <thead> | |
170 | - <row valign="top"> | |
171 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
172 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
173 | - <entry><emphasis role="bold">Valor padrão</emphasis></entry> | |
174 | - </row> | |
175 | - </thead> | |
176 | - <tbody> | |
177 | - <row valign="top"> | |
178 | - <entry>frameworkdemoiselle.​persistence.​jndi.​name</entry> | |
179 | - <entry> | |
180 | - <para> | |
181 | - Define o nome JNDI onde o DataSource está disponível. | |
182 | - </para> | |
183 | - </entry> | |
184 | - <entry></entry> | |
185 | - </row> | |
186 | - <row valign="top"> | |
187 | - <entry>frameworkdemoiselle.​persistence.​driver.​class</entry> | |
188 | - <entry> | |
189 | - <para> | |
190 | - Define a classe que implementa o Driver de conexão com a base de dados. | |
191 | - </para> | |
192 | - </entry> | |
193 | - <entry></entry> | |
194 | - </row> | |
195 | - <row valign="top"> | |
196 | - <entry>frameworkdemoiselle.​persistence.​url</entry> | |
197 | - <entry> | |
198 | - <para> | |
199 | - Define a URL de conexão com a base de dados. | |
200 | - </para> | |
201 | - </entry> | |
202 | - <entry></entry> | |
203 | - </row> | |
204 | - <row valign="top"> | |
205 | - <entry>frameworkdemoiselle.​persistence.​username</entry> | |
206 | - <entry> | |
207 | - <para> | |
208 | - Define o username para estabelecer a conexão com a base de dados. | |
209 | - </para> | |
210 | - </entry> | |
211 | - <entry></entry> | |
212 | - </row> | |
213 | - <row valign="top"> | |
214 | - <entry>frameworkdemoiselle.​persistence.​password</entry> | |
215 | - <entry> | |
216 | - <para> | |
217 | - Define o password para estabelecer a conexão com a base de dados. | |
218 | - </para> | |
219 | - </entry> | |
220 | - <entry></entry> | |
221 | - </row> | |
222 | - <row valign="top"> | |
223 | - <entry>frameworkdemoiselle.​persistence.​default.​datasource.​name</entry> | |
224 | - <entry> | |
225 | - <para> | |
226 | - Define a configuração de banco de dados padrão para aplicações que possuem mais | |
227 | - de um datasource configurado. | |
228 | - </para> | |
229 | - </entry> | |
230 | - <entry></entry> | |
231 | - </row> | |
232 | - </tbody> | |
233 | - </tgroup> | |
234 | - </table> | |
235 | - <table width="100%"> | |
236 | - <title>Configurações da extensão JPA</title> | |
237 | - <tgroup cols="3"> | |
238 | - <colspec align="left" colwidth="0.4*"/> | |
239 | - <colspec align="left" colwidth="0.4*"/> | |
240 | - <colspec align="right" colwidth="0.2*"/> | |
241 | - | |
242 | - <thead> | |
243 | - <row valign="top"> | |
244 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
245 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
246 | - <entry><emphasis role="bold">Valor padrão</emphasis></entry> | |
247 | - </row> | |
248 | - </thead> | |
249 | - <tbody> | |
250 | - <row valign="top"> | |
251 | - <entry>frameworkdemoiselle.​persistence.​default.​unit.​name</entry> | |
252 | - <entry> | |
253 | - <para> | |
254 | - Define o nome da unidade de persistência padrão (configurada em <code>persistence.xml</code>) que será injetada | |
255 | - caso a anotação <code>@Name</code> não seja usada. Não é necessário se apenas uma unidade de persistência for configurada. | |
256 | - </para> | |
257 | - </entry> | |
258 | - <entry></entry> | |
259 | - </row> | |
260 | - | |
261 | - <row valign="top"> | |
262 | - <entry>frameworkdemoiselle.​persistence.​entitymanager.​scope</entry> | |
263 | - <entry> | |
264 | - <para> | |
265 | - Permite determinar o escopo de unidades de persistência injetadas. Dentro do escopo determinado, todos os pontos | |
266 | - de injeção receberão a mesma instância de <code>EntityManager</code>. | |
267 | - </para> | |
268 | - <para> | |
269 | - Os valores possíveis são: | |
270 | - <simplelist type="inline"> | |
271 | - <member>request</member> | |
272 | - <member>session</member> | |
273 | - <member>view</member> | |
274 | - <member>conversation</member> | |
275 | - <member>application</member> | |
276 | - <member>noscope</member> | |
277 | - </simplelist> | |
278 | - </para> | |
279 | - </entry> | |
280 | - <entry>request</entry> | |
281 | - </row> | |
282 | - </tbody> | |
283 | - </tgroup> | |
284 | - </table> | |
285 | - <table width="100%"> | |
286 | - <title>Configurações da extensão JMX</title> | |
287 | - <tgroup cols="3"> | |
288 | - <colspec align="left" colwidth="0.4*"/> | |
289 | - <colspec align="left" colwidth="0.4*"/> | |
290 | - <colspec align="right" colwidth="0.2*"/> | |
291 | - | |
292 | - <thead> | |
293 | - <row valign="top"> | |
294 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
295 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
296 | - <entry><emphasis role="bold">Valor padrão</emphasis></entry> | |
297 | - </row> | |
298 | - </thead> | |
299 | - <tbody> | |
300 | - <row valign="top"> | |
301 | - <entry role="">frameworkdemoiselle.​management.​mbean.​domain</entry> | |
302 | - <entry> | |
303 | - <para>Define o domínio padrão onde classes anotadas com <emphasis>@ManagementController</emphasis> serão registradas no MBeanServer.</para> | |
304 | - <para>Na especificação JMX, um MBean é registrado no MBeanServer com um nome no formato <emphasis>domain:name=MBeanName</emphasis> | |
305 | - (ex: <emphasis>br.​gov.​frameworkdemoiselle:​name=NotificationBroadcaster</emphasis>). Esse parâmetro controla a porção <emphasis>domain</emphasis> | |
306 | - desse formato.</para> | |
307 | - </entry> | |
308 | - <entry>O pacote da classe anotada com <emphasis>@Management​Controller</emphasis></entry> | |
309 | - </row> | |
310 | - <row valign="top"> | |
311 | - <entry colsep="1">frameworkdemoiselle.​management.​notification.​domain</entry> | |
312 | - <entry colsep="1"> | |
313 | - <para>O mesmo que <emphasis>frameworkdemoiselle.​management.​mbean.​domain</emphasis>, mas apenas para o domínio do | |
314 | - MBean <emphasis role="bold">br.​gov.​frameworkdemoiselle.​internal.​NotificationBroadcaster</emphasis>. Esse MBean é automaticamente | |
315 | - registrado para receber notificações enviadas usando a classe <emphasis role="bold">br.​gov.​frameworkdemoiselle.​management.​NotificationManager</emphasis></para> | |
316 | - </entry> | |
317 | - <entry>br.​gov.​frameworkdemoiselle.​jmx</entry> | |
318 | - </row> | |
319 | - <row valign="top"> | |
320 | - <entry>frameworkdemoiselle.​management.​notification.​name</entry> | |
321 | - <entry> | |
322 | - <para>O nome usado para registrar a classe <emphasis role="bold">br.​gov.​frameworkdemoiselle.​internal.​NotificationBroadcaster</emphasis> como MBean.</para> | |
323 | - </entry> | |
324 | - <entry>Notification​Broadcaster</entry> | |
325 | - </row> | |
326 | - </tbody> | |
327 | - </tgroup> | |
328 | - </table> | |
329 | - </para> | |
330 | - | |
331 | - <!-- <section> | |
332 | - <title>Escolhendo Estratégias</title> | |
333 | - <para> | |
334 | - Para escolher as estratégias de <emphasis>Transação</emphasis>, <emphasis>Autorização</emphasis> e <emphasis>Autenticação</emphasis> | |
335 | - devem ser configuradas as propriedades: <literal>frameworkdemoiselle.transaction.class</literal>, | |
336 | - <literal>frameworkdemoiselle.security.authorizer.class</literal> e <literal>frameworkdemoiselle.security.authenticator.class</literal> | |
337 | - , respectivamente. | |
338 | - </para> | |
339 | - <para> | |
340 | - Para utilizar as estratégias fornecidas pelo próprio <emphasis>Framework Demoiselle</emphasis>, você deve configurar essas | |
341 | - propriedades da seguinte forma: | |
342 | - <itemizedlist> | |
343 | - <listitem> | |
344 | - <para> | |
345 | - <literal>frameworkdemoiselle.transaction.class=br.gov.frameworkdemoiselle.transaction.JPATransaction</literal>, | |
346 | - para transações <emphasis>JPA</emphasis>, e <literal>frameworkdemoiselle.transaction.class= | |
347 | - br.gov.frameworkdemoiselle.transaction.JTATransaction</literal>, para transações <emphasis>JTA</emphasis>; | |
348 | - </para> | |
349 | - </listitem> | |
350 | - <listitem> | |
351 | - <para> | |
352 | - <literal>frameworkdemoiselle.security.authorizer.class=br.gov.serpro.inscricao.security.Autorizador</literal>; | |
353 | - </para> | |
354 | - </listitem> | |
355 | - <listitem> | |
356 | - <para> | |
357 | - <literal>frameworkdemoiselle.security.authenticator.class=br.gov.serpro.inscricao.security.Autenticador</literal>. | |
358 | - </para> | |
359 | - </listitem> | |
360 | - </itemizedlist> | |
361 | - As instruções para você construir e utilizar sua própria estratégia estãodescritas nos capítulos <link linkend="transacao">Transação</link> | |
362 | - e <link linkend="security">Segurança</link>. | |
363 | - </para> | |
364 | - </section> --> | |
365 | -</appendix> |
documentation/reference/pt-BR/security.xml
... | ... | @@ -1,620 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ ]> | |
4 | -<chapter id="security"> | |
5 | - | |
6 | - <title>Segurança</title> | |
7 | - | |
8 | - <para> | |
9 | - Neste capítulo será tratada uma questão de grande importância para a maioria das aplicações e motivo de infindáveis | |
10 | - discussões nas equipes de desenvolvimento: controle de acesso. Assim como tudo relacionado ao framework, a | |
11 | - implementação de segurança foi projetada de forma simples e flexível, independente de camada de apresentação ou | |
12 | - tecnologia, te deixando livre para implementar sua própria solução ou utilizar as extensões existentes. | |
13 | - </para> | |
14 | - <para> | |
15 | - Para utilizar o modelo de segurança proposto basta utilizar o Framework Demoiselle, pois no núcleo do framework estão as | |
16 | - interfaces e anotações que definem o comportamento básico da implementação. | |
17 | - </para> | |
18 | - | |
19 | - <section> | |
20 | - <title>Configurando</title> | |
21 | - | |
22 | - <para> | |
23 | - Para um correto funcionamento do Demoiselle é necessário inserir os interceptadores de segurança no arquivo <filename>src/main/webapp/WEB-INF/beans.xml</filename>. | |
24 | - </para> | |
25 | - | |
26 | - <programlisting role="XML"><![CDATA[<beans xmlns="http://java.sun.com/xml/ns/javaee" | |
27 | -xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
28 | -xsi:schemaLocation="http://java.sun.com/xml/ns/javaee | |
29 | - http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> | |
30 | - <interceptors> | |
31 | - <class>br.gov.frameworkdemoiselle.security.RequiredPermissionInterceptor</class> | |
32 | - <class>br.gov.frameworkdemoiselle.security.RequiredRoleInterceptor</class> | |
33 | - </interceptors> | |
34 | -</beans>]]></programlisting> | |
35 | - | |
36 | - <para> | |
37 | - Opcionalmente é possível configurar o comportamento do módulo de segurança definindo propriedades no arquivo <emphasis>demoiselle.properties</emphasis> | |
38 | - da sua aplicação. | |
39 | - </para> | |
40 | - | |
41 | - <table> | |
42 | - <title>Propriedades de segurança do Framework Demoiselle</title> | |
43 | - <tgroup cols="3"> | |
44 | - <colspec align="left" colwidth="40*"/> | |
45 | - <colspec align="left" colwidth="40*"/> | |
46 | - <colspec align="right" colwidth="20*"/> | |
47 | - | |
48 | - <thead> | |
49 | - <row valign="top"> | |
50 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
51 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
52 | - <entry><emphasis role="bold">Valor padrão</emphasis></entry> | |
53 | - </row> | |
54 | - </thead> | |
55 | - <tbody> | |
56 | - <row valign="top"> | |
57 | - <entry>frameworkdemoiselle.​security.​enabled</entry> | |
58 | - <entry> | |
59 | - <para> | |
60 | - Habilita ou desabilita o mecanismo de segurança | |
61 | - </para> | |
62 | - </entry> | |
63 | - <entry>true</entry> | |
64 | - </row> | |
65 | - | |
66 | - <row valign="top"> | |
67 | - <entry>frameworkdemoiselle.​security.​authenticator.​class</entry> | |
68 | - <entry> | |
69 | - <para> | |
70 | - Define a classe que implementa o mecanismo de autenticação. | |
71 | - (Detalhes na seção <link linkend="criando_implementacao_seguranca">Criando sua implementação</link>) | |
72 | - </para> | |
73 | - </entry> | |
74 | - <entry> | |
75 | - - | |
76 | - </entry> | |
77 | - </row> | |
78 | - | |
79 | - <row valign="top"> | |
80 | - <entry>frameworkdemoiselle.​security.​authorizer.​class</entry> | |
81 | - <entry> | |
82 | - <para> | |
83 | - Define a classe que implementa o mecanismo de autorização. | |
84 | - (Detalhes na seção <link linkend="criando_implementacao_seguranca">Criando sua implementação</link>) | |
85 | - </para> | |
86 | - </entry> | |
87 | - <entry> | |
88 | - - | |
89 | - </entry> | |
90 | - </row> | |
91 | - </tbody> | |
92 | - </tgroup> | |
93 | - </table> | |
94 | - | |
95 | - </section> | |
96 | - | |
97 | - <section> | |
98 | - <title>Autenticação</title> | |
99 | - <para> | |
100 | - O mecanismo de autenticação busca verificar a identidade do usuário de um sistema. A forma mais conhecida - e comum - para | |
101 | - executar essa verificação se dá por meio de um formulário de login, geralmente solicitando um nome de usuário e | |
102 | - sua respectiva senha. No entanto, outras formas como reconhecimento biométrico e autenticação por token, para citar | |
103 | - apenas duas, tem ganhado um grande número de adeptos. | |
104 | - </para> | |
105 | - <para> | |
106 | - O Framework Demoiselle deixa o desenvolvedor livre para definir qual forma usar, de acordo com a sua conveniência e necessidade. | |
107 | - A peça chave para tornar isso possível é o contexto de segurança, representado pela interface <code>SecurityContext</code>. Nessa | |
108 | - estão definidos os métodos responsáveis por gerenciar os mecanismos de autenticação como, por exemplo, executar | |
109 | - login/logout de usuários e verificar se os mesmos estão ou não autenticados. | |
110 | - </para> | |
111 | - <para> | |
112 | - Para utilizar o <code>SecurityContext</code>, basta injetá-lo em seu código. O método <code>login</code> ativa o mecanismo de autenticação | |
113 | - e o método <code>logout</code> remove as credenciais atualmente autenticadas do sistema. A classe <code>SecurityContext</code> possui | |
114 | - outros métodos que permitem verificar se há um usuário autenticado e acessar o objeto <emphasis>gerente</emphasis> (representado pela | |
115 | - classe <code>javax.security.Principal</code>), um objeto que contém dados adicionais sobre o usuário atualmente autenticado. Consulte | |
116 | - a documentação da classe <code>SecurityContext</code> para consultar as funcionalidades que ela oferece. | |
117 | - </para> | |
118 | - <para> | |
119 | - Um exemplo do uso do <code>SecurityContext</code> para autenticação segue abaixo: | |
120 | - </para> | |
121 | - <programlisting role="JAVA"><![CDATA[public class ExemploAutenticacao { | |
122 | - | |
123 | - @Inject | |
124 | - private SecurityContext securityContext; | |
125 | - | |
126 | - public void efetuarAutenticacao() { | |
127 | - /* | |
128 | - Obtem as credenciais do usuario, pode ser um login e senha ou um certificado digital. O mais | |
129 | - comum e exibir uma tela HTML contendo um formulario que solicita as informacoes. | |
130 | - */ | |
131 | - | |
132 | - try{ | |
133 | - securityContext.login(); | |
134 | - | |
135 | - //Executa codigo que requer autenticacao | |
136 | - | |
137 | - securityContext.logout(); | |
138 | - } | |
139 | - catch(InvalidCredentialsException exception){ | |
140 | - //Trata credenciais invalidas | |
141 | - } | |
142 | - | |
143 | - } | |
144 | -}]]></programlisting> | |
145 | - </section> | |
146 | - | |
147 | - <section> | |
148 | - <title>Autorização</title> | |
149 | - <para> | |
150 | - Em certos sistemas é necessário não apenas autenticar um usuário, mas também proteger funcionalidades individuais e separar | |
151 | - usuários em grupos que possuem diferentes autorizações de acesso. O mecanismo de autorização é responsável por garantir que apenas | |
152 | - usuários autorizados tenham o acesso concedido a determinados recursos de um sistema. | |
153 | - </para> | |
154 | - | |
155 | - <para> | |
156 | - No modelo de segurança do Framework Demoiselle, a autorização pode acontecer de duas | |
157 | - formas: | |
158 | - <itemizedlist> | |
159 | - <listitem><para>Permissão por funcionalidade, através da anotação @RequiredPermission</para></listitem> | |
160 | - <listitem><para>Permissão por papel, através da anotação @RequiredRole</para></listitem> | |
161 | - </itemizedlist> | |
162 | - </para> | |
163 | - | |
164 | - | |
165 | - <section> | |
166 | - <title>Protegendo o sistema com <emphasis>@RequiredPermission</emphasis></title> | |
167 | - | |
168 | - <para> | |
169 | - A anotação <code>@RequiredPermission</code> permite marcar uma classe ou método e informar que acesso a esse recurso requer | |
170 | - a permissão de executar uma <emphasis>operação</emphasis>. Operação nesse contexto é um nome definido pelo desenvolvedor | |
171 | - que representa uma funcionalidade do sistema. Por exemplo, determinada classe pode ter métodos responsávels por criar, editar, | |
172 | - listar e remover bookmarks, o desenvolvedor pode decidir agrupar esses métodos sobre a operação <emphasis>gerenciar bookmark</emphasis>. | |
173 | - </para> | |
174 | - | |
175 | - <programlisting role="JAVA"><![CDATA[class GerenciadorBookmark { | |
176 | - | |
177 | - @RequiredPermission(resource = "bookmark" , operation = "gerenciar") | |
178 | - public void incluirBookmark(Bookmark bookmark) { | |
179 | - //Ccdigo do metodo | |
180 | - } | |
181 | - | |
182 | - @RequiredPermission(resource = "bookmark", operation = "gerenciar") | |
183 | - public List<Bookmark> listarBookmarks() { | |
184 | - //Codigo do metodo | |
185 | - } | |
186 | - | |
187 | - @RequiredPermission | |
188 | - public List<Bookmark> apagarBookmark(Long idBookmark) { | |
189 | - public List<Bookmark> listarBookmarks() { | |
190 | - } | |
191 | -}]]></programlisting> | |
192 | - | |
193 | - <tip> | |
194 | - Perceba que a anotação <code>@RequiredPermission</code> sobre o método <code>apagarBookmark</code> não contém parâmetros. Quando não | |
195 | - são passados parâmetros o valor padrão para o parâmetro <code>resource</code> é o nome da classe e o valor padrão para <code>operation</code> | |
196 | - é o nome do método. | |
197 | - </tip> | |
198 | - | |
199 | - <tip> | |
200 | - É possível anotar a classe inteira com <code>@RequiredPermission</code>, isso protegerá o acesso a todos os métodos dessa classe. | |
201 | - | |
202 | - <programlisting role="JAVA"><![CDATA[@RequiredPermission(resource="bookmark" , operation="gerenciar") | |
203 | -class GerenciadorBookmark { | |
204 | - | |
205 | - public void incluirBookmark(Bookmark bookmark) { | |
206 | - //Codigo do metodo | |
207 | - } | |
208 | - | |
209 | - public List<Bookmark> listarBookmarks() { | |
210 | - //Codigo do metodo | |
211 | - } | |
212 | - | |
213 | - public List<Bookmark> apagarBookmark(Long idBookmark) { | |
214 | - public List<Bookmark> listarBookmarks() { | |
215 | - } | |
216 | -}]]></programlisting> | |
217 | - </tip> | |
218 | - </section> | |
219 | - | |
220 | - <section> | |
221 | - <title>Protegendo o sistema com <emphasis>@RequiredRole</emphasis></title> | |
222 | - | |
223 | - <para> | |
224 | - Diferente de <code>@RequiredPermission</code>, a anotação <code>@RequiredRole</code> utiliza o conceito | |
225 | - de papéis - ou perfís - para proteger recursos. Uma classe ou método anotado com <code>@RequiredRole</code> | |
226 | - exigirá que o usuário autenticado possua o papel indicado para acessar o recurso. | |
227 | - </para> | |
228 | - | |
229 | - <para> | |
230 | - Voltando ao exemplo de nosso aplicativo de bookmarks, vamos supor que a função de listar os bookmarks existentes | |
231 | - pode ser acessada por qualquer usuário autenticado, mas apenas administradores podem criar um novo bookmark. A classe | |
232 | - responsável por tais funcionalidades pode ser criada da seguinte forma: | |
233 | - </para> | |
234 | - | |
235 | - <programlisting role="JAVA"><![CDATA[class GerenciadorBookmark { | |
236 | - | |
237 | - @RequiredRole("administrador") | |
238 | - public void inserirBookmark(Bookmark bookmark) { | |
239 | - } | |
240 | - | |
241 | - @RequiredRole({"convidado" , "administrador"}) | |
242 | - public List<Bookmark> listarBookmarks() { | |
243 | - } | |
244 | - | |
245 | -}]]></programlisting> | |
246 | - <tip> | |
247 | - É possível informar mais de um papel para a anotação <code>@RequiredRole</code>, neste caso basta que o usuário | |
248 | - autenticado possua um dos papéis listados para ter acesso ao recurso. | |
249 | - </tip> | |
250 | - | |
251 | - <para> | |
252 | - Da mesma forma que a anotação <code>@RequiredPermission</code>, a anotação <code>@RequiredRole</code> pode ser usada | |
253 | - a nível de classe para proteger todos os métodos contidos nessa classe. | |
254 | - </para> | |
255 | - </section> | |
256 | - | |
257 | - <section> | |
258 | - <title>Protegendo porções do código</title> | |
259 | - | |
260 | - <para> | |
261 | - É possível proteger apenas parte de um código ao invés de todo o método ou toda a classe. Isso pode ser necessário em | |
262 | - expressões condicionais, onde um trecho só deve ser executado caso o usuário possua a autorização necessária. | |
263 | - Para isso voltamos a usar a interface <code>SecurityContext</code>, pois ela contém métodos que são funcionalmente equivalentes | |
264 | - às anotações <code>@RequiredPermission</code> e <code>@RequiredRole</code>. | |
265 | - </para> | |
266 | - | |
267 | - <para> | |
268 | - Como um exemplo, vamos supor que ao remover um bookmark um email seja enviado ao administrador, mas se o próprio | |
269 | - administrador executou a operação não é necessário enviar o email. | |
270 | - </para> | |
271 | - | |
272 | - <programlisting role="JAVA"><![CDATA[class GerenciadorBookmark { | |
273 | - | |
274 | - @Inject | |
275 | - private SecurityContext securityContext; | |
276 | - | |
277 | - public void removerBookmark(Long idBookmark) { | |
278 | - | |
279 | - //Codigo que remove o bookmark | |
280 | - | |
281 | - if ( ! securityContext.hasRole("administrador") ){ | |
282 | - //Envia um email ao administrador | |
283 | - } | |
284 | - | |
285 | - } | |
286 | - | |
287 | -}]]></programlisting> | |
288 | - | |
289 | - </section> | |
290 | - | |
291 | - <section> | |
292 | - <title>Protegendo porções de páginas <code>Java Server Faces</code></title> | |
293 | - | |
294 | - <para> | |
295 | - As restrições de segurança podem ser utilizadas ainda em páginas web, com o auxílio de Expression Language. A interface | |
296 | - <code>SecurityContext</code> está automaticamente disponível para páginas <code>Java Server Faces</code> como um <emphasis>bean</emphasis> | |
297 | - de nome <code>securityContext</code>, bastando então acessar seus métodos a partir deste bean. | |
298 | - </para> | |
299 | - | |
300 | - <programlisting role="XHTML"><![CDATA[<p:commandButton value="#{messages['button.save']}" action="#{contactEditMB.insert}" | |
301 | - ajax="false" disabled="#{!securityContext.hasPermission('contact', 'insert')}" />]]></programlisting> | |
302 | - | |
303 | - <para> | |
304 | - Nesse caso, a habilitação de um botão está condicionada à existência de permissão para o usuário autenticado no momento | |
305 | - executar a operação “insert” no recurso “contact”. | |
306 | - </para> | |
307 | - </section> | |
308 | - </section> | |
309 | - | |
310 | - <section> | |
311 | - <title>Redirecionando automaticamente para um formulário de acesso</title> | |
312 | - | |
313 | - <para> | |
314 | - Se sua aplicação usa a extensão <emphasis>demoiselle-jsf</emphasis> ou se você utilizou o arquétipo <emphasis>demoiselle-jsf-jpa</emphasis> | |
315 | - durante a criação de seu projeto, então você pode definir uma página de login e o Framework Demoiselle vai automaticamente lhe redirecionar | |
316 | - para essa página caso haja a tentativa de acessar um recurso protejido e nenhum usuário esteja autenticado no sistema. | |
317 | - </para> | |
318 | - | |
319 | - <tip> | |
320 | - <para>Para acrescentar a extensão <emphasis>demoiselle-jsf</emphasis> em um projeto Maven, adicione a dependência abaixo | |
321 | - no arquivo <emphasis>pom.xml</emphasis>.</para> | |
322 | - | |
323 | - <programlisting role="XML"><![CDATA[ | |
324 | -<dependency> | |
325 | - <groupId>br.gov.frameworkdemoiselle</groupId> | |
326 | - <artifactId>demoiselle-jsf</artifactId> | |
327 | - <scope>compile</scope> | |
328 | -</dependency>]]></programlisting> | |
329 | - | |
330 | - <para> | |
331 | - O arquétipo <emphasis>demoiselle-jsf-jpa</emphasis> já contém essa extensão, se você criou seu projeto | |
332 | - baseado nesse arquétipo nada precisa ser feito. | |
333 | - </para> | |
334 | - </tip> | |
335 | - | |
336 | - <para> | |
337 | - Por padrão a página contendo o formulário de login deve se chamar <emphasis>login.jsp</emphasis> ou <emphasis>login.xhtml</emphasis> | |
338 | - (a depender de como sua aplicação esteja configurada para mapear páginas JSF). Para mudar esse padrão, é possível | |
339 | - editar o arquivo <emphasis>demoiselle.properties</emphasis> para configurar qual página deve ser utilizada. | |
340 | - </para> | |
341 | - | |
342 | - <table> | |
343 | - <title>Propriedades de segurança da extensão <emphasis>demoiselle-jsf</emphasis></title> | |
344 | - <tgroup cols="3"> | |
345 | - <colspec align="left" colwidth="40*"/> | |
346 | - <colspec align="left" colwidth="40*"/> | |
347 | - <colspec align="right" colwidth="20*"/> | |
348 | - | |
349 | - <thead> | |
350 | - <row valign="top"> | |
351 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
352 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
353 | - <entry><emphasis role="bold">Valor padrão</emphasis></entry> | |
354 | - </row> | |
355 | - </thead> | |
356 | - <tbody> | |
357 | - <row valign="top"> | |
358 | - <entry>frameworkdemoiselle.​security.​login.​page</entry> | |
359 | - <entry> | |
360 | - <para> | |
361 | - Define a página de login da aplicação. | |
362 | - </para> | |
363 | - </entry> | |
364 | - <entry>"/login"</entry> | |
365 | - </row> | |
366 | - <row valign="top"> | |
367 | - <entry>frameworkdemoiselle.​security.​redirect.​after.​login</entry> | |
368 | - <entry> | |
369 | - <para> | |
370 | - Define a tela para qual o usuário será redirecionado após o processo de <emphasis>login</emphasis> bem sucedido. | |
371 | - </para> | |
372 | - </entry> | |
373 | - <entry>"/index"</entry> | |
374 | - </row> | |
375 | - <row valign="top"> | |
376 | - <entry>frameworkdemoiselle.​security.​redirect.​after.​logout</entry> | |
377 | - <entry> | |
378 | - <para> | |
379 | - Define a tela para qual o usuário será redirecionado após o processo de <emphasis>logout</emphasis> bem sucedido. | |
380 | - </para> | |
381 | - </entry> | |
382 | - <entry>"/login"</entry> | |
383 | - </row> | |
384 | - <row valign="top"> | |
385 | - <entry>frameworkdemoiselle.​security.​redirect.​enabled</entry> | |
386 | - <entry> | |
387 | - <para> | |
388 | - Habilita ou desabilita o redirecionamento automático para a página de login após uma tentativa | |
389 | - de acessar recurso protegido. | |
390 | - </para> | |
391 | - </entry> | |
392 | - <entry>true</entry> | |
393 | - </row> | |
394 | - </tbody> | |
395 | - </tgroup> | |
396 | - </table> | |
397 | - | |
398 | - </section> | |
399 | - | |
400 | - <section> | |
401 | - <title>Integrando o Framework Demoiselle com a especificação JAAS</title> | |
402 | - | |
403 | - <para> | |
404 | - Até agora vimos como criar código protegido em uma aplicação Demoiselle, mas nada foi dito sobre a tecnologia que implementa essa | |
405 | - proteção. A verdade é que o Framework Demoiselle dá ao desenvolvedor a liberdade de implementar a solução que mais se adequa ao sistema | |
406 | - desenvolvido, mas o framework também conta com suporte nativo à especificação JAAS (<emphasis>Java Authentication and | |
407 | - Authorization Service</emphasis>). | |
408 | - </para> | |
409 | - | |
410 | - <para> | |
411 | - O suporte a JAAS é fornecido para aplicações WEB e está implementado na extensão | |
412 | - <emphasis>demoiselle-servlet</emphasis>, então é necessário declarar a dependência a essa extensão em sua aplicação. | |
413 | - </para> | |
414 | - | |
415 | - <tip> | |
416 | - <para>Para acrescentar a extensão <emphasis>demoiselle-servlet</emphasis> em um projeto Maven, adicione a dependência abaixo | |
417 | - no arquivo <emphasis>pom.xml</emphasis>.</para> | |
418 | - | |
419 | - <programlisting role="XML"><![CDATA[ | |
420 | -<dependency> | |
421 | - <groupId>br.gov.frameworkdemoiselle</groupId> | |
422 | - <artifactId>demoiselle-servlet</artifactId> | |
423 | - <scope>compile</scope> | |
424 | -</dependency>]]></programlisting> | |
425 | - </tip> | |
426 | - | |
427 | - <tip> | |
428 | - <para> | |
429 | - O arquétipo <emphasis>demoiselle-jsf-jpa</emphasis> já conta com a dependência à extensão <emphasis>demoiselle-jsf</emphasis>, que | |
430 | - por sua vez depende da extensão <emphasis>demoiselle-servlet</emphasis>. Se sua aplicação é baseada no arquétipo | |
431 | - <emphasis>demoiselle-jsf-jpa</emphasis> você já possui a extensão <emphasis>demoiselle-servlet</emphasis>. | |
432 | - </para> | |
433 | - </tip> | |
434 | - | |
435 | - <para> | |
436 | - Uma vez que sua aplicação contenha a extensão <emphasis>demoiselle-servlet</emphasis>, tudo que você precisa fazer é configurar | |
437 | - o suporte a JAAS em seu servidor de aplicação e criar os usuários e papéis necessários. Esta configuração depende do servidor de | |
438 | - aplicação utilizado e foge ao escopo deste documento. | |
439 | - </para> | |
440 | - | |
441 | - <para> | |
442 | - Para autenticar um usuário presente no servidor de aplicação através do JAAS, a extensão <emphasis>demoiselle-servlet</emphasis> | |
443 | - oferece a classe <code>Credentials</code>, que deve ser injetada em seu código. O código abaixo mostra como realizar a autenticação a partir de um servlet. | |
444 | - </para> | |
445 | - | |
446 | - <programlisting role="JAVA"><![CDATA[class LoginServlet extends HttpServlet { | |
447 | - | |
448 | - @Inject | |
449 | - private SecurityContext securityContext; | |
450 | - | |
451 | - @Inject | |
452 | - private Credentials credentials; | |
453 | - | |
454 | - public void doPost(HttpServletRequest req, HttpServletResponse resp) { | |
455 | - | |
456 | - credentials.setUsername( req.getParameter("username") ); | |
457 | - credentials.setPassword( req.getParameter("password") ); | |
458 | - | |
459 | - securityContext.login(); | |
460 | - | |
461 | - } | |
462 | - | |
463 | -}]]></programlisting> | |
464 | - | |
465 | - <para> | |
466 | - Uma vez autenticado o usuário, a anotação <code>@RequiredRole</code> passará a verificar se o usuário presente no JAAS possui o papel informado. | |
467 | - </para> | |
468 | - | |
469 | - <caution> | |
470 | - <para> | |
471 | - A especificação JAAS não prevê o uso de permissões para proteger recursos, apenas papéis de usuários. Por isso ao utilizar a segurança | |
472 | - da especificação JAAS o uso da anotação <code>@RequiredPermission</code> fica vetado. Utilizar essa anotação em um sistema que utilize | |
473 | - JAAS para autorização causará uma exceção quando o recurso for acessado. | |
474 | - </para> | |
475 | - </caution> | |
476 | - | |
477 | - <tip> | |
478 | - <para> | |
479 | - É possível utilizar o JAAS para autenticar e autorizar papéis de usuários mas criar sua própria implementação para | |
480 | - implementar a autorização de permissões. Para isso crie uma classe que herde a classe | |
481 | - <code>br.gov.frameworkdemoiselle.security.ServletAuthorizer</code> e sobrescreva o método <code>hasPermission(String resource, String operation)</code> | |
482 | - para implementar seu próprio mecanismo. Feito isso, basta definir sua classe no arquivo <emphasis>demoiselle.properties</emphasis> usando | |
483 | - a propriedade <code>frameworkdemoiselle.security.authorizer.class</code>. | |
484 | - </para> | |
485 | - | |
486 | - <para> | |
487 | - Mais detalhes sobre como criar sua própria implementação ou extender uma implementação existente podem | |
488 | - ser vistos na seção <link linkend="criando_implementacao_seguranca">Criando sua implementação</link>. | |
489 | - </para> | |
490 | - </tip> | |
491 | - | |
492 | - </section> | |
493 | - | |
494 | - <section id="criando_implementacao_seguranca"> | |
495 | - <title>Criando sua implementação</title> | |
496 | - | |
497 | - <para> | |
498 | - Para os mecanismos de autenticação não cobertos pelo Framework Demoiselle, é possível criar sua própria implementação e integra-la | |
499 | - ao framework. Também é possível extender uma implementação existente e acrescentar funcionalidades inexistentes. | |
500 | - </para> | |
501 | - | |
502 | - <para> | |
503 | - O ponto de extensão para o módulo de segurança são as interfaces <code>Authenticator</code> e <code>Authorizer</code>. Para criar | |
504 | - um novo mecanismo de autenticação e autorização, é necessário apenas implementar essas duas interfaces em sua aplicação. Segue | |
505 | - abaixo um exemplo de implementação. | |
506 | - </para> | |
507 | - | |
508 | - <programlisting role="JAVA"><![CDATA[public class MeuAuthenticator implements Authenticator { | |
509 | - | |
510 | - @Override | |
511 | - public void authenticate() throws Exception { | |
512 | - // Execute o procedimento necessario para autenticar o usuario | |
513 | - // Apos isso, a chamada ao metodo getUser() deve returnar o usuario corrente autenticado, | |
514 | - // e ira retornar nulo (null) se o processo de autenticacao falhar | |
515 | - } | |
516 | - | |
517 | - @Override | |
518 | - public User getUser(){ | |
519 | - // Retorna o usuario que esta autenticado, ou nulo (null) se nao houver usuario autenticado | |
520 | - } | |
521 | - | |
522 | - @Override | |
523 | - public void unauthenticate() throws Exception { | |
524 | - // Execute o procedimento necessario para desautenticar um usuario | |
525 | - // Apos isso, a chamada ao metodo getUser() deve returnar nulo (null) | |
526 | - } | |
527 | -}]]></programlisting> | |
528 | - <programlisting role="JAVA"><![CDATA[public class MeuAuthorizer implements Authorizer { | |
529 | - | |
530 | - @Override | |
531 | - public boolean hasRole(String role) throws Exception { | |
532 | - // Verifique se o usuario autenticado tem o papel informado, retorne true em caso positivo | |
533 | - return false; | |
534 | - } | |
535 | - | |
536 | - @Override | |
537 | - public boolean hasPermission(String resource, String operation) throws Exception { | |
538 | - // Escreva aqui seu codigo de verificacao de permissao | |
539 | - return false; | |
540 | - } | |
541 | -}]]></programlisting> | |
542 | - <note> | |
543 | - <para> | |
544 | - Fique atento! Note que para garantir que o usuário não esteja logado, não basta lançar uma | |
545 | - exceção (InvalidCredencialsException) no método authenticator.autenticate(), mas é preciso que o método | |
546 | - authenticator.getUser() retorne null para que o método securityContext.isLoggedIn() retorne false. | |
547 | - </para> | |
548 | - </note> | |
549 | - <para> | |
550 | - Pronto! Sua aplicação já possui uma implementação de segurança definida. | |
551 | - </para> | |
552 | - | |
553 | - <tip> | |
554 | - <para> | |
555 | - Você nunca deve chamar diretamente em sua aplicação as implementações das interfaces <code>Authenticator</code> | |
556 | - e <code>Authorizer</code>, o Framework Demoiselle vai automaticamente chamar os métodos implementados | |
557 | - quando for necessário. | |
558 | - </para> | |
559 | - </tip> | |
560 | - | |
561 | - <para> | |
562 | - Em um sistema que use as anotações <code>@RequiredRole</code> ou <code>@RequiredPermission</code>, deve haver pelo menos uma implementação | |
563 | - dessas duas interfaces. Ao processar essas anotações, o Framework Demoiselle vai buscar uma implementação para essas interfaces | |
564 | - e disparar uma exceção caso não encontre uma implementação adequada. | |
565 | - </para> | |
566 | - | |
567 | - <para> | |
568 | - Se existe mais de uma implementação de <code>Authenticator</code> e/ou <code>Authorizer</code> (o que pode acontecer, por exemplo, quando | |
569 | - seja necessário uma implementação na aplicação principal e outra para os testes), é possível definir no arquivo <filename>demoiselle.properties</filename> | |
570 | - a classe que deve ser usada por padrão: | |
571 | - </para> | |
572 | - | |
573 | - <informaltable width="100%"> | |
574 | - <tgroup cols="3"> | |
575 | - <colspec align="left" colwidth="40%"/> | |
576 | - <colspec align="left" colwidth="40%"/> | |
577 | - <colspec align="right" colwidth="20%"/> | |
578 | - | |
579 | - <thead> | |
580 | - <row valign="top"> | |
581 | - <entry><emphasis role="bold">Propriedade</emphasis></entry> | |
582 | - <entry><emphasis role="bold">Descrição</emphasis></entry> | |
583 | - <entry><emphasis role="bold">Valor padrão</emphasis></entry> | |
584 | - </row> | |
585 | - </thead> | |
586 | - <tbody> | |
587 | - <row valign="top"> | |
588 | - <entry>frameworkdemoiselle.​security.​authenticator.​class</entry> | |
589 | - <entry> | |
590 | - <para> | |
591 | - Define a classe concreta utilizada como implementação da interface Authenticator | |
592 | - </para> | |
593 | - </entry> | |
594 | - <entry> | |
595 | - <emphasis> | |
596 | - nenhum, se houver apenas uma implementação o framework a detectará | |
597 | - automaticamente sem necessidade de definir essa propriedade | |
598 | - </emphasis> | |
599 | - </entry> | |
600 | - </row> | |
601 | - | |
602 | - <row valign="top"> | |
603 | - <entry>frameworkdemoiselle.​security.​authorizer.​class</entry> | |
604 | - <entry> | |
605 | - <para> | |
606 | - Define a classe concreta utilizada como implementação da interface Authorizer | |
607 | - </para> | |
608 | - </entry> | |
609 | - <entry> | |
610 | - <emphasis> | |
611 | - nenhum, se houver apenas uma implementação o framework a detectará | |
612 | - automaticamente sem necessidade de definir essa propriedade | |
613 | - </emphasis> | |
614 | - </entry> | |
615 | - </row> | |
616 | - </tbody> | |
617 | - </tgroup> | |
618 | - </informaltable> | |
619 | - </section> | |
620 | -</chapter> |
documentation/reference/pt-BR/templates.xml
... | ... | @@ -1,109 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="templates"> | |
5 | - | |
6 | - <title>Templates</title> | |
7 | - | |
8 | - <para> | |
9 | - O <emphasis>Demoiselle Framework</emphasis> | |
10 | - provê abstrações de classes para as camadas de apresentação, negócio e | |
11 | - persistência. Tais classes podem ser encontradas no pacote | |
12 | - <literal>br.gov.frameworkdemoiselle.template</literal> | |
13 | - e auxiliam o desenvolvedor ao disponibilizar métodos comuns à maioria das | |
14 | - aplicações. A seguir iremos exemplificar o uso de cada uma delas. | |
15 | - </para> | |
16 | - | |
17 | - <section> | |
18 | - <title>Camada de persistência</title> | |
19 | - <para> | |
20 | - A classe abstrata <literal>JPACrud</literal> implementa as operações básicas de inclusão, | |
21 | - remoção, atualização e recuperação de registros no banco de dados. | |
22 | - Sendo assim, possibilita que o desenvolvedor concentre-se na criação de | |
23 | - métodos específicos para atender as regras de negócio da sua aplicação. | |
24 | - Esta classe recebe dois parâmetros em notação de genéricos: | |
25 | - <itemizedlist> | |
26 | - <listitem><para><literal>T</literal> representa a entidade que será tratada</para></listitem> | |
27 | - <listitem><para><literal>I</literal> representa o tipo do identificador da entidade</para></listitem> | |
28 | - </itemizedlist> | |
29 | - </para> | |
30 | - <para> | |
31 | - No exemplo abaixo demonstra-se a utilização da <literal>JPACrud</literal>, onde o | |
32 | - desenvolvedor precisou implementar apenas um método específico. | |
33 | - </para> | |
34 | - <programlisting role="JAVA"><![CDATA[@PersistenceController | |
35 | -public class SuaEntidadeDAO extends JPACrud<SuaEntidade, Long> { | |
36 | - | |
37 | - public List<SuaEntidade> findByAlgumCriterioEspecifico(final String criterio) { | |
38 | - Query query = getEntityManager().createQuery("select se from SuaEntidade se where se.criterio = :criterio "); | |
39 | - query.setParameter("criterio", criterio); | |
40 | - return query.getResultList(); | |
41 | - } | |
42 | -}]]></programlisting> | |
43 | - </section> | |
44 | - | |
45 | - <section> | |
46 | - <title>Camada de negócio</title> | |
47 | - <para> | |
48 | - De forma semelhante à classe <literal>JPACrud</literal>, a classe <emphasis>DelegateCrud</emphasis> foi criada | |
49 | - com o intuito de dispensar o desenvolvedor de implementar métodos que | |
50 | - serão comuns à maioria das entidades. Além disso, esta classe | |
51 | - implementa a injeção de dependência entre as camadas de negócio e | |
52 | - persistência. Para utilizá-la, três parâmetros devem ser passados em notação de genéricos: | |
53 | - <itemizedlist> | |
54 | - <listitem><para><literal>T</literal> representa a entidade</para></listitem> | |
55 | - <listitem><para><literal>I</literal> representa o tipo do identificador da entidade</para></listitem> | |
56 | - <listitem><para><literal>C</literal> representa uma classe que implemente a interface <literal>CRUD</literal></para></listitem> | |
57 | - </itemizedlist> | |
58 | - </para> | |
59 | - <para> | |
60 | - Segue abaixo um exemplo da utilização do <emphasis>DelegateCrud</emphasis>. | |
61 | - Neste caso, foi implementado um método para validar a entidade antes | |
62 | - de proceder com a inclusão no banco de dados. Para isso, o método | |
63 | - <function>insert()</function> fornecido pela classe foi sobrescrito. | |
64 | - </para> | |
65 | - <programlisting role="JAVA"><![CDATA[@BusinessController | |
66 | -public class SuaEntidadeBC extends DelegateCrud<SuaEntidade, Long, SuaEntidadeDAO> { | |
67 | - | |
68 | - private void validateInsert(SuaEntidade se) { | |
69 | - // valida os atributos da entidade | |
70 | - } | |
71 | - | |
72 | - @Override | |
73 | - @Transactional | |
74 | - public void insert(SuaEntidade se) { | |
75 | - validateInsert(se); | |
76 | - super.insert(se); | |
77 | - } | |
78 | -}]]></programlisting> | |
79 | - </section> | |
80 | - | |
81 | - <section> | |
82 | - <title>Camada de apresentação</title> | |
83 | - <para> | |
84 | - Para a camada de apresentação, existem duas classes que implementam os | |
85 | - comportamentos básicos de navegação para páginas de listagem e edição. | |
86 | - Estas classes são <literal>AbstractListPageBean</literal> e <literal>AbstractEditPageBean</literal>, | |
87 | - respectivamente. De forma semelhante à <literal>DelegateCrud</literal>, estas classes realizam a | |
88 | - injeção de dependência da camada de negócio dentro do artefato da | |
89 | - camada de apresentação. Ambas recebem dois parâmetros em notação de genéricos: | |
90 | - <itemizedlist> | |
91 | - <listitem><para><literal>T</literal> representa a entidade que será tratada</para></listitem> | |
92 | - <listitem><para><literal>I</literal> representa o tipo do identificador da entidade</para></listitem> | |
93 | - </itemizedlist> | |
94 | - </para> | |
95 | - <para> | |
96 | - Estendendo o <literal>AbstractListPageBean</literal>: | |
97 | - </para> | |
98 | - <programlisting role="JAVA"><![CDATA[@ViewController | |
99 | -public class SuaEntidadeListMB extends AbstractListPageBean<SuaEntidade, Long> { | |
100 | -}]]></programlisting> | |
101 | - <para> | |
102 | - Estendendo o <literal>AbstractEditPageBean</literal>: | |
103 | - </para> | |
104 | - <programlisting role="JAVA"><![CDATA[@ViewController | |
105 | -public class SuaEntidadeEditMB extends AbstractEditPageBean<SuaEntidade, Long> { | |
106 | -}]]></programlisting> | |
107 | - </section> | |
108 | - | |
109 | -</chapter> | |
110 | 0 | \ No newline at end of file |
documentation/reference/pt-BR/transacao.xml
... | ... | @@ -1,274 +0,0 @@ |
1 | -<?xml version='1.0' encoding="utf-8"?> | |
2 | -<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | |
3 | - "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" []> | |
4 | -<chapter id="transacao"> | |
5 | - | |
6 | - <title>Transação</title> | |
7 | - | |
8 | - <para> | |
9 | - Esta funcionalidade utiliza os recursos do CDI para interceptar e delegar adequadamente o tratamento das transações. | |
10 | - Em outras palavras, não reinventamos a roda. Criamos algumas estratégias de delegação e | |
11 | - controle de transação com base no que está sendo mais utilizado no mercado, algumas mais simples de configurar, | |
12 | - outras mais completas para utilizar. | |
13 | - </para> | |
14 | - <para> | |
15 | - Além de plugar e usar as estratégias prontas que fizemos para você, é possível também criar a sua. Vai que você | |
16 | - precise de algo que não pensamos ainda. O importante é que você tenha opções, e uma das opções também é não | |
17 | - utilizar a nossa solução. Caso você esteja utilizando o <emphasis>Demoiselle Framework</emphasis> em conjunto | |
18 | - com outro framework (tais como o JBoss Seam, Spring ou Google Guice) que ofereça o controle de transação, | |
19 | - você pode usá-lo também. Viva a liberdade de escolha! | |
20 | - </para> | |
21 | - <para> | |
22 | - Neste capítulo apresentaremos para você como usar a nossa solução de controle de transação, as estratégias | |
23 | - prontas que oferecemos e a criação de sua própria estratégia. | |
24 | - </para> | |
25 | - | |
26 | - <section> | |
27 | - <title>Configurando</title> | |
28 | - <para> | |
29 | - Para um correto funcionamento do Demoiselle é necessário inserir o interceptador de transação no arquivo <filename>src/main/WEB-INF/beans.xml</filename>. | |
30 | - </para> | |
31 | - <programlisting role="XML"><![CDATA[<beans xmlns="http://java.sun.com/xml/ns/javaee" | |
32 | - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
33 | - xsi:schemaLocation="http://java.sun.com/xml/ns/javaee | |
34 | - http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> | |
35 | - | |
36 | - <interceptors> | |
37 | - <class>br.gov.frameworkdemoiselle.transaction.TransactionalInterceptor</class> | |
38 | - </interceptors> | |
39 | -</beans>]]></programlisting> | |
40 | - </section> | |
41 | - | |
42 | - <section> | |
43 | - <title>Métodos transacionais</title> | |
44 | - <para> | |
45 | - Vamos começar pelo mais importante: como declarar os métodos como transacionais? Como informar ao | |
46 | - <emphasis>Demoiselle Framework</emphasis> que o método deve participar da sessão transacional? | |
47 | - A resposta é muito simples: anote seu método com <literal>@Transactional</literal>. | |
48 | - </para> | |
49 | - <programlisting role="JAVA"><![CDATA[@Transactional | |
50 | -public void inserir() { }]]></programlisting> | |
51 | - <para> | |
52 | - Se você desejar que todos os métodos de sua classe sejam transacionais, anote diretamente a classe: | |
53 | - </para> | |
54 | - <programlisting role="JAVA"><![CDATA[@Transactional | |
55 | -public class Simples { | |
56 | - public void inserir() { } | |
57 | - public void alterar() { } | |
58 | - public void excluir() { } | |
59 | -}]]></programlisting> | |
60 | - <para> | |
61 | - Neste exemplo, os métodos <function>inserir()</function>, <function>alterar()</function> e | |
62 | - <function>excluir()</function> da classe <literal>Simples</literal> participarão do contexto transacional. | |
63 | - </para> | |
64 | - </section> | |
65 | - | |
66 | - <section> | |
67 | - <title>E se acontecer uma Exception?</title> | |
68 | - <para> | |
69 | - Caso ocorra uma exceção na execução de um método transacional, o mecanismo fará rollback na transação | |
70 | - automaticamente. É possível mudar este comportamento utilizando exceções de aplicação (para maiores detalhes ver <link linkend="excecao">Exceção</link>). | |
71 | - </para> | |
72 | - <programlisting role="JAVA"><![CDATA[@ApplicationException(rollback = false) | |
73 | -public class AbacaxiException { | |
74 | -}]]></programlisting> | |
75 | - </section> | |
76 | - | |
77 | - <section> | |
78 | - <title>O objeto Transaction</title> | |
79 | - <para> | |
80 | - Para ter acesso à instância da transação corrente, basta injetar <literal>TransactionContext</literal> em sua classe e obter a transação corrente. | |
81 | - </para> | |
82 | - <programlisting role="JAVA"><![CDATA[public class Simples { | |
83 | - @Inject | |
84 | - private TransactionContext transactionContext; | |
85 | - | |
86 | - public void experimento() { | |
87 | - Transaction transaction = transactionContext.getCurrentTransaction(); | |
88 | - } | |
89 | -}]]></programlisting> | |
90 | - </section> | |
91 | - | |
92 | - <section> | |
93 | - <title>A estratégia mais adequada</title> | |
94 | - <para> | |
95 | - Para o controle transacional funcionar corretamente é preciso escolher a estratégia mais adequada para o seu | |
96 | - caso. Não existe a bala de prata, você tem que avaliar a melhor estratégia para o seu projeto. | |
97 | - </para> | |
98 | - <para> | |
99 | - Você também pode optar por não utilizar controle de transação. Neste caso, basta não utilizar a anotação <literal>@Transactional</literal>. Contudo, | |
100 | - caso você a utilize, você poderá escolher entre as estratégias JPA, JDBC, JTA (ambas fornecidas pelo <literal>Framework</literal>) e uma estratégia que você | |
101 | - pode criar ou importar para seu projeto. | |
102 | - </para> | |
103 | - <para> | |
104 | - A forma de selecionar cada uma dessas estratégias é descrita abaixo. Caso tente utilizar o controle de transação e não selecione nenhuma estratégia, | |
105 | - o framework lançará uma exceção lhe avisando sobre isto! | |
106 | - </para> | |
107 | - </section> | |
108 | - | |
109 | - <section> | |
110 | - <title>Estratégia JDBC</title> | |
111 | - <para> | |
112 | - Esta estratégia, que está disponível na extensão <literal>demoiselle-jdbc</literal>, delega o | |
113 | - controle das transações para o <literal>java.sql.Connection</literal> da | |
114 | - especificação JDBC. Você deve escolher esta estratégia quando estiver persistindo dados | |
115 | - com JDBC e utilizando apenas uma base de dados em sua aplicação. Como um <literal>Connection</literal> | |
116 | - acessa apenas uma base de dados, não há como fazer o controle transacional de base de dados distintas. | |
117 | - </para> | |
118 | - <para> | |
119 | - A transação JDBC é simples de configurar e não exige nenhum recurso externo à sua aplicação. | |
120 | - Para utilizá-la basta que seu projeto adicione no arquivo pom.xml dependência à extensão <literal>demoiselle-jdbc</literal>, que o | |
121 | - Demoiselle fará a seleção por essa estratégia de forma automática. | |
122 | - </para> | |
123 | - | |
124 | - <tip><para>Para utilizar a estratégia de transação JDBC, inclua a dependência para extensão JDBC | |
125 | - no arquivo pom.xml.</para> | |
126 | - <programlisting role="XML"><![CDATA[<dependency> | |
127 | - <groupId>br.gov.frameworkdemoiselle</groupId> | |
128 | - <artifactId>demoiselle-jdbc</artifactId> | |
129 | - <scope>compile</scope> | |
130 | -</dependency>]]></programlisting></tip> | |
131 | - </section> | |
132 | - | |
133 | - <section> | |
134 | - <title>Estratégia JPA</title> | |
135 | - <para> | |
136 | - Esta estratégia, que está disponível na extensão <literal>demoiselle-jpa</literal>, delega o | |
137 | - controle das transações para o <literal>javax.persistence.EntityManager</literal> da | |
138 | - especificação JPA. Você deve escolher esta estratégia quando estiver persistindo dados | |
139 | - com JPA e utilizando apenas uma base de dados em sua aplicação. Como um <literal>EntityManager</literal> | |
140 | - acessa apenas uma unidade de persistência, não há como fazer o controle transacional de unidades distintas. | |
141 | - </para> | |
142 | - <para> | |
143 | - A transação JPA é simples de configurar e não exige nenhum recurso externo à sua aplicação. | |
144 | - Para utilizá-la basta que seu projeto adicione no arquivo pom.xml dependência à extensão <literal>demoiselle-jpa</literal>, que o | |
145 | - Demoiselle fará a seleção por essa estratégia de forma automática. | |
146 | - </para> | |
147 | - | |
148 | - <tip><para>Caso não esteja utilizando o arquétipo JSF-JPA fornecidos pelo Demoiselle, confira se a dependência para a | |
149 | - extensão está indicada corretamente no arquivo pom.xml.</para> | |
150 | - <programlisting role="XML"><![CDATA[<dependency> | |
151 | - <groupId>br.gov.frameworkdemoiselle</groupId> | |
152 | - <artifactId>demoiselle-jpa</artifactId> | |
153 | - <scope>compile</scope> | |
154 | -</dependency>]]></programlisting></tip> | |
155 | - </section> | |
156 | - | |
157 | - <section> | |
158 | - <title>Estratégia JTA</title> | |
159 | - <para> | |
160 | - Esta estratégia, também disponível através de uma extensão (<literal>demoiselle-jta</literal>), é | |
161 | - responsável por delegar o controle de transação para um container JEE. Com a <literal>JTATransaction</literal> | |
162 | - é possível incluir várias unidades de persistência de uma mesma aplicação no mesmo contexto transacional. | |
163 | - Isso mesmo, o famoso <emphasis>Two-Phase Commit (2PC)</emphasis>. | |
164 | - </para> | |
165 | - <para> | |
166 | - A estratégia JTA não serve apenas para persistência em banco de dados, serve também para integrar com | |
167 | - tecnologias que façam acesso ao contexto JTA, como é o caso do EJB. Para ativar esta estratégia basta | |
168 | - que seu projeto adicione no arquivo pom.xml a dependência à extensão <literal>demoiselle-jta</literal>, que o | |
169 | - Demoiselle fará a seleção por essa estratégia de forma automática, pois essa estratégia tem prioridade em relação | |
170 | - à estratégia JPA e JDBC. | |
171 | - </para> | |
172 | - <!-- | |
173 | - defina no | |
174 | - arquivo <filename>demoiselle.properties</filename> a seguinte configuração: | |
175 | - </para> | |
176 | - <programlisting>frameworkdemoiselle.transaction.class=br.gov.frameworkdemoiselle.transaction.JTATransaction</programlisting> | |
177 | - --> | |
178 | - <para> | |
179 | - Feito isto, o controle transacional será delegado para a transação acessível via JNDI com o nome | |
180 | - <literal>UserTransaction</literal>. A estratégia acessa o objeto da seguinte maneira: | |
181 | - <literal>Beans.getReference(UserTransaction.class)</literal>. Portanto, para você utilizar esta estratégia, | |
182 | - você precisa de um container JEE ou de um servidor JTA qualquer. | |
183 | - </para> | |
184 | - <para> | |
185 | - Caso você esteja persistindo os dados com JPA, é preciso também informar no arquivo <filename>persistence.xml</filename> | |
186 | - o endereço da conexão JTA gerenciada. Veja um exemplo utilizando o servidor de aplicações JBoss AS7 e com o | |
187 | - provider Hibernate (embutido no JBoss AS) como implementação JPA: | |
188 | - </para> | |
189 | -<programlisting role="XML"><![CDATA[<?xml version="1.0" encoding="UTF-8"?> | |
190 | -<persistence version="2.0" | |
191 | - xmlns="http://java.sun.com/xml/ns/persistence" | |
192 | - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
193 | - xsi:schemaLocation="http://java.sun.com/xml/ns/persistence | |
194 | - http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> | |
195 | - | |
196 | - <persistence-unit name="bookmark-ds" transaction-type="JTA"> | |
197 | - <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source> | |
198 | - <properties> | |
199 | - <property name="hibernate.show_sql" value="true" /> | |
200 | - <property name="hibernate.format_sql" value="false" /> | |
201 | - <property name="hibernate.hbm2ddl.auto" value="update" /> | |
202 | - <property name="hibernate.transaction.jta.platform" | |
203 | - value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" /> | |
204 | - </properties> | |
205 | - </persistence-unit> | |
206 | -</persistence>]]></programlisting> | |
207 | - | |
208 | - <tip><para>Caso não esteja utilizando o arquétipo JSF-JPA fornecidos pelo Demoiselle, confira se a dependência para a | |
209 | - extensão está indicada corretamente, no arquivo pom.xml.</para> | |
210 | - <programlisting role="XML"><![CDATA[<dependency> | |
211 | - <groupId>br.gov.frameworkdemoiselle</groupId> | |
212 | - <artifactId>demoiselle-jta</artifactId> | |
213 | - <scope>compile</scope> | |
214 | -</dependency>]]></programlisting></tip> | |
215 | - | |
216 | - <para> | |
217 | - Caso você esteja persistindo os dados com JDBC, é preciso informar no arquivo <filename>demoiselle.properties</filename> | |
218 | - o endereço da conexão JTA gerenciada. Veja um exemplo utilizando o servidor de aplicações JBoss AS7: | |
219 | - </para> | |
220 | - | |
221 | -<programlisting role="XML"><![CDATA[frameworkdemoiselle.persistence.jndi.name=java:jboss/datasources/ExampleDS]]></programlisting> | |
222 | - </section> | |
223 | - | |
224 | - <section> | |
225 | - <title>Criando sua própria estratégia</title> | |
226 | - <para> | |
227 | - Caso nenhuma das estratégias oferecidas sirva para você, crie a sua. Basta escrever uma | |
228 | - classe não-final que implemente a interface <literal>Transaction</literal> do pacote | |
229 | - <literal>br.gov.frameworkdemoiselle.transaction</literal>. <!--Anote a classe com | |
230 | - <literal>@SessionScoped</literal> e <literal>@Alternative</literal> para que o CDI saiba | |
231 | - que se trata de uma estratégia.-->É preciso que sua classe não possua construtores explícitos ou | |
232 | - que possua um construtor público sem parâmetros. É possível fazer injeções nesta classe. | |
233 | - </para> | |
234 | - <!-- import javax.enterprise.context.SessionScoped; | |
235 | - import javax.enterprise.inject.Alternative; | |
236 | - @Alternative | |
237 | - @SessionScoped --> | |
238 | - <programlisting role="JAVA"><![CDATA[package projeto; | |
239 | - | |
240 | -import br.gov.frameworkdemoiselle.transaction.Transaction; | |
241 | - | |
242 | -public class MyTransaction implements Transaction { | |
243 | - public void begin() { } | |
244 | - public void commit() { } | |
245 | - public void rollback() { } | |
246 | - public void setRollbackOnly() { } | |
247 | - public int getStatus() { } | |
248 | - public void setTransactionTimeout(int seconds) { } | |
249 | - public boolean isActive() { } | |
250 | - public boolean isMarkedRollback() { } | |
251 | -}]]></programlisting> | |
252 | - <para> | |
253 | - Pronto, é só isso! Agora, os métodos anotados com <literal>@Transactional</literal> irão utilizar a estratégia criada em seu projeto de forma automática, | |
254 | - mesmo que as extensões <literal>demoiselle-jdbc</literal>, <literal>demoiselle-jpa</literal> e <literal>demoiselle-jta</literal> sejam adicionadas ao | |
255 | - projeto, pois o framework dará prioridade máxima à estratégia criada no projeto. | |
256 | - </para> | |
257 | - </section> | |
258 | - | |
259 | - <section> | |
260 | - <title>Escolhendo a estratégia manualmente</title> | |
261 | - <para> | |
262 | - Existem alguns casos nos quais você vai ter que definir a estratégia manualmente. Um exemplo é quando seu projeto implementa mais do que uma estratégia | |
263 | - de transação. Outra situação pode acontecer em casos de teste, nos quais você queira utilizar estratégia diferente. Nesses casos você deve definir no | |
264 | - arquivo <filename>demoiselle.properties</filename> qual estratégia será utilizada. Veja alguns exemplos de definição de estratégias própria, | |
265 | - <literal>JDBCTransaction</literal>, <literal>JPATransaction</literal> e <literal>JTATransaction</literal>. É importante notar que apenas uma estratégia | |
266 | - pode estar ativa por vez: | |
267 | - </para> | |
268 | - <programlisting>frameworkdemoiselle.transaction.class=projeto.MyTransaction | |
269 | -frameworkdemoiselle.transaction.class=br.gov.frameworkdemoiselle.transaction.JDBCTransaction | |
270 | -frameworkdemoiselle.transaction.class=br.gov.frameworkdemoiselle.transaction.JPATransaction | |
271 | -frameworkdemoiselle.transaction.class=br.gov.frameworkdemoiselle.transaction.JTATransaction</programlisting> | |
272 | - </section> | |
273 | - | |
274 | -</chapter> |