↓ Arquivos ↓

Arquivo → September, 2008

ODF Easy 0.1 liberado. Facilitando a geração de documentos para o OpenOffice

Tal como mencionei no post anterior, iniciei o desenvolvimento de uma nova API para geração de arquivos no formato ODF (os arquivos com os quais o OpenOffice trabalha). Pois bem, acabo de liberar o primeiro release deste projeto.

Ainda é bastante rudimentar. Basicamente, permite aos usuários apenas criar novas planilhas e inserir algumas células (sem qualquer tipo de formatação ainda) nestas planilhas. Trata-se da versão 0.1 ainda (pré alfa). Para a versão 0.2, está prevista a inclusão de alguma formatação, além do início da inclusão de gráficos nas planilhas.

Para aqueles que se interessarem em participar do projeto, o código fonte (liberado sob a licença LGPL) pode ser baixado em http://sourceforge.net/projects/odfeasy/

Tal como mencionei no post anterior, a ODFEasy consiste em um layer alternativo para ser usado juntamente com o projeto ODFDOM. Sendo assim, para poder contribuir com o projeto, é necessário que você baixe o código fonte deste projeto (também disponível) no SourceForge (no mesmo link).

Gerando arquivos ODF com Java: anunciando o ODFEasy

Semana passada, em um de nossos projetos, precisamos gerar alguns gráficos no Excel usando Java. Não para nossa surpresa, o suporte a esta funcionalidade do formato Excel é extremamente limitada para aqueles que trabalham com Java. Basicamente, vimos duas opções:

  • Criar um modelo pré-definido com um gráfico já pré-criado e, em seguida, simplesmente preencher algumas células do gráfico em questão.
  • Utilizar uma biblioteca como o JExcel, que permite acesso via COM ao Excel, permitindo assim automatizar sua execução.

Para o nosso caso, dado que nossos gráficos serão criados dinâmicamente, a primeira opção foi fácilmente excluida. Isto porque o número de séries de nossos gráficos poderia sofrer inúmeras variações, isto sem mencionar do próprio tipo de gráfico a ser gerado.

A segunda, bem: será que valeria a pena jogar fora a portabilidade que ganhamos com Java? E outra: gerar arquivos do Excel via automação é extremanete leeeeento.

Sendo assim, optamos por adotar o formato ODF. Buscamos algumas bibliotecas e acabamos por optar pelo ODFDOM. A primeira vista, pareceu ser a solução ideal. Navegando rápidamente pela estrutura de classes, vimos todos os componentes de que precisávamos. Já na hora de usar a API…

As coisas nem de longe aparentavam ser tão fáceis assim. Na realidade, gerar arquivos ODF é muito mais complicado do que haviamos imaginado. isto porque a biblitoeca ODFDOM é fortemente focada no XML, e não no documento em si. Pela interface que possuimos com a biblioteca, o tempo inteiro acessamos nós em um documento XML, o que, convenhamos, nem de longe é a maneira mais simples de se visualizar o documento final que se visa criar via código.

(claro, sei que o projeto ainda está na versão 0.6.x, mas mesmo assim, para as nossas necessidades atuais, não é suficiente).

Como resultado, optamos por criar uma nova camada baseada no ODFDOM para a geração de arquivos neste formato. Por enquanto, estamos chamando esta nova API de ODFEasy. Esta possuirá uma interface voltada mais para a geração do documento em si. O código gerado por esta biblioteca, acreditamos, será muito mais simples de ser compreendido do que aquele que produzimos usando o ODFDOM. 

(Acredito que a existência de uma API simplificada como a ODFEasy seja essencial para a adoção bem sucedida do formato ODF. Só para lembrar, uma as principais razões pelas quais o Microsoft Office é adotado consiste justamente na facilidade que possuimos de gerar documentos programáticamente.  

E, convenhamos, a adoção do ODF trará ganhos para todos, visto que se trata de um formato do qual possuimos 100% de conhecimento a respeito, ao contrário do que ocorre com o Microsoft Office)

Inicialmente, nosso foco consiste na geração de planilhas (influenciado pela nossa necessidade atual) e gráficos. Posteriormente, conforme nossas necessidades venham a evoluir, pretendemos abranger outros tipos de documento.

