Lucas Teixeira

@lucastex

Arquivo para October, 2009

Gerenciamento de dependências com Grape

com 8 comentários

Mais uma maneira de se gerenciar dependências :)

Agora é a vez do Grape, um módulo construindo em Groovy que abstrai toda aquela configuração do maven/ivy que vc teria por padrão. O grande diferencial do Grape, é que ele traz essa configuração mais para perto de quem precisa dela, ou seja, no próprio código fonte!

Funciona basicamente assim, você anota o seu método que irá precisar da dependência com a anotação @Grab dizendo qual é o grupo, artefato e versão da biblioteca que você precisa e pronto! Quando a classe for carregada, esta anotação irá disparar o download desta dependência automaticamente. Os arquivos que são baixados via grape são guardados dentro do diretório do usuário na pasta .groovy/grapes

Segue um simples exemplo que depende do commons-lang 2.4 e usa um método simples da classe StringUtils para trocar o case de uma string.

import org.apache.commons.lang.StringUtils

@Grab(group='commons-lang', module='commons-lang', version='2.4')
void testGrape() {

   def name = "Lucas Frare Teixeira"
   println StringUtils.swapCase(name) //lUCAS fRARE tEIXEIRA

}

//Chama a execução do método
testGrape()

Veja que a únca coisa que precisamos fazer, é anotar o método com a dependência e ele fica responsável por fazer o download.

Mas, conversando com o @paulosuzart do CodeMountain, chegamos a conclusão, que sistemas de maior porte, merecem um controle de dependências mais centralizado e até por que não dizer, organizado.

Ou seja, fica a minha dica de uso do Grape para a distribuição de scripts e arquivos pequenos, para evitar aquela coisa chata de enviar jars, setar classpath, ou então ter arquivos pom que definem dependência e etc.

Para evitar esta dor de cabeça, sem dúvidas o grape é ideal!

Written by Lucas Teixeira

October 30th, 2009 at 3:47 pm

Postado em Groovy

Com as tags , , , ,

Data corrente no nome do artefato gerado com ant

sem comentários

Algumas pessoas costumam versionar (e manter guardado) o histórico de versões geradas pelo seu projeto. Uma coisa que não se deve esquecer, é de renomear os pacotes de modo que quando necessário encontrar um específico, seja fácil.

O que eu faço, é sempre renomear o pacote para: projeto-yyyyMMddHHmmss.[jar/war/ear] . Como ant, fica fácil fazer isso usando uma task chamada tstamp, que recupera o timestamp corrente e grava em uma variável seguindo o pattern que você escolher. Segue exemplo que uso aqui.

Armazenando valor:

<tstamp>
   <format property="build-datetime" pattern="yyyyMMddHHmmss"/>
</tstamp>

Pronto, agora basta usar a variável build-datetime como outra qualquer,

<target name="dist" depends="compile" description="gera o jar com a distribuição">
   <jar jarfile="${dist}/${project}-${build-datetime}.jar" basedir="${build}"/>
</target>

É uma boa também para guardar os arquivos em estruturas de pastas separadas por dia/mes/ano.

yyyyMMddHHmmss

Written by Lucas Teixeira

October 28th, 2009 at 3:35 pm

Postado em Ant, Java

Com as tags , , ,

Criando um Transformer customizado para o Solr

com 16 comentários

Solr é um framework uma ferramenta para a construção de servidores de indexação e busca on top of índices lucene.

Possui todas as funcionalidades que existem em um sistema moderno de busca, como paginação, highlight de campos, flexão das palavras e etc. Na minha opinião, de tudo que trabalhei nos últimos anos, sem dúvida, formam o conjunto mais poderoso de frameworks.

O Solr abstrai a camada Java do Lucene e disponibiliza uma interface http para a execução da consulta, fazendo com que fique muito fácil a integração com sistemas não-java.

Um dos recursos avançados de indexação com Solr são os Transformers a serem usados juntamente com o DataImportHandler. Com eles, você pode processar o texto antes de ser indexado. (Um outro post sobre configuração básica de Solr e de DIH deve vir em breve).

Semana passada, precisei de um transformer que pudesse retirar todas as tags HTML do texto a ser indexado (malditos editores rich text em javascript). Como o projeto aqui está usando Solr 1.3 não tive a possibilidade de usar o HTMLStripTransformer que virá no Solr 1.4 (e está enroscado pra sair). Então acabei tendo que criar um semelhante para a funcionalidade.

A criação de transformers é muito simples (imho, simplista até demais, fazendo com que as vezes, o desenvolvedor se perca durante a implementação). Deve ser desenvolvida uma classe simples, que implementa um método com a seguinte assinatura:

public Map<String, Object> transformRow(Map<String, Object> aRow, Context context)

