<?xml version="1.0" encoding="UTF-8"?><feed
  xmlns="http://www.w3.org/2005/Atom"
  xmlns:thr="http://purl.org/syndication/thread/1.0"
  xml:lang="en"
  xml:base="http://blog.sobreira.eti.br/wp-atom.php"
   >
	<title type="text">Fabiano Sobreira</title>
	<subtitle type="text">Groovy, Grails e tudo mais sobre Java</subtitle>

	<updated>2011-12-01T19:40:17Z</updated>

	<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br" />
	<id>http://blog.sobreira.eti.br/feed/atom</id>
	<link rel="self" type="application/atom+xml" href="http://blog.sobreira.eti.br/feed/atom" />

	<generator uri="http://wordpress.org/" version="3.3.1">WordPress</generator>
		<entry>
		<author>
			<name>Fabiano Sobreira</name>
						<uri>http://blog.sobreira.eti.br</uri>
					</author>
		<title type="html"><![CDATA[Exportando Dados para Arquivo Texto com Groovy]]></title>
		<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br/archives/exportando-dados-para-arquivo-texto-com-groovy?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=exportando-dados-para-arquivo-texto-com-groovy" />
		<id>http://blog.sobreira.eti.br/?p=734</id>
		<updated>2011-12-01T19:40:17Z</updated>
		<published>2011-12-01T18:34:14Z</published>
		<category scheme="http://blog.sobreira.eti.br" term="Groovy" />		<summary type="html"><![CDATA[Outro dia desses um amigo precisava fazer a exportação de dados de venda de um supermercado para posterior importação em outro sistema. Ele já havia tentado o processo utilizando algumas ferramentas, mas sem sucesso. A exportação compreendia aproximadamentes 4 milhões de registros de venda sendo que os arquivos deveriam ser gerados dia a dia, separados <a href="http://blog.sobreira.eti.br/archives/exportando-dados-para-arquivo-texto-com-groovy"> read more <span class="meta-nav">&#187;</span></a>]]></summary>
		<content type="html" xml:base="http://blog.sobreira.eti.br/archives/exportando-dados-para-arquivo-texto-com-groovy?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=exportando-dados-para-arquivo-texto-com-groovy"><![CDATA[<p>Outro dia desses um amigo precisava fazer a exportação de dados de venda de um supermercado para posterior importação em outro sistema.</p>
<p>Ele já havia tentado o processo utilizando algumas ferramentas, mas sem sucesso. A exportação compreendia aproximadamentes 4 milhões de registros de venda sendo que os arquivos deveriam ser gerados dia a dia, separados em uma hierarquia de pastas estruturadas num formato tipo /ano/mes.</p>
<p>A solução foi escrever um simples Script em Groovy, que concluiu todo o processo em menos de cinco minutos. Para execução do script foi necessário apenas a instalação do Groovy, baixar o Driver do banco de dados e executar o comando:</p>
<pre>$ groovy -cp "jaybird-full-2.1.6.jar" MegaExport.groovy</pre>
<p>Isto mostra a simplicidade e o poder da linguagem Groovy e como ela pode ser empregada para soluções de problemas corriqueiros. Abaixo o script em questão:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.DriverManager</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">groovy.sql.Sql</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Parâmetros de configuração</span>
def SERVIDOR <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;127.0.0.1&quot;</span>
def BANCO_DE_DADOS <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/path/to/database.fdb&quot;</span>
def USUARIO <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;SYSDBA&quot;</span>
def SENHA <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;masterkey&quot;</span>
def DIRETORIO_DESTINO <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/path/to/files&quot;</span>
def DRIVER <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;org.firebirdsql.jdbc.FBDriver&quot;</span>
def STRING_CONEXAO <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;jdbc:firebirdsql://${SERVIDOR}/${BANCO_DE_DADOS}&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Comando SQL de seleção dos períodos com vendas</span>
def COMANDO_SQL_PERIODO <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\</span>
SELECT EXTRACT(year from sai_d_ve) AS ano
    , EXTRACT(month from sai_d_ve) AS mes 
FROM sai001 
WHERE (not sai_d_ve is null) 
GROUP BY 1, 2 
ORDER by 1, 2
&quot;</span><span style="color: #0000ff;">&quot;&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//Comando SQL de seleção das vendas</span>
def COMANDO_SQL_VENDAS <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\</span>
SELECT EXTRACT(day from sao.sai_d_ve) AS dia
    , sao.cupom AS cupom
    , sao.pro_barr AS ean
    , CAST(coalesce(sao.sai_quan,0) * 1000 AS bigint) AS quantidade
    , CAST(coalesce(sao.sai_quan,0) * coalesce(sao.sai_valo,0) * 100 AS bigint) AS subtotal
    , CAST(coalesce(sao.valor_desconto,0) * 100 AS bigint) AS desconto
    , CAST(coalesce(sao.acrescimo,0) * 100 AS bigint) AS acrescimo
    , CASE sao.item_excluido
        WHEN 'S' then 'C'
        ELSE 'V'
    END AS situacao
    , sao.descricao as descricao
    , CASE sao.id
        WHEN 'FF' then 'F   '
        WHEN 'II' then 'I   '
        WHEN 'NN' then 'N   '
        WHEN '01' then '0700'
        WHEN '02' then '1700'
        WHEN '03' then '1700'
        WHEN '04' then '2500'
        WHEN '05' then '0400'
        WHEN '06' then '0300'
        WHEN '07' then '2700'
        WHEN '08' then '1200'
        ELSE '    '
    END AS tributacao
FROM sai001 sao
WHERE (EXTRACT(year from sao.sai_d_ve) = ?) AND (EXTRACT(month from sao.sai_d_ve) = ?)
ORDER BY sao.sai_d_ve
&quot;</span><span style="color: #0000ff;">&quot;&quot;</span>
&nbsp;
println <span style="color: #0000ff;">&quot;Carregando o driver de conexão (${DRIVER})&quot;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">Class</span>.<span style="color: #006633;">forName</span><span style="color: #009900;">&#40;</span>DRIVER<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
println <span style="color: #0000ff;">&quot;Selecionando as datas para exportação&quot;</span> <span style="color: #339933;">;</span>
def sqlPeriodo <span style="color: #339933;">=</span> Sql.<span style="color: #006633;">newInstance</span><span style="color: #009900;">&#40;</span>STRING_CONEXAO, USUARIO, SENHA, DRIVER<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
    sqlPeriodo.<span style="color: #006633;">eachRow</span><span style="color: #009900;">&#40;</span>COMANDO_SQL_PERIODO<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> periodo <span style="color: #339933;">-&gt;</span>
        println <span style="color: #0000ff;">&quot;Exportando período ${periodo.ANO}/${periodo.MES}&quot;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">int</span> dia <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">int</span> mes <span style="color: #339933;">=</span> periodo.<span style="color: #006633;">MES</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">int</span> ano <span style="color: #339933;">=</span> periodo.<span style="color: #006633;">ANO</span><span style="color: #339933;">;</span>
&nbsp;
        println <span style="color: #0000ff;">&quot; &gt; Criando diretório ${DIRETORIO_DESTINO}/${ano.toString().padLeft(4, '0')}/${mes.toString().padLeft(2, '0')}&quot;</span><span style="color: #339933;">;</span>
        def diretorio <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;${DIRETORIO_DESTINO}/${ano.toString().padLeft(4, '0')}/${mes.toString().padLeft(2, '0')}&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        diretorio.<span style="color: #006633;">mkdirs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        println <span style="color: #0000ff;">&quot; &gt; Exportando os dados das vendas&quot;</span><span style="color: #339933;">;</span>
        def writer <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        def arquivo <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #339933;">;</span>
        def sqlVendas <span style="color: #339933;">=</span> Sql.<span style="color: #006633;">newInstance</span><span style="color: #009900;">&#40;</span>STRING_CONEXAO, USUARIO, SENHA, DRIVER<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
            sqlVendas.<span style="color: #006633;">eachRow</span><span style="color: #009900;">&#40;</span>COMANDO_SQL_VENDAS, <span style="color: #009900;">&#91;</span>ano, mes<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> venda <span style="color: #339933;">-&gt;</span>
                <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>dia <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">||</span> dia <span style="color: #339933;">!=</span> venda.<span style="color: #006633;">DIA</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    dia <span style="color: #339933;">=</span> venda.<span style="color: #006633;">DIA</span><span style="color: #339933;">;</span>					
                    def nomeArquivo <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;IT_${dia.toString().padLeft(2,'0') + mes.toString().padLeft(2, '0')}.txt&quot;</span><span style="color: #339933;">;</span>
&nbsp;
                    println <span style="color: #0000ff;">&quot; &gt; Criando arquivo ${diretorio.absolutePath}/${nomeArquivo}&quot;</span><span style="color: #339933;">;</span>
                    arquivo <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;${diretorio.absolutePath}/${nomeArquivo}&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    arquivo.<span style="color: #006633;">delete</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    arquivo.<span style="color: #006633;">createNewFile</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
                    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>writer<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        writer.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        writer.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                    <span style="color: #009900;">&#125;</span>
                    <span style="color: #666666; font-style: italic;">//a escrita deve ser feita em buffer por questões de desempenho</span>
                    writer <span style="color: #339933;">=</span> arquivo.<span style="color: #006633;">newWriter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
                <span style="color: #009900;">&#125;</span>
                writer.<span style="color: #006633;">write</span> ano.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> mes.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">DIA</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span>, <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> <span style="color: #0000ff;">&quot;000&quot;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">CUPOM</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">6</span>, <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> <span style="color: #0000ff;">&quot;00000&quot;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">EAN</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">14</span>, <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> <span style="color: #0000ff;">&quot;0000000&quot;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">QUANTIDADE</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">9</span>, <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">SUBTOTAL</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">11</span>, <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">DESCONTO</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">7</span>, <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">ACRESCIMO</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">7</span>, <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">SITUACAO</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padLeft</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span>, <span style="color: #0000ff;">&quot; &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">DESCRICAO</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padRight</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">30</span>, <span style="color: #0000ff;">&quot; &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">write</span> venda.<span style="color: #006633;">TRIBUTACAO</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">padRight</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">4</span>, <span style="color: #0000ff;">&quot; &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">newLine</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">finally</span> <span style="color: #009900;">&#123;</span>
            sqlVendas.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>writer<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                writer.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                writer.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
        <span style="color: #009900;">&#125;</span>    
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">finally</span> <span style="color: #009900;">&#123;</span>
    sqlPeriodo.<span style="color: #006633;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
println <span style="color: #0000ff;">&quot;Exportação finalizada.&quot;</span><span style="color: #339933;">;</span></pre></div></div>

]]></content>
		<link rel="replies" type="text/html" href="http://blog.sobreira.eti.br/archives/exportando-dados-para-arquivo-texto-com-groovy?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=exportando-dados-para-arquivo-texto-com-groovy#comments" thr:count="0"/>
		<link rel="replies" type="application/atom+xml" href="http://blog.sobreira.eti.br/archives/exportando-dados-para-arquivo-texto-com-groovy/feed/atom" thr:count="0"/>
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Fabiano Sobreira</name>
						<uri>http://blog.sobreira.eti.br</uri>
					</author>
		<title type="html"><![CDATA[Como Testar Sua Aplicação Grails]]></title>
		<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br/archives/como-testar-sua-aplicacao-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-testar-sua-aplicacao-grails" />
		<id>http://blog.sobreira.eti.br/?p=712</id>
		<updated>2011-06-18T03:48:17Z</updated>
		<published>2011-06-18T02:15:41Z</published>
		<category scheme="http://blog.sobreira.eti.br" term="Grails" />		<summary type="html"><![CDATA[O framework Grails oferece uma API rica e simples para execução de testes, para várias fases do processo de produção do aplicativo. Estas fases são inicialmente separadas em: unit integration functional other Novas fases ou tipos de testes podem ser adicionados a estas através do uso de plugins, sendo que as fases functional e other <a href="http://blog.sobreira.eti.br/archives/como-testar-sua-aplicacao-grails"> read more <span class="meta-nav">&#187;</span></a>]]></summary>
		<content type="html" xml:base="http://blog.sobreira.eti.br/archives/como-testar-sua-aplicacao-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-testar-sua-aplicacao-grails"><![CDATA[<p>O framework Grails oferece uma API rica e simples para execução de testes, para várias fases do processo de produção do aplicativo. Estas fases são inicialmente separadas em:</p>
<ul>
<li>unit
<li>integration
<li>functional
<li>other
</ul>
<p>Novas fases ou tipos de testes podem ser adicionados a estas através do uso de plugins, sendo que as fases <code>functional</code> e <code>other</code> necessitam de plugins específicos antes de serem utilizadas.</p>
<h3>Testes de Unidade</h3>
<p>Os testes de unidade têm por finalidade garantir o funcionamento de porções mínimas do código implementado, como um método ou a verificação do estado de um objeto após uma determinada operação.</p>
<p>Para se testar comportamentos dinâmicamente criados pelo framework, nesta fase, é necessário fazer a injeção manual destes nas classes ou fazer o <code>mocking</code> de objetos para se conseguir testar por exemplo as <code>constraints</code> de uma classe de domínio ou os <code>controllers</code>.</p>
<h3>Teste de integração</h3>
<p>A fase de testes de integração difere da fase de teste de unidade pelo fato de o Grails preparar todo o ambiente de execução dos testes conforme este seria no ambiente de execução do aplicativo.</p>
<p>Nesta fase todos os métodos dinamicamente injetados pelo framework estarão disponíveis para uso, sem necessidade de fazer mocking ou injeção manual dos mesmos.</p>
<p>Durante os testes de integração você tem acesso ao um banco de dados configurado no arquivo <code>conf/DataSource.groovy</code> para o ambiente de testes. Durante os testes o Grails e encarrega de criar a estrutura do banco de dados, iniciar uma transação e no final desfazer (rollback) tudo no final do processo transparentemente.</p>
<h3>Testes funcionais</h3>
<p>Os testes funcionais têm por objetivo enviar requisições <code>HTTP</code> para a aplicação e verificar o comportamento resultante. O Grails não provê suporte nativo para a execução de testes funcionais. Alguns plugins estão disponíveis atualmente para isto:</p>
<ul>
<li><a href="http://grails.org/plugin/webtest">Canoo Webtest</a>
<li><a href="http://grails.org/plugin/functional-test">G-Func</a>
<li><a href="http://grails.org/plugin/selenium-rc">Selenium-RC</a>
<li><a href="http://grails.org/plugin/webdriver">WebDriver</a>
<li><a href="http://grails.org/plugin/geb">Geb</a>
</ul>
<h2>Executando os Testes</h2>
<p>Por definição as classes de teste devem estender a classe <code>GrailsUnitTestCase</code>. Seu nome deve ter o sufixo <code>Tests</code> e seus métodos o prefixo <code>test</code>, conforme a especificação do JUnit 3, que é a base de execução dos testes de unidade e integração do Grails.</p>
<p>As classes de teste de unidade se encontram dentro do diretório <code>test/unit</code> e as de teste de integração no diretório <code>test/integration</code>.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Um exemplo de classe de teste do Grails</span>
<span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">exemplo</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">grails.test.*</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> PessoaTests <span style="color: #000000; font-weight: bold;">extends</span> GrailsUnitTestCase <span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">setUp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> tearDown<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">tearDown</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">void</span> testAlgumaCoisa<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        assertTrue <span style="color: #000066; font-weight: bold;">false</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>As classes de teste de unidade e integração pode ser criadas respectivamentes pelos comandos:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails create-unit-test MeuTesteDeUnidade
$ grails create-integration-test MeuTesteDeIntegracao</pre></div></div>

<p>O comando <code>test-app</code> do Grails oferece algumas opções bem interessantes para acelerar e automatizar o processo de testes da aplicação.</p>
<p>Em sua forma mais comum, sem parâmetros, todos os testes encontrados serão executados:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails test-app</pre></div></div>

<p>Alguns argumentos podem ser adicionados ao comando para agilizar o processo de teste, como por exemplo específicar uma fase de testes:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails test-app unit:
$ grails test-app integration:</pre></div></div>

<p>Além disso você pode combinar mais parâmetros para testar uma classe isoladamente&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails test-app unit: exemplo.Pessoa
$ grails test-app integration: exemplo.PessoaController</pre></div></div>

<p>ou testar um método específico&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails test-app unit: exemplo.Pessoa.testAlgumaCoisa</pre></div></div>

<h3>Metacaracteres</h3>
<p>Você pode utilizar metacaracteres para testar todas as classes de um pacote&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails test-app unit: exemplo.<span style="color: #000000; font-weight: bold;">*</span></pre></div></div>

<p>todas as classes de um pacote e seus subpacotes&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails test-app integration: exemplo.<span style="color: #000000; font-weight: bold;">**</span>.<span style="color: #000000; font-weight: bold;">*</span></pre></div></div>

<p>classes terminadas com uma determinada sentença&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails test-app <span style="color: #000000; font-weight: bold;">*</span>Controller</pre></div></div>

<p>ou combinar tudo isto&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails test-app exemplo.<span style="color: #000000; font-weight: bold;">**</span>.<span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000; font-weight: bold;">*</span>Controller</pre></div></div>

<h3>Visualizando os resultados</h3>
<p>O resultado da execução dos testes é salvo na pasta <code>target/test-reports</code> em formato <code>plain text</code>, <code>HTML</code> e <code>XML</code>.</p>
<h2>Conclusão</h2>
<p>Este artigo é apenas uma breve introdução a API e execução de de testes do Grails. Não deixe de consultar a última versão da <a href="http://grails.org/doc/latest/">documentação</a> do framework.</p>
]]></content>
		<link rel="replies" type="text/html" href="http://blog.sobreira.eti.br/archives/como-testar-sua-aplicacao-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-testar-sua-aplicacao-grails#comments" thr:count="0"/>
		<link rel="replies" type="application/atom+xml" href="http://blog.sobreira.eti.br/archives/como-testar-sua-aplicacao-grails/feed/atom" thr:count="0"/>
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Fabiano Sobreira</name>
						<uri>http://blog.sobreira.eti.br</uri>
					</author>
		<title type="html"><![CDATA[Groovy e Grails em 60 Segundos]]></title>
		<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br/archives/groovy-e-grails-em-60-segundos?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-e-grails-em-60-segundos" />
		<id>http://blog.sobreira.eti.br/?p=703</id>
		<updated>2011-06-18T02:21:51Z</updated>
		<published>2011-06-12T15:00:09Z</published>
		<category scheme="http://blog.sobreira.eti.br" term="Grails" />		<summary type="html"><![CDATA[Este vídeo é um pouco antigo, mas é muito divertido. Ta aí pra quem ainda não viu.]]></summary>
		<content type="html" xml:base="http://blog.sobreira.eti.br/archives/groovy-e-grails-em-60-segundos?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-e-grails-em-60-segundos"><![CDATA[<p>Este vídeo é um pouco antigo, mas é muito divertido. Ta aí pra quem ainda não viu.</p>
<div align=center><iframe width="480" height="390" src="http://www.youtube.com/embed/0xNP0JTSN5o" frameborder="0" allowfullscreen></iframe></div>
]]></content>
		<link rel="replies" type="text/html" href="http://blog.sobreira.eti.br/archives/groovy-e-grails-em-60-segundos?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-e-grails-em-60-segundos#comments" thr:count="0"/>
		<link rel="replies" type="application/atom+xml" href="http://blog.sobreira.eti.br/archives/groovy-e-grails-em-60-segundos/feed/atom" thr:count="0"/>
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Fabiano Sobreira</name>
						<uri>http://blog.sobreira.eti.br</uri>
					</author>
		<title type="html"><![CDATA[Meu Ambiente de Trabalho em 7 Itens]]></title>
		<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br/archives/meu-ambiente-de-trabalho-em-7-itens?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=meu-ambiente-de-trabalho-em-7-itens" />
		<id>http://blog.sobreira.eti.br/?p=690</id>
		<updated>2011-01-30T02:30:24Z</updated>
		<published>2011-01-29T21:52:09Z</published>
		<category scheme="http://blog.sobreira.eti.br" term="Pessoal" /><category scheme="http://blog.sobreira.eti.br" term="ambiente" /><category scheme="http://blog.sobreira.eti.br" term="pessoal" />		<summary type="html"><![CDATA[Não sei quando começou este meme entre desenvolvedores, mas está bem legal e como meu camarada @vixlima me convidou a entrar na brincadeira, vamos lá. 1- Ambiente Meu ambiente de trabalho precisa ser bem iluminado com luz natural e bem fresco, porque não consigo raciocinar corretamente quando estou com calor. Deixo sempre uma caneca de <a href="http://blog.sobreira.eti.br/archives/meu-ambiente-de-trabalho-em-7-itens"> read more <span class="meta-nav">&#187;</span></a>]]></summary>
		<content type="html" xml:base="http://blog.sobreira.eti.br/archives/meu-ambiente-de-trabalho-em-7-itens?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=meu-ambiente-de-trabalho-em-7-itens"><![CDATA[<p>Não sei quando começou <a href="http://www.google.com.br/search?rls=en&#038;q=meu+ambiente+de+trabalho+em+7+itens" target="_blank" rel="nofollow">este meme</a> entre desenvolvedores, mas está bem legal e como meu camarada <a href="http://twitter.com/vixlima" target="_blank" rel="nofollow">@vixlima</a> me convidou a entrar na brincadeira, vamos lá.</p>
<h2>1- Ambiente</h2>
<p>Meu ambiente de trabalho precisa ser bem iluminado com luz natural e bem fresco, porque não consigo raciocinar corretamente quando estou com calor. Deixo sempre uma caneca de água gelada na mesa e gosto de ter algumas guloseimas sempre a disposição. Não uso fones de ouvido e não acho muito educado usá-los enquanto se está trabalhando com outras pessoas. Uma música ambiente agradável tocando baixinho sempre é bem vinda.</p>
<p>Gosto da minha gatinha cutucando o teclado ou tirando um cochilo atrás do monitor enquanto trabalho. Perder o foco um pouquinho e se distrair ajuda a resolver problemas e ela colabora muito com isso.</p>
<h2>2- Sistema Operacional</h2>
<p>Na empresa é Windows e pronto. Não tem como usar outro. Não tenho nada contra o Windows e inclusive acho que a Microsoft até que surpreendeu com o Windows Vista/7. Mas se posso optar quero o melhor e esse é o MacOS.</p>
<p>O MacOS está a anos luz a frente de qualquer outro SO em termos de produtividade, facilidade de uso e estabilidade. Os aplicativos para o MacOS conseguem ser tão bons quanto o sistema, são bem acabados e objetivos. Não sou fanboy da Apple, mas tenho que admitir que o MacOS sempre reinou neste aspecto. Pra mim o tempo é um artigo precioso e com o MacOS eu economizo muito tempo, simplesmente porque as coisas aqui simplesmente funcionam e tudo é fácil e rápido.</p>
<p>Já usei Linux no Desktop (Debian) por muito tempo e até gosto do Ubuntu, mas acho que o Linux só brilha mesmo quando está num servidor. Meu foco é desenvolver software e não quero mais ter que esquentar a cabeça com drivers, configs obscuras, incompatibilidades, etc.</p>
<p>Além do Mac tenho um PC com dual boot Windows/Ubuntu que utilizo para testes. Não utilizo maquinas virtuais.</p>
<h2>3- Editor de texto e IDE</h2>
<p>Na empresa a regra é: &#8220;time que está ganhando não se mexe&#8221;. Absurdamente ainda utilizamos o Delphi 6 e nosso software é completamente acoplado a esta plataforma, a ponto de ser complicado até mesmo mudar para uma versão mais nova. No Windows costumo fazer tudo no Notepad++, que é um excelente editor de textos.</p>
<p>Quando estou num terminal *nix meu editor é o Vim, já tentei o Emacs e fiquei meio perdido. Me limito a usar o Vim basicamente enquanto estou usando o terminal, manipular arquivos de configuração e dar manutenção em scripts.</p>
<p>HTML, JavaScript, PHP, postar no blog e tudo mais eu uso uso o TextMate.</p>
<p>Quando estou programando em Java e Groovy/Grails uso o Intellij Idea. Usava o Eclipse, mas comecei a achar que ele estava me atrapalhando mais do que ajudando e então decidi experimentar o Idea 9.</p>
<p>O Intellij Idea é uma IDE leve e completa que me facilita muito o processo de visualização, organição e refatoração de projetos maiores. Na versão community consigo fazer absolutamente tudo, mesmo as coisas que teoricamente esta versão não da suporte, como programar em Groovy/Grails.</p>
<h2>4- Controle de versão</h2>
<p>Na empresa nosso sistema de bugtracking foi desenvolvido internamente e é muito bom (meus 2 cents!) por ser perfeitamente adaptado aos nossos processos. Não podemos manipular diretamente o repositório, quem faz isso é o sistema de bugtracking e por traz dos panos ele usa o velho CVS.</p>
<p>Nos meu próprios projetos usava o Subversion, mas hoje em dia nada se compara ao Git/GitHub. Só uso ele e não vejo motivos para se escolher outro.</p>
<h2>5- Browsers</h2>
<p>Eu sou um usuário promíscuo quando se fala de browsers. Já usei todos e estou sempre trocando. Considero o Firefox uma extensão da IDE (Selenium, Firebug, etc) e não uso ele para navegar. Já usei o Opera por muito tempo, principalmente quando ainda usava Linux, mas hoje minha preferência é o Safari. Ainda não consegui gostar do Chrome.</p>
<h2>6- Adobe Dreamweaver e Fireworks</h2>
<p>Uso muito o Fireworks e o Dreamweaver para prototipar páginas. São ferramentas fantásticas para webdesigners, mas eu as uso basicamente porque acho entediante e anti-produtivo escrever HTML. Com estas ferramentas consigo feedback visual instantâneo do que estou fazendo.</p>
<h2>7- Produtividade</h2>
<p>Não vivo sem o Google Apps. GMail, Google Agenda e Google Reader são basicamente o que uso na Internet. Tirando alguns sites como o Facebook, YouTube e os fóruns que frequento, leio tudo dentro do Google Reader.</p>
<p>No desktop não vivo sem o iWork, iCal, DropBox e Echofon. Conheci esses dias o Things e comecei a gostar. Comunicação instantânea é Skype e não tem outro. Só mantenho o MSN instalado porque todo mundo que conheço só usa ele.</p>
<p>Mantenho na minha pasta Sites a documentação de todos os frameworks e linguagens que trabalho. É mais rápido e prático assim. Mantenho muitos livros técnicos na minha estante (virtual ou física) que precisam estar sempre a mão para quando eu não lembro de algo porque não gosto de pertubar meus colegas com perguntas enquanto estão trabalhando.</p>
<h2>Dando continuidade à brincadeira</h2>
<p>Agora convido meus amigos <a href="http://twitter.com/vitorhug" target="_blank" rel="nofollow">@vitorhug</a> e <a href="http://twitter.com/eveblood" target="_blank" rel="nofollow">@eveblood</a> a dar continuidade a brincadeira.</p>
]]></content>
		<link rel="replies" type="text/html" href="http://blog.sobreira.eti.br/archives/meu-ambiente-de-trabalho-em-7-itens?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=meu-ambiente-de-trabalho-em-7-itens#comments" thr:count="2"/>
		<link rel="replies" type="application/atom+xml" href="http://blog.sobreira.eti.br/archives/meu-ambiente-de-trabalho-em-7-itens/feed/atom" thr:count="2"/>
		<thr:total>2</thr:total>
	</entry>
		<entry>
		<author>
			<name>Fabiano Sobreira</name>
						<uri>http://blog.sobreira.eti.br</uri>
					</author>
		<title type="html"><![CDATA[Utilizando Codecs em Testes Unitários no Grails]]></title>
		<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br/archives/dica-utilizando-codecs-em-testes-unitarios-do-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dica-utilizando-codecs-em-testes-unitarios-do-grails" />
		<id>http://blog.sobreira.eti.br/?p=667</id>
		<updated>2011-01-23T13:43:52Z</updated>
		<published>2011-01-12T00:36:44Z</published>
		<category scheme="http://blog.sobreira.eti.br" term="Grails" /><category scheme="http://blog.sobreira.eti.br" term="dicas" /><category scheme="http://blog.sobreira.eti.br" term="grails" /><category scheme="http://blog.sobreira.eti.br" term="testes" />		<summary type="html"><![CDATA[Com a função loadCodec da classe GrailsUnitTestCase você pode utilizar facilmente seus codecs dentro de um teste unitário, disponibilizando assim os métodos encodeAs e decode em todos os objetos durante sua execução. Lembrando que os codecs padrões da plataforma ficam no pacote org.codehaus.groovy.grails.plugins.codecs. Veja no exemplo: import grails.test.* import org.codehaus.groovy.grails.plugins.codecs.HTMLCodec &#160; class SomeTests extends GrailsUnitTestCase <a href="http://blog.sobreira.eti.br/archives/dica-utilizando-codecs-em-testes-unitarios-do-grails"> read more <span class="meta-nav">&#187;</span></a>]]></summary>
		<content type="html" xml:base="http://blog.sobreira.eti.br/archives/dica-utilizando-codecs-em-testes-unitarios-do-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dica-utilizando-codecs-em-testes-unitarios-do-grails"><![CDATA[<p>Com a função loadCodec da classe GrailsUnitTestCase você pode utilizar facilmente seus codecs dentro de um teste unitário, disponibilizando assim os métodos encodeAs e decode em todos os objetos durante sua execução. Lembrando que os codecs padrões da plataforma ficam no pacote org.codehaus.groovy.grails.plugins.codecs. Veja no exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">grails.test.*</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.codehaus.groovy.grails.plugins.codecs.HTMLCodec</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> SomeTests <span style="color: #000000; font-weight: bold;">extends</span> GrailsUnitTestCase <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> setUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">setUp</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
        loadCodec<span style="color: #009900;">&#40;</span>HTMLCodec<span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000066; font-weight: bold;">void</span> tearDown<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">super</span>.<span style="color: #006633;">tearDown</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #000066; font-weight: bold;">void</span> testSomething<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        assertEquals <span style="color: #0000ff;">&quot;&amp;lt;p&amp;gt;Hello World&amp;lt;/p&amp;gt;&quot;</span>, <span style="color: #0000ff;">&quot;&lt;p&gt;Hello World&lt;/p&gt;&quot;</span>.<span style="color: #006633;">encodeAsHTML</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content>
		<link rel="replies" type="text/html" href="http://blog.sobreira.eti.br/archives/dica-utilizando-codecs-em-testes-unitarios-do-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dica-utilizando-codecs-em-testes-unitarios-do-grails#comments" thr:count="0"/>
		<link rel="replies" type="application/atom+xml" href="http://blog.sobreira.eti.br/archives/dica-utilizando-codecs-em-testes-unitarios-do-grails/feed/atom" thr:count="0"/>
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Fabiano Sobreira</name>
						<uri>http://blog.sobreira.eti.br</uri>
					</author>
		<title type="html"><![CDATA[Groovy e Performance: Os Tipos Numéricos]]></title>
		<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br/archives/o-groovy-e-sua-baixa-performance-com-calculos?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=o-groovy-e-sua-baixa-performance-com-calculos" />
		<id>http://blog.sobreira.eti.br/?p=579</id>
		<updated>2011-01-23T13:35:22Z</updated>
		<published>2010-12-11T02:28:56Z</published>
		<category scheme="http://blog.sobreira.eti.br" term="Groovy" />		<summary type="html"><![CDATA[Uma das maiores críticas sobre o Groovy tem sido a sua &#8220;baixa performance&#8221;, principalmente ao se executar operações numéricas. O objetivo da linguagem se cumpre pela simpicidade e ganho de produtividade, não pelo desempenho, mas nem por isso podemos virar as costas para a otimização do código ou virar as costas para o Java. O <a href="http://blog.sobreira.eti.br/archives/o-groovy-e-sua-baixa-performance-com-calculos"> read more <span class="meta-nav">&#187;</span></a>]]></summary>
		<content type="html" xml:base="http://blog.sobreira.eti.br/archives/o-groovy-e-sua-baixa-performance-com-calculos?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=o-groovy-e-sua-baixa-performance-com-calculos"><![CDATA[<p>Uma das maiores críticas sobre o Groovy tem sido a sua &#8220;baixa performance&#8221;, principalmente ao se executar operações numéricas. O objetivo da linguagem se cumpre pela simpicidade e ganho de produtividade, não pelo desempenho, mas nem por isso podemos virar as costas para a otimização do código ou virar as costas para o Java.</p>
<p>O que precisa ser observado é que a linguagem possui algumas particularidades que precisam ser conhecidas e algumas fraquezas quanto a invocação e tipagem dinâmicas.</p>
<p>Um coisa básica, que muitos programadores que iniciam na linguagem desconhecem Groovy não possui os tipos primitivos do Java:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span>
<span style="color: #000000; font-weight: bold;">assert</span> i <span style="color: #000000; font-weight: bold;">instanceof</span> java.<span style="color: #006633;">lang</span>.<span style="color: #003399;">Integer</span></pre></div></div>

<p>Apesar de a variável ter sido declarada como int o que obtemos na verdade é um java.lang.Integer. A palavra reservada para o tipo primitivo em java funciona como um atalho para a classe wrapper deste e isto é válido para todos os tipos primitivos do Java (byte, short, int, long, float, double, char e boolean).</p>
<p>Outro detalhe muito importante é que ao se trabalhar com números no Groovy, este utiliza sempre BigDecimal quando não se especifíca estaticamente o tipo da variável, ou não é explicitado o tipo do valor sendo atribuido a variável, quando este é um decimal.

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">def a <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1.1</span>
def b <span style="color: #339933;">=</span> 1.1d
<span style="color: #000066; font-weight: bold;">double</span> c <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1.1</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">assert</span> a <span style="color: #000000; font-weight: bold;">instanceof</span> java.<span style="color: #006633;">math</span>.<span style="color: #003399;">BigDecimal</span>
<span style="color: #000000; font-weight: bold;">assert</span> b <span style="color: #000000; font-weight: bold;">instanceof</span> java.<span style="color: #006633;">lang</span>.<span style="color: #003399;">Double</span>
<span style="color: #000000; font-weight: bold;">assert</span> c <span style="color: #000000; font-weight: bold;">instanceof</span> java.<span style="color: #006633;">lang</span>.<span style="color: #003399;">Double</span></pre></div></div>

<p>Não é necessário dizer como BigDecimal é lento para cálculos, mesmo no Java um código que efetue muitas operações seguidas com BigDecimal poderá resultar numa baixa performance dependendo da situação.</p>
<p>Por outro lado isto é um facilitador quando se trabalha com números decimais, como por exemplo valores monetários</p>
<p>Fique sempre atento a estes detalhes quando estiver programando em Groovy, principalmente porque exeções do seguinte tipo poderão ocorrer ao misturar código Groovy com Java:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">groovy.lang.MissingMethodException: No signature of method: [I.getAt() is applicable for argument types: (java.math.BigDecimal) values: [499999.5]</pre></div></div>

]]></content>
		<link rel="replies" type="text/html" href="http://blog.sobreira.eti.br/archives/o-groovy-e-sua-baixa-performance-com-calculos?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=o-groovy-e-sua-baixa-performance-com-calculos#comments" thr:count="0"/>
		<link rel="replies" type="application/atom+xml" href="http://blog.sobreira.eti.br/archives/o-groovy-e-sua-baixa-performance-com-calculos/feed/atom" thr:count="0"/>
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Fabiano Sobreira</name>
						<uri>http://blog.sobreira.eti.br</uri>
					</author>
		<title type="html"><![CDATA[Entrevista com Graeme Rocher e Guillaume Laforge Sobre o Futuro do Groovy e do Grails]]></title>
		<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br/archives/entrevista-com-graeme-rocher-e-guillaume-laforge-sobre-o-futuro-do-groovy-e-do-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=entrevista-com-graeme-rocher-e-guillaume-laforge-sobre-o-futuro-do-groovy-e-do-grails" />
		<id>http://blog.sobreira.eti.br/?p=548</id>
		<updated>2011-01-12T00:18:15Z</updated>
		<published>2010-12-09T14:24:59Z</published>
		<category scheme="http://blog.sobreira.eti.br" term="Sem categoria" /><category scheme="http://blog.sobreira.eti.br" term="groovy" /><category scheme="http://blog.sobreira.eti.br" term="performance" />		<summary type="html"><![CDATA[Saiu hoje no InfoQ uma entrevista com o Graeme Rocher e o Guillaume Laforge sobre o futuro da linguagem do Groovy e do Grails. Para quem não sabe, Graeme Rocher é líder e co-fundador do Grails e Guillaume Laforge é quem está a frente do Groovy na SpringSource. Laforge também é líder da JSR-241, que <a href="http://blog.sobreira.eti.br/archives/entrevista-com-graeme-rocher-e-guillaume-laforge-sobre-o-futuro-do-groovy-e-do-grails"> read more <span class="meta-nav">&#187;</span></a>]]></summary>
		<content type="html" xml:base="http://blog.sobreira.eti.br/archives/entrevista-com-graeme-rocher-e-guillaume-laforge-sobre-o-futuro-do-groovy-e-do-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=entrevista-com-graeme-rocher-e-guillaume-laforge-sobre-o-futuro-do-groovy-e-do-grails"><![CDATA[<p>Saiu hoje no InfoQ uma <a href="http://www.infoq.com/interviews/rocher-laforge-groovy-grails">entrevista</a> com o <a href="http://graemerocher.blogspot.com/">Graeme Rocher</a> e o <a href="http://glaforge.free.fr/weblog">Guillaume Laforge</a> sobre o futuro da linguagem do Groovy e do Grails.</p>
<p>Para quem não sabe, Graeme Rocher é líder e co-fundador do Grails  e Guillaume Laforge é quem está a frente do Groovy na SpringSource. Laforge também é líder da <a href="http://www.jcp.org/en/jsr/summary?id=241">JSR-241</a>, que tem como objetivo padronizar a linguagem Groovy na plataforma Java.</p>
<p><a href="http://www.infoq.com/interviews/rocher-laforge-groovy-grails">link</a></p>
]]></content>
		<link rel="replies" type="text/html" href="http://blog.sobreira.eti.br/archives/entrevista-com-graeme-rocher-e-guillaume-laforge-sobre-o-futuro-do-groovy-e-do-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=entrevista-com-graeme-rocher-e-guillaume-laforge-sobre-o-futuro-do-groovy-e-do-grails#comments" thr:count="0"/>
		<link rel="replies" type="application/atom+xml" href="http://blog.sobreira.eti.br/archives/entrevista-com-graeme-rocher-e-guillaume-laforge-sobre-o-futuro-do-groovy-e-do-grails/feed/atom" thr:count="0"/>
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Fabiano Sobreira</name>
						<uri>http://blog.sobreira.eti.br</uri>
					</author>
		<title type="html"><![CDATA[Utilizando classes de domínio JPA no Grails]]></title>
		<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br/archives/utilizando-classes-de-dominio-jpa-no-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=utilizando-classes-de-dominio-jpa-no-grails" />
		<id>http://blog.sobreira.eti.br/?p=430</id>
		<updated>2011-01-24T23:06:47Z</updated>
		<published>2010-12-07T01:34:08Z</published>
		<category scheme="http://blog.sobreira.eti.br" term="Grails" /><category scheme="http://blog.sobreira.eti.br" term="constraints" /><category scheme="http://blog.sobreira.eti.br" term="ejb" /><category scheme="http://blog.sobreira.eti.br" term="grails" /><category scheme="http://blog.sobreira.eti.br" term="hibernate" />		<summary type="html"><![CDATA[Utilizando o Metaobject Protocol (MOP) fornecido pelo Groovy e as convenções do GORM, é possível utilizar classes anotadas com JPA do modelo EJB3 como classes de domínio dinâmicas do framework. Além disso o Grails é capaz de injetar finders dinâmicos, constraints e fornecer as funcionalidades que estamos acostumados num classe de domínio padrão do Grails. <a href="http://blog.sobreira.eti.br/archives/utilizando-classes-de-dominio-jpa-no-grails"> read more <span class="meta-nav">&#187;</span></a>]]></summary>
		<content type="html" xml:base="http://blog.sobreira.eti.br/archives/utilizando-classes-de-dominio-jpa-no-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=utilizando-classes-de-dominio-jpa-no-grails"><![CDATA[<p>Utilizando o Metaobject Protocol (MOP) fornecido pelo Groovy e as convenções do GORM, é possível utilizar classes anotadas com JPA do modelo EJB3 como classes de domínio dinâmicas do framework. Além disso o Grails é capaz de injetar finders dinâmicos, constraints e fornecer as funcionalidades que estamos acostumados num classe de domínio padrão do Grails.</p>
<p>O mais interessante nisto tudo é que estas classes tornam-se objetos totalmente dinâmicos, sem qualquer necessidade de acessarmos seu código fonte, bastando apenas seu bytecode. Isto é feito de maneira bem simples e transparente seguindo a filosofia &#8220;Convention Over Configuration&#8221; do framework, como veremos a seguir.</p>
<h3>Preparando um Projeto de Exemplo</h3>
<p>Para iniciar crie uma aplicação de exemplo com o nome bookstore:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails create-app bookstore
$ <span style="color: #7a0874; font-weight: bold;">cd</span> bookstore</pre></div></div>

<p>Faça o download do arquivo <strong>bookstore.jar</strong> <a href="http://blog.sobreira.eti.br/wp-content/uploads/2010/12/bookstore.jar">neste link</a> e coloque-o na pasta lib da aplicação recém criada.</p>
<p>Neste arquivo, no pacote ex.library.entity, estão contidas duas classes anotadas: <a href="http://blog.sobreira.eti.br/wp-content/uploads/2010/12/Author.txt">Author</a> e <a href="http://blog.sobreira.eti.br/wp-content/uploads/2010/12/Book.txt">Book</a>.</p>
<p> Estas classes possuem um relacionamento do tipo many-to-many que demonstra que um autor pode possuir muitos livros, bem como um livro pode ser de autoria de vários autores. Ambas são exemplos muito simples com finalidade meramente didática.</p>
<h3>O hibernate.cfg.xml</h3>
<p>Além do script DataSource.groovy, o Grails nos possibilita utilizar a forma tradicional de mapeamento de classes do Hibernate para definição do domínio da aplicação. Com isso você pode trabalhar exclusivamente com classes que seguem o padrão EJB3 ou mesmo misturando as coisas. Para que funcione o arquivo hibernate.cfg.xml deve obrigatoriamente ser salvo na pasta /grails-app/conf/hibernate.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;?xml</span> <span style="color: #000066;">version</span>=<span style="color: #ff0000;">&quot;1.0&quot;</span> <span style="color: #000066;">encoding</span>=<span style="color: #ff0000;">&quot;UTF-8&quot;</span><span style="color: #000000; font-weight: bold;">?&gt;</span></span>
<span style="color: #00bbdd;">&lt;!DOCTYPE hibernate-configuration PUBLIC</span>
<span style="color: #00bbdd;">		&quot;-//Hibernate/Hibernate Configuration DTD 3.0//EN&quot;</span>
<span style="color: #00bbdd;">		&quot;http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd&quot;&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;hibernate-configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;session-factory<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mapping</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;ex.library.entity.Author&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;mapping</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;ex.library.entity.Book&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/session-factory<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/hibernate-configuration<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>Para quem não conhece o Hibernate, este arquivo diz ao framework basicamente quais classes serão mapeadas para o banco de dados. Numa configuração normal do Hibernate teriamos mais informações neste arquivo, como o driver, dialeto do banco de dados, usuário, senha, etc. Entretanto todas estas informações são supridas pelo arquivo /grails-app/conf/DataSource.groovy não se fazendo necessário estas configurações aqui.</p>
<p>Com esta configuração as classes <strong>Author</strong> e <strong>Book</strong> passam a ser reconhecidas pelo framework como classes de domínio. Note que nem mesmo temos acesso ao código fonte destas, que estão empacotadas no arquivo <strong>bookstore.jar</strong> que depositamos na pasta lib da aplicação.</p>
<p>O uso do script DataSource.groovy em detrimento ao hibernate.cfg.xml para configuração da camada de persistência é preferível, já que a configuração pelo script nos possibilita trabalhar com separação de configuração por ambientes além de não se tratar de um arquivo estático, o que nos dá muita flexibilidade na hora da configuração.</p>
<h3>Scaffolding</h3>
<p>Se com esta configuração o Grails considera as classes mapeadas como classes de domínio, então não há segredo algum para iniciarmos o scaffolding da aplicação.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails generate-all ex.library.entity.Author
$ grails generate-all ex.library.entity.Book</pre></div></div>

<p>Note a seguinte mensagem durante a saída do comando:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">Domain class not found in Grails-app/domain, trying hibernate mapped classes...</pre></div></div>

<p>Quando o Grails não consegue encontrar a classe referida no comando dentro da pasta /Grails-app/domain ele tenta encontrá-la no arquivo hibernate.cfg.xml. Note que isto vale também para os comando create-controller, create-view ou qualquer outro comando em que o argumento seja uma classe de domínio.</p>
<p>Com o scaffolding criado, é hora de verificar se tudo correu bem:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ grails run-app</pre></div></div>

<p><a href="http://blog.sobreira.eti.br/wp-content/uploads/2010/12/ss-grails-jpa-1.png"><img src="/wp-content/uploads/2010/12/ss-grails-jpa-1-300x187.png" width="300" height="187" class="aligncenter"/></a></p>
<h3>Constraints</h3>
<p>Além do mapeamento, é possível adicionar constraints para estas classes de domínio, seguindo o padrão estabelecido pelo GORM. Para isto basta seguir a seguinte convenção:</p>
<ul>
<li>As constraints deverão estar contidas num script Groovy que contenha uma closure constraints;</li>
<li>Este script deve estar localizado na pasta /src/java do projeto, no mesmo pacote que a classe mapeada alvo da constraint;</li>
<li>O script deve ser salvo com o mesmo nome da classe mapeada, acrescentando o sufixo <strong>Constraints</strong> a este nome.</li>
</ul>
<p>Seguindo esta convenção, vamos acrescentar dois scripts Grails na pasta /src/java da aplicação criada, certificando-se de que estejam no mesmo pacote das classes anotadas.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/*
 * Constraints for ex.library.Author
 * File: src/java/ex/library/entity/AuthorConstraints.groovy
 */</span>
<span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">ex.library.entity</span>
&nbsp;
constraints <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    name blank<span style="color: #339933;">:</span><span style="color: #000066; font-weight: bold;">false</span>  
    birthPlace blank<span style="color: #339933;">:</span><span style="color: #000066; font-weight: bold;">false</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Neste script definimos duas constraints incrivelmente simples. As propriedades name e birthPlace de Author não podem estar em branco.</p>
<p><a href="http://blog.sobreira.eti.br/wp-content/uploads/2010/12/ss-grails-jpa-2.png"><img src="/wp-content/uploads/2010/12/ss-grails-jpa-2-300x187.png" width="300" height="187" class="aligncenter"/></a></p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">/*
 * Constraints for ex.library.Book
 * File: src/java/ex/library/entity/BookConstraints.groovy
 */</span>
<span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">ex.library.entity</span>
&nbsp;
constraints <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    title blank<span style="color: #339933;">:</span><span style="color: #000066; font-weight: bold;">false</span>
    publishedYear min<span style="color: #339933;">:</span><span style="color: #cc66cc;">0</span>, max<span style="color: #339933;">:</span><span style="color: #003399;">Calendar</span>.<span style="color: #006633;">instance</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">Calendar</span>.<span style="color: #006633;">YEAR</span><span style="color: #009900;">&#41;</span>
    isbn blank<span style="color: #339933;">:</span><span style="color: #000066; font-weight: bold;">false</span>, matches<span style="color: #339933;">:</span><span style="color: #0000ff;">&quot;[0-9]{3}-[0-9]-[0-9]{5}-[0-9]{3}-[0-9]&quot;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Neste segundo script definimos que um livro não pode ter um título em branco, que o ano de publicação deve ser no mínimo zero e no máximo o ano corrente. Além disso é forçada uma formatação para o campo ISBN por uma expressão regular.</p>
<p><a href="http://blog.sobreira.eti.br/wp-content/uploads/2010/12/ss-grails-jpa-3.png"><img src="/wp-content/uploads/2010/12/ss-grails-jpa-3-300x187.png" width="300" height="187" class="aligncenter" /></a></p>
<p>Você pode verificar as constraints em funcionamento executando a aplicação e tentando inserir valores inválidos.</p>
<p>Neste exemplo demonstrei como Grails é capaz de mapear e injetar comportamento de maneira bem simples em classes de domínio externas. Com isso há um benefício claro de desacoplamento do domínio com o resto do framework e ainda assim podendo-se tirar proveito da camada de infra-estrutura oferecida pelo framework. Um grande benefício para quem emprega Domain Driven Design no projeto da aplicação e precisa de agilidade na hora de lidar com a camada de infra-estrutura</p>
]]></content>
		<link rel="replies" type="text/html" href="http://blog.sobreira.eti.br/archives/utilizando-classes-de-dominio-jpa-no-grails?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=utilizando-classes-de-dominio-jpa-no-grails#comments" thr:count="3"/>
		<link rel="replies" type="application/atom+xml" href="http://blog.sobreira.eti.br/archives/utilizando-classes-de-dominio-jpa-no-grails/feed/atom" thr:count="3"/>
		<thr:total>3</thr:total>
	</entry>
		<entry>
		<author>
			<name>Fabiano Sobreira</name>
						<uri>http://blog.sobreira.eti.br</uri>
					</author>
		<title type="html"><![CDATA[Groovy: Os métodos equals() e is()]]></title>
		<link rel="alternate" type="text/html" href="http://blog.sobreira.eti.br/archives/groovy-equals-e-o-metodo-is?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-equals-e-o-metodo-is" />
		<id>http://sobreira.eti.br/blog/?p=475</id>
		<updated>2010-12-10T01:12:06Z</updated>
		<published>2010-12-06T15:12:07Z</published>
		<category scheme="http://blog.sobreira.eti.br" term="Groovy" /><category scheme="http://blog.sobreira.eti.br" term="equals" /><category scheme="http://blog.sobreira.eti.br" term="groovy" /><category scheme="http://blog.sobreira.eti.br" term="operadores" />		<summary type="html"><![CDATA[A linguagem Groovy introduz uma série de novos métodos e modifica de maneira sutíl o comportamento de alguns operadores da linguagem Java. Dentre eles, um que causa certa confusão a princípio é o operador == que passa a operar sobre o método equals() de uma classe. Na linguagem Java este operador apenas compara se duas <a href="http://blog.sobreira.eti.br/archives/groovy-equals-e-o-metodo-is"> read more <span class="meta-nav">&#187;</span></a>]]></summary>
		<content type="html" xml:base="http://blog.sobreira.eti.br/archives/groovy-equals-e-o-metodo-is?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-equals-e-o-metodo-is"><![CDATA[<p>A linguagem Groovy introduz uma série de novos métodos e modifica de maneira sutíl o comportamento de alguns operadores da linguagem Java.</p>
<p>Dentre eles, um que causa certa confusão a princípio é o operador == que passa a operar sobre o método equals() de uma classe. Na linguagem Java este operador apenas compara se duas variáveis distintas referem-se a mesma instância do objeto e não tem nenhuma relação direta com a implementação do método equals().</p>
<p>A comparação de instâncias no Groovy deve ser feita usando-se o método is() que se comporta exatamente como o operador == da linguagem Java. Por exemplo:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Person <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
    Person<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span> <span style="color: #339933;">=</span> name
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">boolean</span> equals<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> other<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>other <span style="color: #000000; font-weight: bold;">instanceof</span> Person<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            Person otherPerson <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Person<span style="color: #009900;">&#41;</span> other
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span> <span style="color: #339933;">==</span> otherPerson.<span style="color: #006633;">name</span>
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span>
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
def a <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Jim&quot;</span><span style="color: #009900;">&#41;</span>
def b <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Person<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Jim&quot;</span><span style="color: #009900;">&#41;</span>
<span style="color: #000000; font-weight: bold;">assert</span> a <span style="color: #339933;">==</span> b <span style="color: #666666; font-style: italic;">//== chama o método equals</span>
<span style="color: #000000; font-weight: bold;">assert</span> <span style="color: #339933;">!</span>a.<span style="color: #006633;">is</span><span style="color: #009900;">&#40;</span>b<span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">//são instâncias diferentes</span></pre></div></div>

<p>Note que propositalmente não fiz a verificação inicial no método equals() se o parâmetro other se refere a mesma instância do objeto em que o método está sendo chamado.</p>
<p>Se for introduzido no método equals() algo como:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">boolean</span> equals<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> other<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span> <span style="color: #339933;">==</span> other<span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">//comapara as duas instâncias</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span>
    <span style="color: #666666; font-style: italic;">//...</span></pre></div></div>

<p>A chamada a:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">assert</span> a <span style="color: #339933;">==</span> b</pre></div></div>

<p>Lançará uma java.lang.StackOverflowError, porque o método equals() da classe Person entra em recursividade infinita com esta implementação. Um erro muito comum de quem está começando com Groovy</p>
<p>Isto ocorre porque para o Groovy utilizar o operador == ou chamar o método equals() significa a mesma coisa. A implementação correta de equals() para a classe Person neste caso é:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Person <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">String</span> name<span style="color: #339933;">;</span>
    Person<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span> <span style="color: #339933;">=</span> name
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000066; font-weight: bold;">boolean</span> equals<span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> other<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">is</span><span style="color: #009900;">&#40;</span>other<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #666666; font-style: italic;">//comapara as duas instâncias</span>
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span>
        <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>other <span style="color: #000000; font-weight: bold;">instanceof</span> Person<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            Person otherPerson <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>Person<span style="color: #009900;">&#41;</span> other
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">name</span> <span style="color: #339933;">==</span> otherPerson.<span style="color: #006633;">name</span> 
        <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span>
            <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">false</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content>
		<link rel="replies" type="text/html" href="http://blog.sobreira.eti.br/archives/groovy-equals-e-o-metodo-is?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=groovy-equals-e-o-metodo-is#comments" thr:count="0"/>
		<link rel="replies" type="application/atom+xml" href="http://blog.sobreira.eti.br/archives/groovy-equals-e-o-metodo-is/feed/atom" thr:count="0"/>
		<thr:total>0</thr:total>
	</entry>
	</feed>

<!-- Dynamic page generated in 3.652 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-05-14 17:50:29 -->