O projeto ainda não possui um site (pretendo construi-lo no decorrer desta semana) para que possamos liberar o código fonte (cuja licença será a LGPL), mas já aproveito a ocasião para convidá-los a participar deste projeto, bastando para isto entrar em contato comigo a partir deste blog.

Sendo assim, nesta semana podem esperar mais posts sobre o desenvolvimento deste projeto neste blog (e, com isto, maiores informações sobre como é de fato o formato ODF).

RESTfull Grails:artigo de Scott Davis sobre aplicação de REST usando Grails

Encontrei hoje pela manhã este excelente artigo de Scott Davis sobre como implementar uma arquitetura orientada a serviços usando REST.

O que achei interessante é que contém uma introdução muito bem feita aos conceitos básicos do REST para aqueles que estão se iniciando na área.

Fica aí a dica.

Grails: acessando bases de dados legadas.

Então chegou o dia no qual você conheceu Grails, se apaixonou pelo bichinho mas não sabe ainda como configurá-lo para acessar sua base de dados legada. Ao primeiro contato com Grails, uma impressão que surge é que, para criarmos algo com o bichinho, precisamos partir do zero no que diz respeito a base de dados. Felizmente nada poderia ser mais distante da verdade.

Se você já possui uma base de dados legada, e gostaria de reaproveitá-la em sua aplicação feita em Grails, apresento-lhe a propriedade mapping, responsável por permitir ao desenvolvedor customizar o modo como Grails acessa suas bases de dados (leia aqui: o chato do legado). É neste bloco de código aonde definimos, por exemplo, o nome dos campos que queremos acessar em nossa aplicação.

Sendo assim, suponhamos que eu já possua em um banco de dados (não irei explicar aqui como configurar a conexão com o mesmo, pois o assunto do tópico consiste apenas em como customizar o mapeamento de nossas classes com suas respectivas tabelas) uma tabela chamada tbUsuario. Esta foi definida tal como descrito abaixo (não costumo dar estes nomes a meus campos. Irei usar aqui nomes que se afastem o máximo possível dos padrões normalmente criados pelo Grails):

create table tbUsuario (
idUsuario varchar(36) not null,
strNome varchar(128) not null,
strLogin varchar(64) not null,
strSenha varchar(128) not null,
primary key (Id)
)

Nossa tabela utiliza como chave primária o campo idUsuario que armazena valores gerados usando o algoritmo UUID, diferente do padrão definido pelo Grails quando trabalhamos com MySQL por exemplo (neste caso, Grails utiliza valores auto incrementais).

Suponhamos agora, que nossa classe de domínio possua o código definido abaixo:

class Usuario {
String nome
String login
String senha

static constraints = {
nome(maxSize: 128, nullable:false, blank:false, unique: true)
login(maxSize: 64, nullable:false, blank:false, unique: true)
senha(maxSize: 128, nullable:false, blank:false)
}
}

Se fossemos usar o padrão do Grails para a geração de tabelas no MySQL, gerariamos em nosso banco uma tabela tal como a descrita no código abaixo:

create table usuario {
id integer not null auto_increment,
version integer not null, // para versionamento do banco, o Grails cria este campo por default
nome varchar(128) not null,
login varchar(128) not null,
senha varchar(128) not null,
primary key (id),
// e algum código para a geração dos indices unicos para os campos login e nome
}

Como pode ser observado, a tabela gerada por default é muito diferente da que intencionamos usar. Para resolver este problema, iremos incluir o bloco de código mapping em nossa classe de domínio, tal como no código abaixo:

class Usuario {
String id // repare: estou redefinindo o atributo id como String.
String nome
String login
String senha

static constraints = {
nome(maxSize: 128, nullable:false, blank:false, unique: true)
login(maxSize: 64, nullable:false, blank:false, unique: true)
senha(maxSize: 128, nullable:false, blank:false)
}

static mapping = {
table 'tbUsuario'
version false
id column:'idUsuario', generator:'uuid'
nome column:'strNome'
login column:'strLogin'
senha column:'strSenha'
}
}

