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

<channel>
	<title>SubMundo Java &#187; domain driven design</title>
	<atom:link href="http://submundojava.com.br/wordpress/category/domain-driven-design/feed/" rel="self" type="application/rss+xml" />
	<link>http://submundojava.com.br/wordpress</link>
	<description>Um pouco de tudo, mas tecnologia acima de tudo!</description>
	<lastBuildDate>Wed, 26 May 2010 15:00:26 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Injetando Repositorios em entidades de maneira transparente com Spring</title>
		<link>http://submundojava.com.br/wordpress/2010/04/04/injetando-repositorios-em-entidades-com-spring/</link>
		<comments>http://submundojava.com.br/wordpress/2010/04/04/injetando-repositorios-em-entidades-com-spring/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 01:36:42 +0000</pubDate>
		<dc:creator>Henrique Lima</dc:creator>
				<category><![CDATA[domain driven design]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[ddd]]></category>
		<category><![CDATA[maven 2]]></category>
		<category><![CDATA[repository]]></category>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

if(matcher.matches()) {

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

} else {

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

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

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

    public static void main(String argz[]) {

        RegexComposer composer = RegexComposer.getInstance();

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

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

        if (matcher.matches()) {

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

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

    }

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