<?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>DestaqueBlog &#187; java</title>
	<atom:link href="http://weblog.destaquenet.com/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://weblog.destaquenet.com</link>
	<description>Blog da equipe Destaquenet.</description>
	<lastBuildDate>Tue, 23 Nov 2010 17:06:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Fecha-se um ciclo; outro se inicia&#8230;</title>
		<link>http://weblog.destaquenet.com/2010/09/27/fecha-se-um-ciclo-outro-se-inicia/</link>
		<comments>http://weblog.destaquenet.com/2010/09/27/fecha-se-um-ciclo-outro-se-inicia/#comments</comments>
		<pubDate>Mon, 27 Sep 2010 17:07:58 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Português]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[oportunidade]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[trabalho]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1138</guid>
		<description><![CDATA[Atualização (15/Nov): Gostaria de agradecer a todos que divulgaram este post e/ou me enviaram propostas, algumas delas muito boas. Aproveito também para comunicar que inicio meus trabalhos na Globo.com nas próximas semanas. Pois bem. Após quase três anos de serviços &#8230; <a href="http://weblog.destaquenet.com/2010/09/27/fecha-se-um-ciclo-outro-se-inicia/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><strong>Atualização</strong> (15/Nov): Gostaria de agradecer a todos que divulgaram este post e/ou me enviaram propostas, algumas delas muito boas. Aproveito também para comunicar que inicio meus trabalhos na <a href="http://globo.com">Globo.com</a> nas próximas semanas.</p>
<p><a href="http://globo.com"><img src="http://weblog.destaquenet.com/wp-content/uploads/2010/09/globocom.png" alt="Globo.com" title="Globo.com" width="200" height="115" class="aligncenter size-full wp-image-1310" /></a></p>
<p>Pois bem. Após quase três anos de serviços prestados e <a href="http://www.destaquenet.com/portifolio/">vários projetos</a> desenvolvidos ao longo desse tempo, chegou a hora de me despedir de meu principal cliente, a <a href="http://gsp.com.br/">GSP</a>, uma das maiores loteadoras do Brasil. Um abraço aos amigos que ficaram, e aos que já não estão mais lá. Foi um prazer!</p>
<p>A principal tecnologia com que eu trabalhei nesse período foi <a href="http://java.com/">Java</a>, com uma pitada de <a href="http://python.org/">Python</a> aqui e ali. Mas, como irremediável curioso que sou, não pude deixar de brincar com <a href="http://pharo-project.org/">outras</a> <a href="http://clojure.org/">coisas</a> também.</p>
<p>Agora, no entanto, é hora de pensar no futuro. Se você precisa de um profissional <a href="http://www.destaquenet.com/empresa/#daniel">com o meu perfil</a>, ou conhece alguma empresa que precise, <a href="http://www.destaquenet.com/contato/">entre em contato comigo</a> ou passe o link deste post adiante. Busco trabalhar com empresas ou pessoas que:</p>
<ol>
<li>Tenham projetos não convencionais;</li>
<li>Tratem a tecnologia com a devida atenção;</li>
<li>Contem com equipes multi-disciplinares, com gente que ama o que faz e que busca melhorar a todo instante.</li>
</ol>
<p>Apesar de morar no interior de São Paulo, estou aberto a propostas de outras cidades, de preferência em tempo integral.</p>
<p>Valeu!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/09/27/fecha-se-um-ciclo-outro-se-inicia/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clojure Invade o Dev In Sampa</title>
		<link>http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/</link>
		<comments>http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 11:30:34 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Português]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[devinsampa]]></category>
		<category><![CDATA[encontro]]></category>
		<category><![CDATA[evento]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jvm]]></category>
		<category><![CDATA[palestra]]></category>
		<category><![CDATA[sao paulo]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=1062</guid>
		<description><![CDATA[No próximo sábado, dia 14/08, acontecerá em São Paulo o 2º Dev In Sampa, um encontro de desenvolvedores de software que não faz propaganda do governo nem apresenta palestras com foco em um único fornecedor. Já era hora! Infelizmente, por &#8230; <a href="http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No próximo sábado, dia 14/08, acontecerá em São Paulo o 2º <a href="http://devinsampa.com.br/">Dev In Sampa</a>, um encontro de desenvolvedores de software que não <a href="http://fisl.softwarelivre.org/">faz propaganda do governo</a> nem apresenta palestras com <a href="http://www.oracle.com/us/javaonedevelop/index.html">foco em um único fornecedor</a>. Já era hora!</p>
<p>Infelizmente, por <a href="http://weblog.destaquenet.com/2009/10/05/use-web-scraping-para-acompanhar-seus-pedidos-na-ticketmaster/">razões de força maior</a> eu não pude comparecer na primeira edição do evento, mas este ano eu estarei presente, e ainda por cima <a href="http://devinsampa.com.br/palestras#presentation-3">como palestrante</a>.</p>
<p>Por isso, antes de mais nada, eu gostaria de agradecer àqueles que votaram na minha palestra. Isso mostra que <a href="http://clojure.org/">Clojure</a> anda despertando o interesse da rapazeada também no Brasil, o que é muito bom.</p>
<p><strong>Update:</strong> Apresentação e códigos-fonte <a href="http://github.com/danielfm/clojure-devinsampa">disponíveis para download</a>.</p>
<p><span id="more-1062"></span></p>
<h3>Sobre a palestra</h3>
<p>Apresentar uma linguagem de programação numa palestra de 50 minutos é sempre uma tarefa complicada, especialmente se essa linguagem de programação traz consigo uma <a href="http://clojure.org/rationale">bagagem</a> que vai muito além da sintaxe.</p>
<p>Quando eu assisto uma palestra sobre linguagens de programação, existem duas coisas que me irritam. A primeira é quando o palestrante soca um monte de código e se limita à sintaxe, explicando tudo vírgula por vírgula, sem nenhum contexto. A outra é quando o palestrante fala sobre uma linguagem mas não mostra nenhum exemplo.</p>
<p>Para não repetir esses erros, eu optei por um estilo diferente, onde a linguagem é abordada e explorada aos poucos, mas sempre seguindo uma linha para que haja um começo, um meio e um fim.</p>
<p>Meu objetivo não será ensinar ninguém a programar em Clojure, e sim mostrar alguns dos recursos que eu considero importantes. Assim, quem se interessar pode pesquisar mais por conta própria. Afinal, não somos todos auto-didatas?</p>
<p>Quem tiver dúvidas ao final da palestra, ou quiser apenas jogar conversa fora, é só me chamar pelo <a href="http://twitter.com/danielfmt">Twitter</a>. Também não irei reclamar se alguém quiser pagar meu almoço. <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h3>O &#8220;pós-evento&#8221;</h3>
<p>Ao final, a apresentação será disponibilizada para download no <a href="http://github.com/danielfm">GitHub</a>, juntamente com os <em>muitos</em> exemplos de código. Os slides virão acompanhados de notas que poderão ser lidas como uma espécie de artigo.</p>
<p>Deixarei os comentários deste post habilitados para quem quiser deixar dúvidas ou mensagens sobre a palestra.</p>
<p>É isso aí. Nos encontramos lá!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/08/10/clojure-invade-o-dev-in-sampa/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>At World Cup Season&#8230;</title>
		<link>http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/</link>
		<comments>http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/#comments</comments>
		<pubDate>Thu, 17 Jun 2010 16:42:02 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[bet]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[football]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[meme]]></category>
		<category><![CDATA[pool]]></category>
		<category><![CDATA[program]]></category>
		<category><![CDATA[soccer]]></category>
		<category><![CDATA[sweepstakes]]></category>
		<category><![CDATA[world cup]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=909</guid>
		<description><![CDATA[Some people think &#8212; and I agree &#8212; that the UEFA Champions League is a more relevant tournament than the World Cup itself, but we cannot deny that an event of this magnitude is really awesome to keep an eye &#8230; <a href="http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Some people think &#8212; and I agree &#8212; that the <a href="http://www.uefa.com/uefachampionsleague/index.html">UEFA Champions League</a> is a more relevant tournament than the <a href="http://www.fifa.com/worldcup/index.html">World Cup</a> itself, but we cannot deny that an event of this magnitude is really awesome to keep an eye on. Even those who doesn&#8217;t love the sport tend to follow the teams, the matches, the celebration.</p>
<p>And with the World Cup comes the sweepstakes. Lots of.</p>
<p>Although the rules might change from one place to another, these are the ones we use the most here in Brazil:</p>
<ol>
<li>Everyone try to predict the score of a particular match, paying a fixed amount for each guess (eg $1.00).</li>
<li>At the end, the ammount collected is divided equally among the winners. If there are no winners: (a) the sweepstake &#8220;accumulates&#8221;<sup class='footnote'><a href='#fn-909-1' id='fnref-909-1'>1</a></sup>, or (b) everyone get their money back, or (c) you-crazy-rule-here.</li>
</ol>
<p>I like this kind of sweepstake, but it could be better in some respects.</p>
<p>First, not everybody has the habit of carrying small bills around, so the sweepstakes manager (a.k.a. YOU) loses a lot of time chasing change. Besides, I think the fixed-valued bet is kind of boring since the amount collected is divided equally among the winners. I think things get more exciting when people can choose how much to pay for each guess, so the amount collected is divided <strong>proportionally</strong> among the winners. In this case, when several people win, earns more who bets more.</p>
<p>Since I don&#8217;t like to do the math myself, here&#8217;s the challenge: create a program that receives a list with all guesses and returns the list of winners along with the proportional amount to be paid to each one of them.</p>
<p>So, shall we?</p>
<p><span id="more-909"></span></p>
<h3>Solving the problem&#8230; with Clojure</h3>
<p>Write more code than necessary is going out of style these days, so I decided to code a solution in <a href="http://clojure.org">Clojure</a>, a functional programming language that makes this sort of &#8220;problem&#8221; really easy to solve. Just launch <a href="http://clojure.org/repl_and_main">the REPL</a> and profit!</p>
<p>The first thing to do is define how to represent each guess:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>All guesses has the same information. That&#8217;s why we defined a <a href="http://clojure.org/data_structures#Data%20Structures-StructMaps">StructMap</a> with the keys <code>:name</code>, <code>:amount</code>, <code>:guess</code>, and <code>:rate</code>.</p>
<p>A list of possible guesses might be:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def pool
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span> <span style="color: #cc66cc;">2.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Daniel bets $2.00 on score 2x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;John&quot;</span>   <span style="color: #cc66cc;">4.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; John bets $4.00 on score 0x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Maria&quot;</span>  <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Maria bets $1.00 on score 2x0</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Okay, we already know how each guess is represented. Now, how to find the sweepstake&#8217;s total amount? Simple, all we have to do is to sum the amount of all guesses:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testing</span>
<span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">7.0</span></pre></div></div>

<p>Great, but how much each guess represent in relation to the whole, that is, what&#8217;s the proportion of each guess? All we have to do is to divide the amount of each guess by the sweepstake&#8217;s total amount:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testing</span>
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.285</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.571</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.142</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">1.0</span></pre></div></div>

<p>Note that, if everyone wins, the amount earned by John would be the double of the amount earned by Daniel, which would be the double of the amount earned by Maria. Justice, finally!</p>
<p>To finish the code, we just need a function that filters the winners and calculates how much to pay to each winner:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testing</span>
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; no winners</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; just one winner</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.0</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">1.0</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; several winners</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Daniel&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">4.66</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.66</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Maria&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">2.33</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.33</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>A major advantage of this solution is that it allows you to bet on anything. Want to bet on the sex of a baby shortly after the good news (or bad news, whatever)?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def pool <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span> <span style="color: #cc66cc;">3.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">male</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;John&quot;</span>   <span style="color: #cc66cc;">5.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Maria&quot;</span>  <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;John&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Maria&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">1.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>There you go, a simple solution for a simple problem.</p>
<h3>The code</h3>
<p>Although it&#8217;s possible to solve this problem in Lisp/Clojure with a one-liner (<a href="http://clojure.org/reader">the Reader</a> works with <strong>data structures</strong> after all), I decided to write a code that is as readable as possible for those who are starting with Clojure:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<h3>Your turn</h3>
<p>Do you program in Haskell? Python? Ruby? <a href="http://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a>? How would you solve such problem in your favorite programming language?</p>
<p><strong>Update (Nov 3, 2010).</strong> Common Lisp solution, using <code>copy-*</code> to avoid changes in state:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #b1b100;">name</span> amount guess rate<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-amount <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>reduce #'+ <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> #'bet-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-rates <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>bet<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-winners <span style="color: #66cc66;">&#40;</span>pool result<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>winners <span style="color: #66cc66;">&#40;</span>loop for bet in pool <span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">equal</span> <span style="color: #66cc66;">&#40;</span>bet-guess bet<span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> collect bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>winner<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet winner<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-909-1'>The amount collected remains available for the next match&#8217;s sweepstakes, but everyone must pay again for a new guess. <span class='footnotereverse'><a href='#fnref-909-1'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/06/17/at-world-cup-season-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Em Tempos de Copa do Mundo&#8230;</title>
		<link>http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/</link>
		<comments>http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 11:00:16 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[aposta]]></category>
		<category><![CDATA[bolão]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[copa do mundo]]></category>
		<category><![CDATA[futebol]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[meme]]></category>
		<category><![CDATA[programa]]></category>
		<category><![CDATA[solução]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=898</guid>
		<description><![CDATA[Há quem ache &#8212; e eu concordo &#8212; que a UEFA Champions League é um torneio mais relevante do que a Copa do Mundo, mas não podemos negar que o Mundial mexe com a nossa rotina. Mesmo quem não é &#8230; <a href="http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Há quem ache &#8212; e eu concordo &#8212; que a <a href="http://www.uefa.com/uefachampionsleague/index.html">UEFA Champions League</a> é um torneio mais relevante do que a <a href="http://www.fifa.com/worldcup/index.html">Copa do Mundo</a>, mas não podemos negar que o Mundial mexe com a nossa rotina. Mesmo quem não é apaixonado pelo esporte passa a prestar atenção nas seleções, nas partidas, na festa.</p>
<p>E com a Copa do Mundo vem os bolões. Muitos bolões.</p>
<p>Todo mundo já sabe como funciona um bolão, embora a mecânica possa mudar de um lugar para outro:</p>
<ol>
<li>Cada palpite tem um valor fixo (ex: R$2,00).</li>
<li>Cada um pode dar quantos palpites quiser.</li>
<li>No final, o montante arrecadado é dividido igualmente entre os vencedores. Se não houverem vencedores: (a) o bolão &#8220;acumula&#8221;<sup class='footnote'><a href='#fn-898-1' id='fnref-898-1'>1</a></sup>, ou (b) todo mundo recebe seu dinheiro de volta, ou (c) sua-regra-maluca-aqui.</li>
</ol>
<p>Esse tipo de bolão é interessante, mas ele podia ser melhor em alguns aspectos.</p>
<p>Primeiro, o organizador acaba perdendo muito tempo correndo atrás de troco, afinal não é todo mundo que anda com dinheiro trocado na carteira. Além disso, valor fixo de palpite é muito chato, pois o valor arrecadado é dividido por igual entre os ganhadores. O bolão fica muito mais interessante quando o valor do palpite é variável e o valor arrecadado é dividido proporcionalmente entre os ganhadores. Assim, no caso de vários ganhadores, ganha mais quem apostar mais.</p>
<p>O problema de se fazer bolões com palpite variável é ter que ficar calculando o valor proporcional a ser dado a cada ganhador. Portanto eis o desafio: criar um programa que receba uma lista com todos os palpites e retorne uma lista com os palpites vencedores juntamente com o valor proporcional a ser pago a cada ganhador.</p>
<p>E aí, topa?</p>
<p><span id="more-898"></span></p>
<h3>Resolvendo o problema&#8230; em Clojure</h3>
<p>Como escrever mais código do que necessário está saindo de moda, optei por codificar uma possível solução em <a href="http://clojure.org">Clojure</a>. Por ser uma <a href="http://weblog.destaquenet.com/2009/06/16/programacao-funcional-vale-a-pena-aprender/">linguagem funcional</a>, Clojure é excelente para esse tipo de tarefa. Basta iniciar o <a href="http://clojure.org/repl_and_main">REPL</a> e mãos à obra!</p>
<p>Primeiramente, devemos definir como um palpite deve ser representado:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Todos os palpites possuem o mesmo conjunto de informações, por isso definimos um <a href="http://clojure.org/data_structures#Data%20Structures-StructMaps">StructMap</a> com as chaves <code>:name</code>, <code>:amount</code>, <code>:guess</code> e <code>:rate</code>.</p>
<p>Abaixo, uma possível lista de palpites:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>def pool
     <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span>  <span style="color: #cc66cc;">2.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Daniel aposta R$2,00 no placar 2x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Antônio&quot;</span> <span style="color: #cc66cc;">4.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Antônio aposta R$4,00 no placar 0x0</span>
      <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Marcela&quot;</span> <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; Marcela aposta R$1,00 no placar 2x0</span>
     <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Certo, já sabemos como os palpites são representados. Agora, como saber o montante total de uma lista de palpites (a.k.a. bolão)? Simples, basta calcular o somatório dos valores de todos os palpites:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testando</span>
<span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">7.0</span></pre></div></div>

<p>Beleza, mas quanto cada palpite representa em relação ao total arrecadado? Afinal, precisamos calcular o valor proporcional a ser pago a cada ganhador.</p>
<p>Sem problemas, basta dividir o valor de cada palpite pelo montante total:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testando</span>
<span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.285</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.571</span> <span style="color: #66cc66;">...,</span> <span style="color: #cc66cc;">0.142</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>pool-rates pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">1.0</span></pre></div></div>

<p>Repare que, se todos os participantes ganhassem um bolão, o valor recebido pelo Antônio seria o dobro do valor recebido pelo Daniel, que seria o dobro do valor recebido pela Marcela. Justiça, finalmente!</p>
<p>Pronto, agora só falta uma função para filtrar os ganhadores da lista de participantes e calcular o valor proporcional a ser pago a cada um deles:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">;; testando</span>
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; sem ganhadores</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; apenas um ganhador</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Antônio&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.0</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">1.0</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; vários ganhadores</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Daniel&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">4.66</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.66</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span>
    <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Marcela&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">2.33</span> <span style="color: #66cc66;">...,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #cc66cc;">0.33</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Uma grande vantagem dessa solução é que ela permite que você aposte em qualquer coisa. Quer apostar no sexo de um bebê logo após a boa notícia (ou má notícia, sei lá)?</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">;; :male = masculino, :female = feminino</span>
<span style="color: #66cc66;">&#40;</span>def pool <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Daniel&quot;</span>  <span style="color: #cc66cc;">3.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">male</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Antônio&quot;</span> <span style="color: #cc66cc;">5.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>struct bet <span style="color: #ff0000;">&quot;Fran&quot;</span>    <span style="color: #cc66cc;">1.0</span> <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>pool-winners pool <span style="color: #66cc66;">:</span><span style="color: #555;">female</span><span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">;; testando</span>
<span style="color: #66cc66;">=&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Antônio&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">7.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #ff0000;">&quot;Fran&quot;</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #cc66cc;">1.5</span><span style="color: #66cc66;">,</span> <span style="color: #66cc66;">...</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Aí está, uma solução simples para um problema simples. Como deveria ser sempre.</p>
<h3>Minha solução, na íntegra</h3>
<p>Embora seja possível resolver isso com um one-liner em Lisp/Clojure (afinal o <a href="http://clojure.org/reader">Reader</a> não trabalha com linhas, mas com <strong>estruturas de dados</strong>), eu optei por escrever um código que fosse o mais legível possível para quem não conhece ou está aprendendo Clojure:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-amount <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span>reduce<span style="color: #66cc66;"> + </span><span style="color: #66cc66;">&#40;</span>map <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-rates <span style="color: #66cc66;">&#91;</span>poolseq<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>defn pool-winners <span style="color: #66cc66;">&#91;</span>poolseq result<span style="color: #66cc66;">&#93;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#91;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount poolseq<span style="color: #66cc66;">&#41;</span>
        winners <span style="color: #66cc66;">&#40;</span>filter #<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">guess</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> poolseq<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#93;</span>
    <span style="color: #66cc66;">&#40;</span>map #<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> <span style="color: #66cc66;">%</span> <span style="color: #66cc66;">:</span><span style="color: #555;">amount</span> <span style="color: #66cc66;">&#40;</span>double <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">:</span><span style="color: #555;">rate</span> <span style="color: #66cc66;">%</span><span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<h3>Levando adiante</h3>
<p>Você programa em Haskell? Python? Ruby? <a href="http://en.wikipedia.org/wiki/Brainfuck">Brainfuck</a>? Qual seria a sua solução para este problema de extrema importância para o desenvolvimento da raça humana? <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p><strong>Atualização (03/11/2010).</strong> Solução em Common Lisp, usando <code>copy-*</code> para evitar mutabilidade:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defstruct bet <span style="color: #b1b100;">name</span> amount guess rate<span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-amount <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>reduce #'+ <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> #'bet-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-rates <span style="color: #66cc66;">&#40;</span>pool<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>bet<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>/ <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> pool-winners <span style="color: #66cc66;">&#40;</span>pool result<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>pool-amount pool<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>winners <span style="color: #66cc66;">&#40;</span>loop for bet in pool <span style="color: #b1b100;">when</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">equal</span> <span style="color: #66cc66;">&#40;</span>bet-guess bet<span style="color: #66cc66;">&#41;</span> result<span style="color: #66cc66;">&#41;</span> collect bet<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>winner<span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>x <span style="color: #66cc66;">&#40;</span>copy-bet winner<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">&#40;</span>bet-amount x<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>* <span style="color: #66cc66;">&#40;</span>bet-rate x<span style="color: #66cc66;">&#41;</span> sum<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                x<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>pool-rates winners<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-898-1'>Todo o montante recebido continua disponível no próximo bolão, mas os participantes devem pagar um novo palpite. <span class='footnotereverse'><a href='#fnref-898-1'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2010/06/15/em-tempos-de-copa-do-mundo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSP e tag files: criando templates em 10 minutos</title>
		<link>http://weblog.destaquenet.com/2009/12/17/jsp-e-tag-files-criando-templates-em-10-minutos/</link>
		<comments>http://weblog.destaquenet.com/2009/12/17/jsp-e-tag-files-criando-templates-em-10-minutos/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 12:30:41 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jsp]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[servlet]]></category>
		<category><![CDATA[tag]]></category>
		<category><![CDATA[tagfiles]]></category>
		<category><![CDATA[taglib]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=801</guid>
		<description><![CDATA[Este mês têm sido bastante curioso pelo fato de três pessoas terem me feito a mesma pergunta: &#8220;- Você largou o Java de vez?&#8221;. A resposta é não, mas, para não deixar dúvidas, eu resolvi voltar a escrever sobre Java. &#8230; <a href="http://weblog.destaquenet.com/2009/12/17/jsp-e-tag-files-criando-templates-em-10-minutos/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Este mês têm sido bastante curioso pelo fato de três pessoas terem me feito a mesma pergunta: &#8220;- Você largou o Java de vez?&#8221;. A resposta é <strong>não</strong>, mas, para não deixar dúvidas, eu resolvi voltar a escrever sobre Java. O assunto foge um pouco do que costumo escrever, mas é algo que considero importante.</p>
<p>Ultimamente, tenho visto a forma como certos desenvolvedores escrevem seus JSPs, e o que me preocupou foi ver o quanto eles desconhecem a tecnologia. Não é raro achar páginas cheias de <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaou.html">scriptlets</a>, includes malucos, código du-tri-quadri-plicado e nenhuma taglib além da fornecida pelo framework web em uso.</p>
<p>É muito fácil escrever JSPs da forma errada, mas fazer as coisas de um jeito melhor é mais fácil ainda. Ao contrário do que muitos pensam, é possível sim criar JSPs limpos sem o uso de qualquer framework de layout (como <a href="http://www.opensymphony.com/sitemesh/">Sitemesh</a>) ou biblioteca (com exceção da <a href="http://java.sun.com/products/jsp/jstl/reference/docs/index.html">JSTL</a>, é claro).</p>
<p><span id="more-801"></span></p>
<h3>Um exemplo</h3>
<p>O primeiro passo é definir o template base para as páginas da aplicação. Considere o seguinte exemplo de XHTML e sua representação gráfica:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=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;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;keyword1, keyword2, keyword3&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Page title<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Essential scripts --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;link</span> <span style="color: #000066;">rel</span>=<span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;css/style.css&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/query.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Extra header --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrapper&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;footer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            // Other scripts (e.g. Google Analytics)
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<div id="attachment_803" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2009/12/layout.gif"><img src="http://weblog.destaquenet.com/wp-content/uploads/2009/12/layout-300x156.gif" alt="Representação gráfica do layout" title="layout" width="300" height="156" class="size-medium wp-image-803" /></a><p class="wp-caption-text">Representação gráfica do layout</p></div>
<p>O que costuma acontecer, mesmo em um layout simples como esse, é o alto índice de duplicação de código entre as diferentes páginas, principalmente em função do uso de <a href="http://en.wikipedia.org/wiki/Copy_and_paste_programming">Copy and Paste Programming</a>. Muitos desenvolvedores por aí escreveriam o seguinte JSP para representar o layout proposto:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=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;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;keyword1, keyword2, keyword3&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Page title<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Essential scripts --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:include</span> <span style="color: #000066;">page</span>=<span style="color: #ff0000;">&quot;scripts.jsp&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Extra header --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrapper&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:include</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;header.jsp&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Page content here<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:include</span> <span style="color: #000066;">page</span>=<span style="color: #ff0000;">&quot;footer.jsp&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            // Other scripts
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Viu o problema? De nada adianta separar os pedaços com <jsp:include> e continuar duplicando código. O ideal seria traduzir o layout em algo assim:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">tagdir</span>=<span style="color: #ff0000;">&quot;/WEB-INF/tags/layout&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:page</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Title&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> <span style="color: #000066;">keywords</span>=<span style="color: #ff0000;">&quot;keyword1, keyword2, keyword3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        // Other scripts (e.g. Google Analytics)
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        Page content here
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/layout:page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>A boa notícia é que isso é possível, através de tag files.</p>
<h3>Reúso de conteúdo com tag files</h3>
<p>Existem pelo menos três formas de se criar custom tags em JSP, cada qual com seu propósito: <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaow.html#bnaoy">classic tag handlers</a>, <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnann.html">simple tag handlers</a> e <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnama.html">tag files</a>. Neste post tratarei somente das tag files, mas saber como e quando utilizar simple tag handlers também é extremamente recomendado a todos que usam JSP no dia-a-dia.</p>
<p>A primeira coisa a fazer é criar o diretório <code>WEB-INF/tags/layout</code>. É nesse diretório que as tag files referentes ao template devem ficar. Agora, crie dois arquivos neste diretório, um para o cabeçalho e outro para o rodapé:</p>
<p><strong>header.tag</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ tag <span style="color: #000066;">body-content</span>=<span style="color: #ff0000;">&quot;empty&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Header tag file&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- Header section here --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><strong>footer.tag</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ tag <span style="color: #000066;">body-content</span>=<span style="color: #ff0000;">&quot;empty&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Footer tag file&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;footer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- Footer section here --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Como podemos ver, as tag files são como JSPs, mas com algumas propriedades especiais.</p>
<p>A última tag file, <strong>page.tag</strong>, define o esqueleto das páginas da aplicação:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ tag <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;title&quot;</span>       <span style="color: #000066;">required</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page title&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">required</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page keywords to improve SEO&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">required</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Extra code to put before &lt;/head&gt;</span></span>&quot; %&gt;
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Extra code to put before &lt;/body&gt;</span></span>&quot; %&gt;
&nbsp;
<span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">tagdir</span>=<span style="color: #ff0000;">&quot;/WEB-INF/tags/layout&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Displaying the attributes using EL --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;${keywords}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;${description}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${title}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Essential scripts --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;link</span> <span style="color: #000066;">rel</span>=<span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;css/style.css&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/query.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Process the given input fragment --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:invoke</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrapper&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- Renders the page header --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:header</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!-- Renders the tag body inside a DIV --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;jsp:doBody</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!-- Renders the page footer --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:footer</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Process the given input fragment --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:invoke</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Esta última tag file é mais complexa que as anteriores, pois recebe dados e blocos de código (através de <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaln.html#bnalq">fragments</a>). Além disso, ela aceita um corpo, que é executado com <code>&lt;jsp:doBody/&gt;</code>.</p>
<p>O exemplo usado aqui é razoavelmente simples e, por isso, não precisamos apelar para outros recursos mais avançados como <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaln.html#bnaly">variables</a> e <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaln.html#bnaly">dynamic attributes</a>. De qualquer forma, procure conhecer bem a tecnologia, pois você nunca sabe quando um ou outro recurso lhe pode ser útil.</p>
<h3>Exemplo de uso</h3>
<p>Novamente, um exemplo de uso das tags que criamos:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">tagdir</span>=<span style="color: #ff0000;">&quot;/WEB-INF/tags/layout&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">uri</span>=<span style="color: #ff0000;">&quot;http://java.sun.com/jsp/jstl/core&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;c&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:page</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Index page&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;This is the index page of my amazing app&quot;</span> <span style="color: #000066;">keywords</span>=<span style="color: #ff0000;">&quot;amazing, app&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/some_jquery_plugin.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        $(function() {
            // Call some JQuery function here, specific for this page
        });
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        Welcome to my amazing app!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        1+1 = ${1+1}
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;c:forEach</span> <span style="color: #000066;">items</span>=<span style="color: #ff0000;">&quot;${objects}&quot;</span> <span style="color: #000066;">var</span>=<span style="color: #ff0000;">&quot;obj&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${obj.attr}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/c:forEach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/layout:page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Embora a aplicação como um todo siga um mesmo padrão visual, cada página pode necessitar de recursos adicionais (JavaScript, CSS, etc). Isso não chega a ser um problema, pois nosso template contempla a inclusão de conteúdo extra, se necessário.</p>
<p>Outra vantagem é que as tag files permitem o uso de custom tags e <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnahq.html">unified EL</a>, mas <strong>proíbem o uso de scriptlets</strong>, o que já é meio caminho andado rumo a um JSP mais limpo.</p>
<h3>Leitura recomendada</h3>
<ul>
<li><a href="http://java.sun.com/javaee/5/docs/tutorial/doc/">The Java EE 5 Tutorial</a>;</li>
<li><a href="http://www.amazon.com/Head-First-Servlets-JSP-Certified/dp/0596516681/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1260993372&#038;sr=8-1">Head First Servlets &#038; JSP</a>;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/12/17/jsp-e-tag-files-criando-templates-em-10-minutos/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Templates in 10 minutes with JSP and tag files</title>
		<link>http://weblog.destaquenet.com/2009/12/17/templates-in-10-minutes-with-jsp-and-tag-files/</link>
		<comments>http://weblog.destaquenet.com/2009/12/17/templates-in-10-minutes-with-jsp-and-tag-files/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 12:30:06 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jsp]]></category>
		<category><![CDATA[layout]]></category>
		<category><![CDATA[servlet]]></category>
		<category><![CDATA[tag]]></category>
		<category><![CDATA[tagfiles]]></category>
		<category><![CDATA[taglib]]></category>
		<category><![CDATA[template]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=822</guid>
		<description><![CDATA[Have you ever seen JSPs full of Aramaic-like scriptlets, crazy includes, duplicated code and no taglibs beyond that provided by the web framework in use? Are you staring at one right now? This is a fairly common thing, at least &#8230; <a href="http://weblog.destaquenet.com/2009/12/17/templates-in-10-minutes-with-jsp-and-tag-files/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Have you ever seen JSPs full of Aramaic-like scriptlets, crazy includes, duplicated code and no taglibs beyond that provided by the web framework in use? Are you staring at one right now?</p>
<p>This is a fairly common thing, at least for the companies I worked for so far, and that&#8217;s what scares me the most. Hopefully, you can easily make things better if you want to.</p>
<p>In this post, I&#8217;ll show you a few techniques that can be used to write clean JSPs without resorting to any kind of templating system whatsoever.</p>
<p><span id="more-822"></span></p>
<h3>An example</h3>
<p>The first step is to define the base template for the application pages. Consider the following XHTML example and its graphic representation:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=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;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;keyword1, keyword2, keyword3&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Page title<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Essential scripts --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;link</span> <span style="color: #000066;">rel</span>=<span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;css/style.css&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/query.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Extra header --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrapper&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;footer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            // Other scripts (e.g. Google Analytics)
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<div id="attachment_803" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2009/12/layout.gif"><img src="http://weblog.destaquenet.com/wp-content/uploads/2009/12/layout-300x156.gif" alt="Template graphic representation" title="layout" width="300" height="156" class="size-medium wp-image-803" /></a><p class="wp-caption-text">Template graphic representation</p></div>
<p>What usually happens, even with a simple template such as this, is a high level of code duplication among the different pages due to the heavy use of <a href="http://en.wikipedia.org/wiki/Copy_and_paste_programming">Copy and Paste Programming</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=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;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;keyword1, keyword2, keyword3&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Page title<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Essential scripts --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:include</span> <span style="color: #000066;">page</span>=<span style="color: #ff0000;">&quot;scripts.jsp&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Extra header --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrapper&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:include</span> <span style="color: #000066;">file</span>=<span style="color: #ff0000;">&quot;header.jsp&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Page content here<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:include</span> <span style="color: #000066;">page</span>=<span style="color: #ff0000;">&quot;footer.jsp&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            // Other scripts
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>See? Why break the template into small pieces if you are going keep duplicating code anyway? The best thing to do is to translate that template into something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">tagdir</span>=<span style="color: #ff0000;">&quot;/WEB-INF/tags/layout&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:page</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Title&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> <span style="color: #000066;">keywords</span>=<span style="color: #ff0000;">&quot;keyword1, keyword2, keyword3&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        // Other scripts (e.g. Google Analytics)
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        Page content here
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/layout:page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<h3>Content reuse with tag files</h3>
<p>There are three types of JSP tags, each with its own strengths and weaknesses: <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaow.html#bnaoy">classic tag handlers</a>, <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnann.html">simple tag handlers</a> and <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnama.html">tag files</a>. Today I&#8217;ll cover the basics of tag files, but every Java developer should learn when and how to use the other two.</p>
<p>The first thing we need to do is create the <code>WEB-INF/tags/layout</code> directory, which will keep the tag files we are about to create. Now, create two files inside this directory, one for the header and the other for the footer:</p>
<p><strong>header.tag</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ tag <span style="color: #000066;">body-content</span>=<span style="color: #ff0000;">&quot;empty&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Header tag file&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;header&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- Header section here --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><strong>footer.tag</strong></p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ tag <span style="color: #000066;">body-content</span>=<span style="color: #ff0000;">&quot;empty&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Footer tag file&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;footer&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #808080; font-style: italic;">&lt;!-- Footer section here --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>As we can see, tag files are just like JSPs, but with some special properties.</p>
<p>The last tag file, <strong>page.tag</strong>, defines the overall page structure:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ tag <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;title&quot;</span>       <span style="color: #000066;">required</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page title&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">required</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page keywords to improve SEO&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">required</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Page description&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Extra code to put before &lt;/head&gt;</span></span>&quot; %&gt;
<span style="color: #009900;">&lt;%@ attribute <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;true&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;Extra code to put before &lt;/body&gt;</span></span>&quot; %&gt;
&nbsp;
<span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">tagdir</span>=<span style="color: #ff0000;">&quot;/WEB-INF/tags/layout&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
&nbsp;
<span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span>
<span style="color: #00bbdd;">    &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;html</span> <span style="color: #000066;">xmlns</span>=<span style="color: #ff0000;">&quot;http://www.w3.org/1999/xhtml&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">http-equiv</span>=<span style="color: #ff0000;">&quot;content-type&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Displaying the attributes using EL --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;keywords&quot;</span>    <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;${keywords}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;meta</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;description&quot;</span> <span style="color: #000066;">content</span>=<span style="color: #ff0000;">&quot;${description}&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${title}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/title<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Essential scripts --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;link</span> <span style="color: #000066;">rel</span>=<span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">href</span>=<span style="color: #ff0000;">&quot;css/style.css&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/query.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Process the given input fragment --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:invoke</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/head<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;wrapper&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #808080; font-style: italic;">&lt;!-- Renders the page header --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:header</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!-- Renders the tag body inside a DIV --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;div</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;content&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;jsp:doBody</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
            <span style="color: #808080; font-style: italic;">&lt;!-- Renders the page footer --&gt;</span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:footer</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div<span style="color: #000000; font-weight: bold;">&gt;</span></span></span> <span style="color: #808080; font-style: italic;">&lt;!-- Main --&gt;</span>
&nbsp;
        <span style="color: #808080; font-style: italic;">&lt;!-- Process the given input fragment --&gt;</span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:invoke</span> <span style="color: #000066;">fragment</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/html<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>This last tag file is more complex than the other two, because you can pass to it both values and <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaln.html#bnalq">fragments</a>. Besides, this tag accepts a body, which gets executed with <code>&lt;jsp:doBody/&gt;</code>.</p>
<p>Of course, the example shown here is fairly simple, so we didn&#8217;t have to use more advanced features like <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaln.html#bnaly">variables</a> and <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnaln.html#bnaly">dynamic attributes</a>. Be that as it may, it&#8217;s a good idea to know what the technology has to offer. You&#8217;ll never know when a feature will be useful until you need it.</p>
<h3>Usage</h3>
<p>Now, let&#8217;s put those tag files to use:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">tagdir</span>=<span style="color: #ff0000;">&quot;/WEB-INF/tags/layout&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;layout&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;">&lt;%@ taglib <span style="color: #000066;">uri</span>=<span style="color: #ff0000;">&quot;http://java.sun.com/jsp/jstl/core&quot;</span> <span style="color: #000066;">prefix</span>=<span style="color: #ff0000;">&quot;c&quot;</span> %<span style="color: #000000; font-weight: bold;">&gt;</span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout:page</span> <span style="color: #000066;">title</span>=<span style="color: #ff0000;">&quot;Index page&quot;</span> <span style="color: #000066;">description</span>=<span style="color: #ff0000;">&quot;This is the index page of my amazing app&quot;</span> <span style="color: #000066;">keywords</span>=<span style="color: #ff0000;">&quot;amazing, app&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraHeader&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/util.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;script</span> <span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;text/javascript&quot;</span> <span style="color: #000066;">src</span>=<span style="color: #ff0000;">&quot;js/some_jquery_plugin.js&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/script<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:attribute</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;extraBottom&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
        $(function() {
            // Call some JQuery function here, specific for this page
        });
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:attribute<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        Welcome to my amazing app!<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;br</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        1+1 = ${1+1}
&nbsp;
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;c:forEach</span> <span style="color: #000066;">items</span>=<span style="color: #ff0000;">&quot;${objects}&quot;</span> <span style="color: #000066;">var</span>=<span style="color: #ff0000;">&quot;obj&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${obj.attr}<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/li<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/c:forEach<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/ul<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/jsp:body<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/layout:page<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Although the application as a whole follow the same visual standard, each page may need additional resources (JavaScript, CSS, etc.). This is hardly a problem because our template allows us to include extra content if necessary.</p>
<p>The other advantage is that tag files allow the use of custom tags and <a href="http://java.sun.com/javaee/5/docs/tutorial/doc/bnahq.html">unified EL</a>, but <strong>deny the use of scriptlets</strong>, which is a good thing if you want to get rid of messy JSPs.</p>
<h3>Recommended reading</h3>
<ul>
<li><a href="http://java.sun.com/javaee/5/docs/tutorial/doc/">The Java EE 5 Tutorial</a>;</li>
<li><a href="http://www.amazon.com/Head-First-Servlets-JSP-Certified/dp/0596516681/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1260993372&#038;sr=8-1">Head First Servlets &#038; JSP</a>;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/12/17/templates-in-10-minutes-with-jsp-and-tag-files/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Por favor, usem typesafe enums!</title>
		<link>http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/</link>
		<comments>http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 02:20:35 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[análise]]></category>
		<category><![CDATA[banco de dados]]></category>
		<category><![CDATA[boas práticas]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[enums]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[modelagem]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=349</guid>
		<description><![CDATA[Enquanto conversava com um amigo, há alguns dias atrás, surgiu um assunto a respeito de algo que costumamos ver com certa frequência. Vou tentar contextualizar essa conversa com o diagrama UML Entidade-Relacionamento a seguir: Nem irei perder tempo explicando esse &#8230; <a href="http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Enquanto conversava com um amigo, há alguns dias atrás, surgiu um assunto a respeito de algo que costumamos ver com certa frequência. Vou tentar contextualizar essa conversa com o diagrama <span style="text-decoration: line-through;">UML</span> Entidade-Relacionamento a seguir:</p>
<div id="attachment_358" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2009/02/diagram01.png"><img class="size-medium wp-image-358" title="Diagrama" src="http://weblog.destaquenet.com/wp-content/uploads/2009/02/diagram01-300x218.png" alt="Modelo-exemplo de banco de dados" width="300" height="218" /></a><p class="wp-caption-text">Modelo-exemplo de banco de dados</p></div>
<p>Nem irei perder tempo explicando esse modelo, até porque não há nada nele que precise de explicações. Bem, na verdade, há uma coisa sim: <strong>por que raios existe uma tabela só para armazenar os tipos de contato?!</strong> Qual é o problema com os bons e velhos códigos fixos (1-email, 2-celular, N-&#8230;)?</p>
<p>Um argumento a favor dessa abordagem é que &#8220;o usuário pode querer cadastrar um contato cujo tipo não seja suportado pela aplicação&#8221;. Mas será mesmo que colocar essa informação no banco de dados resolve o problema? E, mais importante, existe algum efeito colateral?</p>
<p>Bem, na minha experiência, embora essa abordagem pareça boa o bastante para resolver a questão num sistema simples de &#8220;cadastro&#8221;, a bomba explode quando o sistema passa a depender dessas flags para a realização de lógicas de negócio que vão além do famigerado CRUD. <span id="more-349"></span></p>
<h3>Anti-pattern?</h3>
<p>E se eu te dissesse que usar tabelas no banco de dados para armazenar flags é um anti-pattern? Digo isso pois, como veremos a seguir, as vantagens são irrisórias frente às desvantagens:</p>
<p><strong>Poluição do modelo de dados.</strong> Um sistema não muito grande provavelmente conta com mais de uma centena de tabelas. Isso todo mundo sabe. O que todo mundo também sabe, mas parece ignorar, é que não seria surpreendente constatar que 10-15% dessas tabelas serviriam apenas para armazenar flags (situação de pedido, estado civil, forma de pagamento, e por aí vai). E o pior: essas tabelas, quase sempre, possuem exatamente a mesma estrutura, que apelidei carinhosamente de <strong>tabelas código-descrição</strong>. A tabela <code>TipoContato</code>, mostrada no diagrama que encabeça este texto, é um exemplo desse tipo de tabela.</p>
<p><strong>Ruim para o meio ambiente.</strong> Poluir o modelo de dados com dezenas de <strong>tabelas código-descrição</strong> torna o modelo desnecessariamente maior e mais difícil de compreender. Imprimir um modelo desses consome mais papel, o que é ruim numa época onde o desenvolvimento sustentável está em voga. Quantas árvores suas <strong>tabelas código-descrição</strong> já derrubaram?</p>
<p><strong>Ultra-normalização.</strong> Quanto mais tabelas uma consulta envolver, mais joins, e mais dados indo e vindo para o banco de dados. E, considerando que o banco de dados é (quase) sempre o gargalo, isso não é muito bom para a performance do seu sistema.</p>
<p><strong>Poluição do modelo de objetos.</strong> As linguagens com suporte à orientação a objetos figuram entre as <a href="http://www.tiobe.com/content/paperinfo/tpci/index.html">mais usadas atualmente</a>, por isso eu diria que muito provavelmente você utiliza esse paradigma no desenvolvimento dos seus sistemas. Se este for o caso, também é bem provável que você utilize algum framework ORM para facilitar a tarefa de integração do software com o banco de dados. Como muitos frameworks ORM exigem um modelo de objetos compatível com o modelo de dados, bem, você acaba sendo forçado a poluir seu modelo de objetos com classes burras que apelidei carinhosamente de (pasmem!) <strong>classes código-descrição</strong>.</p>
<p><strong>Se tem tabela, tem cadastro.</strong> Bom, já que todas as flags possuem suas tabelinhas no banco de dados, isso significa que você, pobre desenvolvedor, terá que fazer &#8220;cadastros&#8221; para todas elas (e reze para não precisar fazer relatórios, também). Além da chatisse costumeira de se fazer um cadastro, devemos levar em consideração que fazê-los consome tempo e, tempo é dinheiro.</p>
<p><strong>Código quebradiço.</strong> Essa é feia. Vamos supor que, nessa nossa aplicação de gerenciamento de clientes/contatos, você queira incluir uma funcionalidade que permita enviar um torpedo ao cliente caso ele possua um contato do tipo <code>Celular</code>. Como mostrado no trecho de código a seguir, você fatalmente terá que incluir no código-fonte referências a registros armazenados no banco de dados, tornando o código quebradiço. Consequentemente, um único <code>UPDATE</code> ou <code>DELETE</code> executado por engano no banco de dados pode fazer o sistema cair de joelhos.</p>
<p>Enviando torpedos a um cliente:</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: #000066; font-weight: bold;">void</span> enviarTorpedo<span style="color: #009900;">&#40;</span>Cliente cliente, <span style="color: #003399;">String</span> texto<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">// Tenta localizar um contato do tipo celular</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Contato contato <span style="color: #339933;">:</span> cliente.<span style="color: #006633;">getContatos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">// WTF!! Estamos referenciando um registro do banco de dados!!</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getCodigo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> 10L<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            SMSUtil.<span style="color: #006633;">enviarTorpedo</span><span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getValor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, texto<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>A solução</h3>
<p>Com certeza existem outros problemas que eu acabei deixando passar, mas espero que os problemas que listei já sejam o suficiente para te convencer que guardar flags em tabelas no banco de dados é uma má idéia.</p>
<p>Mas, como resolver isso então? Simples: <strong>use enums sempre que possível.</strong> A única desvantagem é que os usuários não poderão mais sair criando novas flags a torto e a direito, o que não é realmente um problema frente às vantagens que as enums oferecem<strong>.<br />
</strong></p>
<p><strong>Poluição do modelo de dados?</strong> As flags virariam campos numéricos ou alfanuméricos nas tabelas que as usam e o framework ORM se encarregaria de converter esses campos de/para objetos enum. Diga adeus às <strong>tabelas código-descrição</strong>.</p>
<p><strong>Ruim para o meio-ambiente?</strong> Sem as <strong>tabelas código-descrição</strong>, seu modelo fica menor, mais enxuto, facilitando a visualização e gastando menos papel ao imprimí-lo. A natureza agradece.</p>
<p><strong>Ultra-normalização?</strong> Usando enums você diminui a quantidade de ligações entre as tabelas, tornando as entidades um pouco mais auto-contidas. Menos tabelas, menos joins, mais performance.</p>
<p><strong>Poluição do modelo de objetos?</strong> As enums tomariam o lugar das <strong>classes código-descrição</strong>, o que por si só tornaria o código mais claro, pois, ao contrário das classes &#8220;normais&#8221;, as enums possuem um propósito bem definido.</p>
<p><strong>Se tem tabela, tem cadastro?</strong> Ué, por que você está com esse sorriso estampado no rosto?</p>
<p><strong>Código quebradiço?</strong> Quem mais se beneficia das enums são os trechos de código onde as lógicas de negócio são definidas. Mais especificamente, seu código deixa de referenciar registros do banco de dados, eliminando a fragilidade e melhorando a legibilidade. As enums também impedem que valores arbitrários sejam usados em atribuições e comparações, tornando o código ainda mais confiável. Um exemplo disso pode ser visto no código a seguir, que é uma adaptação <span style="text-decoration: line-through;">da atrocidade</span> do código mostrado anteriormente:</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: #000066; font-weight: bold;">void</span> enviarTorpedo<span style="color: #009900;">&#40;</span>Cliente cliente, <span style="color: #003399;">String</span> texto<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Contato contato <span style="color: #339933;">:</span> cliente.<span style="color: #006633;">getContatos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">// Bem melhor agora!</span>
         <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getTipo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> TipoContato.<span style="color: #006633;">CELULAR</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            SMSUtil.<span style="color: #006633;">enviarTorpedo</span><span style="color: #009900;">&#40;</span>contato.<span style="color: #006633;">getValor</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, texto<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>O fato de a sua linguagem do coração não ter suporte nativo a enums não deve ser um impedimento para que você deixe de usufruir de suas vantagens. <a href="http://www.ditchnet.org/wp/2005/05/08/typesafe-enum-pattern-in-python/">Existem formas</a> de se conseguir uma funcionalidade semelhante sem muito esforço.</p>
<h3>Conclusão</h3>
<p>Desenvolver software é, antes de tudo, fazer escolhas. É o custo/benefício, os prós e contras antes de se tomar uma decisão. A boa notícia é que o nosso produto, o software, é maleável o suficiente para permitir que decisões ruins sejam re-feitas sempre que elas resultam em problemas como o descrito neste texto.</p>
<p>Bom carnaval!</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2009/02/18/por-favor-usem-typesafe-enums/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Integração Contínua de aplicações Python com Hudson</title>
		<link>http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/</link>
		<comments>http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 12:00:24 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[build]]></category>
		<category><![CDATA[configuração]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[integração contínua]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[projeto]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[testes]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[unittest]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=166</guid>
		<description><![CDATA[No começo deste mês eu dei dicas sobre como usar o Fabric para automatizar o build e o deployment de aplicações Python. Essa automatização por si só já quebra uma árvore, mas ela possibilita ainda o uso de Integração Contínua, &#8230; <a href="http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>No começo deste mês <a href="http://weblog.destaquenet.com/2008/10/05/deployment-de-aplicacoes-python-com-fabric/">eu dei dicas</a> sobre como usar o <a href="http://www.nongnu.org/fab/">Fabric</a> para automatizar o <em>build</em> e o <em>deployment</em> de aplicações <a href="http://python.org/">Python</a>.</p>
<p>Essa automatização por si só já quebra uma árvore, mas ela possibilita ainda o uso de Integração Contínua, uma prática extremamente importante que costuma ajudar muitas equipes a manter seus projetos nos trilhos. Para mais informações sobre Integração Contínua, eu recomendo a leitura <a href="http://martinfowler.com/articles/continuousIntegration.html">deste artigo</a>, até porque este <em>post</em> terá um enfoque mais prático.</p>
<p>Neste texto será mostrado como configurar um projeto Python no <a href="http://hudson.dev.java.net/">Hudson</a>, um servidor de Integração Contínua muito simples de configurar e utilizar. O sistema de controle de versões que eu utilizo aqui é o <a href="http://git.or.cz/">Git</a>, mas usuários de outros sistemas também poderão achar este texto útil.<span id="more-166"></span></p>
<h3>Baixando o Hudson</h3>
<p>Acesse o site do <a href="http://hudson.dev.java.net/">Hudson</a> e baixe o arquivo <code>.war</code> através do link disponível na página principal. Quando o download terminar, basta rodar o comando abaixo para subir o servidor na porta <code>8080</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">java <span style="color: #660033;">-jar</span> hudson.war</pre></div></div>

<div id="attachment_185" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson01.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson01-300x187.png" alt="Tela inicial do Hudson" title="Tela inicial do Hudson" width="300" height="187" class="size-medium wp-image-185" /></a><p class="wp-caption-text">Tela inicial do Hudson</p></div>
<p>Perca uns cinco minutos dando uma navegada no Hudson para ter uma idéia melhor do que é possível de ser feito com ele.</p>
<h3>Hudson e plugins</h3>
<p>O Hudson vem com suporte a <a href="http://maven.apache.org/">Maven</a> e <a href="http://ant.apache.org/">Ant</a>, duas das mais populares ferramentas para <em>build</em> de aplicações Java. Mas não se engane: o Hudson pode ser aproveitado em praticamente qualquer projeto, independente da linguagem e dos <em>frameworks</em> utilizados.</p>
<p>As funcionalidades do Hudson podem ser estendidas através de <em>plugins</em>, sendo que neste artigo utilizaremos dois deles: o <em>Git Plugin</em>, necessário para que o Hudson consiga trabalhar com repositórios Git, e o <em>Violations</em>, que consegue interpretar a saída de diferentes verificadores de código (dentre eles o <a href="http://www.logilab.org/857">pylint</a>, um analisador de código Python!) e exibir informações a respeito da qualidade do código-fonte.</p>
<p>Para instalar esses plugins, basta acessar a tela de gerenciamento de plugins, marcar o <em>Git Plugin</em> e o <em>Violations</em>, e confirmar:</p>
<div id="attachment_186" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson02.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson02-300x187.png" alt="Instalando os plugins" title="Instalando os plugins" width="300" height="187" class="size-medium wp-image-186" /></a><p class="wp-caption-text">Instalando os plugins</p></div>
<p>Assim que a instalação terminar, reinicie o Hudson.</p>
<h3>Integrando testes escritos com PyUnit ao Hudson</h3>
<p>Apesar de existirem várias opções para criação e execução de testes unitários para Python, o <a href="http://pyunit.sourceforge.net/">PyUnit</a> costuma ser o mais usado pelo fato de já estar incluído na distribuição padrão do Python.</p>
<p>Quem já fuçou no código do PyUnit sabe que ele define <strong>apenas um</strong> <code>TestRunner</code>, o <a href="http://pyunit.sourceforge.net/pyunit.html#RUNNING_INT"><code>TextTestRunner</code></a>. O que este <code>TestRunner</code> basicamente faz é gerar em um fluxo qualquer (geralmente no <code>sys.stderr</code>) uma saída parecida com a seguinte:</p>
<pre>.....
----------------------------------------------------------------------
Ran 5 tests in 0.067s</pre>
<p>Apesar de eu me contentar com essa saída mais simples, bom, ferramentas como o próprio Hudson <strong>não se contentam</strong>; elas preferem algo como o bom e velho XML, que, convenhamos, é muito mais fácil de parsear.</p>
<p>Perdi algumas horas na Internet procurando por um <code>TestRunner</code> que conseguisse gerar arquivos XML no mesmo formato que os gerados pelo Ant e Maven, mas não encontrei nenhuma opção que fosse minimamente confiável. Por isso, eu tomei a liberdade de escrever meu próprio <code>TestRunner</code>: <a href="http://github.com/danielfm/unittest-xml-reporting/tree">XMLTestRunner</a>. O código deste &#8220;projeto&#8221;, disponibilizado no <a href="http://github.com/">Github</a>, contém instruções de uso e scripts de exemplo. <strong>Clonem e forkem à vontade!</strong></p>
<p>Antes de prosseguirmos, baixe o módulo <code>xmlrunner.py</code> do <a href="http://github.com/danielfm/unittest-xml-reporting/tree">site do projeto</a> e o copie em algum lugar dentro do seu <code>PYTHONPATH</code>.</p>
<h3>Integrando um projeto Python no Hudson</h3>
<p>Para não perdermos tempo criando do zero um projeto de exemplo em Python, eu mostrarei como fazer para integrar o próprio <code>XMLTestRunner</code> com o Hudson.</p>
<p>Abra o console administrativo do Hudson e clique no link <em>New Job</em>:</p>
<div id="attachment_214" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson03.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson03-300x172.png" alt="Criando um projeto &quot;free-style&quot;" title="Criando um projeto &quot;free-style&quot;" width="300" height="172" class="size-medium wp-image-214" /></a><p class="wp-caption-text">Criando um projeto &quot;free-style&quot;</p></div>
<p>Na próxima tela, precisamos configurar o Job com os dados necessários:</p>
<div id="attachment_215" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson04.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson04-300x172.png" alt="Configuração de projeto" title="Configuração de projeto" width="300" height="172" class="size-medium wp-image-215" /></a><p class="wp-caption-text">Configuração de projeto</p></div>
<div id="attachment_216" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson05.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson05-300x172.png" alt="Configuração de projeto" title="Configuração de projeto" width="300" height="172" class="size-medium wp-image-216" /></a><p class="wp-caption-text">Configuração de projeto</p></div>
<p>Isso é tudo! Confirme as alterações e clique no link <em>Build now</em>. Aguarde alguns segundos enquanto o projeto é baixado do repositório Git e testado:</p>
<div id="attachment_220" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson06.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson06-300x172.png" alt="Exemplos de builds feitos pelo Hudson" title="Exemplos de builds feitos pelo Hudson" width="300" height="172" class="size-medium wp-image-220" /></a><p class="wp-caption-text">Exemplos de builds feitos pelo Hudson</p></div>
<div id="attachment_238" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson07.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson07-300x172.png" alt="Relatório de execução de testes" title="Relatório de execução de testes" width="300" height="172" class="size-medium wp-image-238" /></a><p class="wp-caption-text">Relatório de execução de testes</p></div>
<div id="attachment_239" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson08.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/10/hudson08-300x172.png" alt="Análise de código feita pelo pylint" title="Análise de código feita pelo pylint" width="300" height="172" class="size-medium wp-image-239" /></a><p class="wp-caption-text">Análise de código feita pelo pylint</p></div>
<h3>Como disparar o <em>build</em> de forma automática?</h3>
<p>Uma vez que o projeto tenha sido configurado corretamente, basta um clique do mouse para que o Hudson faça todo o trabalho sujo. O problema agora é lembrar de fazer o <em>build</em> sempre que alguém modificar código no repositório.</p>
<p>Felizmente, temos duas opções para nos livrar de mais essa tarefa manual: a primeira seria configurar, nas propriedades do Job, uma expressão Cron que indique de quanto em quanto tempo o <em>build</em> deve ser feito; a segunda alternativa é apenas disparar o <em>build</em> quando alguém modificar código no repositório.</p>
<p>Como acontece com outros sistemas de controle de revisão, o Git possui <em>hooks</em> que nos permite executar ações em determinados momentos. Esses <em>hooks</em> nada mais são do que scripts executáveis localizados no diretório <code>.git/hooks</code>.</p>
<p>Mas enfim, quando disparar o <em>build</em>? Se o repositório Git e o servidor Hudson não são capazes de se comunicar diretamente, talvez a única alternativa seja disparar o <em>build</em> periodicamente. Para isso, você deve configurar um ou mais <em>Build Triggers</em>, na tela de configuração do Job.</p>
<p>Entretanto,  se você mantém o repositório Git e o servidor Hudson na mesma máquina, ou mesmo em máquinas diferentes mas capazes de se comunicar via rede, podemos considerar a utilização dos <em>hooks</em> como ferramenta de integração entre o repositório Git e o Hudson.</p>
<p>Agora a pergunta que não quer calar: <strong>como integrar o Git e o Hudson?</strong> Bem, isso ficará como exercício para o leitor.</p>
<p>Dicas:</p>
<ul>
<li>O Hudson <a href="http://hudson.gotdns.com/wiki/display/HUDSON/Remote+access+API">disponibiliza uma API</a> através da qual se pode agendar <em>builds</em>, alterar as configurações do Job, criar Jobs, entre outras coisas.</li>
<li>Para conhecer os <em>hooks</em> oferecidos pelo Git, consulte a <a href="http://www.kernel.org/pub/software/scm/git/docs/githooks.html">documentação</a>.</li>
</ul>
<h3>Conclusão</h3>
<p>Já faz algum tempo que eu venho utilizando o Hudson para integrar projetos Java, e esta ferramenta vem se mostrando muito útil no meu dia-a-dia. Só quem pratica Integração Contínua sabe o quanto é complicado não contar com a segurança que ela proporciona ao desenvolvimento.</p>
<p>O problema, no entanto, começou quando eu optei pelo Python em vez do Java em certos projetos. Obviamente, eu queria aproveitar o ambiente de Integração Contínua que eu já utilizava, o que foi bastante complicado já que o PyUnit, <em>framework</em> de testes que eu costumo utilizar, não oferece uma forma de gerar relatórios XML, da mesma forma que Ant e Maven fazem.</p>
<p>Depois de estudar o funcionamento interno do PyUnit, eu decidi implementar um <code>TestRunner</code> que fosse capaz de gerar arquivos XML no formato esperado pelo Hudson. Deu um bocado de trabalho, é verdade, mas pelo menos agora eu consigo utilizar os excelentes relatórios gerados pelo Hudson para acompanhar a execução dos meus testes PyUnit.</p>
<p>Como o Brasil é grande, seria burrice achar que eu fui o único a enfrentar esse tipo de dificuldade. Por esse motivo, eu resolvi escrever este texto e, quem sabe, ajudar àqueles que enfrentam um problema semelhante.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/10/27/integracao-continua-de-aplicacoes-python-com-hudson/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Em tempos de Mega Sena acumulada&#8230;</title>
		<link>http://weblog.destaquenet.com/2008/09/27/em-tempos-de-mega-sena-acumulada/</link>
		<comments>http://weblog.destaquenet.com/2008/09/27/em-tempos-de-mega-sena-acumulada/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 01:06:11 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Off Topic]]></category>
		<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[desafio]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[meme]]></category>
		<category><![CDATA[smalltalk]]></category>
		<category><![CDATA[squeak]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=56</guid>
		<description><![CDATA[Há algum tempo atrás eu acabei me deparando com um desafio bastante interessante proposto por Rodrigo Sol. O desafio em questão pede a criação do menor programa possível &#8212; em qualquer linguagem &#8212; para gerar um jogo da Mega Sena. &#8230; <a href="http://weblog.destaquenet.com/2008/09/27/em-tempos-de-mega-sena-acumulada/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Há algum tempo atrás eu acabei me deparando com <a href="http://macacochefe.blogspot.com/2007/08/code-contest-em-tempos-de-mega-sena.html">um desafio</a> bastante interessante proposto por <a href="http://macacochefe.blogspot.com/">Rodrigo Sol</a>. O desafio em questão pede a criação do menor programa possível &#8212; em qualquer linguagem &#8212; para gerar um jogo da Mega Sena. Hehe, impressionante o poder de uma loteria acumulada sobre as pessoas! <img src='http://weblog.destaquenet.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Seguem as regras do desafio nas palavras do próprio Rodrigo:</p>
<blockquote><p>
Escrever em qualquer linguagem de programação um programa que realize 100.000 sorteios de um numero entre 1 e 60 e mostre na tela os 6 mais freqüentes.</p>
<p>Ganha quem fizer o programa com o menor numero de linhas possíveis, lembrando que a linha considerada é a linha da unidade léxica da linguagem, portanto a seguinte linha em Java seria considerada duas: int i =0; sysout(i);
</p></blockquote>
<p>Como na época eu estava aprendendo <a href="http://groovy.codehaus.org/">Groovy</a>, não podia deixar esta oportunidade passar. E, de fato, não deixei! <span id="more-56"></span></p>
<p>Veja, abaixo, uma solução para o &#8220;problema&#8221; proposto, usando a linguagem Groovy:</p>

<div class="wp_syntax"><div class="code"><pre class="groovy" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">def</span> hist <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span>:<span style="color: #66cc66;">&#93;</span>, v
<span style="color: #cc66cc;">100000</span>.<span style="color: #993399;">times</span><span style="color: #66cc66;">&#123;</span>hist<span style="color: #66cc66;">&#91;</span>v <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">+</span> <span style="color: #aaaadd; font-weight: bold;">Math</span>.<span style="color: #006600;">random</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">*</span> <span style="color: #cc66cc;">60</span> <span style="color: #000000; font-weight: bold;">as</span> <span style="color: #993333;">int</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">!</span>hist<span style="color: #66cc66;">&#91;</span>v<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">?</span> <span style="color: #cc66cc;">1</span> : hist<span style="color: #66cc66;">&#91;</span>v<span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">+</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#125;</span>
<span style="color: #993399;">println</span> hist.<span style="color: #006600;">keySet</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #663399;">toList</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #663399;">sort</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">-</span>hist<span style="color: #66cc66;">&#91;</span>it<span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#91;</span><span style="color: #cc66cc;">0</span>..<span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#93;</span>.<span style="color: #663399;">join</span><span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">','</span><span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Será que dá para reduzir ainda mais esse código?</p>
<p><strong>Update:</strong> Resolvi tentar resolver o mesmo problema, só que agora usando Smalltalk:</p>

<div class="wp_syntax"><div class="code"><pre class="smalltalk" style="font-family:monospace;">|<span style="color: #00007f;"> s </span>|
<span style="color: #00007f;">s</span> <span style="color: #000066; font-weight:bold;">:=</span> <span style="">&#40;</span><span style="">&#40;</span><span style="color: #0000ff;">OrderedCollection</span> withAll: <span style="">&#40;</span><span style="">&#40;</span><span style="color: #00007f;">1</span> to: <span style="color: #00007f;">100000</span><span style="">&#41;</span> collect: <span style="">&#91;</span>:<span style="color: #00007f;">each</span> | <span style="color: #7f0000;">60</span> atRandom<span style="">&#93;</span><span style="">&#41;</span><span style="">&#41;</span> groupBy: <span style="">&#91;</span>:<span style="color: #00007f;">each</span> | each<span style="">&#93;</span> having: <span style="">&#91;</span>:<span style="color: #00007f;">each</span> | <span style="color: #7f007f;">true</span><span style="">&#93;</span><span style="">&#41;</span> asSortedCollection: <span style="">&#91;</span>:<span style="color: #00007f;">a</span> :<span style="color: #00007f;">b</span> | b size &lt; a size<span style="">&#93;</span>.
<span style="color: #00007f;">1</span> to: <span style="color: #00007f;">6</span> do: <span style="">&#91;</span>:<span style="color: #00007f;">each</span> | <span style="color: #0000ff;">Transcript</span> show: <span style="">&#40;</span><span style="">&#40;</span><span style="color: #00007f;">s</span> at: <span style="color: #00007f;">each</span><span style="">&#41;</span> at: <span style="color: #00007f;">1</span><span style="">&#41;</span>; cr<span style="">&#93;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/09/27/em-tempos-de-mega-sena-acumulada/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Debugando aplicações JavaEE no Glassfish v2</title>
		<link>http://weblog.destaquenet.com/2008/09/22/debugando-aplicacoes-javaee-no-glassfish-v2/</link>
		<comments>http://weblog.destaquenet.com/2008/09/22/debugando-aplicacoes-javaee-no-glassfish-v2/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 01:51:40 +0000</pubDate>
		<dc:creator>Daniel Martins</dc:creator>
				<category><![CDATA[Português]]></category>
		<category><![CDATA[Programação]]></category>
		<category><![CDATA[Tutoriais]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[dicas]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javaee]]></category>
		<category><![CDATA[netbeans]]></category>

		<guid isPermaLink="false">http://weblog.destaquenet.com/?p=50</guid>
		<description><![CDATA[Este post, na verdade, é uma dica rápida para quem possui aplicações JavaEE rodando em servidores Glassfish e está tendo dificuldades na hora de rastrear a origem de possíveis bugs no código. Habilitando o modo de debug Existem duas maneiras &#8230; <a href="http://weblog.destaquenet.com/2008/09/22/debugando-aplicacoes-javaee-no-glassfish-v2/">Continue lendo <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Este <em>post</em>, na verdade, é uma dica rápida para quem possui aplicações <a href="http://java.sun.com/javaee/">JavaEE</a> rodando em servidores <a href="http://glassfish.dev.java.net/">Glassfish</a> e está tendo dificuldades na hora de rastrear a origem de possíveis <em>bugs</em> no código. <span id="more-50"></span></p>
<h3>Habilitando o modo de debug</h3>
<p>Existem duas maneiras de se habilitar o modo de <em>debug</em> no Glassfish: através do painel de administração ou durante a inicialização do domínio.</p>
<p>Para habilitar o modo de <em>debug</em> por padrão, através do painel de administração, basta marcar o campo <em>Debug</em> na tela <em>JVM Settings</em> e clicar em <em>Save</em>:</p>
<div id="attachment_51" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/debug_mode.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/debug_mode-300x254.png" alt="Habilitando o modo de Debug" title="Modo de Debug" width="300" height="254" class="size-medium wp-image-51" /></a><p class="wp-caption-text">Habilitando o modo de Debug</p></div>
<p>Basta reiniciar o domínio para ver que o servidor abre a porta <code>9009</code>, através da qual podemos conectar um <em>debugger</em>:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">asadmin start-domain domain1</pre></div></div>

<p>Eis um resumo da saída ecoada pelo Glassfish:</p>
<pre>
Starting Domain domain1, please wait.
Log redirected to .../server.log.
Redirecting output to .../server.log
Listening for transport dt_socket at address: 9009
Application server is listening at address 9009 for debugger to attach using transport dt_socket
...
</pre>
<p>A outra forma de se habilitar o modo de <em>debug</em> é fornecer o parâmetro <code>--debug</code> ao iniciar o domínio. Por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">asadmin start-domain <span style="color: #660033;">--debug</span> domain1</pre></div></div>

<h3>Conectando o debugger da IDE ao servidor</h3>
<p>Agora, basta usar os recursos de <em>debugging</em> presentes na sua IDE Java para debugar o código. Por exemplo, se você usa o <a href="http://netbeans.org/">NetBeans</a> 5.5, basta acessar o menu <em>Run &#8211; Attach Debugger&#8230;</em> e o configurar da seguinte forma:</p>
<div id="attachment_52" class="wp-caption aligncenter" style="width: 310px"><a href="http://weblog.destaquenet.com/wp-content/uploads/2008/09/screenshot-attach.png"><img src="http://weblog.destaquenet.com/wp-content/uploads/2008/09/screenshot-attach-300x152.png" alt="Anexando o debugger do NetBeans" title="Anexando o debugger" width="300" height="152" class="size-medium wp-image-52" /></a><p class="wp-caption-text">Anexando o debugger do NetBeans</p></div>
<p>O procedimento é semelhante em outras IDEs Java.</p>
<p>Pronto! Feito isso, é só colocar os <em>breakpoints</em> e disparar a execução do código problemático.</p>
]]></content:encoded>
			<wfw:commentRss>http://weblog.destaquenet.com/2008/09/22/debugando-aplicacoes-javaee-no-glassfish-v2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