Vamos agora analisar o que foi feito no bloco mapping linha a linha (ou quase):

table 'tbUsuario'

Simples: defino qual o nome da tabela na qual os dados se encontram armazenados.

version false

O Grails por default cria um campo chamado version em suas tabelas para versionamento dos dados. Podemos desabilitar este padrão usando o comando acima. Dado que em nossa base de dados legada não existe campo similar, ignorar este detalhe iria travar nossa aplicação.

id column:'idUsuario', generator:'uuid'

Como não iremos usar o padrão para armazenamento de chaves primárias, que varia de acordo com o banco de dados (MySQL, por exemplo, tem por default campos incrementais no que diz respeito a chaves primárias), precisamos redefinir nossa coluna id.

No caso, primeiro definimos qual o nome da coluna na qual os dados estão armazenados. Em seguida, definimos qual o algoritmo usado na geração destes valores. Em nosso caso, o algoritmo UUID (já inclusive escrevi sobre isto aqui).

Com relação aos demais campos, apenas foi definido o nome relacionado à tabela em questão:

nome column:'strNome'
login column:'strLogin'
senha column:'strSenha'

E por incrível que pareça, basicamente é isto o que você precisa fazer caso queira lidar com bases de dados legadas. Todo o código CRUD referente a classe de domínio em questão será feito com base nestas customizações.

Caso queira se aprofundar mais sobre o assunto, sugiro que dê uma lida na própria documentação do Grails (aliás, excelente) clicando aqui.

Lendo XML com Groovy (ou como causar inveja em um programador Java (e depois satisfazê-la!)) – (ou ainda, como ler XML SEMPRE deveria ter sido)

Sempre achei XML paradoxal. Por um lado, trata-se de uma tecnologia fantástica: a sintaxe do XML é simplíssima. Qualquer um consegue gerar um documento no formato XML. No entanto, em contrapartida, ler o bem dito documento (ao menos em Java) pode ser um suplício.

Há ferramentas que facilitam este trabalho (Dom4J, XStreamer, etc.), mas é uma pena que, na própria linguagem, nativamente, tais recursos não existam (é compreensível, mas é chato). Sendo assim, gostaria de incluir mais uma ferramenta para facilitar a vida do desenvolvedor Java: Groovy! Neste post (que pode ser considerado uma continuação do anterior), irei mostrar como se parseia um documento XML usando Groovy em, em seguida, como integrar este parser em seu código Java (satisfaço assim a sua inveja).

Para começar, iniciemos com o documento XML que iremos parsear:

<?xml encoding="ISO-8859-1" version="1.0"?>
<enderecos>
    <endereco id="1">
        <rua>Paraíba</rua>
        <numero>1061</numero>
        <bairro>Savassi</bairro>
        <cidade>Belo Horizonte</cidade>
    </endereco>
    <endereco id="2">
        <rua>Av. Afonso Pena</rua>
        <numero>4114</numero>
        <bairro>Cruzeiro</bairro>
        <cidade>Belo Horizonte</cidade>
    </endereco>
</enderecos>

E, o código feito em Groovy para parsear este XML é…

def registros = new XmlParser().parseText(str)
def enderecos = registros.endereco.size()
for (int i = 0; i < registros.endereco.size(); i++) {
    print "\n${registros.endereco[i].'@id'}"
    print "\n\t${registros.endereco[i].rua.text()}"
    print "\n\t${registros.endereco[i].numero.text()}"
    print "\n\t${registros.endereco[i].bairro.text()}"
    print "\n\t${registros.endereco[i].cidade.text()}"
}

Agora, vamos comentar este código linha a linha: primeiro, iremos comentar a não linha deste código. Repare que não há instrução alguma de importação de classes ou pacotes. Isto porque a classe XmlParser se trata de um recurso nativo da linguagem.

def registros = new XmlParser().parseText(str)

É declarada aqui uma variável chamada registros, que é o resultado da função parseText do objeto XmlParser, que acabamos de instanciar. Este método recebe como parâmetro apenas uma string (no caso, imaginemos que exista uma variável chamada str em nosso código fonte, que contenha o XML descrito acima). registros consiste em uma Collection, que armazena objetos cujos métodos e atributos serão definidos de acordo com o conteúdo do XML parseado.


