<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Codemountain, Paulo Suzart&#039;s Blog</title>
	<atom:link href="http://codemountain.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://codemountain.wordpress.com</link>
	<description></description>
	<lastBuildDate>Thu, 17 Dec 2009 15:20:01 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>pt-br</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='codemountain.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/e6cb19913843ce26ea4b843e55b25f1e?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Codemountain, Paulo Suzart&#039;s Blog</title>
		<link>http://codemountain.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://codemountain.wordpress.com/osd.xml" title="Codemountain, Paulo Suzart&#039;s Blog" />
		<item>
		<title>Oracle Coherence: Além do Put e do Get</title>
		<link>http://codemountain.wordpress.com/2009/11/03/oracle-coherenc-alem-put-get/</link>
		<comments>http://codemountain.wordpress.com/2009/11/03/oracle-coherenc-alem-put-get/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 00:59:21 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[coherence]]></category>
		<category><![CDATA[escalabilidade]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[cache]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=519</guid>
		<description><![CDATA[Segundo a querida Wikipedia, &#8220;Cache é uma coleção de dados duplicando valores existentes em algum lugar ou previamente calculados, &#8230;&#8221; [Tradução minha]. Aplicações frequentemente utilizam cache para poupar recursos com custo alto de acesso tais como Bases de Dados Relacionais, arquivos, comunicações remotas. A intenção é manter o mais próximo da aplicação, de maneira rápida e [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=519&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Segundo a querida <a href="http://en.wikipedia.org/wiki/Data_grid" target="_blank">Wikipedia</a>, &#8220;<em>Cache é uma coleção de dados duplicando valores existentes em algum lugar ou previamente calculados, &#8230;</em>&#8221; [Tradução minha]. Aplicações frequentemente utilizam cache para poupar recursos com custo alto de acesso tais como Bases de Dados Relacionais, arquivos, comunicações remotas. A intenção é manter o mais próximo da aplicação, de maneira rápida e barata o acesso a dados necessários para alguma computação, ou seja: Caches são em sua maioria um conjunto de dados em memória.</p>
<p>Alguma vez na vida já utilizamos Cache no desenvolvimento de uma aplicação. E muito frequentemente este Cache está fortemente integrado a um framework <a href="http://en.wikipedia.org/wiki/Object-relational_mapping" target="_blank">ORM</a> como <a href="http://docs.jboss.org/hibernate/stable/core/reference/en/html_single/#performance-cache" target="_blank">Hibernate</a> ou <a href="http://www.oracle.com/technology/products/ias/toplink/index.html" target="_self">TopLink</a>. O lado bom é que abstrai-se para o desenvolvedor os meios necessários para obtenção de dados a partir do cache, ou a partir da fonte de dados real (Banco de Dados nesse caso).  Mas essa é de longe a estratégia mais simples e, de fato, mais pobre quando se trata de tirar o máximo da sua ferramenta de Caching ou <a href="http://en.wikipedia.org/wiki/Data_grid" target="_blank">data grid</a>.</p>
<p>Outro uso comum de Cache são os Caches locais, os que residem na memória da aplicação. É aí que o uso dos cache.get(key) e cache.put(key, value) aparecem, mas o simples uso destes dois métodos traz uma série de questões:</p>
<ul>
<li>Toda vez que uma entrada no cache é atualizada, como e quando devo aplicar tais mudanças para a fonte de dados original (ex.:  Base de Dados)?</li>
<li>E se eu obtiver uma entrada no cache, iniciar um processamento e, antes de concluir este processamento a entrada for alterada?</li>
<li>Eu tenho servidores geograficamente distribuídos, como compartilhar um mesmo cache para um recurso extremamente custoso entre estes servidores?</li>
<li>Utilizo Cache para evitar acesso constante à Base Relacional, mas minha aplicação é &#8220;Clusterizada&#8221; e uma próxima requisição frequentemente é destinada a um servidor cuja entrada ainda não foi inserida no Cache. Como evitar acessos repetidos para os mesmos dados processados em servidores diferentes?</li>
<li>Acessar uma entrada pela chave não é suficiente, isso me força a criar chaves modificadas &#8211; como &#8220;SP-Republica&#8221;, uma junção entre dados de dois campos distintos de uma mesma entidade (supondo Endereco(UF, Bairro)) &#8211; ou mesmo ignorar o cache e efetuar consultas constantemente na Base de Dados.</li>
<li>Preciso realizar uma operação em milhares de entradas no cache, mas cada get() executado traz os dados para a memória local o que pode causar OutOfMemory, como contornar isso?</li>
</ul>
<p>Poderíamos ter um Post inteiro só com questionamentos do gênero. Pelo menos um destas dúvidas você já teve, certo? Resolvi apresentar o <a href="http://www.oracle.com/technology/products/coherence/index.html" target="_blank">Oracle Coherence</a> desta maneira, respondendo estas. O Coherence é uma suite poderosa para Data Grid e Cache provida pela Oracle e permite a replicação (particionada) de dados em cluster.</p>
<p>Não é minha intenção (nem seria possível) cobrir todos os aspectos da ferramenta, mas sim de oferecer um Overview, um ponto de vista e até mesmo dicas para o uso da ferramenta baseado na minha experiência.</p>
<p>Neste Post trago uma resposta ao menos à primeira pergunta:</p>
<p><strong>Toda vez que uma entrada no cache é atualizada, como e quando devo aplicar tais mudanças para a fonte de dados original (ex.:  Base de Dados)?</strong></p>
<p>A técnica comumente utilizada para escrita simultânea no cache e na fonte de dados é conhecida por Write-Through (veja artigo na Wikipedia). É possível utilizar um DAO conhecedor do Cache que faz um put e um insert em uma tabela, por exemplo. Dessa maneira o Write-Through é feito com o Cache-aside, ou seja o cache participa passivamente neste processo.</p>
<p>O Oracle Coherence utiliza o conceito de CacheStore e oferece a interface <strong>com.tangosol.net.cache.CacheStore </strong>para onde a operação de persistência é delegada:</p>
<pre class="brush: java;">

public class YourCacheStore implements com.tangosol.net.cache.CacheStore {
   ...
   @Override
   public void store(Object key, Object value) {
   ... // code to actually persist the value.
   }

   @Override
   public void storeAll(Map cached) {
      for (Object key : cached.keySet()) {
        ... //persist it!
      }
   }
}
</pre>
<p>O CacheStore é uma classe qualquer que conhece como obter e salvar definitivamente as informações para uma entrada no Cache. <strong>Logo</strong>, não é relevante para o Coherence como o dado é acessado, seja via JDBC, JPA, WebService, RMI, etc. O Coherece delagará a execução para a classe configurada em um cache do tipo <strong>read-write-backing-map-scheme</strong>:</p>
<pre class="brush: xml;">
	&lt;read-write-backing-map-scheme&gt;
		&lt;scheme-name&gt;DB&lt;/scheme-name&gt;
		&lt;internal-cache-scheme&gt;
			&lt;local-scheme/&gt;
		&lt;/internal-cache-scheme&gt;
		&lt;cachestore-scheme&gt;
			&lt;class-scheme&gt;
				&lt;class-name&gt;com.codemountain.grid.store.YourCacheStore&lt;/class-name&gt;
			&lt;/class-scheme&gt;
		&lt;/cachestore-scheme&gt;
		&lt;write-delay&gt;5s&lt;/write-delay&gt;
                &lt;write-batch-factor&gt;0.3&lt;/write-batch-factor&gt;
	&lt;/read-write-backing-map-scheme&gt;
</pre>
<p>Note o parâmetro <strong>write-delay:5s</strong>, isso significa que o Coherence vai iniciar a escrita após o tempo especificado de 5 segundos. Assim passamos a fazer o uso da técnica de Write-Behind, ou seja os dados se mantém consistentes e disponíveis para a aplicação, enquanto num momento futuro o Coherence iniciará uma escrita Assíncrona para o repositório de dados.</p>
<p>Até aqui temos um mecanismo integrado à ferramenta de Cache, garantindo consistência dos dados em cache e em Base de Dados. O Coherence executa o que ele chama de <em>coalescing</em> , ou seja, sucessivas escritas a uma mesma entrada não gerarão diversos updates/inserts para a entrada.</p>
<p>Write-Behind é uma técnica particularmente interessante e pode reduzir drasticamente o acesso a uma base de dados enviando em lote uma quantidade maior de registros alterados ou inseridos. É possível configurar um fator (<strong>write-bacth-factor:0.3</strong>), tal que, toda entrada cujo tempo de espera para persistência tenha atingido uma percentagem do  tempo total de delay, será enviada em lote para escrita. A formula para o wirte-batch-factor é : (1 &#8211; 0.3) * 5 = 3.5s.</p>
<p>Sem esta possibilidade de definir uma janela de tempo, as escritas só aconteceriam num momento diferente do insert da entrada no cache, mantendo a alta carga carga no banco de dados.  Um CacheStore implementado corretamente deve tirar proveito disso e utilizar apenas uma conexão/transação para a escrita do lote através do método <strong>storeAll()</strong>. Ah! Fique atento as necessidades de negócio e até mesmo acesso de outras aplicações a esta base dedados, estes são pontos determinantes para a adoção desta técnica.</p>
<p>Com o Write-Behind você pode cortar pela metade a quantidade de acesso à base de dados. Numa aplicação onde eu e minha equipe aplicamos o Oracle Coherence, eliminamos um INSERT + SELECT + UPDATE por apenas um INSERT. Ou seja, o dado era criado em memória no cluster, obtido em um momento posterior e então atualizado. Com o Coherence, e as operações ocorrendo em memória, todas as manipulações se traduzem para um único INSERT no final do procedimento. Multiplique 3 acesso à base de dados por 2 milhoes de transações e note que uma operação é muito menos custosa para todo o seu ambiente.</p>
<p>A geração de IDs para registros na base de dados pode ser feita em cluster de forma segura (leia-se consistente) evitando até mesmo um MY_SEQUENCE.nextval. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>É importante saber que há também <a href="http://glinden.blogspot.com/2008/04/replication-caching-and-partitioning.html" target="_blank">aqueles que não acreditam em Caches</a> como a melhor solução. Como disse <a href="http://glinden.blogspot.com/" target="_blank">Greg Linden</a>: &#8220;<em>Camadas de Cache adicionam complexidade ao design, latência para entradas não encontradas no cache, e uso infeficiente de recursos &#8216;clusterizados&#8217;</em>&#8221; (Tradução livre minha). Greg ainda advoga a favor da remoção das camadas de cache e transferência de tais máquinas para a camada de banco de dados, que por sua vez deve apostar alto no particionamento e em seus próprios mecanismos de cache.</p>
<p>Ao tomar decisões de design para aplicações que demandam alta disponibilidade, baixar latência e alta performance, esteja ciente das vantagens e desvantagens das diversas topologias e abordagens disponíveis, inclusive o caching.</p>
<h6><em>Todas as informações sobre o produto podem ser encontradas na documentação do próprio produto<strong> Oracle Coherence de propriedade da Oracle. Este blog não expressa direta ou indiretamente quaisquer opinião da Oracle.</strong></em><strong><br />
</strong></h6>
Posted in coherence, escalabilidade, Java, oracle  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/519/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=519&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/11/03/oracle-coherenc-alem-put-get/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>
	</item>
		<item>
		<title>Sem Elvis Operator? Crie um!</title>
		<link>http://codemountain.wordpress.com/2009/10/22/sem-elvis-operator-crie-um/</link>
		<comments>http://codemountain.wordpress.com/2009/10/22/sem-elvis-operator-crie-um/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 19:57:44 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=508</guid>
		<description><![CDATA[Meu querido amigo @lucastex Postou sobre Elvis operator em Groovy. Ele também me perguntou se Scala tinha este operador. E eu disse: Não, mas eu posso criar agora. E assim fiz:

implicit def toRockStar[B](v : B) = new { def ?: (opt: =&#62; B) : B =
          [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=508&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Meu querido amigo <a href="http://twitter.com/lucastex" target="_blank">@lucastex</a> <a href="http://lucastex.com.br/2009/10/22/maravilhas-do-groovy-elvis-operator/" target="_blank">Postou</a> sobre <a href="http://groovy.codehaus.org/Operators#Operators-ElvisOperator%28%3F%3A%29" target="_blank">Elvis operator</a> em Groovy. Ele também me perguntou se Scala tinha este operador. E eu disse: Não, mas eu posso criar agora. E assim fiz:</p>
<pre class="brush: scala;">
implicit def toRockStar[B](v : B) = new { def ?: (opt: =&gt; B) : B =
                                           if (opt == null) v else opt}
</pre>
<p>Se voce observar bem neste <a href="http://codemountain.wordpress.com/2009/08/01/scala-implicits-options-and-pattern-match-to-start-with-rabbitmq/" target="_blank">Post</a>, eu criei o operador % aplicável a Strings para facilitar a configuração de alguns parâmetros em uma conexão com o <a href="http://www.rabbitmq.com/" target="_blank">RabbitMQ</a>.</p>
<p>Então, para usarmos nosso Rock Start Elvis operator fazemos assim:</p>
<pre class="brush: scala;">
scala&gt; val name : String = null
name: String = null

scala&gt; val l = name ?: &quot;Lucas&quot;
l: java.lang.String = Lucas // resultado deve ser Lucas

scala&gt; val p = l ?: &quot;Paulo&quot; // Resultado Deve ser Lucas
p: java.lang.String = Lucas
</pre>
<p>A variável imutável <strong>p</strong> só deve receber o valor Paulo se a variável <strong>l</strong> não tiver sido atribuído a uma String. O Elvis aqui serve para qualquer tipo, pois foi construído de forma genérica com tipos parametrizados (ver o [B]).</p>
<p>Em Scala os operadors aritiméticos também são funções e não operadores da linguagem. <strong>Logo</strong>, existe a possibilidade de criação de qualquer operador com o nível de complexidade necessário para resolver o seu problema.</p>
<p>Foi um post curto, e um bate bola com o Lucas. Tento usar o público dele e de outras linguagens para atrair a atenção para Scala, uma linguagem sem dúvida promissora. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Com Scala é assim, não espere a linguagem criar um operador interessante como esse, simplesmente o faça.</p>
Posted in scala  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/508/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/508/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/508/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/508/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/508/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/508/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/508/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/508/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/508/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/508/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=508&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/10/22/sem-elvis-operator-crie-um/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>
	</item>
		<item>
		<title>Especificando validações com Scala, Specs e Lift – Parte II</title>
		<link>http://codemountain.wordpress.com/2009/10/20/especificando-validacoes-com-scala-specs-e-lift-parte-ii/</link>
		<comments>http://codemountain.wordpress.com/2009/10/20/especificando-validacoes-com-scala-specs-e-lift-parte-ii/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 10:55:10 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[bdd]]></category>
		<category><![CDATA[lift]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[specs]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=447</guid>
		<description><![CDATA[No último Post tivemos uma visão inicial do uso de Specs, BDD e um exemplo de utilização do framework. Mas como você deve ter percebido, as especificações eram blocos de códigos ainda soltos no Post. Specifications são objects ou classes Scala, vejamos como declarar a especificação do post anterior, configurar uma sessão Lift, criar um [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=447&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">No <a href="http://codemountain.wordpress.com/2009/10/14/especificando-validacoes-com-scala-specs-e-lift-i/" target="_blank">último Post</a> tivemos uma visão inicial do uso de Specs, BDD e um exemplo de utilização do framework. Mas como você deve ter percebido, as especificações eram blocos de códigos ainda soltos no Post. Specifications são objects ou classes Scala, vejamos como declarar a especificação do post anterior, configurar uma sessão Lift, criar um contexto de execução das especificações, e por fim estender o framework Specs com Matchers personalizados.</p>
<pre class="brush: scala;">
object TodoSpec extends Specification with Contexts {

    &quot;Create/Update a ToDo item&quot; should {
       //... spec from last post.
    }

   //Inicia um sessão Lift
    val session = new LiftSession(&quot;&quot;, StringHelpers.randomString(20),
                                                new MockHttpSession, null)
   //Executa a dentro da sessão Lift
   def inSession(a: =&gt; Any) = {
        S.initIfUninitted(session) { a }
    }

   //Novo usuário para execução da especificação
    def loginUser = inSession {
        val user = User.create
        user.email(&quot;tester@gmail.com&quot;).password(&quot;xxxxxx&quot;)
        user.save
        User.logUserIn(user)
    }

    //Contexto de execuão da Especificação
    new SpecContext {
        //Estabelece Conexão com o banco antes da execução.
        beforeSpec {
            if (!DB.jndiJdbcConnAvailable_?)
            DB.defineConnectionManager(DefaultConnectionIdentifier,
                                                     DBVendor)
            loginUser //Acontece o login do usuário
        }
        aroundExpectations(inSession(_))

        //Remove o usuário de teste
        afterSpec {
            val user = User.find(By(User.email, &quot;tester@gmail.com&quot;))
            User.delete_!(user.open_!)
        }
    }
}
class TodoSpecTest extends JUnit4(TodoSpec)
</pre>
<p style="text-align:justify;">Uma especificação é um objeto que extends a classe <strong>org.specs.Specification</strong>. Specification oferece um conjunto de <a href="http://codemountain.wordpress.com/2009/08/01/scala-implicits-options-and-pattern-match-to-start-with-rabbitmq/" target="_blank">conversores implícitos</a> para Strings, por isso os métodos <strong>should</strong>, <strong>in</strong> e <strong>&gt;&gt;</strong> aparentam serem invocados a partir das strings que descrevem a especificação.</p>
<p style="text-align:justify;">Como todo teste que deve acontecer dentro de um contexto (jndi, spring, hibernate, ejb3, etc), precisamos de um código extra para usarmos recursos do Lift e definir um contexto para a execução da especificação. Por isso, aqui usamos a <a href="http://code.google.com/p/specs/wiki/DeclareSpecifications#Specification_context_(_from_1.6.1_)" target="_blank">trait Contexts</a> e criamos uma nova instância de SpecContext com os métodos <em>beforeSpec</em> fazendo a conexão com a base de dados e <em>aroundExpectations</em> garantindo que a especificação ocorra dentro da sessão Lift criada.</p>
<p style="text-align:justify;">Com Specs, você pode visulizar o resultado das execuções na sua IDE como se fossem testes JUnit. Por isso a TodoSpec é um objecto e há uma classe TodoSpecTest que extends org.specs.runner.JUnit4. O objeto da especificação é passado como construtor do runner de JUnit4. Assim temos a execução da especificação integrada com a IDE. Veja outras formas executá-las <a href="http://code.google.com/p/specs/wiki/RunningSpecs" target="_blank">aqui</a>.</p>
<p style="text-align:justify;">Usamos o próprio Lift Test Kit  uma instância de HttpSession (<em>new MockHttpSession</em>), assim podemos instanciar corretamente uma sessão Lift.</p>
<p style="text-align:justify;">
<p style="text-align:justify;">Para a execução dos testes vamos precisar das dependências abaixo. Lembre-se de instalar no seu repositório local Maven a versão SNAPSHOT do Specs 1.6.1 encontrado <a href="http://code.google.com/p/specs/wiki/DeclareSpecifications#Specification_context_(_from_1.6.1_)" target="_blank">aqui</a>.</p>
<pre class="brush: xml;">
        &lt;dependency&gt;
            &lt;groupId&gt;org.scala-tools.testing&lt;/groupId&gt;
            &lt;artifactId&gt;specs&lt;/artifactId&gt;
            &lt;version&gt;1.6.1&lt;/version&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;net.liftweb&lt;/groupId&gt;
            &lt;artifactId&gt;lift-testkit&lt;/artifactId&gt;
            &lt;version&gt;1.0&lt;/version&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;
</pre>
<p style="text-align:justify;">Outro ponto importante do framework Specs, é a sua extensibilidade. Podemos criar Matchers tão poderosos quanto queiramos para oferecer um melhor suporte à linguagem única utilizada no negócio do sistema. Supondo que a especificação descreva que um usuário logado no sistema deve ser um usuário Gmail, podemos criar nosso próprio matcher para tornar nossa especificação mais natural. Vamos adicionar o seguinte sistema para especificar o comportamento do nosso matcher, facilitando o entendimento:</p>
<pre class="brush: scala;">
    &quot;A logged user&quot; should {
        &quot;be a Gmail user&quot; in {
            val user = User.currentUser.open_!
            user.email.asString must beAtGmail
        }
    }
</pre>
<p style="text-align:justify;">beAtGamil é um matcher definido em um object que pode conter diversos matchers customizados. Até aqui temos apenas um matcher:</p>
<pre class="brush: scala;">
object CustomMatcherSpec extends Specification {
    &quot;beAtGmail&quot; can {
        &quot;assert users at Gmail&quot; in {
            &quot;paulosuzart@gmail.com&quot; must beAtGmail
        }
    }
}

object CustomMatcher {
    import java.util.regex.Pattern
    val beAtGmail = new Matcher[String]{
        def apply(m : =&gt; String) = {
            val pattern = Pattern.compile(&quot;.+\\@gmail.com&quot;)
                                      (pattern.matcher(m).matches,
                        m + &quot; is at Gmail&quot;,  m + &quot; is not at Gmail&quot;)
        }
    }
}
class CustomSpecTest extends JUnit4(CustomMatcherSpec)
</pre>
<p>Não podemos esquecer de um executor JUnit4 para a integração com a IDE. Seguindo os passos do post passado, você pode ver o resultado das especificações do sistema ToDo e a especificação do Matcher customizado.</p>
<p>BDD é sem dúvida uma metodologia com grande potencial de expansão no mercado e torço pra que muito em breve apareçam oportunidades com tecnologias e metodologias como essas.</p>
<p>Ainda não sei dizer em qual a dimensão de projeto o BDD é mais apropriado, talvez as mesmas dimensões onde TDD e DDD são aplicáveis.</p>
<p>Detalhes como as classes DB, S e todos os fontes do Post, você vai encontrar na aplicação disponibilizada no meu repositório <a href="http://github.com/paulosuzart/todo/" target="_blank">github.</a> Reforço que o projeto froi criado seguindo o tutorial de <a href="http://www.liftweb.net/docs/getting_started.html" target="_blank">Getting Started do Lift</a> e modificado para a construção do Post. E não se esqueça de me seguir no <a href="twitter.com/paulosuzart" target="_blank">Twitter</a>.</p>
Posted in bdd, lift, scala  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/447/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/447/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/447/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/447/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/447/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/447/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/447/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/447/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/447/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/447/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=447&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/10/20/especificando-validacoes-com-scala-specs-e-lift-parte-ii/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>
	</item>
		<item>
		<title>Especificando validações com Scala, Specs e Lift &#8211; Parte I</title>
		<link>http://codemountain.wordpress.com/2009/10/14/especificando-validacoes-com-scala-specs-e-lift-i/</link>
		<comments>http://codemountain.wordpress.com/2009/10/14/especificando-validacoes-com-scala-specs-e-lift-i/#comments</comments>
		<pubDate>Wed, 14 Oct 2009 03:21:18 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[bdd]]></category>
		<category><![CDATA[lift]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[specs]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=393</guid>
		<description><![CDATA[Pra variar um post sem ligação alguma com o anterior. Mas vamos lá.
Há pouco mais de um ano que comecei a estudar Scala, e durante este tempo me dediquei quase que puramente à linguagem. O máximo que brinquei foi com Scala SBT, o Dispatch do n8han e outras coisinhas. Acredito que até mesmo por não [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=393&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Pra variar um post sem ligação alguma com o anterior. Mas vamos lá.</p>
<p>Há pouco mais de um ano que comecei a estudar <a href="http://www.scala-lang.org/" target="_blank">Scala</a>, e durante este tempo me dediquei quase que puramente à linguagem. O máximo que brinquei foi com <a href="http://code.google.com/p/simple-build-tool/" target="_blank">Scala SBT</a>, o <a href="http://technically.us/code">Dispatch</a> do <a href="http://twitter.com/n8han" target="_blank">n8han</a> e outras coisinhas. Acredito que até mesmo por não ser meu foco profissional (por hora) demorei pra estudar o <a href="http://www.liftweb.net/" target="_blank">Lift</a>, o framework MVC para Scala.</p>
<p>Completei o <a href="http://www.liftweb.net/docs/getting_started.html" target="_blank">getting started</a> do framework e comecei a fazer uma segunda aplicação de estudo com <a href="http://twitter.com/lucastex" target="_blank">@lucastex</a> e <a href="http://twitter.com/r4f4e1" target="_blank">@r4f4e1</a>. Mas o motivo desse post é um processo de desenvolvimento que me chamou a atenção depois que vi o Cucumber. BDD, ou <a href="http://behaviour-driven.org/" target="_blank">BehaviourDrivenDevelopment</a> é uma metodologia ágil que vem como um complemento &#8211; ou mesmo evolução &#8211; ao TDD (Test Driven Development) e se transformando em uma ferramenta primordial para o <a href="http://domaindrivendesign.org/" target="_blank">DDD (DomainDrivenDesign)</a>.</p>
<p>Existem muitos frameworks BDD como <a href="http://rspec.info/" target="_blank">RSpec</a>, <a href="http://code.google.com/p/specs/" target="_blank">Specs</a>, <a href="http://www.artima.com/scalatest/" target="_blank">Scala Test</a>, <a href="http://cukes.info/" target="_blank">Cucumber</a>, <a href="http://jbehave.org/" target="_blank">JBehave</a>, <a href="http://code.google.com/p/jsspec/" target="_blank">jsspec</a>, e escolhi o Specs por algum motivo obscuro.</p>
<p>Sendo bem objetivo e tentando reduzir a quantidade de palavras no post (deixando o máximo de código possível), o foco do BDD é a construção de comportamentos esperados para o sistema ao invés de testes. A construção de testes, em última instância, tem interesse em verificar o comportamento que o sistema deve (<strong>should</strong>) ter em diversos cenários (<strong>examples</strong>), por isso BDD.</p>
<p>Outro ponto importante é a tão falada linguagem ubíqua, ou seja, uma linguagem que todos os envolvidos na construção do software consigam entender. Frameworks BDD permitem que esta linguagem seja executável e escrita na propria linguagem de construção do sistema. Scala é muito poderosa na construção de <a href="http://en.wikipedia.org/wiki/Domain-specific_language" target="_blank">DSLs (Domain Specific Languages)</a>, chegando ao ponto do código se parecer com uma escrita em ingles, não em uma linguagem de programação. Neste post, o comportamento que escolhi especificar foi de validação de dados de domínio:</p>
<pre class="brush: scala;">
&quot;Create/Update a ToDo item&quot; should {
   &quot;show the following error messages:&quot; &gt;&gt; {
     &quot;Description must be 3 characters&quot; &gt;&gt; {
       &quot;if description field length is less than 3&quot; in {
         val todo = ToDo.create.owner(User.currentUser)
         todo.desc(&quot;&quot;).validate must
         contain(FieldError(todo.desc, Text(&quot;Description must be 3 characters&quot;)))
       }
     }
     &quot;Priority must be 1-10&quot; &gt;&gt; {
       &quot;if priority field is not between, including, 1 and 10&quot; in {
         val todo = ToDo.create.owner(User.currentUser)
         todo.priority(-1).validate must
         contain(FieldError(todo.priority, &lt;b&gt;Priority must be 1-10&lt;/b&gt;))
        }
     }
   }
 }
</pre>
<p>Nos parágrafos acima note em negrito as palavras <strong>should</strong> e <strong>example</strong>. Indicamos com should o que o sistema (ToDo app) deve fazer nos (<strong>in</strong>) exemplos, ou cenários, que seguem.</p>
<p>Dada cada uma das mensagens esperadas, o trecho de código delimitado por in {&#8230;} é implementado com um ou mais matchers.  o matcher must contain é usado aqui por que o método de Validação de uma classe mapper no lift retorna um List[FieldError]. FieldError é uma case class de construção FieldError[Identifier, NodeSeq]. Logo, o matcher must contain verifica a existência de um objeto com o formato especificado na lista de erros retornados na validação.</p>
<p><strong>Logo</strong>, os matcher são os responsáveis por assegurar que a especificação descrita no texto será atendida pelo resultado do código nos exemplos.</p>
<p>O <a href="http://code.google.com/p/specs/wiki/MatchersGuide" target="_blank">guia de matchers</a> apresenta uma listagem completa desta DSL que pode ser aplicada em Iterables, String, Objects, Maps, Numer, Options, ScalaChecks, XML, Arquivos e grafos de objetos. E para ilustrar o uso de matchers para string.</p>
<p>Ao executar a especificação acima, temos o resultado:</p>
<pre class="brush: bash;">
-------------------------------------------------------
Running com.liftworkshop.todo.TodoSpecTest
Tests run: 3, Failures: 3, Errors: 0, Skipped: 0, Time elapsed: 2.694 sec &lt;&lt;&lt; FAILURE!
Running com.liftworkshop.todo.AppTest
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.042 sec
Results :
Failed tests:
  Create/Update a ToDo item should show the following error messages: Description must be 3 characters if description field length is less than 3
  Create/Update a ToDo item should show the following error messages: Priority must be 1-10 if priority field is not between, including, 1 and 10
  Create/Update a ToDo item should show the following error messages: Priority must be 1-10 if priority field is not between, including, 1 and 10
Tests run: 5, Failures: 3, Errors: 0, Skipped: 0
</pre>
<p>Isto por que os campos desc e priority (mostrados abaixo) não implementam nenhuma validação:</p>
<pre class="brush: scala;">
class ToDo extends LongKeyedMapper[ToDo] with IdPK {
    lazy val priorityList = (1 to 10).map(v =&gt;; (v.toString, v.toString))
    def getSingleton = ToDo
    object done extends MappedBoolean(this)
    object owner extends MappedLongForeignKey(this, User)
    object priority extends MappedInt(this) {
        override def defaultValue = 5
        override def _toForm = Full(select(ToDo.priorityList,
                                           Full(is.toString),
                                           f =&gt; set(f.toInt)))
    }
    object desc extends MappedPoliteString(this, 128)
}
object ToDo extends ToDo with LongKeyedMetaMapper[ToDo]
</pre>
<p>E aqui chegamos a um ponto interessante do BDD, certamente herdado do TDD: vamos escrever o código estritamente necessário para atender a nossa especificação. Supondo que você tenha o mínimo de conhecimento com Lift e quem sabe tenha feito o getting started, adicionemos as validações assim:</p>
<pre class="brush: scala;">
    object desc extends MappedPoliteString(this, 128) {
        override def validations = valMinLen(3, &amp;quot;Description must be 3 characters&amp;quot;) _ :: super.validations
    } // para o mapeamento da descrição e ...
    object priority extends MappedInt(this) {
    ...
        override def validations = validPriority _ :: super.validations
        def validPriority(in : Int) : List[FieldError] =
        if (in &amp;gt; 0 &amp;&amp; in &gt;= 10) Nil
        else List(FieldError(this, &lt;b&gt;Priority must be 1-10&lt;/b&gt;))
    ...
    }
&lt;p&gt;</pre>
<p>O método validations é redefinido em cada propriedade mepada que necessida validação. O campo desc apenas obriga o tamanho mínimo para 3 com a mensagem especificada definido pela função utilitária valMinLen. Já o campo priority instancia diretamente um FieldError passando o campo contendo o erro junto com a mensagem em negrito.</p>
<p>Este projeto foi montado usando o NetBeans junto com o Maven conforme descrito no getting started do Lift. Fazendo um pequeno ajuste (descrito no próximo post), temos a execução da especificação integrada ao JUnit na IDE NetBeans.</p>
<p>Executando outra vez a especificação, teremos todos os testes ok como na figura a seguir. Um print do Netbeans.</p>
<div class="wp-caption aligncenter" style="width: 595px"><img title="Spec ok" src="http://dl.getdropbox.com/u/180764/test.png" alt="Especificação atendida!" width="585" height="189" /><p class="wp-caption-text">Especificação atendida!</p></div>
<p>Esta foi talvez a parte mágica da coisa. Onde tudo já está funcionando e precisamos só curtir o BDD num exemplo sofrível com intuito de ilustrar esta metodologia, o framework Specs, o framework Lift e a linguagem Scala.</p>
<p>O código completo do projeto estará disponível no próximo Post desta série. As versões utilizadas no projeto são: Lift 1.0, <a href="http://www.scala-tools.org/repo-snapshots/org/scala-tools/testing/specs/1.6.1-SNAPSHOT" target="_blank">Scala Specs 1.6.1</a>, <a href="http://easymock.org/" target="_blank">EasyMock 2.5.2</a> (instalada no repositório maven local). E no próximo Post teremos: Configurando seu projeto Maven para o uso de Scala Specs; Explorando mais matchers; Configurando Contexto Specs para execução da especificação em uma LiftSession acessando a base de dados; Especificando Snippets Lift, e mais. Será que cabe tudo em mais um Post? Vai ter que caber.</p>
<p>Se puder visite <a href="http://behaviour-driven.org/" target="_blank">o site do BDD</a> e conheça mais sobre esta metodologia no mínimo interessante. Dado que não sou especialista em nenhum metodologia ágil, se você tem ou teve alguma experiência prática com BDD, TDD ou DDD deixe seu comentário ou sua sugestão sobre como abordar o tema de maneira mais prática.</p>
<p>Veja a <a href="http://codemountain.wordpress.com/2009/10/20/especificando-validacoes-com-scala-specs-e-lift-parte-ii/" target="_self">Parte II</a> deste post.</p>
Posted in bdd, lift, scala  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/393/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/393/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/393/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=393&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/10/14/especificando-validacoes-com-scala-specs-e-lift-i/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>

		<media:content url="http://dl.getdropbox.com/u/180764/test.png" medium="image">
			<media:title type="html">Spec ok</media:title>
		</media:content>
	</item>
		<item>
		<title>Adeus GenericAbstractBaseWhateverDAO!</title>
		<link>http://codemountain.wordpress.com/2009/10/08/adeus-genericabstractbasewhateverdao/</link>
		<comments>http://codemountain.wordpress.com/2009/10/08/adeus-genericabstractbasewhateverdao/#comments</comments>
		<pubDate>Thu, 08 Oct 2009 15:49:47 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[grepo]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=346</guid>
		<description><![CDATA[Update (09/10/09): Conversando com Daniel Guggi (Desenvolvedor Grepo), ele me alertou sobre a possibilidade de uma configuração mais enxuta no applicationContext.xml do Spring. Eu mantive essa configuração no post por ser a utilizada no projeto em questão. Daniel também falou sobre a versão estável do framework que será lançada até o final da semana que [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=346&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;"><strong>Update (09/10/09):</strong> <em>Conversando com Daniel Guggi (Desenvolvedor Grepo), ele me alertou sobre a possibilidade de uma configuração mais enxuta no applicationContext.xml do Spring. Eu mantive essa configuração no post por ser a utilizada no projeto em questão. Daniel também falou sobre a versão estável do framework que será lançada até o final da semana que segue.</em></p>
<p style="text-align:justify;">Outra vez longe do blog! Passei o último mês até o pescoço em um projeto um pouco apertado. Algo que acontece só as vezes não é mesmo?</p>
<p style="text-align:justify;">Despois de quase um ano focado apenas em SOA e todo seu &#8220;pequeno&#8221; universo, precisei fazer o setup e os primeiros códigos/camadas deste projeto. <strong>Logo</strong>, juntando o pouco tempo para entrega com minha ausência na construção de aplicações standalone no último ano, temos como resultado: Desespero! <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Mas um desespero divertido. ;p</p>
<p style="text-align:justify;">A aplicação possui bastante CRUD, e na equipe começaram os rumores dos famosos AbstractDAO. Wow! Realmente não dá pra fazer o mesmo código sempre pra operações básicas. Mas construir seu próprio AbstractDAO tem lá seus riscos e desvantagens, a saber:  não atingir um nível de abstração satisfatório que permita a construção realmente rápida de telas básicas, perda de tempo fazendo a abstração se não existir uma, discussões sobre quem não obedeceu a abstração corretamente, e coisas do gênero.</p>
<p style="text-align:justify;">E é aí que entra o <a href="http://grepo.codehaus.org/index.html" target="_blank">GREPO</a>, um framework da <a href="http://codehaus.org/" target="_blank">Codehaus</a> que se entitula como simples, flexível e consistênte. E é verdade. A simplicidade pode ser atribuída ao fato de nenhum implementação ser necessária para o seus DAOs. Isso sim é ganhar tempo!</p>
<p style="text-align:justify;">O Grepo, ou Generic Repository permite iterações via <a href="http://grepo.codehaus.org/doc/getting-started-gquery-jpa.html" target="_blank">JPA</a>, <a href="http://grepo.codehaus.org/doc/getting-started-gquery-hibernate.html" target="_self">Hibernate</a> e ainda execução de procedures. Meu foco aqui é JPA. O Grepo trabalha em conjunto com o spring, então os exemplos aqui foram construídos numa aplicação com Spring. Chega de conversa e vamos ao primeiro DAO:</p>
<pre class="brush: java;">
//Entidade
@Entity
public class Administrador {
  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Integer id;

  @Basic
  private String email;

  @Temporal(TemporalType.TIMESTAMP)
  private Date cadastro;
  //get/set etc ...
}

//Código do DAO
public interface AdministradorDAO extends ReadWriteJpaRepository&lt;Administrador, Integer&gt; {}
</pre>
<p style="text-align:justify;">Supondo uma entidade Administrador de Primary Key do tipo Integer, criamos a nossa interface AdministradorDAO que extende ReadWriteJpaRepository passando a entidade e o tipo da sua chave como parâmetro de tipos (generics).</p>
<p style="text-align:justify;">ReadWriteJpaRepository, como o nome já diz, fornece operações de leitura e escrita em uma entidade, ao contrário de ReadOnlyJpaRepository. E é só! Imagine agora o código de uma classe Service:</p>
<pre class="brush: java;">
@Autowired
private AdministradorDAO dao;

public Administrador findById(Integer id) {
  return dao.find(id);
}

public void removeAdministrador(Administrador admin) {
  dao.remove(dao.merge(admin));
}
</pre>
<p style="text-align:justify;">Na verdade, a interface herdada fornece todos os métodos do EntityManager JPA: find, remove, refresh, merge, lock e persist. E isso sem sem escrever código algum para o DAO. Mas sim, há necessidade de escrevermos consultas que permitam retornar entidades que não seja pelo seu id.</p>
<p>Mantendo a abordagem de código zero, definimos um método na interface do dao assim:</p>
<pre class="brush: java;">
public interface AdministradorDAO extends ReadWriteJpaRepository&lt;Administrador, Integer&gt; {
   @GenericQuery(query = &quot;from Administrador where email = :email&quot;)
   public Administrador getByEmail(@Param(&quot;email&quot;) String email);
}
</pre>
<p style="text-align:justify;">Quase dispensa explicações! adicionando este método, definimos via anotação a query que deve ser executada. O parâmetro nomeado JPA é mapeada para o argumento email passado ao método via anotação @Param(&#8220;email&#8221;). É possível usar named queries, passando em @GenericQuery o valor de queryName. O Grepo fornece algumas possibilidades para um bind de um método na interface para uma named query definida, por exemplo, na entidade.</p>
<p style="text-align:justify;">Todo tipo de query jpa, incluindo o uso de QueryHints é possível. Operações de deleção, update, etc, tudo pode ser usado normalmente sem limitações.</p>
<p style="text-align:justify;">Outra sitaução comum é a filtragem de entidades a partir de parâmetros preenchidos em um formulário de filtro html, o que exige uma query gerada dinamicamente a partir dos dados pesquisados. Numa tela de filtro de administradores onde a busca por e-mail e/ou data de cadastro usamos o AbstractJpaQueryGenerator para gerar a consulta:</p>
<pre class="brush: java;">
public interface AdministradorDAO extends ReadWriteJpaRepository&lt;Administrador, Integer&gt; {
  @GenericQuery(query = &quot;from Administrador where email = :email&quot;)
  public Administrador getByEmail(@Param(&quot;email&quot;) String email);

  @GenericQuery(queryGenerator=AdministradorFiltro.class)
  public List&lt;Administrador&gt; findByFilter(AdministradorFiltroBean filtro)

  public static class AdministradorFiltro extends  AbstractJpaQueryGenerator {
    @Override
    public String generate(QueryMethodParameterInfo info) {
      AdministradorFiltroBean bean = info.getParameter(0, AdministradorFiltroBean.class);
      StringBuilder query = new StringBuilder();
      query.append(&quot; from Administrador where 1=1 &quot;);
      if (bean.getEmail() != null){
        query.append(&quot; and email = :email &quot;);
        this.addDynamicNamedParam(new DynamicNamedJpaParam(&quot;email&quot;, bean.getEmail()));
      }

      if (filtro.getDe() != null) {
       query.append(&quot; and cadastro &gt;= :de&quot;);
       this.addDynamicNamedParam(new DynamicNamedJpaParam(&quot;de&quot;, bean.getDe()));
      }

      if (filtro.getAte() != null) {
       query.append(&quot; and cadastro &lt;= :ate&quot;);
       this.addDynamicNamedParam(new DynamicNamedJpaParam(&quot;ate&quot;, bean.getAte()));
      }

      return query.toString();
    }
  }
}
</pre>
<p style="text-align:justify;">Preenchendo o Bean de pesquisa que guarda o e-mail e data de início e fim de cadastro a pesquisar, passamos como argumento para o método findByFilter de AdministradorDAO e automagicamente o Grepo invoca o AdministradorFiltro, que por sua vez implementa o método generate.</p>
<p style="text-align:justify;">QueryMethodParameterInfo armazena os parâmetros passados para a inferface de pesquisa, no nosso caso o único parâmetro passado é o Bean de Filtro. Note tambémm as classes DybamicNamedJpaParam, que é responsável por fazer o mapeamento do valor do Bean e um parâmetro nomeado.</p>
<p style="text-align:justify;">Pronto, temos um filtro conciso!</p>
<p style="text-align:justify;">Outro ponto que vale a pena observar é que os nomes de métodos no DAO estão todos em inglês. Isto por que o Grepo usa <em>convention over configuration</em> para decidir pela invocação de getSingleResult() ou getResultList() por exemplo. As convenções seguidas são a partir do prefixo dos métodos e podem ser: is|has|find|get|load|delete|updat.</p>
<p style="text-align:justify;">Mas o Grepo não força o uso destes prefixos, voce pode escolher um nome qualquer e construir seu próprio QueryExecutor, ganhando flexibilidade como prometido. Confesso que foi ótimo usar estas convenções e a equie absorveu muito rápido o uso delas.</p>
<p style="text-align:justify;">Você deve estar se perguntando onde configurar isso, ta tudo muito bonito e muito simples até agora. E continuará simples. Mas afinal de onde vem o código para a interface do DAO? Qual a instância injetada classe service acima via @Autowired?</p>
<p style="text-align:justify;">Com pequenas configurações no seu Spring applicationContext.xml, você define seu repositório abstrato de onde todos os seus repositórios (leia-se DAO) irão herdar, passando pra ele o EntityManagerFactory, configurações de transação (opcional) e outras configurações do Grepo:</p>
<pre class="brush: xml;">

&lt;!-- Configuracao repositorios --&gt;
&lt;import resource=&quot;classpath:META-INF/spring/grepo-query-jpa-default.cfg.xml&quot; /&gt;
&lt;bean id=&quot;abstractRepositoryTarget&quot; abstract=&quot;true&quot;&gt;
  &lt;property name=&quot;entityManagerFactory&quot; ref=&quot;entityManagerFactory&quot; /&gt;
  &lt;property name=&quot;executorFindingStrategy&quot; ref=&quot;grepo.queryExecutorFindingStrategy&quot; /&gt;
  &lt;property name=&quot;resultConversionService&quot; ref=&quot;grepo.resultConversionService&quot; /&gt;
  &lt;property name=&quot;executorFactory&quot; ref=&quot;grepo.defaultQueryExecutorFactory&quot; /&gt;
&lt;/bean&gt;

&lt;!-- Todo repositorio sera um filho do repositorio abstrato --&gt;
&lt;bean id=&quot;abstractRepository&quot; abstract=&quot;true&quot;&gt;
  &lt;property name=&quot;interceptorNames&quot; value=&quot;grepo.genericQueryIntroductionInterceptor&quot; /&gt;
&lt;/bean&gt;

&lt;!-- nossa interface --&gt;
&lt;bean id=&quot;administradorDAO&quot; parent=&quot;abstractRepository&quot;&gt;
  &lt;property name=&quot;proxyInterfaces&quot;&gt;
    &lt;value&gt;com.codemountain.dao.AdministradorDAO&lt;/value&gt;
  &lt;/property&gt;
  &lt;property name=&quot;target&quot;&gt;
    &lt;bean parent=&quot;abstractRepositoryTarget&quot;&gt;
      &lt;constructor-arg value=&quot;com.codemountain.Administrador&quot; /&gt;
    &lt;/bean&gt;
  &lt;/property&gt;
&lt;/bean&gt;
</pre>
<p style="text-align:justify;">A interface é registrada no Spring, e o Grepo fornece a implementação que por traz utiliza Spring <a href="http://static.springsource.org/spring/docs/2.5.x/reference/orm.html" target="_self">JPA Template</a> através de um <em>proxy</em> dessa interface. A EntityManager Factory utilizada foi previamente configurada.</p>
<p style="text-align:justify;">Um DAO Grepo pode ser transacional se a propriedade transactionTemplate for configurada com um transactionManager para o  bean abstractRepositoryTarget.</p>
<p style="text-align:justify;">A intenção do post é apresentar o básico deste framework que realmente conseguiu me chamar atenção. O projeto que citei no início do post está entrando em produção e os desenvolvedores envolvidos ficarm muito satisfeitos com o uso desta ferramenta.</p>
<p style="text-align:justify;">De fato um DAO capaz de fornecer operações básicas é frequentemente necessário, o que não precisamos é gastar tempo construindo ou utilizando implementações não capazes de satisfazer as necessidades do projeto. Experimente, vale a pena. Até a próxima. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
Posted in Java, jpa, spring  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/346/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/346/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/346/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/346/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/346/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/346/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/346/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/346/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/346/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/346/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=346&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/10/08/adeus-genericabstractbasewhateverdao/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>
	</item>
		<item>
		<title>ESB? Até que ponto?</title>
		<link>http://codemountain.wordpress.com/2009/08/26/esb-ate-que-ponto/</link>
		<comments>http://codemountain.wordpress.com/2009/08/26/esb-ate-que-ponto/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 00:22:10 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[soa]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=325</guid>
		<description><![CDATA[Olá a todos. Desde que fiz a primeira fase da Certificação SOA Architect da BEA em 2008, não escrevi nada sobre SOA aqui no blog.
Infelizmente não vou começar falando do Paradigma de design Service-Orientation [01], tão pouco como ela se Encaixa em Service-Oriented Computing [01] até chegar em SOA de fato. Dois termos, alias, completamente [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=325&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">Olá a todos. Desde que fiz a primeira fase da Certificação SOA Architect da BEA em 2008, não escrevi nada sobre SOA aqui no blog.<br />
Infelizmente não vou começar falando do Paradigma de design Service-Orientation [01], tão pouco como ela se Encaixa em Service-Oriented Computing [01] até chegar em SOA de fato. Dois termos, alias, completamente desconhecidos por quem imagina que trabalha com SOA.</p>
<p style="text-align:justify;">Não vai dar pra postar nada introdutório neste artigo, tão pouco tratar SOA por completo. Mas vou falar de um dos enganos mais comuns quando se trata de SOA dentre  muitos  que já presenciei, a saber:</p>
<p style="text-align:justify;">&#8220;Um Webservice é um seviço&#8221;, &#8220;Ter um ESB é ter SOA&#8221;, &#8220;Ter Webservices é fazer SOA&#8221;, &#8220;ESB deve ser o responsável por fazer <a href="http://www.eurescom.eu/message/messageJun2003/Web_Service_Orchestration.asp" target="_blank">Service Orchestration</a>&#8220;, &#8220;Meu sistema X &#8216;chama&#8217; o BUS que &#8216;chama&#8217; o sistema Y&#8221;. Bom, dá pra fazer uma lista vasta aqui, mas paremos por aqui.</p>
<p>E o engano que trato neste post é: &#8220;Todo e qualquer serviço deve ser exposto no barramento de serviço ESB&#8221;. Mas por quê? Existem alguns <a href="http://blogs.zdnet.com/service-oriented/?p=1021" target="_self">outros blogs</a> que já falaram sobre <a href="http://java.dzone.com/articles/esb-or-not-esb" target="_blank">quando usar</a> <a href="http://blogs.msdn.com/richardt/archive/2005/03/23/401146.aspx" target="_self">ou não</a> um ESB adotando uma abordagem diferente desta aqui.</p>
<p style="text-align:justify;">Primeiro vamos ao Papa Thomas Erl [01] para a definição de ESB:</p>
<p><em>&#8220;An <strong>enterprise service bus</strong> represents an environment designed to foster sophisticated interconectivity</em> <em><strong>between services</strong>. It estabilishes an intermediate layer of processing that <strong>can</strong> help overcome problems associated with reliability, scalability, and <strong>communications disparity</strong></em>&#8220;.</p>
<p style="text-align:justify;">É um bonto de partida. Podemos agregar outras e outras definições e ter uma definição mais completa ou à contento.</p>
<p style="text-align:justify;">Um pouco da minha humilde vivência em SOA concorda com isso e diz que o ESB é puramente um mediador e deve ser visto como um <strong>componente da</strong> <strong>infra estrutura de serviços</strong> de uma corporação, não como o &#8220;ambiente soa&#8221; (outro engano).  Um Service BUS deve prover algumas características como capacidade de roteamento de mensagem, transformação de mensagem, tradução de protocolos, virtualizaçao de serviço, balanceamento de carga, message throttling, dentre outros.</p>
<p style="text-align:justify;">Mas aí o engano que diz que um webservice é um serviço aparece por aqui. E essa é uma das maiores falácias que a humanidade já conheceu, tal como 2+2 = 5.</p>
<p style="text-align:justify;">Um serviço dentro do contexto SOA, segundo a Wikipedia é: <em>&#8220;&#8230; the term service refers to a set of related software functionality, together with the policies that should control their usage.&#8221; </em>[02]</p>
<p style="text-align:justify;">Logo, um serviço é acessível por sua <strong>interface</strong> [03] que expõe sua <strong>implementação*</strong>, que por sua vez obedece a um <strong>contrato</strong> bem definido para o serviço (funcionalidade). O contrato é o descritor, comumente não técnico, das capabilidades [01]  de um serviço. Estas capacidades por sua vez foram derivadas de alguma necessidade do negócio, ou seja, um Serviço existe pois uma necessidade (requerimento funcional) corporativa existe. Vamos parar por aqui, não vamos chegar ao ponto de onde uma necessidade corporativa (Business Requirement) é derivada. Por tanto temos (de forma resumida, e me perdõem meus amigos conhecedores da ESEF pela simplicidade aqui) os seguintes elementos que compõe um serviço:</p>
<p style="text-align:justify;"><img class="aligncenter" title="Componentes de um Serviço" src="http://dl.getdropbox.com/u/180764/blog/soa/service.jpg" alt="" width="512" height="320" />Agora que chegamos a um ponto onde sabemos o que é um serviço e (mais ou menos) de onde ele brotou, voltemos aos Requisitos Funcionais Corporativos, ou seja, funções desenpenhadas pela corporação.</p>
<p style="text-align:justify;">Uma funcionalidade corporativa pode não ser justificável como um Serviço compartilhado, que embora obedeça a definição de um serviço (Acima), o seu uso deve ocorrer apenas no escopo de uma aplicação. Quando isso acontece, diz-se que um serviço X é pertencente ao <strong>escopo</strong> de Aplicação pois é acessível somente por esta. Frequentemente os demais escopos são: Aplicação, Inter-departamental, Empresarial e público. Escopo está diretamente ligado a que tipo de consumidor o serviço atende.</p>
<p style="text-align:justify;"><strong>STOP!</strong> Aqui temos uma boa razão  para não expor um serviço na infraestrutura SOA corporativa da empresa: O serviço tem um escopo tão reduzido (De aplicação) que se restringe a atender uma única aplicação. (escrevi o post basicamente pra mostrar isso, outras razões para não expor um serviço em um ESB vem de bom senso e prática, além de depender do cenário em questão).</p>
<p style="text-align:justify;">Seguindo a idéia de classificar um serviço quanto ao seu uso, temos uma segunda forma de classificação, comumente chamada de categorização, onde um serviço pertence a uma categoria, ou camada, dada sua capabilidade. Ou seja, serviços capazes de acessar uma função de um sistema legado e expor tal para o ambiente SOA (dentro de algum escopo acima) como ela é, é comumenta categorizado (ou reside na camada de) serviço de conectividade.</p>
<p style="text-align:justify;">Tal categoria pertence a um conjunto mairo de categorias, ou camadas, que facilitam a abstração e auxiliam nas decisões de design. Outra camadas, não menos importante são:</p>
<ul>
<li>Serviços de Dados &#8211; Requisitos Corporativos frequentemente tratam de entidades corporativas a exemplo de Cliente, Contrato, Endereço, etc. Serviços que provêem acesso unificado, bem como uma visão única entre os diversos formatos de diversas fontes em uma corporação, residem nesta camada.</li>
<li>Serviços de Negócio &#8211; São comumente subdivididos em serviços que executam atividades corporativas atômicas (ex: validar cartão de crédito) e serviços de granularidade mais espessa, também chamados de processos de negócio (ex: Processar pedido em e-commerces)</li>
<li>Serviços de Apresentação &#8211; São serviços que permitem a reutilização de uma interface com o usuário (ex: portlets e <a href="http://en.wikipedia.org/wiki/Mashup_(web_application_hybrid)" target="_self">mash-ups</a>.</li>
<li>Serviços utilitários &#8211; São serviços que não estão associados a um contexto específico dentro do negócio (ex: Serviços de Notificação).</li>
</ul>
<p style="text-align:justify;">De fato, dada uma combinação Categoria x Escopo, tem-se uma série de boas práticas aplicáveis aqui. E considerando um serviço de acesso a dados que atende exclusivamente a uma aplicação, não há a necessidade de mediação pelo ESB, ou ainda, não há necessidade de que este serviço resida na infraestrutura da companhia.</p>
<p style="text-align:justify;">Numa abordagem simplista, temos a distribuição de camadas/categorias de serviços como exemplifiquei ano passado <a href="http://raseablog.blogspot.com/2008/12/rasea-e-soa-parte-i.html" target="_blank">aqui</a> [04]. Pra ficar mais coerente com este post e a minha modesta evolução em SOA no último ano, considere a camada vertical vermelha como a camada de serviços utilitários. Ah! Vamos imaginar uma última camada abaixo da camada de serviços de dados, de acesso ou conectividade.</p>
<p style="text-align:justify;"><img class="aligncenter" title="Camadas de Serviços" src="http://dl.getdropbox.com/u/180764/blog/soa/rasea.png" alt="" width="273" height="285" /></p>
<p style="text-align:justify;">O bom senso ajuda muito, mas ter noção de onde um serviço nasce, é tão importante quanto isso. Decidir cegamente se um serviço, e sua <strong>interface física </strong>(WSDL em caso de uso de webservices) deve residir no barramento de serviços é um equívoco. Definir nomes, tipos, escopos, quantidade e relacionamento entre serviços sem uma justificativa é algo que leva ao erro e uma frustração no programa SOA do cliente. E quando isso acontece, todos nós que acreditamos em SOA, pagamos por isso. Agindo assim, fazemos SOA perder credibilidade e estar fadado ao fracasso.</p>
<p style="text-align:justify;">Toda essa história de Requisito Funcional, Serviços e seu componentes, Escopo, Camada de serviços vêm de uma metodologia, de uma engenharia de serviço. SOA também precisa de uma metodologia, e governança. Por favor, nada de empirismo <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align:justify;">ESB faz parte da infraestrutura SOA e deve ser tratado como tal. E considerando as novas tendências e o uso de Composite Applications baseadas em <a href="http://www.osoa.org/display/Main/Service+Component+Architecture+Home" target="_blank">SCA</a>, teremos uma ajuda para colocarmos o ESB em seu devido lugar. Ou então SCA vai terminar de confundir mais algumas pessoas que imaginam fazer SOA.</p>
<p style="text-align:justify;">*existem outras definições para os componentes de um serviço e como eles se relacionam.</p>
<p>Referências:</p>
<p>[01] <a href="http://www.amazon.com/Design-Patterns-Prentice-Service-Oriented-Computing/dp/0136135161/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1251246996&amp;sr=1-1" target="_blank">SOA Design Patterns by Thomas Erl</a></p>
<p>[02] <a href="http://www.amazon.com/SOA-Practice-Distributed-System-Design/dp/0596529554/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1251246853&amp;sr=8-1" target="_blank">SOA in Practice: The Art of Distributed System Design (Theory in Practice) by Nicolai M. Josuttis</a></p>
<p>[03] <a href="http://en.wikipedia.org/wiki/Service_(systems_architecture)" target="_blank">Service (systems architecture) from Wikipedia</a></p>
<p>[04] <a href="http://raseablog.blogspot.com/2008/12/rasea-e-soa-parte-i.html" target="_blank">Rasea e SOA &#8211; Parte I by Paulo Suzart</a></p>
Posted in soa  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/325/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/325/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/325/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=325&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/08/26/esb-ate-que-ponto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>

		<media:content url="http://dl.getdropbox.com/u/180764/blog/soa/service.jpg" medium="image">
			<media:title type="html">Componentes de um Serviço</media:title>
		</media:content>

		<media:content url="http://dl.getdropbox.com/u/180764/blog/soa/rasea.png" medium="image">
			<media:title type="html">Camadas de Serviços</media:title>
		</media:content>
	</item>
		<item>
		<title>Scala: Implicits, Options and Pattern Match to start with RabbitMQ</title>
		<link>http://codemountain.wordpress.com/2009/08/01/scala-implicits-options-and-pattern-match-to-start-with-rabbitmq/</link>
		<comments>http://codemountain.wordpress.com/2009/08/01/scala-implicits-options-and-pattern-match-to-start-with-rabbitmq/#comments</comments>
		<pubDate>Sat, 01 Aug 2009 19:52:25 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[RabbitMQ]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=290</guid>
		<description><![CDATA[update: link to code, now using sxr 0.2.1
Hi folks. Long time away! Confess I hadn&#8217;t had nice ideas to work on, but now I have a lot.
While implementing one of them (sort of Scala lib to use Actors as RabbitMQ Queue consumers over the Java API), I figured that my lib user shouldn&#8217;t explicitly instantiate [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=290&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p><strong>update: link to code, now using sxr 0.2.1</strong></p>
<p>Hi folks. Long time away! Confess I hadn&#8217;t had nice ideas to work on, but now I have a lot.</p>
<p>While implementing one of them (sort of Scala lib to use Actors as RabbitMQ Queue consumers over the Java API), I figured that my lib user shouldn&#8217;t explicitly instantiate or even interact with some original RabbitMQ Java API classes. This small piece of my construct is sufficient to show nice Scala features and functional programming style (the following is not the unique solution or the best way to do that, but funny and teaching).</p>
<p>To consume a Queue, we  first connect to the broker and get a Connection and a Channel. Using <a href="http://www.rabbitmq.com/releases/rabbitmq-java-client/v1.6.0/rabbitmq-java-client-javadoc-1.6.0/com/rabbitmq/client/ConnectionFactory.html#ConnectionFactory(com.rabbitmq.client.ConnectionParameters)" target="_blank">this</a> ConnectionFactory constructor is useful to get a Connection. However, it takes a set of parameters wrapped in <a href="http://www.rabbitmq.com/releases/rabbitmq-java-client/v1.6.0/rabbitmq-java-client-javadoc-1.6.0/com/rabbitmq/client/ConnectionParameters.html" target="_blank">ConnectionParameters</a> class.</p>
<p>So I decided follow these rules:</p>
<p>1. lib users must not instantiate ConnectionParameters directly</p>
<p>2. configuration must appear in the order: user, password, virtual host</p>
<p>3. configuration must take one line and be transparent to lib client</p>
<p>4. Ah! Users shouldn&#8217;t use common Scala Lists</p>
<p>How to make it happens in Scala? My answer was put some interesting features together such as Pattern Match, Options, Case Classes and Implicit Conversions.</p>
<p>Using a <a href="http://code.google.com/p/simple-build-tool/" target="_blank">SBT</a> aproach to declare project dependencies, We have the format:</p>
<pre class="brush: ruby;">

val connParams = &quot;guest&quot; % &quot;guest&quot; % &quot;/&quot; //say a abstract val named connParams
</pre>
<p>An implicit function will help to convert a String to an object that takes a String value and the previous declared parameter as arguments. So we get  Param(&#8220;/, Param(&#8220;guest&#8221;, Param(&#8220;guest&#8221;, None))). Every time the user call the function % on a String, this implicit converter will instantiate a new Param.</p>
<p>The convertion function can be done as:</p>
<pre class="brush: ruby;"> implicit def s2Param(s : String) = Param(s, None)</pre>
<p>Here a new element takes place, the Param class hasn&#8217;t a <strong>new</strong> keyword. That is a Case Class, a especial Class that help us with PatternMatch and  doesn&#8217;t need such a keyword.  And more, the parameters of a case class are &#8220;mapped to&#8221; attributes accessible by its own names:</p>
<pre class="brush: ruby;">
case class Param(value : String, precending : Option[Param])
</pre>
<p>So, say a variable named x referencing Param, x allows x.value and x.precending without any extra declarations. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>s2Param implicitly converts a String to a Param Instance to bring the function %. Let see the function %:</p>
<pre class="brush: ruby;">

case class Param(value : String, preceding : Option[Param]) {

def % (value : String) = Param(value, Some(this))

}
</pre>
<p>For our surprise, we have one more element here, the <strong>Some</strong> -  in conjunction with None (see s2Param) &#8211; extends Option[+A]. Option is used to represent optional values, and here is a nice place to apply it. For example, the preceding Param of a Param is not required for the first in the chain.</p>
<p>None means no value, and Some means some value of the type of +A. Option has many other features not covered here.</p>
<p>Now, with the class designed,  we can add another function (used strictly by the lib) to transform the parameter chain into the Rabbit ConnectionParameters:</p>
<pre class="brush: ruby;">

def asConnectionParams = { 

 val (user, pass, vHost)  = this match {
   case Param(user, None) =&gt;  (user, ConnectionParameters.DEFAULT_PASS, ConnectionParameters.DEFAULT_VHOST)
   case Param(pass, Some(Param(user, None))) =&gt; (user, pass, ConnectionParameters.DEFAULT_VHOST)
   case Param(vHost, Some(Param(pass, Some(Param(user, None))))) =&gt; (user, pass, vHost)
   case _=&gt; error(&quot;ConnectionParameters configuration Failed&quot;)
 }

 //Returning ConnectionParametters
 new ConnectionParameters {
   setUsername(user)
   setPassword(pass)
   setVirtualHost(vHost)
 }

 }
</pre>
<p>asConnectionParams uses Pattern Match to declare the val <strong>user</strong>, <strong>pass</strong> and <strong>vHost</strong> matching the current instance of Param (supposed to be the las declared by the user) against some expected patterns. This Pattern Match carres about the default values to configure the ConnectionParametters instance returned. Any other Param combination not allowed will fall into <strong>case _</strong>, and a error is raised.</p>
<p>Now the Param class complete:</p>
<pre class="brush: ruby;">

   case class Param(value : String, preceding : Option[Param]) {

      require(value != null)  

      def % (value : String) = Param(value, Some(this))

      def asConnectionParams = { 

        val (user, pass, vHost)  = this match {
           case Param(user, None) =&gt;  (user, ConnectionParameters.DEFAULT_PASS, ConnectionParameters.DEFAULT_VHOST)
           case Param(pass, Some(Param(user, None))) =&gt; (user, pass, ConnectionParameters.DEFAULT_VHOST)
           case Param(vHost, Some(Param(pass, Some(Param(user, None))))) =&gt; (user, pass, vHost)
           case _=&gt; error(&quot;ConnectionParameters configuration Failed&quot;)
          }

        //Returnin ConnectionParametters
        new ConnectionParameters {
        	setUsername(user)
        	setPassword(pass)
        	setVirtualHost(vHost)
        }

      }
    }
</pre>
<p>Usage:</p>
<pre class="brush: ruby;">

val params = &quot;guest&quot; % &quot;guest&quot; % &quot;/&quot;
</pre>
<p>Thus, the super class can execute params asConnectionParams to grab the params required to get a Connection and a RabbitMQ channel.</p>
<p>To make things simple to test by yourself, you can find the code that runs stand alone <a href="http://dl.getdropbox.com/u/180764/blog/postrab1/classes.sxr/net/conejos/communication/Comunication.scala.html#9420" target="_blank">here</a> (with Scala<a href="http://github.com/harrah/browse/tree/master" target="_blank"> X-Ray</a>). Next time I promess a Scalatest or something like.</p>
<p>Thats it! Impressive? No! Useful? Maybe. Funny? For sure!!!</p>
<p>Stay up and see more POSTs about real RabbitMQ and Scala soon. It was an appetizer to play around with Scala.</p>
<p>Thanks for coming!</p>
Posted in RabbitMQ, scala  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/290/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/290/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/290/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=290&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/08/01/scala-implicits-options-and-pattern-match-to-start-with-rabbitmq/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>
	</item>
		<item>
		<title>Slides para o talk Scala</title>
		<link>http://codemountain.wordpress.com/2009/06/10/slides-para-o-talk-scala/</link>
		<comments>http://codemountain.wordpress.com/2009/06/10/slides-para-o-talk-scala/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 14:17:46 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=283</guid>
		<description><![CDATA[Depois do talk não acontecer (veja posts anteriores), resolvi disponibilizar no Slideshare toda a apresentação que seria utilizada no evento, e que provavelmente usarei numa próxima oportunidade:

Por enquanto é isso. Ainda devo continuar em estudos profundo so bre SOA Security por mais tempo, uma demanda do trabalho. Mas falou em estudar, é comigo mesmo!!!  [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=283&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Depois do talk não acontecer (veja posts anteriores), resolvi disponibilizar no <a href="slideshare.net" target="_blank">Slideshare</a> toda a apresentação que seria utilizada no evento, e que provavelmente usarei numa próxima oportunidade:<br />
<object type='application/x-shockwave-flash' wmode='transparent' data='http://static.slideshare.net/swf/ssplayer2.swf?id=1561662&#038;doc=funcionalscala-090610090709-phpapp02' width='600' height='492'><param name='movie' value='http://static.slideshare.net/swf/ssplayer2.swf?id=1561662&#038;doc=funcionalscala-090610090709-phpapp02' /><param name='allowFullScreen' value='true' /><param name='allowScriptAccess' value='always' /></object><br />
Por enquanto é isso. Ainda devo continuar em estudos profundo so bre SOA Security por mais tempo, uma demanda do trabalho. Mas falou em estudar, é comigo mesmo!!! <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Espero voltar em breve falando de Scala já na versão 2.8, agora com <a href="http://en.wikipedia.org/wiki/Continuation">Continuations</a> e <a href="http://www.scala-lang.org/node/2075">Named Arguments</a>, o que vai deixar essa linguagem simplesmente imbatível de uma vez por todas. Até a próxima!</p>
<p><strong>Update: Se você não consegue ver os slides no seu leitor de feeds, clique <a href="http://www.slideshare.net/paulosuzart/scala-uma-breve-breve-mesmo-introduo">aqui</a>.</strong></p>
Posted in scala  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/283/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/283/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/283/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=283&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/06/10/slides-para-o-talk-scala/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>
	</item>
		<item>
		<title>Talk #FAIL</title>
		<link>http://codemountain.wordpress.com/2009/05/28/talk-fail/</link>
		<comments>http://codemountain.wordpress.com/2009/05/28/talk-fail/#comments</comments>
		<pubDate>Thu, 28 May 2009 13:33:53 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[me]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=267</guid>
		<description><![CDATA[É pessoal, o talk não aconteceu por alguns motivos particulares na empresa. Mas ainda temos a esperança de conseguir agendar uma data para o evento.
No final, a possibilidade do talk me rendeu material para apresentação sobre a linguagem (Scala) numa próxima oportunidade  
Tenho estado sumido ultimamente pois algumas atividades no trabalho exigiram um estudo [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=267&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">É pessoal, o talk não aconteceu por alguns motivos particulares na empresa. Mas ainda temos a esperança de conseguir agendar uma data para o evento.</p>
<p style="text-align:justify;">No final, a possibilidade do talk me rendeu material para apresentação sobre a linguagem (Scala) numa próxima oportunidade <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align:justify;">Tenho estado sumido ultimamente pois algumas atividades no trabalho exigiram um estudo mais focado sobre o tema (SSO, <a href="http://saml.xml.org/saml-specifications" target="_blank">SAML</a>, WSS). Por isso pisei um pouco no freio na minha vertente de estudo de novas tendências. </p>
<p><img class="alignleft" title="RabbitMQ logo" src="http://www.rabbitmq.com/img/RabbitMQLogo.png" alt="" width="197" height="52" /></p>
<p style="text-align:justify;">Ainda assim consegui ler bastante sobre <a href="http://www.rabbitmq.com/" target="_blank">RabbitMQ</a> (implementação do Advanced Message Queue Protocol &#8211; <a href="http://www.amqp.org/" target="_blank">AMQP</a>), e fiquei realmente interessado.  A propósito o RabbitMQ foi o broker utilizado no Twitter por um tempo, e por conta de uma necessidade particuliar, eles acabaram desistindo do uso. Mas o RabbitMQ não vai ficar atrás, e nas próximas versões disponibilizará a <em>feature</em>. Veja a discussão entre Alex Payne (Twitter) e Alexis (RabbitMQ) <a href="http://unlimitednovelty.com/2009/04/twitter-blaming-ruby-for-their-mistakes.html?showComment=1238989980000#c5705232150439487357" target="_self">aqui</a>, e veja <a href="http://robey.lag.net/2008/11/27/scarling-to-kestrel.html" target="_blank">aqui</a> o que o Robey (Twitter) fez pra atender as necessidades deles.</p>
<p style="text-align:justify;">Detalhe: o Lift sempre deu <a href="http://scala-blogs.org/2007/12/i-love-scala-actors.html" target="_blank">suporte ao Rabbit</a> e eu não sabia o.O!</p>
<p>Dediquei um pouco (pouco mesmo) de tempo a uma outra linguagem funcional chamada <a href="http://clojure.org/" target="_blank">Clojure</a>. A brincadeira começou justamente enquanto preparava os slides para o talk (#fail) e tive que ler bastante sobre <a href="http://en.wikipedia.org/wiki/Lambda_calculus" target="_blank">Lambda Calculus</a> (de onde vem a FP). O gostoso do Clojure é a encarnação do Lambda Calculus como ele é, numa syntax Lisp. <a href="http://lotrepls.appspot.com/" target="_blank">Aqui</a> você pode brincar um pouco com a linguagem; um &#8220;console&#8221; on line. Ah! E dá pra brincar com outras linguagens também como Scala e até OCaml <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
<p style="text-align:justify;">Bom, no final vi um pouco sobre <a href="http://github.com/blog/308-compojure-clojure-web-framework" target="_blank">Compojure</a>, um framework web pra Clojure muito irado.</p>
<p style="text-align:justify;">Por enquanto é só. Estou pensando em abordar mais tópicos sobre Scala, pois ainda há muito o que falar sobre os recursos e características da linguagem com Actors, Extractors, Pattern Matching, Lists e mais. Aguardem!</p>
<p style="text-align:justify;"> </p>
Posted in me, scala  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/267/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=267&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/05/28/talk-fail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>

		<media:content url="http://www.rabbitmq.com/img/RabbitMQLogo.png" medium="image">
			<media:title type="html">RabbitMQ logo</media:title>
		</media:content>
	</item>
		<item>
		<title>Preparando um Talk</title>
		<link>http://codemountain.wordpress.com/2009/04/20/preparando-um-talk/</link>
		<comments>http://codemountain.wordpress.com/2009/04/20/preparando-um-talk/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 02:02:22 +0000</pubDate>
		<dc:creator>paulosuzart</dc:creator>
				<category><![CDATA[me]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://codemountain.wordpress.com/?p=261</guid>
		<description><![CDATA[Em breve, eu e alguns colegas de trabalho faremos um talk na empresa.
O objetivo é apresentar ao restante da companhia, as algumas inovações tecnológicas que cada um vem estudando nos últimos meses.
Dentre elas, Groovy/Grails, CEP, SOA, Terracotta e um talk sobre Scala apresentado por mim.
Para o exemplo usado, Scala X-Ray vai ajudar a ilustrar o [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=261&subd=codemountain&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;"><img class="size-full wp-image-262 alignright" title="AccurTalk" src="http://codemountain.files.wordpress.com/2009/04/acctalk.png?w=250&#038;h=145" alt="AccurTalk" width="250" height="145" />Em breve, eu e alguns colegas de trabalho faremos um talk na empresa.<br />
O objetivo é apresentar ao restante da companhia, as algumas inovações tecnológicas que cada um vem estudando nos últimos meses.<br />
Dentre elas, <a href="http://www.twitter.com/lucastex" target="_blank">Groovy/Grails</a>, <a href="http://twitter.com/erbernardino" target="_blank">CEP</a>, SOA, <a href="http://twitter.com/rafaelfelini" target="_blank">Terracotta</a> e um talk sobre Scala apresentado por <a href="http://twitter.com/paulosuzart" target="_blank">mim</a>.<br />
Para o exemplo usado, <a href="http://github.com/harrah/browse/tree/master" target="_blank">Scala X-Ray</a> vai ajudar a ilustrar o uso da linguagem: <a href="http://is.gd/tmFg" target="_blank">http://is.gd/tmFg</a></p>
<p style="text-align:justify;">Acompanhe! <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p style="text-align:justify;"><em>obs: logo não oficial.</em></p>
Posted in me, scala  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codemountain.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codemountain.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codemountain.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codemountain.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codemountain.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codemountain.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codemountain.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codemountain.wordpress.com/261/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codemountain.wordpress.com/261/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codemountain.wordpress.com/261/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codemountain.wordpress.com&blog=2558149&post=261&subd=codemountain&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://codemountain.wordpress.com/2009/04/20/preparando-um-talk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/3c4d6e49c62a7db180a095900783ffc5?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">paulosuzart</media:title>
		</media:content>

		<media:content url="http://codemountain.files.wordpress.com/2009/04/acctalk.png" medium="image">
			<media:title type="html">AccurTalk</media:title>
		</media:content>
	</item>
	</channel>
</rss>