Quando disse que é simplista demais, é pelo fato de que, (imho novamente), condições restritivas como esta deveriam estar documentadas em interfaces, mas não, quando necessário, o método é chamado via reflection, tendo certeza que ele está implementado.

No meu caso, eu precisaria além de implementar o Transformer, deixar explícito no arquivo de configuração do DIH (data-config.xml) quais os campos que deveriam receber o tratamento desta tag, fiz isso adicionando a tag removeHtml no nó de cada campo (não, este xml não passa por validação).

<field name="txt" column="texto" removeHtml="true" />

Com isto, estamos deixando claro para o DIH que o valor que retornar da query na coluna texto será repassado ao Solr para indexação no field txt (definido no schema.xml) e terá processamento do meu HtmlTransformer. Ah, não podemos esquecer da declaração do transformer para a entidade:

<entity name="posts" transformer="br.com.lucastex.dih.transformer.HtmlTransformer" />

Pronto, a classe está agora carregada e pronta para ser chamada quando um campo necessitar. Agora, vamos a implementação da classse. No meu caso, ela ficou bem trivial, pois o campo em questão nunca será multivalorado (ou seja, não preciso tratar a possibilidade do argumento ser um List, mas apenas uma String.

package br.com.lucastex.dih.transformer;

import java.util.Map;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.solr.handler.dataimport.Context;
import org.apache.solr.handler.dataimport.DataImporter;
import org.apache.solr.handler.dataimport.RegexTransformer;
import org.apache.solr.handler.dataimport.Transformer;

public class HtmlTransformer extends Transformer {

  public static final String TAG = "removeHtml";

  public Map<String, Object> transformRow(Map<String, Object> aRow, Context context) {

    for (Map<String, String> map : context.getAllEntityFields()) {
      if (!Boolean.TRUE.toString().equals(map.get(TAG)))
        continue;
      String columnName = map.get(DataImporter.COLUMN);
      String sourceColumnName = map.get(RegexTransformer.SRC_COL_NAME);
      if (sourceColumnName == null)
        sourceColumnName = columnName;
      Object value = aRow.get(sourceColumnName);
      if (value instanceof String) {
        String result = stripHtml((String) value);
        aRow.put(columnName, result);
      }
    }
    return aRow;
  }

  private String stripHtml(String text) {
    try {
      String cleanText = StringEscapeUtils.unescapeHtml(text.replaceAll("\\<.*?\\>", " "));
      cleanText = cleanText.trim().replaceAll("\n"," ");
      cleanText = cleanText.replaceAll("\t"," ");
      cleanText = cleanText.replaceAll("[\\s]+", " ");
      return cleanText;
    } catch (Exception e) {
      //trata exception de acordo com seu contexto solr
    }
    return text;
  }
}

Bom, o código é bem auto-explicativo. Basicamente recebe o além do contexto em execução do Solr/DIH, um Map de String e Object, que contém todos os campos e valores da linha que está sendo analisada/indexada no momento. Vale lembrar que este modelo de passagem de parâmetro é feito exatamente como descrito no Pattern BCDR.

Enfim, as linhas 18 e 19 garantem que o código só será executado para campos que tenham declarado a tag removeHtml=true como descrito anteriormente.

A linha 24 recupera o valor original do campo, ou seja, o que foi retornado pela query no banco de dados, e nas linhas 26 e 27 o resultado é tratado (através da chamada para o método stripHtml) e devolvida ao Map.

Ou seja, este é o momento onde você tem acesso a todos os campos que estão vindo do banco antes de irem ao índice. É nesta hora que você duplica seus campos, faz tratamentos, aplica padrões e templates, enfim trabalha a informação bruta original do banco de dados.

Já o método de remoção de tags HTML, não é nada além de um conjunto de regexes encadeadas  com uma ajudinha do StringEscapeUtils (que saudade deste post) do Commons-lang.

Simples como

Written by Lucas Teixeira

October 26th, 2009 at 6:59 pm

Maravilhas do Groovy: A propriedade metaClass

com 14 comentários

Uma das facilidades que o groovy também traz, é a possibilidade de adicionar métodos em nossas classes em tempo de execução através da propriedade metaClass dos objetos.

Agora mesmo, eu precisava de um recurso para criar “slugs” (essas URLs amigáveis que o WordPress cria) de titulos de artigos. Tradicionalmente, o processo é criar aquelas classes **Utils.java com todos os métodos utilitários, mas com a metaprogramação, o mais usual passa a ser adicionar o métodos nas próprias classes que geram este comportamento.

No exemplo abaixo, eu adicionei o método slug() em runtime dentro da classe String e a partir de agora, qualquer objeto da classe java.lang.String possui o método slug(), com o comportamento descrito abaixo.

String.metaClass.slug { ->
    def s = delegate.toLowerCase()
    s = s.replaceAll(/[^a-z0-9\s-]/, "").replaceAll(/\s+/, " ").trim()
    if (s.length() > 45)
        s = s.substring(0, 45).trim()
    s.replaceAll(/\s/, "-")
 }

Em primeiro, definimos uma varíavel interna ’s’ com o valor da própria string que está sendo usada (através da propriedade delegate), após isso, aplicamos a primeira regex de caracteres especiais, outra para substituir os espaços em excesso e cortamos a string caso ela tenha mais que 45 caracteres. Por fim, substituímos os espaços por dashes.

Você pode rodar este script neste endereço, basta clicar em “Execute script”

Written by Lucas Teixeira

October 25th, 2009 at 12:55 pm

Maravilhas do Groovy: Elvis Operator

com 8 comentários

Nova categoria de posts “Maravilhas do Groovy”, inspirada pelo MrHaki e seus posts sobre o diferencial e tricks que o groovy oferece.

O Elvis Operator é um operador em Groovy (já estará embutido no Java7) representado pelo “ponto de interrogação” seguido pelos caracteres “dois pontos” ou seja  ?:

O objetivo é fazer a comparação do valor de uma referencia a null, para decidir sobre uma atribuição de valor. Um exemplo bem comum é comparar o um parametro que vem do request de qual página irá ser mostrada de uma lista de objetos, porém, caso a página não esteja presente, devemos sempre mostrar a primeira página.

Tradicionalmente, em java, com o operador ternário:

Integer pageParam = (...)
pageParam = (pageParam == null) ? 1 : pageparam;

Com o elvis operator, ele já faz esta comparação implicitamente e caso o valor da variável seja null, recebe o valor que está a direita do operador.

def pageParam = (...)
pageParam = pageParam ?: 1

— Post editado as 18:10 do dia 22/10 —
Meu amigo @paulosuzart do CodeMountain fez um post sobre o Elvis Operator em Scala.
A gente sabe que não existe, mas ele criou um. Vale a pena conferir. :)