(

Já se perguntou pra que serve este lance de ficar incluindo métodos e atributos em uma classe em tempo de execução? Eis aqui um bom exemplo.
O objeto retornado pelo Parser possuirá métodos e atributos definidos de acordo com o XML parseado! Veja o código abaixo:

)

def enderecos = registros.endereco.size()

O objeto enderecos representa o elemento raiz do XML lido. Como o XML lido possui mais de um elemento endereco, Groovy o trata como uma coleção. Então, chama-se o método size desta coleção para se saber quantos endereços estão armazenados na estrutura registros.

Dentro do loop, fica ainda mais nítido como acessar estes valores a partir do XML:

print "\n${registros.endereco[i].'@id'}"

Em cada objeto do tipo endereco (criado dinâmicamente por Groovy), imprimo o atributo id do mesmo. Faço isto usando o operador @id.

O operador @[nome do atributo] consiste em um construtor do Groovy que nos permite acessar diretamente um atributo de determinado objeto. Groovy criou um atributo chamado id na classe endereco. Sacou? id era um atributo do elemento endereco no XML. Logo, vira um atributo da classe endereco criada dinâmicamente!

print "\n\t${registros.endereco[i].rua.text()}"

Aqui, percebe-se que foi criado um objeto chamado rua dentro da estrutura do objeto endereco. Como trata-se de um elemento XML, Groovy o transforma em outro objeto! Para saber o seu conteúdo, simplesmente chamo a função text() deste objeto criado.

Como pode-se observar (não vou ficar repetindo as últimas linhas do código), o modo como o Groovy parseia o XML é muito simples. É criado um código muito mais fácil de entender do que aquele que estamos acostumados a trabalhar com Java (ou C#). Nada de NodeLists, Elements, etc. Os elementos do XML recebem nomes que correspondem aquilo representado no documento. Seu cliente poderia ler este código e compreendê-lo sem problemas (pense nisto).

Então, agora que criei inveja em programadores que trabalhem com Java, vou sacia-la. Código Groovy é 100% integrado ao código Java. Um chama o outro sem a menor dificuldade. Sendo assim, segue abaixo uma classe, escrita em Java, que expõe como integrar seu código Java com Groovy :)

import java.io.IOException;
import java.util.List;

import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

public class EnderecoParser {

    // GroovyShell é a classe responsável por executar código Groovy
    private static GroovyShell shell;
    // Binding passa parâmetros ao seu código Groovy
    private static Binding binding = new Binding();
    // Script corresponde ao seu código fonte
    private static Script script;

    /* Função que retorna o código fonte do Groovy
        Pega o código fonte que esteja no classpath da aplicação*/
    private String getCodigoFonte() throws IOException {
        InputStream streamEntrada = getClass().getClassLoader().getResourceAsStream("EnderecoParser.groovy");
        if (streamEntrada != null) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(streamEntrada));
            String str = null;
            StringBuilder builder = new StringBuilder();
            while ((str = reader.readLine()) != null) {
                builder.append(str).append("\n");
            }
            reader.close();
            return builder.toString();
        }
        return null;
    }
    // Recebo como parametro o XML armazenado em uma String
    public List getActions(String str) throws IOException {
        if (str != null) {
           // Passo esta variável ao meu script groovy (o mesmo código que citei acima!)
            binding.setVariable("str", str);
            if (shell == null) {
                shell = new GroovyShell(binding);
                script = shell.parse(getCodigoFonte());
            }
           /*
                     Eu poderia ter uma classe chamada Endereco, que é populada com os dados do XML
                     pelo próprio parser.
            */
              return  (List) script.run();
          }
        return null;
    }
}

Groovy: detalhes que encantam aqueles que programam em Java

Confesso: estou viciado em Groovy. Desde que aprendi a linguagem a um ano e meio (ou dois?) anos atrás, toda vez que vou programar em Java sinto falta de algum detalhe da sintaxe do Groovy na mesma. Aqui pretendo expor alguns detes pequenos detalhes que, embora não essenciais, são extremamente úteis no dia a dia (e, acredite, você realmente sentiria falta dos mesmos ao trabalhar com Java). Estes detalhes tornariam Groovy um Java++?

