<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SubMundo Java &#187; Henrique Lima</title>
	<atom:link href="http://submundojava.com.br/wordpress/author/henrique/feed/" rel="self" type="application/rss+xml" />
	<link>http://submundojava.com.br/wordpress</link>
	<description>Um pouco de tudo, mas tecnologia acima de tudo!</description>
	<lastBuildDate>Wed, 26 May 2010 15:00:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Avaliação de desempenho de sistemas &#8211; parte 1</title>
		<link>http://submundojava.com.br/wordpress/2010/04/18/avaliacao-desempenho-sistemas/</link>
		<comments>http://submundojava.com.br/wordpress/2010/04/18/avaliacao-desempenho-sistemas/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 23:27:43 +0000</pubDate>
		<dc:creator>Henrique Lima</dc:creator>
				<category><![CDATA[analise de desempenho]]></category>
		<category><![CDATA[garbage collector]]></category>
		<category><![CDATA[gc]]></category>
		<category><![CDATA[gcviewer]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jhap]]></category>
		<category><![CDATA[jmap]]></category>
		<category><![CDATA[leak memory]]></category>
		<category><![CDATA[vazamento de memória]]></category>

		<guid isPermaLink="false">http://submundojava.com.br/wordpress/?p=121</guid>
		<description><![CDATA[A análise de desempenho consiste em identificar e mensurar as atividades de um sistema durante um determinado intervalo de tempo, a fim de estabelecer um plano de aumento de performance. O resultado desta análise é a compilação de uma lista de ações contendo o ganho, a prioridade e o impacto no sistema. Desta forma, pode [...]]]></description>
			<content:encoded><![CDATA[<div><span id="internal-source-marker_0.9085238836705685">A análise de desempenho consiste em identificar e mensurar as atividades de um sistema durante um determinado intervalo de tempo, a fim de estabelecer um plano de aumento de performance. O resultado desta análise é a compilação de uma lista de ações contendo o ganho, a prioridade e o impacto no sistema. Desta forma, pode ser decidido a ordem em que serão tomadas as ações. </span><span>Na plataforma Java são muitos os aspectos que podem comprometer o desempenho de um sistema, entre eles:</p>
<p></span></div>
<div>
<p><strong>Dimensionamento do pool de conexões</strong><span> &#8211; se, por exemplo,  um banco de dados tiver um limite de 100 conexões e você possuir 3 aplicações com pools de 100 conexões (300 conexões ao total) você pode ter alguma requisição aguardando uma conexão ser liberada pelo pool, ocasionando lentidão no sistema. </span><br />
<strong></strong></p>
<p><strong>PreparedStatements</strong><span> &#8211; </span><span>Normalmente uma conexão tem uma relação de “um pra um” com um PreparedStatement, entretanto, a criação deste objeto pode ser custoso. Em servidores de aplicações modernos é possível “cachear” PreparedStatements. Para cada conexão é criado um cache, tornando as consultas ao banco de dados mais veloz. É possível configurar o tamanho do cache de PreparedStatements o que pode impactar na velocidade do sistema para baixo ou para cima.</span></p>
<p><strong>Gerenciamento de memória</strong><span> &#8211; </span><span>Embora a JVM possua um mecanismo eficiente de coleta de lixo, um bug na aplicação pode fazer com que o coletor de lixo (garbage collector) não identifique os objetos que devem ser excluídos da memória, resultando em um fenômeno conhecido como vazamento de memória (leak memory) e consequentemente em OutOfMemoryError.</span></p>
<p><strong>Outros</strong> &#8211; Outros fatores envolvendo e/ou não a plataforma Java podem ocasionar lentidão em seu sistema como CPU, Run Queue, I/O, Network Throughput e etc.</p>
<p><strong>Por onde iniciar</strong></p>
<p><span>É muito comum iniciar uma análise de desempenho “atacando” os gargalos. Em Java, um dos problemas mais comuns esta justamente no gerenciamento de memória, ocasinado pela sua aplicação ou por um framework de terceiro. Muitas vezes apenas a atualização de um framework pode garantir um ganho enorme de performance. Neste primeiro POST, irei abordar uma das maneiras de analisar a heap de uma aplicação Java, tendo como foco a identificação de vazamento de memória.<br />
</span></p>
<p><strong>Entendendo a coleta de lixo</strong></p>
<p><span>De uma maneira bem simples, um objeto é elegível a ser coletado pelo mecanismo de coleta de lixo quando nenhum outro objeto da heap o referencia. Desta forma, se criamos uma aplicação cujo a soma de número de objetos instanciados (em bytes) é maior que o tamanho configurado da heap, então acontece OutOfMemoryError. É muito comum isto acontecer em relatórios cujo o número de registros apresentados ao usuário é muito grande e em funcionalidades stateful. É justamente nesta parte do sistema que devemos suspeitar em um primeiro momento.</span></p>
<p><strong>Identificando “O” vazamento de memória</strong></p>
<p><span>Muitas vezes nós, desenvolvedores, não temos a noção (embora devessemos) de qual funcionalidade é mais utilizada do sistema e para sistemas com muitas funcionalidades fica ainda mais difícil saber por onde começar, desta forma, uma maneira eficiente de identificar vazamento de memória é no sistema em produção.</span></p>
<p><span>A maneira mais simples de identificar um vazamento de memória é através de <a title="JMX" href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/" target="_blank">JMX</a>, entretanto, para que isto funcione é necessário que <a title="JMX" href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/" target="_blank">JMX</a> esteja ativado no servidor, o que pode ser incomum (ou apenas não permitir conexão remota). A maneira que irei demonstrar a seguir, consiste em utilizar do log do garbage collector para obter um gráfico similar ao obtido pelo <a title="jconsole" href="http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html" target="_blank">jconsole</a>, pois é muito mais simples você convencer ao administrador a ativar o log do que o suporte a <a title="JMX" href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/" target="_blank">JMX</a> (ou conexão remota via <a title="JMX" href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/" target="_blank">JMX</a>).</span></p>
<p><strong>Obtendo o log do GC</strong></p>
<p><span>Para ativar o log da <a title="JVM Sun Hotspot" href="http://java.sun.com/javase/technologies/hotspot/" target="_blank">JVM (Sun Hostpot)</a> passe os seguintes parâmetros ao inicia-la:</span></p>
<p><span>-verbose:gc </span><br />
<span>-Xloggc:PATH_TO_LOG_FILE</span></p>
<p><strong>Exemplo: </strong></p>
<p><span>java -Xms16M -Xmx16M -verbose:gc -Xloggc:/logs/gc.log -jar leak-memory.jar</span></p>
<p><strong>O que significa:</strong></p>
<p><span>Execute o programa leak-memory.jar com tamanho inicial e total de 16M (-Xms16M e Xmx16M), ative o log do GC (-verborse:gc) e grave no arquivo /logs/gc.log (-Xloggc:gc.log)</span></p>
<p><span>O arquivo /logs/gc.log deve conter algo como:</span></p>
<p><span>9.317: [GC 4160K-&gt;1491K(15744K), 0.0190010 secs]</span><br />
<span>27.595: [GC 5651K-&gt;5302K(15744K), 0.0467940 secs]</span><br />
<span>34.715: [GC 9462K-&gt;9182K(15744K), 0.0414860 secs]</span><br />
<span>34.757: [Full GC 9182K-&gt;9177K(15744K), 0.0700270 secs]</span></p>
<p><strong>Exemplo prático</strong></p>
<p><span>Observe a imagem abaixo:</span></p>
<div id="attachment_124" class="wp-caption alignnone" style="width: 281px"><a title="Leak memory" href="http://submundojava.com.br/wordpress/wp-content/uploads/2010/04/programa.png" target="_blank"><img class="size-medium wp-image-124" title="Leak Memory" src="http://submundojava.com.br/wordpress/wp-content/uploads/2010/04/programa.png" alt="Leak Memory" width="271" height="100" /></a><p class="wp-caption-text">Leak Memory</p></div>
<p><span>Para analisarmos o log do GC, criei uma aplicação Swing que instância um número determinado de objetos User e adiciona a uma collection (List, atributo da classe Main), estes objetos estão sempre sendo referenciados, desta forma, nenhum deles será coletado pelo coletor de lixo.</span></p>
<p><strong><span>DICA:</span></strong></p>
<p><span>Configure o programa para instanciar 1000 objetos User e clique no botão GO! a cada 10 segundos, depois de mais ou menos 5 minutos acontecerá o OutOfMemoryError indicado pela seguinte mensagem:</span></p>
<p><span>Exception in thread &#8220;AWT-EventQueue-0&#8243; java.lang.OutOfMemoryError: Java heap space</span></p>
<p><strong><span>Obtendo o gráfico da heap</span></strong></p>
<p><span>Para obtermos o gráfico da memória da JVM utilizaremos o gc.log gerado. Você pode parsear o arquivo e transforma-lo em um CSV criando o gráfico através de um programa de planilha como o excel, mas pra agilizar o processo, iremos utilizar o programa <a title="gcviewer" href="http://www.tagtraum.com/gcviewer.html" target="_blank">gcviewer</a>. </span></p>
<p><span>Utilizando o <a title="gcviewer" href="http://www.tagtraum.com/gcviewer.html" target="_blank">gcviewer</a>, abra o arquivo gc.log (obtido pela experiência proposta acima) e será apresentado um gráfico como este:</span></p>
<div id="attachment_125" class="wp-caption alignnone" style="width: 310px"><a title="gcviewer" href="http://submundojava.com.br/wordpress/wp-content/uploads/2010/04/gcviewer.png" target="_blank"><img class="size-medium wp-image-125" title="gcviewer" src="http://submundojava.com.br/wordpress/wp-content/uploads/2010/04/gcviewer-300x152.png" alt="gcviewer" width="300" height="152" /></a><p class="wp-caption-text">gcviewer</p></div>
<p><span>No <a title="gcviewer" href="http://www.tagtraum.com/gcviewer.html" target="_blank">gcviewer</a> desabilite todas as opções (menu view) deixando apenas Data Panel, Full GC Lines e Used Heap.</span></p>
<p><span>Em degradê (vermelho pra branco) temos o tamanho total da heap (~16 MB), a linha horizontal azul representa o tamanho em bytes usado na heap pela aplicação e as linhas verticais pretas representam o momento que foi efetuado o Full GC. </span></p>
<p><span>É possível identificar que nesta aplicação existe um vazamento de memória devido ao used heap space sempre crescer e nunca diminuir (o que seria desejável em uma aplicação saudável). Ou seja, em uma aplicação normal, quando é executado o GC a parte utilizada da heap deveria diminuir, ou seja, a linha deveria descer. Perceba que mesmo ao ser executado o full GC a linha não desce, o que é totalmente compreensível pois estamos referenciando todos os objetos que criamos. Além disso, um pouco antes de ocorrer o OutOfMemoryError muitos full GCs acontecem o que faz com que a aplicação fique muito lenta. </span></p>
<p><strong><span>Identificando “ONDE ESTÁ” o vazamento de memória</span></strong></p>
<p><span>Existem muitas maneiras de descobrir onde está o vazamento de memória. Irei descrever duas maneiras de se obter um dump para podermos analisar os objetos da heap.</span></p>
<p><strong><span>Heap dump on OutOfMemoryError</span></strong><span> &#8211; Através de um parâmetro da <a title="JVM Sun Hotspot" href="http://java.sun.com/javase/technologies/hotspot/" target="_blank">JVM</a> um arquivo de dump com a extensão .hprof será criado no diretório em que foi executado o programa, quando ocorrer um OutOfMemoryError.</span></p>
<p><strong><span>Exemplo:</span></strong></p>
<p><span>java -XX:+HeapDumpOnOutOfMemoryError -Xms16M -Xmx16M -verbose:gc -Xloggc:/logs/gc.log -jar leak-memory.jar</span></p>
<p><strong><span>Heap shot</span></strong><span> &#8211; Consiste em tirar um shot da heap com o programa em execução.</span></p>
<p><span>Para tanto, precisamos saber qual o PID do processo Java que queremos obter o dump, usaremos então o <a title="jps" href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jps.html" target="_blank">jps</a> para obter o PID e o <a title="jmap" href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jmap.html" target="_blank">jmap</a> para obter o dump (ambos já vem com a <a title="JVM Sun Hotspot" href="http://java.sun.com/javase/technologies/hotspot/" target="_blank">JVM</a>):</span></p>
<p><span>henrique@henrique-ubuntu:/logs$ jps</span><br />
<span>12594 Jps</span><br />
<span>12577 jar</span><br />
<span>10857 gcviewer-1.29.jar</span><br />
<span>10363 Main</span></p>
<p><span>No caso, Main é a classe principal do leak-memory.jar. Para obtermos o dump deste programa executamos:</span></p>
<p><span>jmap -F -dump:format=b,file=dump.hprof 10363</span></p>
<p><span>Após obtermos o dump (de qualquer uma das maneiras descritas acima) podemos carregar um relatório que nos possibilitará enxergarmos o que está acontecendo dentro da heap. Para tanto, utilizaremos uma outra ferramenta da JDK chamada <a title="jhat" href="http://java.sun.com/javase/6/docs/technotes/tools/share/jhat.html" target="_blank">jhat</a>.</span></p>
<p><span>OBS: Após obtermos o dump é desejável retirá-lo de produção para um máquina local.</span></p>
<p><span>henrique@henrique-ubuntu:~/dev/workspace/netbeans/leak-memory/dist$ jhat java_pid12635.hprof</span><br />
<span>Reading from java_pid12635.hprof&#8230;</span><br />
<span>Dump file created Sun Apr 18 19:00:44 BRT 2010</span><br />
<span>Snapshot read, resolving&#8230;</span><br />
<span>Resolving 755646 objects&#8230;</span><br />
<span>Chasing references, expect 151 dots&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.</span><br />
<span>Eliminating duplicate references&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.</span><br />
<span>Snapshot resolved.</span><br />
<span>Started HTTP server on port 7000</span><br />
<span>Server is ready.</span></p>
<p><span>Conforme descrito na saída do programa, um HTTP server é criado na porta 7000, desta forma basta acessarmos http://localhost:7000 e obtemos o relatório desejado, conforme demonstra a figura abaixo:</span></p>
<div id="attachment_126" class="wp-caption alignnone" style="width: 310px"><a title="jhat" href="http://submundojava.com.br/wordpress/wp-content/uploads/2010/04/jhat.png" target="_blank"><img class="size-medium wp-image-126" title="jhat" src="http://submundojava.com.br/wordpress/wp-content/uploads/2010/04/jhat-300x142.png" alt="jhat" width="300" height="142" /></a><p class="wp-caption-text">jhat</p></div>
<p><span>Conforme é possível observar na imagem acima, todas as classes usadas no programa leak-memory.jar que não fazem parte da <a title="JVM Sun Hotspot" href="http://java.sun.com/javase/technologies/hotspot/" target="_blank">JVM</a> são apresentadas e existem várias maneiras de encontrarmos a informação necessária. O que estamos procurando é um número grande de instâncias de uma mesma classe, desta forma ao clicar no link “Heap Histogram” será apresentada uma tela conforme demonstra a imagem a seguir:</span></p>
<div id="attachment_127" class="wp-caption alignnone" style="width: 310px"><a title="jhat histogram" href="http://submundojava.com.br/wordpress/wp-content/uploads/2010/04/histogram.png" target="_blank"><img class="size-medium wp-image-127" title="histogram" src="http://submundojava.com.br/wordpress/wp-content/uploads/2010/04/histogram-300x168.png" alt="histogram" width="300" height="168" /></a><p class="wp-caption-text">histogram</p></div>
<p><span>Se navegarmos um pouco sobre esta tela descobrimos que:</span></p>
<p><span>Existem 359770 da classe java.util.LinkedList$Entry (cujo tamanho é 20 bytes)</span><br />
<span>Existem 359756 da classe br.com.submundojava.User (cujo tamanho é 16 bytes)</span></p>
<p><span>Ou seja, calculando o valor total destes objetos obtemos o seguinte resultado:</span></p>
<p><span>(359770 * 20) + (359756 * 16) = 12951496 (~12.3 MB)</span></p>
<p><span>Considerando que o número muito próximo de Entry e User deduzimos que Entry contém User. Além disso, o tamanho da <a title="JVM Sun Hotspot" href="http://java.sun.com/javase/technologies/hotspot/" target="_blank">JVM</a> é de ~16 MB, o que significa que estas duas classes possuem instâncias que ocupam cerca de 80% da memória o que nos indica um forte candidato a ser o culpado pelo OutOfMemoryError.</span></p>
<p>OBS: Os valores aqui descritos são aproximados, nas minhas contas o tamanho em bytes das instâncias de User bateram exatamente com o programa <a title="eclipse memory analyzer" href="http://www.eclipse.org/mat/" target="_blank">eclipse memory analyzer</a> (citado no final), entretanto, o valor em bytes das instâncias de Entry foram apenas parecidos.</p>
<p><strong><span>Próximos passos</span></strong></p>
<p><span>Existem muitas maneiras (talvez mais fáceis e inteligentes do que esta) para encontrarmos gargalos na memória. Além disso, as ferramentas <a title="jmap" href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jmap.html" target="_blank">jmap</a> e <a title="jhat" href="http://java.sun.com/javase/6/docs/technotes/tools/share/jhat.html" target="_blank">jhat</a> possuem vários outros recurso, recomendo um estudo mais profundo das mesmas.</span><br />
<span>No exemplo citado nest POST fica óbvio onde encontrar o problema e posso garantir que no mundo real a “coisa” não é tão simples assim. Além disso, existem ferramentas mais modernas do que o <a title="jhat" href="http://java.sun.com/javase/6/docs/technotes/tools/share/jhat.html" target="_blank">jhat</a>, como é o caso do <a title="eclipse memory analyzer" href="www.eclipse.org/mat/" target="_blank">eclipse memory analyzer</a> que possui recursos maravilhosos que indicam onde pode ser encontrado um possível vazamento de memória.</span></p>
<p><strong><span>Conclusão</span></strong></p>
<p><span>O que foi apresentado neste POST é uma maneira criativa de se obter informações sobre a heap de um sistema em produção, esta técnica já foi utilizada muitas vezes e solucionou diversos problemas. Espero ter contribuido com as horas de sono de algum leitor.</span></p>
<p><strong>Arquivos e Referências</strong></p>
<p><a title="leak memory " href="http://www.submundojava.com.br/henrique/leak-memory.jar">leak-memory.jar</a> &#8211; Usado para efetuar os testes.</p>
<p><a title="tunning garbage collector" href="http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html" target="_blank">Tuning Garbage Collection with the 5.0 Java[tm] Virtual Machine</a> &#8211; O título já diz tudo<a title="tunning garbage collector" href="http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html" target="_blank"><br />
</a></p>
<p><a title="arquitetura java" href="http://www.arquiteturajava.com.br/" target="_blank">http://www.arquiteturajava.com.br/</a> &#8211; Capítulo 3.2, Gerenciar memória não é simples</p>
<p><a title="Java performance tunning" href="http://www.javaperformancetuning.com/" target="_blank">http://www.javaperformancetuning.com/</a> &#8211; Alguns artigos bem antigos mas ainda válidos</p>
<p><span>Forte abraço e aguardo seus comentários.</span></div>
]]></content:encoded>
			<wfw:commentRss>http://submundojava.com.br/wordpress/2010/04/18/avaliacao-desempenho-sistemas/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Injetando Repositorios em entidades de maneira transparente com Spring</title>
		<link>http://submundojava.com.br/wordpress/2010/04/04/injetando-repositorios-em-entidades-com-spring/</link>
		<comments>http://submundojava.com.br/wordpress/2010/04/04/injetando-repositorios-em-entidades-com-spring/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 01:36:42 +0000</pubDate>
		<dc:creator>Henrique Lima</dc:creator>
				<category><![CDATA[domain driven design]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[ddd]]></category>
		<category><![CDATA[maven 2]]></category>
		<category><![CDATA[repository]]></category>

		<guid isPermaLink="false">http://submundojava.com.br/wordpress/?p=100</guid>
		<description><![CDATA[Tenho conversado com alguns amigos sobre os projetos que tenho participado no emprego novo e uma das dúvidas que surge é como utilizar repositórios em entidades, para tornar o domínio um pouco mais rico.
Obviamente, este POST não tem o intuito de levantar nenhuma discussão sobre como você deve tratar sua camada de persistência e o [...]]]></description>
			<content:encoded><![CDATA[<p>Tenho conversado com alguns amigos sobre os projetos que tenho participado no emprego novo e uma das dúvidas que surge é como utilizar repositórios em entidades, para tornar o domínio um pouco mais rico.</p>
<p>Obviamente, este POST não tem o intuito de levantar nenhuma discussão sobre como você deve tratar sua camada de persistência e o seu domínio, mas sim, mostrar como é possível injetar repositórios dentro de entidades de maneira transparente usando Spring.</p>
<p>Para saber mais a respeito do conceito por trás desta solução, leia este <a href="http://blog.caelum.com.br/2007/06/09/repository-seu-modelo-mais-orientado-a-objeto/" target="_blank">POST</a></p>
<p><strong>O problema</strong></p>
<p>Ao recuperar uma entidade (user, por exemplo) de um repositório, as dependências desta entidade devem ser injetadas manualmente dentro do método find.</p>
<p><strong>Exemplo:</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> User findById<span style="color: #009900;">&#40;</span><span style="color: #003399;">Long</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    User user <span style="color: #339933;">=</span> entityManager.<span style="color: #006633;">find</span><span style="color: #009900;">&#40;</span>User.<span style="color: #000000; font-weight: bold;">class</span>, id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    user.<span style="color: #006633;">setUserRepository</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    user.<span style="color: #006633;">setRoleRepository</span><span style="color: #009900;">&#40;</span>...<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    user.<span style="color: #006633;">setXXXRepository</span><span style="color: #009900;">&#40;</span>...<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Você talvez queira injetar só um repositório, mas talvez não. Imagine, se ao invés de todos estes setters eu apenas usasse a annotation @ResolveDependencies no método e todas as dependências (no caso, repositórios) fossem injetadas automaticamente na entidade. Um outro problema é que a cada nova dependência (não que eu pretenda ter muitas), mais um set você tem que efetuar no método find e isso daria um pouco mais de trabalho. Além disso, muitas vezes seus repositórios já estão sendo gerenciados pelo container de injeção de dependências e você não gostaria de criar uma nova instância a cada find que efetuar.</p>
<p><strong>A solução</strong></p>
<p>A classe ApplicationContext do Spring possui recursos para resolver as dependências de um objeto não gerenciado pelo Spring. Desta forma, se a minha entidade User possuir um atributo chamado userRepository anotado pela annotation @Autowired (Spring) ou @Inject (JSR-330), através da chamada do método ctx.getAutowireCapableBeanFactory().autowireBean(user), todas as dependências serão injetadas. Onde, ctx é uma instância de ApplicationContext, user é uma instância de User e userRepository é uma instância de UserDAO gerenciada pelo Spring.</p>
<p>A seguir, as classes citadas:</p>
<p><strong>UserRepository.java</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> UserRepository <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> User findById<span style="color: #009900;">&#40;</span><span style="color: #003399;">Long</span> id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> save<span style="color: #009900;">&#40;</span>User user<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>UserDAO.java</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Named<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;userRepository&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> UserDAO <span style="color: #000000; font-weight: bold;">implements</span> UserRepository <span style="color: #009900;">&#123;</span>
&nbsp;
    @Override
    @ResolveDependencies
    <span style="color: #000000; font-weight: bold;">public</span> User findById<span style="color: #009900;">&#40;</span><span style="color: #003399;">Long</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">new</span> User<span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    @Override
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> save<span style="color: #009900;">&#40;</span>User user<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;salvando user id=[&quot;</span> <span style="color: #339933;">+</span> user.<span style="color: #006633;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #0000ff;">&quot;]&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>A classe UserDAO, foi anotada pela annotation @Named que faz parte da JSR-330 (Dependency Injection) suportada pelo Spring, o parâmetro passado (userRepository) é a String que identifica o DAO dentro do container de injeção de dependência (no caso, Spring). Toda classe anotada por esta anotação, será gerenciada pelo Spring.</p>
<p>O método save, simplemente imprime uma mensagem com o id do user.</p>
<p>O método findById, foi anotado pela a annotation @ResolveDependencies, que utilizaremos para indicar que a entidade retornada por este método deve ter todas as suas dependências resolvidas (injetadas).</p>
<p><strong>A mágica</strong></p>
<p>Como foi dito anteriormente, o Spring tem condições de resolver dependências de objetos não gerenciados pelo mesmo, desta forma, utilizaremos este recurso para o exemplo acima:</p>
<p><strong>SpringUtils.java</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">abstract</span> <span style="color: #000000; font-weight: bold;">class</span> SpringUtils <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> autowire<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> obj, ApplicationContext ctx<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
       ctx.<span style="color: #006633;">getAutowireCapableBeanFactory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">autowireBean</span><span style="color: #009900;">&#40;</span>obj<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Esta classe abstrata possui um método chamado autowire que, simplesmente, injeta as dependências (contidas no container, no caso, ApplicationContext) em um dado objeto (obj).</p>
<p>Para juntarmos tudo, utilizaremos AOP para interceptarmos os métodos anotados por @ResolveDependencies e, através da classe SpringUtils, resolvermos as dependências do objeto de retorno, conforme demostra a classe a seguir:</p>
<p><strong>DetachedSpringBeanDependencyResolver.java</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Aspect
@Named
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> DetachedSpringBeanDependencyResolver <span style="color: #009900;">&#123;</span>
&nbsp;
    @Inject
    @Named<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;applicationContext&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> ApplicationContext applicationContext<span style="color: #339933;">;</span>
&nbsp;
    @AfterReturning<span style="color: #009900;">&#40;</span>value<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;@annotation(br.com.submundojava.ResolveDependencies)&quot;</span>, returning<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;retVal&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> resolve<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> retVal<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Throwable</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>retVal <span style="color: #339933;">!=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
            SpringUtils.<span style="color: #006633;">autowire</span><span style="color: #009900;">&#40;</span>retVal, applicationContext<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Aqui complica um pouco, mas é bem simples:</p>
<p><strong>@Aspect</strong>, sucintamente informa que esta classe utilizará AOP.</p>
<p><strong>@Named</strong>, um objeto gerenciado pelo Spring.</p>
<p><strong>@Inject + @Named(&#8221;applicationContext&#8221;)</strong>, como esta classe também será gerenciada pelo Spring e no próprio Spring existe uma instância de ApplicationContext (obtida pelo nome applicationContext) podemos então injetar o applicationContext dentro do aspecto, pois o SpringUtils precisa do applicationContext para obter as instâncias que serão injetadas no objeto retornado.</p>
<p><strong>@AfterReturning</strong>, indica que após o retorno do método anotado pela annotation @ResolveDependencies e antes de retornar ao cliente, o aplicativo deverá passar pelo método resolve.</p>
<p><strong>Método resolve(retVal)</strong>, acho que fica óbvio que retVal é o valor retornado pelo método anotado por @ResolveDependencies. No caso o retorno é uma instância de User.</p>
<p><strong>SpringUtils.autowire</strong>, resolve todas as dependências contidas em applicationContext, do objeto retornado.</p>
<p>Para finalizar, a entidade User, a anotação @ResolveDependencies e o application-context.xml</p>
<p><strong>User.java</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> User <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">Long</span> id<span style="color: #339933;">;</span>
&nbsp;
    @Inject
    @Named<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;userRepository&quot;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #000000; font-weight: bold;">private</span> UserRepository userRepository<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> User<span style="color: #009900;">&#40;</span><span style="color: #003399;">Long</span> id<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">id</span> <span style="color: #339933;">=</span> id<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Long</span> getId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">return</span> id<span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> save<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #000000; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>userRepository <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span>
            <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">IllegalStateException</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;userRepository == null&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        userRepository.<span style="color: #006633;">save</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>ResolveDependencies.java</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">@Retention<span style="color: #009900;">&#40;</span>RetentionPolicy.<span style="color: #006633;">RUNTIME</span><span style="color: #009900;">&#41;</span>
@Target<span style="color: #009900;">&#40;</span>ElementType.<span style="color: #006633;">METHOD</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">public</span> @<span style="color: #000000; font-weight: bold;">interface</span> ResolveDependencies <span style="color: #009900;">&#123;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>application-context.xml</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;beans</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.springframework.org/schema/beans&quot;</span></span>
<span style="color: #009900;"><span style="color: #000066;">xmlns:xsi</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span>
<span style="color: #009900;"><span style="color: #000066;">xmlns:context</span>=<span style="color: #ff0000;">&quot;http://www.springframework.org/schema/context&quot;</span></span>
<span style="color: #009900;"><span style="color: #000066;">xmlns:aop</span>=<span style="color: #ff0000;">&quot;http://www.springframework.org/schema/aop&quot;</span></span>
<span style="color: #009900;"><span style="color: #000066;">xsi:schemaLocation</span>=<span style="color: #ff0000;">&quot;http://www.springframework.org/schema/aop </span>
<span style="color: #009900;">http://www.springframework.org/schema/aop/spring-aop-3.0.xsd</span>
<span style="color: #009900;">http://www.springframework.org/schema/beans </span>
<span style="color: #009900;">http://www.springframework.org/schema/beans/spring-beans-3.0.xsd</span>
<span style="color: #009900;">http://www.springframework.org/schema/context </span>
<span style="color: #009900;">http://www.springframework.org/schema/context/spring-context-3.0.xsd&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
    <span style="color: #808080; font-style: italic;">&lt;!-- Procura por classes anotadas nos sub-pacotes do base-package --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;context:component-scan</span> <span style="color: #000066;">base-package</span>=<span style="color: #ff0000;">&quot;br.com.submundojava&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
    <span style="color: #808080; font-style: italic;">&lt;!-- Ativa suporte a aspectos --&gt;</span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;aop:aspectj-autoproxy</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/beans<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><strong>Executando</strong></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> argz<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
    ApplicationContext ctx <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ClassPathXmlApplicationContext<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;classpath:application-context.xml&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    UserRepository repository <span style="color: #339933;">=</span> ctx.<span style="color: #006633;">getBean</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;userRepository&quot;</span>, UserRepository.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    User user <span style="color: #339933;">=</span> repository.<span style="color: #006633;">findById</span><span style="color: #009900;">&#40;</span>1L<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    user.<span style="color: #006633;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>A saída deverá ser algo parecido com:</p>
<p>salvando user id=[1]</p>
<p><strong>Conclusão</strong></p>
<p>O que tentei demonstrar aqui é uma maneira simples de resolver dependências de objetos que não fazem parte do container de injeção de dependências. Esta abordagem está sendo utilizada atualmente nos meus projetos e tem solucionado uma porção de problemas.</p>
<p>Para ter uma melhor visualização você pode abaixar o projeto <a href="http://www.submundojava.com.br/henrique/entity-repository.zip">aqui</a>. Certifique-se de ter java 5+ e maven 2 instalados.</p>
<p>Dúvidas, críticas ou sugestões. Deixe um comentário.</p>
<p>Abraços.</p>
]]></content:encoded>
			<wfw:commentRss>http://submundojava.com.br/wordpress/2010/04/04/injetando-repositorios-em-entidades-com-spring/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Fluent Regex Composer</title>
		<link>http://submundojava.com.br/wordpress/2009/07/26/fluent-regex-composer/</link>
		<comments>http://submundojava.com.br/wordpress/2009/07/26/fluent-regex-composer/#comments</comments>
		<pubDate>Sun, 26 Jul 2009 20:32:47 +0000</pubDate>
		<dc:creator>Henrique Lima</dc:creator>
				<category><![CDATA[domain driven design]]></category>
		<category><![CDATA[fluent interface]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://submundojava.com.br/wordpress/?p=30</guid>
		<description><![CDATA[Na semana passada, Martin Fowler escreveu um artigo demonstrando as práticas que ele costuma utilizar ao trabalhar com expressões regulares. Neste artigo, o senhor Fowler propõe uma maneira de separar uma expressão regular em partes menores, recompondo tal expressão posteriormente para, entre outra coisas, dar maior legibilidade ao código. Ao acabar de ler o artigo [...]]]></description>
			<content:encoded><![CDATA[<p>Na semana passada, <a title="Martin Fowler" href="http://www.martinfowler.com/" target="_blank">Martin Fowler</a> escreveu um <a title="artigo" href="http://martinfowler.com/bliki/ComposedRegex.html" target="_blank">artigo</a> demonstrando as práticas que ele costuma utilizar ao trabalhar com expressões regulares. Neste artigo, o senhor Fowler propõe uma maneira de separar uma expressão regular em partes menores, recompondo tal expressão posteriormente para, entre outra coisas, dar maior legibilidade ao código. Ao acabar de ler o <a title="artigo" href="http://martinfowler.com/bliki/ComposedRegex.html" target="_blank">artigo</a> a primeira coisa que veio em minha cabeça foi <a title="Fluent Interface" href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank">Fluent Interfaces</a>. Na atualização de seu <a title="artigo" href="http://martinfowler.com/bliki/ComposedRegex.html" target="_blank">artigo</a>, Martin Fowler cita este assunto (inclusive expôe sua preferência por não utilizar <a title="Fluent Interfaces" href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank">Fluent Interfaces</a>) e sugere uma <a title="alternativa fluente" href="http://flimflan.com/blog/ReadableRegularExpressions.aspx" target="_blank">alternativa fluente</a> criada por <a title="Joshua Flanagan" href="http://flimflan.com/blog/default.aspx" target="_blank">Joshua Flanagan</a> para C#.</p>
<p>Este post não tem como  objetivo discutir se utilizar <a title="Fluent Interfaces" href="http://en.wikipedia.org/wiki/Fluent_interface" target="_blank">Fluent Interfaces</a>, ou não, é a melhor maneira de resolver problemas relacionados a expressões regulares, mas sim, propor um exercício a fim de criar uma <strong>possível</strong> API fluente e, ao final do artigo, demonstrar uma pequena porção de código Java que pode solucionar alguns problemas relacionados a expressões regulares utilizando esta abordagem.</p>
<p><strong>O problema</strong></p>
<p>O grande problema de quando trabalhamos com expressões regulares é conhecer todos os recursos disponíveis (metacaracteres, quantificadores gananciosos, possessivos, relutantes, etc) para validarmos determinada String e posteriormente recuperarmos os grupos que nos interessa para aplicarmos a lógica que necessitamos. Além disso, quanto maior for a expressão mais difícil será de interpretá-la, por isso, utilizar a abordagem &#8220;<a title="Divisão e Conquista" href="http://pt.wikipedia.org/wiki/Divis%C3%A3o_e_conquista" target="_blank">Divisão e Conquista</a>&#8221; é uma boa prática a ser seguida.</p>
<p><strong>A solução</strong></p>
<p>Criar uma API para abstrair os recursos (metacaracteres, quantificadores, etc) e disponibilizar ao usuário, métodos mais legíveis e simples de escrever. Para chegar a este fim, me propus a analisar as expressões regulares que mais utilizo no dia-a-dia, &#8220;mapeá-las&#8221; para o português estruturado e, então, escrever uma porção de código que reflita a interpretação do português estruturado o mais fluente possível.</p>
<p><strong>Interpretando Expressões Regulares</strong></p>
<p>Analisando uma expressão regular que tem como objetivo validar se Strings representam uma data em um formato dd/mm/aaaa (em java dd/MM/yyyy), temos:</p>
<p><strong>Expressão Regular:</strong> \\d{2}/\\d{2}/\\d{4}</p>
<p><strong>Português estruturado:</strong> A String em questão: Inicia com dois dígitos (numéricos), seguido de uma barra, seguido de dois dígitos (numéricos), seguido de uma barra e finaliza com quatro dígitos (númericos).</p>
<p><strong>Código Java:</strong></p>
<pre class="prettyprint">RegexComposer composer = RegexComposer.getInstance();
composer
    .startsWith(exactly(2, digit()))
    .followedBy(exactly(1, literal("/")))
    .followedBy(exactly(2, digit()))
    .followedBy(exactly(1, literal("/")))
    .finishedWith(exactly(4, digit()));</pre>
<p>Parece bacana, mas não está ao contrário? Porque o quantificador vem antes do dígito no código Java e na expressão regular não? Pois ao interpretarmos a expressão regular em português estruturado, também passamos o quantificador a frente do dígito e é essa a diferença, pois, ao interpretarmos uma expressão como: \\d{2} nós não escrevemos &#8220;Esta expressão representa digítos (numéricos) <strong>dois</strong>&#8220;, e sim &#8220;Esta expressão representa <strong>dois</strong> dígitos (numéricos)&#8221;.</p>
<p>Este foi o meu principal questionamento quando analisei a <a title="API" href="http://flimflan.com/blog/ReadableRegularExpressions.aspx" target="_blank">API</a> do senhor <a title="Joshua Flanagan" href="http://flimflan.com/blog/default.aspx" target="_blank">Joshua Flanagan</a>, pois acredito que ao utilizarmos a abordagem fluente, devemos valorizar a maneira  como escreveríamos em uma língua (português/inglês) e não como é a sintaxe de uma determinada linguagem (de programação).</p>
<p><strong>Delimitadores</strong></p>
<p>Uma ocorrência constante (inclusive citado no <a title="artigo" href="http://martinfowler.com/bliki/ComposedRegex.html" target="_blank">artigo</a> do <a title="Martin Fowler" href="http://www.martinfowler.com/" target="_blank">Martin Fowler</a>) é a utilização de delimitadores para separarmos os dados em Strings (tokens). São exemplos disto, os arquivos CSV (valores separados por vírgula) e também a data do exemplo anterior (separados por barra &#8220;/&#8221;). Desta forma, seria conveniente se pudessemos configurar a API para interpretar delimitadores. A seguir, demostro um exemplo de como isto poderia ser feito:</p>
<p><strong>Expressão Regular:</strong> \\d{2}/\\d{2}/\\d{4}</p>
<p><strong>Português estruturado:</strong> A String em questão: Inicia com dois dígitos (numéricos), seguido de dois dígitos (numéricos), finaliza com quatro dígitos (númericos) e é delimitada por uma barra.</p>
<p><strong>Código Java:</strong></p>
<pre class="prettyprint">RegexComposer composer = RegexComposer.getInstance();
composer
    .startsWith(exactly(2, digit()))
    .followedBy(exactly(2, digit()))
    .finishedWith(exactly(4, digit()))
    .delimitedBy(exactly(1, literal("/")));</pre>
<p>Tá começando a melhorar, mas existe um recurso muito importante que deve ser considerado, os agrupamentos.</p>
<p><strong>Agrupamentos</strong></p>
<p>Os agrupamentos em Java são efetuados através inserção da expressão em parênteses, isto possibilita recuperar a String de determinado grupo uma vez que foi validado que a String se encontra no padrão requerido. A seguir demonstro uma maneira que, inicialmente, acreditei ser adequada para este fim.</p>
<p>Imagine que, após validar uma determinada data, você queira recuperar o dia, mês e ano separadamente para efetuar alguma lógica, então, teríamos algo como:</p>
<p><strong>Expressão Regular: </strong>(\\d{2})/(\\d{2})/(\\d{4})</p>
<p><strong>Português estruturado:</strong> A String em questão: Inicia com dois dígitos (numéricos) <strong>agrupados</strong>, seguido de dois dígitos (numéricos) <strong>agrupados</strong>, finaliza com quatro dígitos (númericos) <strong>agrupados</strong> e é delimitada por uma barra.</p>
<p><strong>Código Java:</strong></p>
<pre class="prettyprint">RegexComposer composer = RegexComposer.getInstance();

Pattern p = composer
                 .startsWith(exactly(2, digit()).<strong>grouped()</strong>)
                 .followedBy(exactly(2, digit())<strong>.grouped()</strong>)
                 .finishedWith(exactly(4, digit())<strong>.grouped()</strong>)
                 .delimitedBy(exactly(1, literal("/")))
                 .compile();

Matcher matcher = p.matcher("05/01/1979");

if(matcher.matches()) {

    System.out.println("Dia: " + matcher.group(1));
    System.out.println("Mes: " + matcher.group(2));
    System.out.println("Ano: " + matcher.group(3));

} else {

     System.out.println("Formato invalido");

}</pre>
<p>Legal, ao menos à primeira vista, entretanto eu ainda precisaria saber em qual grupo está o dia (matcher.group(1)), o mês (matcher.group(2)) e o ano (matcher.group(3)) e isto não é muito bacana. Creio que o ideal seria criarmos um alias para cada grupo e depois recuperarmos o número do grupo através do alias. Seria algo como <strong>.startsWith(exactly(2, digit()).grouped(usingAlias(&#8221;dia&#8221;)))</strong> e depois recuperarmos o grupo usando <strong>matcher.group(composer.getAliasGroup(&#8221;dia&#8221;))</strong>. Uma outra questão é que há outra interpretação para expressões agrupadas, por exemplo, &#8220;A String em questão: Inicia com<strong> um grupo</strong> de dois dígitos &#8230;&#8221;. Isto quer dizer que escreveriamos algo como: <strong>.startsWith(groupOf(exactly(2, digit())).usingAlias(&#8221;dia&#8221;))</strong>.</p>
<p>Embora eu considere estas opções adequadas, não escrevi nada disso ainda. No exemplo, a seguir, irei demonstrar um pouco mais de detalhes do que já implementei.</p>
<p><strong>Exemplo prático</strong></p>
<p>Utilizando o exemplo que o <a title="Martin Fowler" href="http://www.martinfowler.com/" target="_blank">Martin Fowler</a> deu em seu <a title="artigo" href="http://martinfowler.com/bliki/ComposedRegex.html" target="_blank">artigo</a>, irei validar se a String <strong>&#8220;score 400 for 2 nights at Minas Tirith Airport&#8221;</strong> se encontra no padrão correto e ,após isto, recuperar os números 400 e 2.</p>
<p><strong>Código Java:</strong></p>
<pre class="prettyprint">import br.com.submundojava.regexcomposer.RegexComposer;
import static br.com.submundojava.regexcomposer.quantifier.Quantifiers.*;
import static br.com.submundojava.regexcomposer.value.MetaCharacters.*;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 *
 * @author Henrique Lima
 */
public class Test {

    public static void main(String argz[]) {

        RegexComposer composer = RegexComposer.getInstance();

        Pattern pattern = composer
                        .startsWith(exactly(1, literal("score")))
                        .followedBy(oneOrMore(digit()).grouped())
                        .followedBy(exactly(1, literal("for")))
                        .followedBy(oneOrMore(digit()).grouped())
                        .followedBy(exactly(1, literal("night")))
                        .followedBy(zeroOrOne(literal("s")))
                        .followedBy(exactly(1, literal("at")))
                        .delimitedBy(zeroOrMore(whiteSpace()))
                        .finishedWith(oneOrMore(any()))
                        .compile();

        Matcher matcher = pattern.matcher("score 400 for 2 nights at Minas Tirith Airport");

        if (matcher.matches()) {

            System.out.println(matcher.group(1));
            System.out.println(matcher.group(2));

        } else {
            System.out.println("Formato inválido");
        }

    }

}</pre>
<p>Muito simples! Veja que não utilizamos nenhum metacaracter, nenhum quantificador, agrupamos os dados necessários e ainda utilizamos um delimitador. Uma pessoa nem precisaria conhecer de expressões regulares para validar a String (embora seja desejável).</p>
<p>Perceba que novas coisas aconteceram e utilizamos <strong>import static</strong> do Java 5 para disponibilizarmos os métodos necessários à nossa classe. Além disso, utilizamos novos métodos quantificadores (não regex) que são: <strong>zeroOrMore</strong>(), para zero ou mais ocorrências (análogo a *), <strong>oneOrMore</strong>(), para uma ou mais ocorrências (análogo a +), <strong>zeroOrOne</strong>() para zero ou uma ocorrência (análogo a ?) e por final utilizamos o método <strong>compile()</strong> para obtermos um objeto do tipo <strong>java.util.regex.Pattern</strong> para podermos validar a String.</p>
<p><strong>Código fonte</strong></p>
<p>Abaixo segue o projeto que criei para efetuar este post.</p>
<p>Para netbeans: <a title="download" href="http://www.submundojava.com.br/henrique/regular-expression-composer-netbeans.zip" target="_blank">download</a><br />
Para eclipse: <a title="download" href="http://www.submundojava.com.br/henrique/regular-expression-composer-eclipse.zip" target="_blank">download</a></p>
<p><strong>Considerações Finais</strong></p>
<p>Procurei demonstrar uma maneira fluente de trabalhar com expressões regulares, abstraindo seus recursos e disponibilizando métodos de alto nível. O exemplo que escrevi ainda está muito &#8220;verde&#8221;, com nomes esquisitos para algumas classes, métodos e pacotes. Na verdade, em alguns casos, nem sei se o inglês está correto.</p>
<p>Além disso, existem muitas limitações, por exemplo, se eu quiser usar um delimitador e ao mesmo tempo validar um dos tokens com um outro RegexComposer, não é possível. Seria desejável poder aninhar RegexComposer&#8217;s para este fim. Outro detalhe é que os métodos da classe RegexComposer recebem sempre uma instância de Quantifier e deveriam receber uma instância de uma classe com um nome mais adequado, como Expression ou ExpressionGroup. Detalhes a serem resolvidos.</p>
<p>Aguardo seus comentários e quem quiser entrar em contato, meu twitter é <a title="hgflima" href="http://twitter.com/hgflima" target="_blank">hgflima</a></p>
<p>Um abraço.</p>
]]></content:encoded>
			<wfw:commentRss>http://submundojava.com.br/wordpress/2009/07/26/fluent-regex-composer/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Arquivo eclipse.ini para evitar o tão odiado &#8220;java.lang.OutOfMemoryError: PermGen Space&#8221; Exception.</title>
		<link>http://submundojava.com.br/wordpress/2008/01/15/arquivo-eclipseini-para-evitar-o-tao-odiado-javalangoutofmemoryerror-permgen-space-exception/</link>
		<comments>http://submundojava.com.br/wordpress/2008/01/15/arquivo-eclipseini-para-evitar-o-tao-odiado-javalangoutofmemoryerror-permgen-space-exception/#comments</comments>
		<pubDate>Tue, 15 Jan 2008 23:01:07 +0000</pubDate>
		<dc:creator>Henrique Lima</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://submundojava.com.br/wordpress/2008/01/15/arquivo-eclipseini-para-evitar-o-tao-odiado-javalangoutofmemoryerror-permgen-space-exception/</guid>
		<description><![CDATA[Na verdade, quero ser breve neste POST. A questão é que ontem comecei a escrever um novo POST e precisei instalar o eclipse numa máquina antiga e depois de alguns minutos trabalhando lentamente o tão temido &#8220;permgen&#8221; (para os íntimos) apareceu. Toda vez que isso aconteceu eu preciso entrar no google e lembrar dos valores [...]]]></description>
			<content:encoded><![CDATA[<p>Na verdade, quero ser breve neste POST. A questão é que ontem comecei a escrever um novo POST e precisei instalar o eclipse numa máquina antiga e depois de alguns minutos trabalhando lentamente o tão temido &#8220;permgen&#8221; (para os íntimos) apareceu. Toda vez que isso aconteceu eu preciso entrar no google e lembrar dos valores que eu utilizava para a minha máquina. Segue abaixo o meu eclipse.ini.</p>
<pre class="prettyprint">
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256M
-vmargs
-Dosgi.requiredJavaVersion=1.5
-Xms128m
-Xmx512m
-XX:MaxPermSize=128m
</pre>
<p>E se por um acaso alguém quiser saber mais detalhes sobre este problema, recomendo a leitura do POST <a href="http://xlml.com/aehso/2007/04/05/the-dreaded-javalangoutofmemoryerror-permgen-space-exception/" title="dreaded “java.lang.OutOfMemoryError: PermGen space” error" target="_blank" id="o7z5">dreaded “java.lang.OutOfMemoryError: PermGen space” error</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://submundojava.com.br/wordpress/2008/01/15/arquivo-eclipseini-para-evitar-o-tao-odiado-javalangoutofmemoryerror-permgen-space-exception/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JBoss RichFaces 3.1.3 está nas ruas!</title>
		<link>http://submundojava.com.br/wordpress/2007/12/18/jboss-richfaces-313-esta-nas-ruas/</link>
		<comments>http://submundojava.com.br/wordpress/2007/12/18/jboss-richfaces-313-esta-nas-ruas/#comments</comments>
		<pubDate>Tue, 18 Dec 2007 17:45:04 +0000</pubDate>
		<dc:creator>Henrique Lima</dc:creator>
				<category><![CDATA[Java Server Faces]]></category>

		<guid isPermaLink="false">http://submundojava.com.br/wordpress/2007/12/18/jboss-richfaces-313-esta-nas-ruas/</guid>
		<description><![CDATA[Foi liberado ontem (17/12/2007) mais uma nova versão do conjunto de componentes para JSF conhecido como JBoss RichFaces. Nesta nova versão foram corrigidos dezenas de bugs, aperfeiçoados alguns componentes, atualizados os frameworks Prototype e script.aculo.us(para 1.6.0 e 1.8.0 respectivamente), além da adição de 4 novos componentes: Ordering List, List Shuttle, Component Control e Context Menu. [...]]]></description>
			<content:encoded><![CDATA[<p>Foi liberado ontem (17/12/2007) mais uma nova versão do conjunto de componentes para JSF conhecido como JBoss RichFaces. Nesta nova versão foram corrigidos dezenas de bugs, aperfeiçoados alguns componentes, atualizados os frameworks Prototype e script.aculo.us(para 1.6.0 e 1.8.0 respectivamente), além da adição de 4 novos componentes: Ordering List, List Shuttle, Component Control e Context Menu. Para mais informações sobre as novidades desta versão leia o <a href="http://labs.jboss.com/wiki/RichFacesWhatIsNewIn3_1_3" title="JBoss RichFaces 3.1.3 WhatsNew" target="_blank" id="q_km">WhatsNew</a>. Faça download dos fontes, binários e documentação na <a href="http://labs.jboss.com/jbossrichfaces/" title="JBoss RichFaces - Página Oficial" target="_blank" id="aula">página oficinal</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://submundojava.com.br/wordpress/2007/12/18/jboss-richfaces-313-esta-nas-ruas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Criando aplicações Ajax, sem Javascript, utilizando Java Server Faces 1.2 e RichFaces</title>
		<link>http://submundojava.com.br/wordpress/2007/12/17/criando-aplicacoes-ajax-sem-javascript-utilizando-java-server-faces-12-e-richfaces/</link>
		<comments>http://submundojava.com.br/wordpress/2007/12/17/criando-aplicacoes-ajax-sem-javascript-utilizando-java-server-faces-12-e-richfaces/#comments</comments>
		<pubDate>Mon, 17 Dec 2007 13:51:14 +0000</pubDate>
		<dc:creator>Henrique Lima</dc:creator>
				<category><![CDATA[Java Server Faces]]></category>

		<guid isPermaLink="false">http://submundojava.com.br/wordpress/2007/12/17/criando-aplicacoes-ajax-sem-javascript-utilizando-java-server-faces-12-e-richfaces/</guid>
		<description><![CDATA[
Introdução
Dando continuidade ao meu último POST, estarei apresentando uma maneira simples de trabalhar com Ajax utilizando componentes JSF.
As aplicações que usufruem de recursos Ajax têm evoluído de diversas maneiras nos últimos tempos e um dos aspectos importantes é a produtividade. Quando iniciei os meus estudos sobre Ajax, era necessário escrever uma quantidade significativa de código [...]]]></description>
			<content:encoded><![CDATA[<p><strong><br />
Introdução</strong></p>
<p>Dando continuidade ao meu último POST, estarei apresentando uma maneira simples de trabalhar com Ajax utilizando componentes JSF.<br />
As aplicações que usufruem de recursos Ajax têm evoluído de diversas maneiras nos últimos tempos e um dos aspectos importantes é a produtividade. Quando iniciei os meus estudos sobre Ajax, era necessário escrever uma quantidade significativa de código javascript, manipulando o objeto XmlHttpRequest diretamente, além de uma porção adicional de código em alguma linguagem server side (para gerar XML dinamicamente). Depois de um certo tempo vieram os frameworks javascript que diminuiram a quantidade de código a ser escrito e atualmente é possível desenvolver aplicações inteiras sem utilizar nenhum código javascript, através dos componentes do RichFaces (entre outros).<br />
<br style="font-weight: bold" /><strong>Requisitos</strong></p>
<p>Antes de seguir os passos aqui descritos, é recomendável  que você leia o POST <a href="http://submundojava.com.br/wordpress/2007/08/27/java-server-faces-12-hello-world/" title="Java Server Faces 1.2 Hello World" target="_blank" id="c:o:">Java Server Faces 1.2 Hello World</a> ou tenha conhecimentos compatíveis.</p>
<p><strong>Configurando o ambiente</strong></p>
<p>Para rodar aplicações Java Server Faces 1.2 é necessário um container que implemente a especificação da JSP 2.1. Para este tutorial iremos utilizar o container Tomcat 6.0.<strong><br />
Download:</strong> <a href="http://tomcat.apache.org/download-60.cgi">http://tomcat.apache.org/download-60.cgi</a></p>
<p>Além dos jars para rodar o Java Server Faces 1.2 serão necessários mais 3 jars do RichFaces. Quando este POST foi escrito a versão mais recente do RichFaces era a 3.1.2. Desta forma, os nomes dos jars são: richfaces-api-3.1.2.GA.jar,  richfaces-impl-3.1.2.GA.jar e richfaces-ui-3.1.2.GA.jar e se encontram dentro da pasta lib do arquivo disponível para download.<br />
<strong>Download:</strong> <a href="http://labs.jboss.com/jbossrichfaces/downloads/" title="http://labs.jboss.com/jbossrichfaces/downloads/" target="_blank" id="rdrb">http://labs.jboss.com/jbossrichfaces/downloads/</a></p>
<p>Para configurar o RichFaces serão necessárias algumas pequenas modificações no <strong>web.xml</strong> demonstrado no POST <a href="http://submundojava.com.br/wordpress/2007/08/27/java-server-faces-12-hello-world/" title="Java Server Faces 1.2 Hello World" target="_blank" id="c:o:">Java Server Faces 1.2 Hello World</a>. A listagem 1 apresenta o código completo do novo<strong> web.xml</strong>.</p>
<p><strong>Listagem 1</strong></p>
<pre class="prettyprint">
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"&gt;
&lt;display-name&gt;JSFAjax&lt;/display-name&gt;

	&lt;context-param&gt;
		&lt;param-name&gt;com.sun.faces.verifyObjects&lt;/param-name&gt;
		&lt;param-value&gt;true&lt;/param-value&gt;
	&lt;/context-param&gt;

	&lt;context-param&gt;
		&lt;param-name&gt;com.sun.faces.validateXml&lt;/param-name&gt;
		&lt;param-value&gt;true&lt;/param-value&gt;
	&lt;/context-param&gt;

	&lt;context-param&gt;
		&lt;param-name&gt;javax.faces.STATE_SAVING_METHOD&lt;/param-name&gt;
		&lt;param-value&gt;clien+t&lt;/param-value&gt;
	&lt;/context-param&gt;

	&lt;context-param&gt;
		&lt;param-name&gt;org.richfaces.SKIN&lt;/param-name&gt;
		&lt;param-value&gt;blueSky&lt;/param-value&gt;
	&lt;/context-param&gt;

	&lt;filter&gt;
		&lt;display-name&gt;RichFaces Filter&lt;/display-name&gt;
		&lt;filter-name&gt;richfaces&lt;/filter-name&gt;
		&lt;filter-class&gt;org.ajax4jsf.Filter&lt;/filter-class&gt;
	&lt;/filter&gt;

	&lt;filter-mapping&gt;
		&lt;filter-name&gt;richfaces&lt;/filter-name&gt;
		&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
		&lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
		&lt;dispatcher&gt;FORWARD&lt;/dispatcher&gt;
		&lt;dispatcher&gt;INCLUDE&lt;/dispatcher&gt;
	&lt;/filter-mapping&gt;

	&lt;servlet&gt;
		&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
		&lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;

	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/faces/*&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;

	&lt;welcome-file-list&gt;
		&lt;welcome-file&gt;faces/index.jsp&lt;/welcome-file&gt;
	&lt;/welcome-file-list&gt;

&lt;/web-app&gt;</pre>
<p>Um novo parâmetro de contexto foi adicionado para configurar qual skin o RichFaces irá utilizar. Por padrão, podem ser utilizados 8 valores: DEFAULT, plain, emeraldTown, blueSky, wine, japanCherry, ruby, classic e deepMarine. É possível criar novas skins e modificar os estilos dos componentes através de CSS, entretanto,  este assunto será abordado em uma outra oportunidade.<br />
Para utilizar o restante dos recursos do RichFaces o filtro <strong>org.ajax4jsf.Filter </strong>deverá ser configurado. Existem algumas opções de configuração e até diferentes tipos de configurações para um grupo de páginas. Para maiores detalhes sobre  configurações dos filtros do RichFaces utilize a <a href="http://labs.jboss.com/file-access/default/members/jbossrichfaces/freezone/docs/devguide/en/html/ArchitectureOverview.html#FilterConfiguration" title="seção 5.5 - Filter Configuration" target="_blank" id="yp8d">seção 5.5 &#8211; Filter Configuration</a> da documentação.</p>
<p><strong>Criando o javabean</strong></p>
<p>Utilizaremos um simples javabean para efetuarmos um CRUD. Na listagem 2 será apresentado a classe Contato.java que deverá ser criada no pacote <strong>br.com.jsfajax.entity.</strong></p>
<p><strong>Listagem 2</strong></p>
<pre class="prettyprint" id="java">
package br.com.jsfajax.entity;

import java.util.Date;

public class Contato {

	private String nome;
	private Date dataNascimento;
	private String email;

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public Date getDataNascimento() {
		return dataNascimento;
	}

	public void setDataNascimento(Date dataNascimento) {
		this.dataNascimento = dataNascimento;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

}</pre>
<p><strong><br />
Criando o Bean Gerenciado (Managed Bean ou Backing Bean)</strong></p>
<p>Crie no pacote <strong>br.com.jsfajax.web.mbean</strong> o arquivo <strong>ContatoManager.java</strong> conforme demostra a listagem 3.</p>
<p><strong>Listagem 3</strong></p>
<pre class="prettyprint" id="java">
package br.com.jsfajax.web.mbean;

import br.com.jsfajax.entity.Contato;

import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;

public class ContatoManager {

	private Contato contato;
	private List&lt;Contato&gt; contatos;
	private DataModel contatosData;

	public ContatoManager() {

		contato = new Contato();
		contatos = new ArrayList&lt;Contato&gt;();
		contatosData = new ListDataModel(contatos);

	}

	public Contato getContato() {
		return contato;
	}

	public void setContato(Contato contato) {
		this.contato = contato;
	}

	public List&lt;Contato&gt; getContatos() {
		return contatos;
	}

	public void setContatos(List&lt;Contato&gt; contatos) {
		this.contatos = contatos;
	}

	public DataModel getContatosData() {
		return contatosData;
	}

	public void setContatosData(DataModel contatosData) {
		this.contatosData = contatosData;
	}

	public void salvar(ActionEvent e) {

		// Se o contato já existia antes na lista de contatos, atualiza os dados. Do contrário adiciona.
		if(contatos.contains(contato))
			contatos.set(contatos.lastIndexOf(contato), contato);
		else
			contatos.add(contato);

		// Zera o contato para que os campos do formulário sejam limpos.
		contato = new Contato();

		// Cria uma nova mensagem de informação para o JSF
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
							"Contato adicionado com sucesso!",
							"Contato adicionado com sucesso!");

		// Adiciona a mensagem ao formulário de cadastro
		FacesContext.getCurrentInstance().addMessage("formularioCadastro", message);

	}

	public void deletar(ActionEvent e) {
		contatos.remove((Contato)contatosData.getRowData());
	}

	public void editar(ActionEvent e) {
		contato = (Contato)contatosData.getRowData();
	}

	public boolean isRendered() {
		return !contatos.isEmpty();
	}

}</pre>
<p><strong><br />
Configurando o Bean Gerenciado no faces-config.xml<br />
</strong><br />
Adicione ao <strong>faces-config.xml</strong> o código conforme demonstra a listagem 4:</p>
<p><strong>Listagem 4</strong></p>
<pre class="prettyprint">
&lt;managed-bean&gt;
	&lt;managed-bean-name&gt;contatoManager&lt;/managed-bean-name&gt;
	&lt;managed-bean-class&gt;br.com.jsfajax.web.mbean.ContatoManager&lt;/managed-bean-class&gt;
	&lt;managed-bean-scope&gt;session&lt;/managed-bean-scope&gt;
&lt;/managed-bean&gt;</pre>
<p><strong><br />
Criando a página JSP </strong></p>
<p>Crie um arquivo chamado <strong>index.jsp</strong>,  no diretório <strong>WEB-INF/</strong> de sua aplicação WEB, com o conteúdo demonstrado na listagem 5.</p>
<p><strong>Listagem 5</strong></p>
<pre class="prettyprint">
&lt;%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%&gt;
&lt;%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%&gt;
&lt;%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%&gt;
&lt;%@ taglib uri="http://richfaces.org/rich" prefix="rich"%&gt;
&lt;html&gt;
	&lt;head&gt;
		&lt;meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"&gt;
		&lt;title&gt;Contato CRUD&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
	&lt;f:view&gt;
          &lt;h:form id="formularioCadastro"&gt;
         	&lt;rich:panel id="cadastro" header="Cadastro de Contatos"&gt;
         		Nome:
         		&lt;h:inputText value="#{contatoManager.contato.nome}" id="nome" required="true"
				requiredMessage="Digite o nome corretamente!"/&gt; &lt;br /&gt;
         		Data Nascimento (dd/mm/aaaaa):
         		&lt;h:inputText value="#{contatoManager.contato.dataNascimento}" id="dataNascimento"
				required="true" requiredMessage="Digite a data de nascimento!"
				converterMessage="Digite a data de nascimento no formato correto!"&gt;
         			&lt;f:convertDateTime pattern="dd/MM/yyyy"  /&gt;
         		&lt;/h:inputText&gt; &lt;br /&gt;
         		E-mail:
			&lt;h:inputText value="#{contatoManager.contato.email}" id="email" required="true"
				requiredMessage="Digite o e-mail corretamente!"/&gt; &lt;br /&gt;
         		&lt;a4j:commandButton value="Salvar"  actionListener="#{contatoManager.salvar}"
				reRender="cadastro,formularioLista" /&gt;&lt;br /&gt;&lt;br /&gt;
         		&lt;h:messages errorStyle="color:red" infoStyle="color:#5ac67e"  /&gt;
         	&lt;/rich:panel&gt;
           &lt;/h:form&gt;
           &lt;h:form id="formularioLista"&gt;
           	&lt;rich:dataTable value="#{contatoManager.contatosData}" var="contato"
			id="listaContatos" rendered="#{contatoManager.rendered}"&gt;
           		&lt;h:column&gt;
				&lt;f:facet name="header"&gt;
					&lt;h:outputText value="Nome" /&gt;
				&lt;/f:facet&gt;
				&lt;h:outputText value="#{contato.nome}"/&gt;
			&lt;/h:column&gt;
			&lt;h:column&gt;
				&lt;f:facet name="header"&gt;
					&lt;h:outputText value="Data Nascimento" /&gt;
				&lt;/f:facet&gt;
				&lt;h:outputText value="#{contato.dataNascimento}"&gt;
					&lt;f:convertDateTime pattern="dd/MM/yyyy"/&gt;
				&lt;/h:outputText&gt;
			&lt;/h:column&gt;
			&lt;h:column&gt;
				&lt;f:facet name="header"&gt;
					&lt;h:outputText value="E-mail" /&gt;
				&lt;/f:facet&gt;
				&lt;h:outputText value="#{contato.email}"/&gt;
			&lt;/h:column&gt;
			&lt;h:column&gt;
				&lt;f:facet name="header"&gt;
					&lt;h:outputText value="Editar" /&gt;
				&lt;/f:facet&gt;
				&lt;a4j:commandLink value="Editar"
					actionListener="#{contatoManager.editar}" reRender="cadastro"/&gt;
			&lt;/h:column&gt;
			&lt;h:column&gt;
				&lt;f:facet name="header"&gt;
					&lt;h:outputText value="Deletar" /&gt;
				&lt;/f:facet&gt;
				&lt;a4j:commandLink value="Deletar"
					actionListener="#{contatoManager.deletar}" reRender="listaContatos"/&gt;
			&lt;/h:column&gt;
           	&lt;/rich:dataTable&gt;
           &lt;/h:form&gt;
        &lt;/f:view&gt;
     	&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Conforme demonstrado na listagem 5, serão utilizadas mais duas taglibs responsáveis pelas funcionalidades Ajax,  <strong>http://richfaces.org/a4j</strong> representada pelo apelido <strong>a4j</strong> e <strong>http://richfaces.org/rich </strong>representada pelo apelido <strong>rich</strong>.<br />
Foram utilizados 2 formulários pois todo formulário com campos cujo atributo <strong>required</strong> possua o valor <strong>true </strong>só pode ser submetido se tais campos estiverem preenchidos. Desta forma, se os botões de editar e deletar (quando em um mesmo form) forem acionados e os campos (com required=true) estiverem vazios uma mensagem de erro será apresentada.<br />
O atributo <span style="font-weight: bold">requiredMessage</span> do componente <span style="font-weight: bold">h:inputText </span>é utilizado para configurar a mensagem de erro a ser apresentada quando este campo não for preenchido e seu atributo <span style="font-weight: bold">required</span> possuir o valor <span style="font-weight: bold">true</span>.<br />
O converter <span style="font-weight: bold">f:converterDateTime </span>é utilizado para transformar a String digitada (no campo em que este converter for aplicado) em um objeto do tipo java.util.Date e vice-versa.<br />
O atributo <span style="font-weight: bold">converterMessage </span>do componente <span style="font-weight: bold">h:inputText </span>é utilizado para configurar a mensagem de erro a ser apresentada quando não for possível efetuar a conversão da String para o objeto java.util.Date ou vice-versa.<br />
Os componentes <span style="font-weight: bold">commandButton</span> e <span style="font-weight: bold">commandLink</span> do <span style="font-weight: bold">a4j </span>serão responsáveis por efetuar as chamadas assíncronas. No atributo <span style="font-weight: bold">actionListener</span> destes componentes é configurado qual método do managed bean será executado. No atributo <span style="font-weight: bold">reRender </span>será configurado quais componentes serão atualizados depois de ser executado o método do managed bean. Desta forma, quando o botão salvar for pressionado o método salvar do managed bean será  executado e o componente cujo ID é listaContatos será atualizado com um novo registro.<br />
O componente h:messages é reponsável por apresentar as mensagens adicionadas ao FacesContext através da classe FacesMessage.<br />
É possível customizar os estilos  CSS das mensagens em função do tipo de mensagem. Um FacesMessage pode ser classificada em 4 tipos:</p>
<ul>
<li><span style="font-weight: bold">FacesMessage.SEVERITY_ERROR</span> &#8211; Indica que um erro ocorreu.</li>
<li><span style="font-weight: bold">FacesMessage.SEVERITY_FATAL </span>-<span style="font-weight: bold"> </span>Indica que um erro grave ocorreu.</li>
<li><span style="font-weight: bold">FacesMessage.SEVERITY_INFO </span>- Mensagem com caráter informativo.</li>
<li><span style="font-weight: bold">FacesMessage.SEVERITY_WARN </span>-<span style="font-weight: bold"> </span>Indica que um erro pode ter acontecido.</li>
</ul>
<p>Para utilizar estilos de CSS diferente para cada tipo de mensagem existem atributos correspondentes no componente h:messages, são eles: errorClass, fatalClass, infoClass, warnClass, errorStyle, fatalStyle, infoStyle e warnStyle. Estes atributos são correspondentes aos atributos style e class dos componentes html.</p>
<p><span style="font-weight: bold">Considerações Finais</span></p>
<p>Através da utilização de componentes JSF é possível ganhar produtividade, diminuindo a quantidade de código e, na maioria das vezes, ganhar performance. Entretanto, em muitas situações isto não ocorre, devido a grande quantidade de chamadas assíncronas, consultas à base de dados desnecessárias, utilização indevida de session entre outros fatores. Em uma próxima oportunidade darei continuidade a este POST adicionando recursos da Java Persistence API e mostrando como otimizar o desempenho desta pequena aplicação.</p>
]]></content:encoded>
			<wfw:commentRss>http://submundojava.com.br/wordpress/2007/12/17/criando-aplicacoes-ajax-sem-javascript-utilizando-java-server-faces-12-e-richfaces/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Java Server Faces 1.2 Hello World</title>
		<link>http://submundojava.com.br/wordpress/2007/08/27/java-server-faces-12-hello-world/</link>
		<comments>http://submundojava.com.br/wordpress/2007/08/27/java-server-faces-12-hello-world/#comments</comments>
		<pubDate>Mon, 27 Aug 2007 17:51:10 +0000</pubDate>
		<dc:creator>Henrique Lima</dc:creator>
				<category><![CDATA[Java Server Faces]]></category>

		<guid isPermaLink="false">http://submundojava.com.br/wordpress/2007/08/27/java-server-faces-12-hello-world/</guid>
		<description><![CDATA[ Requisitos
Será necessário o conhecimento dos seguintes itens para a criarmos nosso primeiro exemplo:

Nível básico de conhecimento de orientação a objetos utilizando Java.
Nível básico de conhecimento na criação de aplicações WEB utilizando Tomcat, de preferência versão 6.0.
Manipulação de bibliotecas jar. (Utilizando IDE ou não).
Nível básico de conhecimento de HTML e XML.

Configurando o ambiente
Para rodar aplicações [...]]]></description>
			<content:encoded><![CDATA[<p><strong> Requisitos</strong></p>
<p>Será necessário o conhecimento dos seguintes itens para a criarmos nosso primeiro exemplo:</p>
<ol>
<li>Nível básico de conhecimento de orientação a objetos utilizando Java.</li>
<li>Nível básico de conhecimento na criação de aplicações WEB utilizando Tomcat, de preferência versão 6.0.</li>
<li>Manipulação de bibliotecas jar. (Utilizando IDE ou não).</li>
<li>Nível básico de conhecimento de HTML e XML.</li>
</ol>
<p><strong>Configurando o ambiente</strong></p>
<p>Para rodar aplicações Java Server Faces 1.2 é necessário um container que implemente a especificação da JSP 2.1.</p>
<p>Para este tutorial iremos utilizar o container Tomcat 6.0.<strong><br />
Download:</strong> <a href="http://tomcat.apache.org/download-60.cgi">http://tomcat.apache.org/download-60.cgi</a></p>
<p>Serão necessários 8 arquivos jars que devem estar no classpath ou no diretorio WEB-INF/lib de sua aplicação WEB, são eles:</p>
<ul>
<li> <strong>jsf-api.jar e jsf-impl.jar</strong><br />
<strong>Download:</strong> <a href="https://javaserverfaces.dev.java.net/download.html">https://javaserverfaces.dev.java.net/download.html</a></li>
<li> <strong>commons-beanutils.jar</strong><br />
<strong>Download:</strong> <a href="http://commons.apache.org/downloads/download_beanutils.cgi">http://commons.apache.org/downloads/download_beanutils.cgi</a></li>
<li> <strong>commons-colletions.jar<br />
Download:</strong> <a href="http://commons.apache.org/downloads/download_collections.cgi">http://commons.apache.org/downloads/download_collections.cgi </a></li>
<li> <strong>commons-logging.jar<br />
Download:</strong> <a href="http://commons.apache.org/downloads/download_logging.cgi">http://commons.apache.org/downloads/download_logging.cgi </a></li>
<li> <strong>commons-diggester.jar</strong><br />
<strong>Download:</strong> <a href="http://commons.apache.org/downloads/download_digester.cgi">http://commons.apache.org/downloads/download_digester.cgi </a></li>
<li> <strong>jstl.jar e standard.jar (Standard Taglib)</strong><br />
<strong>Download:</strong> <a href="http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi">http://jakarta.apache.org/site/downloads/downloads_taglibs-standard.cgi </a></li>
</ul>
<p>Para que o Java Server Faces funcione adequadamente se faz necessário a configuração do Faces Servlet para que este<br />
atenda às requisições das páginas JSF. A Listagem 1 mostra um exemplo de configuração do web.xml.</p>
<p><strong>Listagem 1</strong></p>
<pre class="prettyprint">&lt;?xml version="1.0" encoding="UTF-8"?&gt;&lt;web-app version="2.5"</pre>
<pre class="prettyprint">xmlns="http://java.sun.com/xml/ns/javaee"</pre>
<pre class="prettyprint">xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee</pre>
<pre class="prettyprint">http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd"&gt;</pre>
<pre class="prettyprint">&lt;context-param&gt;</pre>
<pre class="prettyprint"> 	&lt;param-name&gt;com.sun.faces.verifyObjects&lt;/param-name&gt;

 	&lt;param-value&gt;true&lt;/param-value&gt;

&lt;/context-param&gt;

&lt;context-param&gt;

 	&lt;param-name&gt;com.sun.faces.validateXml&lt;/param-name&gt;

 	&lt;param-value&gt;true&lt;/param-value&gt;

&lt;/context-param&gt;

&lt;context-param&gt;

 	&lt;param-name&gt;javax.faces.STATE_SAVING_METHOD&lt;/param-name&gt;

 	&lt;param-value&gt;client&lt;/param-value&gt;

&lt;/context-param&gt;

&lt;servlet&gt;

&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;

&lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;

&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;

&lt;/servlet&gt;

&lt;servlet-mapping&gt;

&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;

&lt;url-pattern&gt;/faces/*&lt;/url-pattern&gt;

&lt;/servlet-mapping&gt;

&lt;welcome-file-list&gt;

&lt;welcome-file&gt;faces/index.jsp&lt;/welcome-file&gt;

&lt;/welcome-file-list&gt;

&lt;/web-app&gt;</pre>
<p>Como pode-se observar foram configurados 3 parâmetros de contexto. A utilidade destes será descrita a seguir:</p>
<ul>
<li><strong>com.sun.faces.verifyObjects</strong><br />
Esta flag é configurada como true quando se quer que implementação do Java Server Faces verifique se os objetos da aplicação<br />
(conversores, etc) foram criados adequadamente. Seu valor padrão é false, por afetar a performance no início da execução<br />
da aplicação.</li>
<li><strong>com.sun.faces.validateXml</strong><br />
Esta flag é configurada como true quando se quer que a implementação do Java Server Faces verifique a integridade do arquivo<br />
faces-config.xml em função do seu DTD correspondente. Seu valor padrão é false.</li>
<li><strong>javax.faces.STATE_SAVING_METHOD</strong><br />
Esta flag é usada para configurar em que lado da aplicação o estado da “view” deve ser salvo.<br />
Existem 2 valores possíveis: server e client. Quando configurado como client o estado de toda camada de visão será renderizado<br />
em um campo hidden na página jsp. Seu valor padrão é server.</li>
</ul>
<p><strong>Criando o Bean Gerenciado (Managed Bean ou Backing Bean)</strong></p>
<p>O Bean Gerenciado é a camada de negócios das aplicações JSF. Sua principal função é compartilhar seus atributos e métodos<br />
com as páginas JSP. Cada campo de um formulário da página JSP é integrado com uma atributo e cada ação e/ou evento<br />
com um método do Bean Gerenciado, resultando numa ótima separação da camada de negócio da camada de visão. Crie no<br />
pacote <strong>br.com.jsftutorial</strong> o arquivo <strong>HelloWorldBean.java</strong> conforme demostra a listagem 2.</p>
<p><strong> Listagem 2</strong></p>
<pre class="prettyprint">package br.com.jsftutorial;public class HelloWorldBean {private String nome;

public HelloWorldBean() {

}

public String getNome() {

return nome;

}

public void setNome(String nome) {

this.nome = nome;

}

public String acao() {

return "sucesso";

}

}</pre>
<p>Todo Bean Gerenciado deve possuir o construtor default (sem nenhum argumento), do contrário será lançado uma java.lang.InstantiationException.<br />
Todo atributo integrado à página JSP deverá possuir seus métodos setters e getters mesmo que seu modificador de visibilidade<br />
seja public, como por exemplo o atributo nome do HelloWorldBean.</p>
<p><strong>Configurando o Bean Gerenciado no faces-config.xml</strong></p>
<p>O arquivo faces-config.xml é o arquivo de configuração do Java Server Faces.<br />
Este arquivo deve estar na pasta WEB-INF/ de sua aplicação e contém entre outras configurações as declarações dos Beans Gerenciados que deverão ser instanciados pela<br />
implementação do JSF. Na listagem 3 é apresentado um modelo típico de configuração de um Bean Gerenciado.</p>
<p><strong>Listagem 3</strong></p>
<pre class="prettyprint">&lt;?xml version='1.0' encoding='UTF-8'?&gt;</pre>
<pre class="prettyprint">&lt;faces-config version="1.2"</pre>
<pre class="prettyprint"> 	xmlns="http://java.sun.com/xml/ns/javaee"</pre>
<pre class="prettyprint"> 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee</pre>
<pre class="prettyprint"> 	http://java.sun.com/xml/ns/javaee/webfacesconfig_1_2.xsd"&gt;

&lt;managed-bean&gt;

&lt;managed-bean-name&gt;hwBean&lt;/managed-bean-name&gt;

&lt;managed-bean-class&gt;br.com.jsftutorial.HelloWorldBean&lt;/managed-bean-class&gt;

&lt;managed-bean-scope&gt;request&lt;/managed-bean-scope&gt;

&lt;/managed-bean&gt;

&lt;/faces-config&gt;</pre>
<p>Entre as tags &lt;faces-config&gt; e &lt;/faces-config&gt; se localizam toda a configuração da aplicação JSF.<br />
A configuração necessária para um Bean Gerenciado é bem intuitiva, abaixo segue a descrição das tags utilizadas:</p>
<ul>
<li> <strong>managed-bean</strong><br />
Toda a configuração de um, e apenas um, Bean Gerenciado deve estar contido nesta tag.</li>
<li> <strong>managed-bean-name</strong><br />
Nome utilizado para referenciar o Bean Gerenciado nas páginas JSP.</li>
<li> <strong>managed-bean-class</strong><br />
O caminho completo para a classe que representa este Bean Gerenciado.</li>
<li> <strong>Managed-bean-scope</strong><br />
Indica de qual escopo (scope) este Bean Gerenciado será resgatado. Existem 4 tipos possíveis.</p>
<ul>
<li> <strong>none</strong><br />
Só poderá ser utilizado como propriedade de um outro managed bean.</li>
<li> <strong>request</strong><br />
Estará disponível através do request, ou seja, seu tempo de vida acaba após a submissão do formulário.</li>
<li> <strong>session</strong><br />
Estará disponível através da session, ou seja, seu tempo de vida é o mesmo que o tempo de vida da session configurada no web.xml.</li>
<li> <strong>application</strong><br />
Estará disponível através do objeto application, ou seja, seu tempo de vida é o mesmo da aplicação.</li>
</ul>
</li>
</ul>
<p>Existem outras tags que adicionam funcionalidades ao Bean Gerenciado, aconselho a utilizar o<br />
Java (TM) EE 5 tutorial capítulo 5 item Backing Beans que pode ser acessado<br />
através da url <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/">http://java.sun.com/javaee/5/docs/tutorial/doc/</a>.</p>
<p><strong>Criando o index.jsp</strong></p>
<p>Crie a página index.jsp na pasta de arquivos WEB (mesma altura que WEB-INF/ e META-INF/) de sua aplicação com o conteúdo da Listagem 4.</p>
<p><strong>Listagem 4</strong></p>
<pre class="prettyprint">&lt;%@page contentType="text/html"%&gt;&lt;%@page pageEncoding="UTF-8"%&gt;

&lt;%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%&gt;

&lt;%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%&gt;

&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;

&lt;html&gt;

&lt;head&gt;

&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;

&lt;title&gt;Java Server Faces Tutorial&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;
<pre class="prettyprint">	&lt;f:view&gt;</pre>
<p>&lt;h:form id="formulario"&gt;</p>
<p>&lt;b&gt;Nome:&lt;/b&gt;</p>
<p>&lt;h:inputText id="nome" value="#{hwBean.nome}" required="true" requiredMessage="O campo nome deve ser preenchido!"/&gt;</p>
<p>&lt;h:commandButton value="GO" action="#{hwBean.acao}" /&gt;&lt;br&gt;</p>
<p>&lt;h:message for="nome" errorStyle="color:red"/&gt;</p>
<p>&lt;/h:form&gt;</p>
<p>&lt;/f:view&gt;</p>
<p>&lt;/body&gt;</p>
<p>&lt;/html&gt;</pre>
<p>Nas linhas 3 e 4 temos as declarações das taglibs core e html do Java Server Faces que serão utilizadas para criarmos os<br />
componentes na página JSP.</p>
<p>A tag &lt;f:view&gt; deve conter os componentes JSF.</p>
<p>A tag &lt;h:form&gt; é análogo a tag &lt;form&gt; do html.</p>
<p>Através da tag &lt;h:inputText&gt; será criado um componente input do html e do tipo text (&lt;input type=”text”&gt;).<br />
O atributo value permite integrar o valor deste componente a uma propriedade do Managed Bean, ou seja, quando o formulário for<br />
submetido o valor deste componente será copiado para a propriedade “nome” do Managed Bean configurado no faces-config.xml<br />
cujo o nome foi configurado como hwBean (&lt;managedbean-name&gt;hwBean&lt;/managed-bean-name&gt;). O atributo<br />
required determina que o formulário não poderá ser submetido caso este campo não seja preenchido.<br />
O atributo requiredMessage determina a mensagem de erro que será apresentada caso, ao submeter o formulário, este componente não seja preenchido.</p>
<p>Através da tag &lt;h:commandButton&gt; será criado um componente button do html (&lt;input type=”button”&gt;).<br />
O atributo action determina o método do Managed Bean que será executado quando este botão for pressionado.</p>
<p>A tag &lt;h:message&gt; é um componente utilizado para apresentar as mensagens ao usuário. O atributo “for” deve ser<br />
preenchido com o id do componente que desejamos que esta mensagem seja integrada, ou seja, serão apresentadas as<br />
mensagens referentes apenas ao campo cujo o id é “nome” do formulário. O atributo errorStyle permite aplicarmos um estilo<br />
CSS ao componente quando a mensagem for de erro.</p>
<p><strong>Criando o resultado.jsp</strong></p>
<p>Crie a página resultado.jsp na pasta de arquivos WEB (mesma altura que WEB-INF/ e META-INF/) de sua aplicação com o conteúdo da Listagem 5.</p>
<p><strong>Listagem 5</strong></p>
<pre class="prettyprint">&lt;%@page contentType="text/html"%&gt;&lt;%@page pageEncoding="UTF-8"%&gt;

&lt;%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%&gt;

&lt;%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%&gt;</pre>
<pre class="prettyprint">&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"

"http://www.w3.org/TR/html4/loose.dtd"&gt;

&lt;html&gt;

&lt;head&gt;

&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;

&lt;title&gt;Java Server Faces Tutorial&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;f:view&gt;

Ola, &lt;h:outputText value="#{hwBean.nome}" /&gt;!

&lt;/f:view&gt;

&lt;/body&gt;

&lt;/html&gt;</pre>
<p><strong>Criando o fluxo do aplicativo</strong></p>
<p>Para determinarmos o fluxo do aplicativo adicionamos uma “navigation rule” ao faces-config.xml.<br />
Ao executarmos o método acao() do Managed Bean, a String “sucesso” será retornada e pela “navigation rule” determinamos que a página resultado.jsp<br />
deverá ser apresentada. A listagem 6 demonstra o conteúdo do faces-config.xml.</p>
<p><strong>Listagem 6</strong></p>
<pre class="prettyprint">&lt;?xml version='1.0' encoding='UTF-8'?&gt;</pre>
<pre class="prettyprint">&lt;faces-config version="1.2"</pre>
<pre class="prettyprint">xmlns="http://java.sun.com/xml/ns/javaee"</pre>
<pre class="prettyprint">xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee</pre>
<pre class="prettyprint">http://java.sun.com/xml/ns/javaee/webfacesconfig_1_2.xsd"&gt;</pre>
<pre class="prettyprint">&lt;managed-bean&gt;

&lt;managed-bean-name&gt;hwBean&lt;/managed-bean-name&gt;

&lt;managed-bean-class&gt;br.com.jsftutorial.HelloWorldBean&lt;/managed-bean-class&gt;

&lt;managed-bean-scope&gt;request&lt;/managed-bean-scope&gt;

&lt;/managed-bean&gt;

&lt;navigation-rule&gt;

&lt;navigation-case&gt;

&lt;from-outcome&gt;sucesso&lt;/from-outcome&gt;

&lt;to-view-id&gt;/resultado.jsp&lt;/to-view-id&gt;

&lt;/navigation-case&gt;

&lt;/navigation-rule&gt;

&lt;/faces-config&gt;</pre>
<p>Após a submissão do formulário, a propriedade “nome” do Managed Bean terá o valor digitado no componente &lt;h:inputText&gt; do index.jsp,<br />
então a página resultado.jsp será apresentada (conforme configurado no faces-config.xml).<br />
Para testar a aplicação inicie o tomcat e acesse a url: http://localhost:8080/HelloJSF/faces/index.jsp</p>
<p><strong>Próximos Passos</strong></p>
<p>Existem ainda diversos recursos e componentes do JSF, aconselho a leitura da referência da API,<br />
acessando a url <a href="http://java.sun.com/javaee/javaserverfaces/reference/api/index.html">http://java.sun.com/javaee/javaserverfaces/reference/api/index.html</a>.<br />
Além disso, existem outras ótimas implementações que disponibilizam novos componentes e<br />
recursos como a utilização de Ajax e DOM na renderização das páginas. Recomendo o estudo do <a href="http://www.icefaces.org">IceFaces</a> e do <a href="http://www.icefaces.org">Ajax4Jsf</a>, ambos open source.</p>
<p><strong>Conclusão</strong></p>
<p>Apesar de muita discussão sobre a qualidade dos diversos frameworks open source do mercado, Java Server Faces se apresenta<br />
como uma ótima opção no desenvolvimento de interfaces para aplicações JEE. Com a inclusão deste framework na JEE 5,<br />
existe uma grande tendência ao crescimento de sua utilização o que torna indispensável o conhecimento de seus recursos e<br />
de suas diversas implementações. Neste tutorial foi abordado o conceito básico do funcionamento deste framework e em<br />
uma nova oportunidade voltarei a escrever sobre esta tecnologia. Até lá.</p>
]]></content:encoded>
			<wfw:commentRss>http://submundojava.com.br/wordpress/2007/08/27/java-server-faces-12-hello-world/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