Written by Lucas Teixeira

October 22nd, 2009 at 12:09 pm

Não tenha medo das closures

com 13 comentários

Você tem medo das closures? Já vi muita gente dizer que closures são perigosas e trazê-las a tona seria como acordar um monstro adormecido (o medonho GOTO – veja uma ótima definição neste link).

Não eu não concordo, closures só querem o seu bem, eis a razão.

Bom, uma closure nada mais é que um trecho de código! Mas o que difere este bloco de instruções chamado closure de um método? A grande diferença neste caso, é que as closures são um pouco mais flexíveis que os métodos, e por sua vez podem até ser passadas como parâmetro na chamada de outras funções, ou seja, podem ser atribuídas a uma variável.

Em java não temos closures nativas na linguagem, e uma das formas de tentar alcançar o objetivo é através do uso de classes anônimas, o que particularmente não me agrada muito, pela sujeira que fica no código.

Em um primeiro exemplo, mais simples, segue como definir uma closure, associá-la a uma variável e depois executá-la. (exemplo em groovy).

def c = {
    println "Testando o uso de uma closure"
}
c.call()

Este é um exemplo simples, onde a frase acima será impressa no console.

Para incrementarmos um pouco, podemos fazer com que nossa closure receba um parâmetro para usá-lo dentro da execução, além de criar um método que faça o uso dela. O exemplo abaixo mostra isto.

//definição da closure para dizer oi
def ola = { nome ->
    println "E ai ${nome}, tudo bom?"
}

//definição da closure para dizer tchau
def tchau = { nome ->
    println "To indo ${nome}, ate a proxima!"
}

//criação do método que fará o uso da closure
void falar(Closure c, String paraQuem) {
    c.call(paraQuem)
}

//invoke do método com as closures de parametro
//note que a closure é passada como se fosse uma variável qualquer
falar(ola, "Fulano")
falar(tchau, "Ciclano")

Mas uma das maiores vantagens que eu enxergo nas closures, é a possibilidade de definição delas em runtime. Isso mesmo, conforme você programa, pode criar uma nova closure e chamar uma função que precise dela! Vemos isso em ruby e groovy com frequência para métodos onde iteramos listas e mapas.

Por exemplo, as listas e arrays em groovy possuem um método each que recebe uma closure como parâmetro, esta closure define o que será feito com cada um dos items da lista/array em questão. O exemplo abaixo mostra a praticidade de se fazer a definição da closure inline, ou seja, sem criar uma variável para ela antes.

Em groovy

//groovy
def lista = ["Ferrari", "RBR", "STR", "Brawn", "Renault", "Williams"]
lista.each { equipe ->
    println "A equipe ${equipe} correu na #F1 em 2009"
}

Em ruby