Strings

Interpolação de valores:

Java

int valorInteiro = 3;
// No java pré 5
String valor = "O valor inteiro vale" + Integer.toString(valorInteiro);
// No java 5 e posterior (bem melhor!)
String valor5 = "O valor inteiro vale " + valorInteiro

Groovy

int valorInteiro = 3
// Repare: sem concatenação de Strings!
String valor = "O valor inteiro vale ${valorInteiro}"

Strings com mais de uma linha

Java

String multiLinha = "Esta é a minha string \n" +
                         "com mais de uma \n" +
                         "linha!"

Groovy

String multiLinha = """Uma string com áspas triplas
                             me permite escrever strings
                             com quantas linhas eu
                             quiser"""

Evitando NullPointerException

Java

 Object valor = construaObjeto();
 if (valor != null) { // bla bla bla }

Groovy

 def valor = construaObjeto()
 if (valor) {//bla bla bla}

Em Groovy, a verdade nem sempre é um booleano. Um valor nulo equivale a um false tradicional.

Verificando valores nulos na concatenação de uma string
Java

 Object obj = criarObjeto();
 String str = "O valor do objeto será igual a " + obj == null ? "nulo" : obj.toString();

Groovy

 Object obj = criarObjeto()
 String str = "O valor do objeto será igual a ${?obj.toString()}"

Criando getters e setters

Convenhamos: um dos recursos mais utilizados em nossas IDE´s consiste na opção de refatoração que encapsula atributos gerando getters e setters. Em Java, quando precisamos criar getters e setters, precisamos digitá-los explicitamente em nosso código, tal como no exemplo abaixo:
Java

class ClasseQuente {
   private int valor;
   public int getValor() {return this.valor;}
   public void setValor(int v) {this.valor = v;}

  private String texto;
  public String getTexto() {return this.texto;}
  public void setTexto(String v) {this.texto = v;}
}

Em groovy…
Groovy

class ClasseQuentissima {
     int valor
     String texto
}

Se coloco o acesso padrão, não preciso criar gets e sets explícitamente! Groovy os cria para nós em tempo de execução. Simples não?

return opcional

Em Java, sempre que quero retornar um valor, preciso de usar a palavra-chave return. Em Groovy, o último comando de um bloco de código corresponde ao valor retornado. Exemplo:

  int soma(int a, int b) {
      a + b
  }

Closures

Closures encontram-se previstas para serem incluídas no Java 7, mas antes de expô-las, convém perguntar: que bicho é este?

Basicamente, closures são um tipo de dados que, na realidade, consiste em um bloco de código executável. Você pode então ter variáveis em seu código que, na realidade, são código executável, tal como no exemplo abaixo:

  def closureQuente = {
        print "\nSou uma closure. Ao ser chamada, imprimo isto!"
  }

Uma closure também pode ter parâmetros, tal como em

   def closureQuenteComParametros = {a, b ->
         a + b}

E como eu poderia usar tais valores em Java? Em qualquer situação na qual determinado método de uma classe tenha de ser definido dinamicamente. Imagine, por exemplo, a utilização de closures em um enum. Abaixo exponho como imagino que as closures poderiam ser definidas em Java neste caso:

enum OperacoesMatematicas {

   Soma({a, b -> return a+b;}),
   Subtracao({a,b -> return a-b;});

   Closure operacao;
   getOperacao() {return this.operacao;}

   OperacoesMatematicas(Closure o) {this.operacao = o;}
}

Estes são apenas alguns dos detalhes que me encantaram em Groovy quando comecei a aprender a lingaugem. São suficientes para que eu troque de linguagem definitivamente? Claro que não! Java ainda apresenta uma performance muito superior e, querendo ou não, na JVM, é a lingaugem padrão. Isto sem mencionar que não existe um Groovy Community Process, tal como ocorre no caso do Java.

E aqui fico ansioso para, no futuro, escrever algo neste blog como Linguagem X (pode até ser Java): detalhes que encantam aqueles que programam em Groovy :)

Get Adobe Flash playerPlugin by wpburn.com wordpress themes