#ruby
lista = ["Ferrari", "RBR", "STR", "Brawn", "Renault", "Williams"]
lista.each { |equipe|
    puts "A equipe #{equipe} correu na #F1 em 2009"
}

Em scala

//scala
val teams = List("Ferrari", "RBR", "STR", "Brawn", "Renault", "Williams")
teams foreach {
   team => printf("A equipe %s correu na #F1 em 2009", team)
}

Dá pra perceber que a closure foi criada já no momento em que ela foi usada. Desta maneira, além de fácil, um código muito mais limpo e fácil de ser entendido.

Acredite, closures são suas amigas, e estão aqui pra te ajudar, então aproveite!

Ahh, e fica a dica de sempre: Ler a documentação:

Closures em Groovy (wiki) (groovydoc) (definição formal)
Closures (Proc) em Ruby (doc) (wiki)
Closures em Scala (wiki)

Written by Lucas Teixeira

October 21st, 2009 at 11:55 am

Postado em Groovy, Ruby, Scala

Com as tags , , , ,

Enviando emails com Spring e Velocity

com 10 comentários

Primeiro post do meu blog totalmente em português!

Esta semana, precisei adicionar na aplicação a funcionalidade de enviar e-mails usando templates do Velocity para o corpo do e-mail. Claro que o poderíamos usar o arroz com feijão do Velocity para isso, fazendo o merge do template com nosso contexto de variáveis, mas acabei esbarrando em um site, e descobri que o próprio Spring já possui um FactoryBean para a criação do meu VelocityEngine além de também ficar responsável com o carregamento dos templates (na minha opinião, a parte mais chata).

Bom, explicando brevemente como resolvi o problema:

Defini este bean no applicationContext.xml para controlar a injeção do VelocityEngine

<bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean">
  <property name="resourceLoaderPath" value="/WEB-INF/templates/" />
</bean>

Notem que a propriedade resourceLoaderPath já é definida ali, e é neste diretório indicado que os templates deverão estar.

Este bean do core do spring já encapsula o envio da mensagem, neste exemplo, está configurado com estas propriedades que vieram de um arquivo de propriedades que carreguei no início do meu applicationContext.xml

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
  <property name="host" value="${mail.smtp.host}" />
  <property name="username" value="${mail.smtp.user}" />
  <property name="password" value="${mail.smtp.pass}" />
  <property name="port" value="${mail.smtp.port}" />
</bean>

Este é o bean que será o template da mensagem. É um “modelo” de mensagem, que carrega o endereço ‘from’ e também o subject do e-mail do mesmo arquivo de configuração.

<bean id="templateMailMessage" class="org.springframework.mail.SimpleMailMessage">
  <property name="from" value="${mail.from}" />
  <property name="subject" value="${mail.subject}" />
</bean>

Com isso, já tenho os 3 beans que serão injetados em meu componente de envio de e-mails.

  • Template velocity do e-mail

O template que eu criei para o teste é bem simples e segue abaixo. Se chama mail.vm e como dito ali em cima, está dentro de /WEB-INF/templates/

Oi ${nome}, seu e-mail (${email}) foi cadastrado no sistema.
  • Componente final para o envio do e-mail

Chamei o componente de MailComponent (bem criativo, né?), e a única coisa que ele faz, é receber os beans que definimos via injeção, criar uma nova mensagem usando o template de e-mails e setar como body da mensagem o resultado do merge entre o template e as minhas variáveis. Segue o código do componente.

import java.util.HashMap;
import java.util.Map;

import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Component;
import org.springframework.ui.velocity.VelocityEngineUtils;

@Component
public class MailComponent {

  @Autowired
  private MailSender mailSender;

  @Autowired
  private SimpleMailMessage templateMailMessage;

  @Autowired
  private VelocityEngine velocityEngine;

  public void sendMail(String template, Stirng nome, String email, String ... to) {

    Map<String, Object> ctx= new HashMap<String, Object>() {{
      put("nome", nome);
      put("email", email);
    }};

    String body = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, template, ctx);
    SimpleMailMessage msg = new SimpleMailMessage(this.templateMailMessage);
    msg.setTo(to);
    msg.setText(body);

    mailSender.send(msg);
  }
}

Pronto, o componente está pronto, agora a qualquer momento, em qualquer classe (que tenha acesso ao contexto de DI do spring é claro) você poderá chamar o seu componente

@Autowired
private MailComponent mailComponent

E enviar os e-mails aos usuários:

//Envia e-mail para o usuário com cópia ao admin
mailComponent.sendMail("mail.vm", "Lucas", "[email protected]", "[email protected]", "[email protected]");

É isso aí.

[]s,

VelocityEngineFactoryBean

Written by Lucas Teixeira

October 8th, 2009 at 9:53 am

Postado em Spring, Velocity

Com as tags , , ,

Get Adobe Flash playerPlugin by wpburn.com wordpress themes