Friday, October 14, 2011

Oracle linguistic sort: desconsiderar letras minúsculas/maiúsculas e acentuação

A partir da versão 10g o Oracle passou a suportar a busca em String utilizando classificação linguística (linguistic sort). O que na prática permite a busca em um campo String desconsiderando diferenças, por exemplo, entre letras minúsculas e maiúsculas ou o uso de acentuação.

Os comandos a seguir habilitam, na sessão do usuário, a comparação por linguística e a classificação binária desconsiderando acentuação e case insensitive:

ALTER SESSION SET NLS_SORT='BINARY_AI';
ALTER SESSION SET NLS_COMP='LINGUISTIC';

CREATE TABLE teste (texto VARCHAR2(10));
INSERT INTO teste VALUES('Macaco');
INSERT INTO teste VALUES('maça');
INSERT INTO teste VALUES('maçarico');
INSERT INTO teste VALUES('MAÇONARIA');

SELECT texto FROM teste WHERE texto like 'mac%';

TEXTO
---------
Macaco
maça
maçarico
MAÇONARIA


O mesmo resultado é processado com a seguinte instrução:

SELECT texto FROM teste WHERE texto like 'MAÇ%';

Mesmo informando o acento, como no segundo comando, registros sem acentuação são Macaco sem acento é retornado.

O Oracle também suporta a busca ordena por um idioma:

SELECT texto FROM teste ORDER BY NLSSORT(texto, 'NLS_LANG = PT');

Outra funcionalidade, apresentar a descrição da data em um determinado idioma:

SELECT to_char(sysdate, 'DD/MON/YYYY', 'nls_date_language = French') 
FROM dual;

Link para a documentação online dessas funcionalidades.



Tuesday, August 23, 2011

Solução em Java 7 para a prova do Google Developer Day 2011

Semana passada me diverti um pouco com a prova para o Google Developer Day 2011. A prova não é obrigatória, na verdade faz parte do processo de inscrição e dever ser utilizada como filtro para identificar as pessoas que se adequema o público alvo do evento: Developers.

A prova era composta por 5 questões, todas em torno de 2 textos do idioma Googlon.


Regras do idioma

Letras e ordem do idioma: t w d c r z p s v h m k l n f x q j b g

Esse idioma estipula grupos de letras:
  - letras tipo foo: g, f, z, t e s
  - letras tipo bar: todas as outras.

As preposições são identificadas com a seguinte regra: palavras com 3 letras que terminam com uma letra do tipo bar, mas que não pode ser m.

A regra para identificar verbos: palavras de 7 ou mais letras que terminam com uma letra do tipo bar. Caso a palavra seja um verbo e começe com uma letra do tipo bar, deve ser considerado um verbo de primeira pessoa.

E os números? As palavras são números. Esses números são formados em base 20, onde cada letra é uma digito ordenado do menos para o mais significativo (contrário do binário). Dessa forma a primeira posição é 1, a segunda é 20, a terceira é 400 e assim por diante. Outro detalhe importante: cada letra tem um valor (posição) conforme a ordem do alfabeto, por exemplo t é 0, w é 1, d é 2, etc. Ainda para os números, existem uma classificação de números bonitos. Em Googlon um número bonito deve ser maior ou igual a 502344 e divisível por 4.


Questões

Todas as questões contavam com uma dica do Google, elas eram respondidas levando em consideração a o texto A, mas o participante deveria responder considerando o texto B.
  1. Qual a quantidade preposições no texto B?
  2. Quantos verbos existem no texto B?
  3. Quantos verbos em 1a pessoa existem no texto B?
  4. Imprimir o texto B colocando as palavras na ordem alfabética do Googlon.
  5. Quantos números bonitos existem no texto B?

A solução

Na semana passada estava focado em terminar demos e a apresentação que fiz no TDC2011 em Floripa, sobre Java 7. Aproveitei o embalo pra implementar a solução da prova do GDD usando Java, mas com um detalhe especial: primeiro programa utilizando Java 7. Coloquei as letras na ordem do Googlon em um List e fiz um split do texto (uma String). Dessa forma iteirei sob as palavras para encontrar as preposições, verbos (1a pessoa tb) e números, além de aplicar a ordenação Googlon.

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

import static java.lang.System.out;

public class Googlon {

static List<Character> alf_ordem = 
    Arrays.asList( new Character[] {'t','w','d','c','r','z','p','s','v','h',
      'm','k','l', 'n','f','x','q','j','b','g'} );

  public static void main(String[] args) {
    String textoB = "prm pmqcf flqk mblz fzrr ..."; //um pedaco do texto B

    int preposicoes = 0, verbos = 0, verbos1Pessoa = 0, numerosBonitos = 0;
    //determina as letras do tipo foo
    List<Character> foo = 
      Arrays.asList( new Character[]{'g','f','z','t','s'} );

    //treeset com comparator resolvendo a ordem as palavras (questao 3)
    TreeSet<String> listaEmOrdem = new TreeSet<>(new Comparator<String>(){
      @Override
      public int compare(String s1, String s2) {
        int len1 = s1.length(), len2 = s2.length();
        int lim = Math.min(len1, len2);
        char chars1[] = s1.toCharArray(), chars2[] = s2.toCharArray();

        int i = 0;
        while (i < lim) {
          char c1 = chars1[i];
          char c2 = chars2[i];
          if (c1 != c2) {
            return alf_ordem.indexOf(c1) - alf_ordem.indexOf(c2);
          }
          i++;
        }
        return len1 - len2;
      }
    });

    //aqui percorro todas palavras, para ordernar e validar
    for (String s: textoB.split(" ")) {
      listaEmOrdem.add(s);

      if (isNumeroBonito(converteParaNumero(s))) {
        numerosBonitos++;
      }

      if (s.length() == 3) {
        if (!foo.contains(s.charAt(s.length()-1)) && s.indexOf('m') == -1) {
          preposicoes++;
        }
        continue;
      }

      if (s.length() >= 7) {
        if (!foo.contains(s.charAt(s.length()-1))) {
          verbos++;
          if (!foo.contains(s.charAt(0))) {
            verbos1Pessoa++;
          }
        }
      }
    }

    StringBuilder textoOrdenadoTeste = new StringBuilder();
    for (String s: listaEmOrdem) {
      textoOrdenadoTeste.append(s).append(" ");
    }

    out.println("1a resposta, qtde de preposicoes: "+preposicoes);
    out.println("2a resposta, qtde de verbos: "+verbos);
    out.println("3a resposta, qtde de verbos 1a pessoa: "+verbos1Pessoa);
    out.println("4a resposta, o texto ordenado: "+ textoOrdenadoTeste);
    out.println("5a resposta, qtde de numeros bonitos? "+numerosBonitos);
  }


  private static long converteParaNumero(String palavra) {
    int n = 0;
    long total = 0;
    for (char c: palavra.toCharArray()) {
      int codigo = alf_ordem.indexOf(c);
      total += codigo * (long) Math.pow(20,n++);
    }
    return total;
  }

  private static boolean isNumeroBonito(long numero) {
    //literal int com separador _ e a literal 4 em binario
    return numero >= 502_344 && numero % 0b100 == 0;
  }

}
Para rodar essa classe em versões anteriores do Java é muito simples, na ordem:
  • defina a tipagem de String na instância do objeto TreeSet no lugar do operador diamond.
  • dentro do método isNumeroBonito, na linha 92, remova o "_" entre o número 502304 e utiliza 4 em decimal ao invés de binário (0b100).

@edermag
www.yaw.com.br

Friday, August 05, 2011

Como mudar o encoding de arquivo com conteúdo para UTF-8 no Linux

Alguns dias atrás trabalhei um projeto para customizar um portal para China. Nada muito complicado, afinal era só usar a estrutura do projeto já implementado no Brasil, EUA e outros países para a China.

Mas.... o portal foi projetado com o padrão de charset ISO-8859-1, que não suporta os caracteres do mandarim. A solução então era migrar a estrutura atual, em ISO-8859-1 para UTF-8, mas o buraco era mais embaixo!

São vários detalhes para resolver, por exemplo:
  • Configuração do ambiente servidor e desenvolvimento;
  • Configuração de web-server, application server e database;
  • Outros...

Aqui vou falar apenas de: arquivos texto com algum conteúdo/caractere especial.

O que fazer com os milhares de arquivos Java, JSP, HTML, JS, PHP e outros com algum caractere especial que foram transformados em �?

Lembrando que por se tratar de um projeto já implementado qualquer arquivo com caractere especial em ISO-8859-1 aberto em UTF-8 fica assim: �. Mudar o texto na mão, arquivo a arquivo era completamente fora de cogitação!

Ainda bem que o Linux quebrou nosso galho, e converteu a codificação dos caracteres especiais de um charset para outro, com o mínimo de esforço! Graças ao programa: iconv

Como utilizar o iconv?
$ iconv -f [charset original] -t [charset desejado] < [arquivo original] > [novo arquivo charset desejado]
$ iconv -f ISO-8859-1 -t UTF-8 < htmlEspecial.html > htmlEspecialNovo.html

O iconv considera o conteúdo do arquivo atual (original) no charset indicado e converte o conteúdo, no caso o(s) caractere(s) especial para o novo charset indicado. Portanto, o arquivo htmlEspecialNovo.html não vai conter o símbolo �, e sim o caractere na formatação correta.

Ficou fácil, mas executar o iconv arquivo a arquivo também seria muito trabalhoso, além de que o objetivo era substituir o arquivo para o novo charset sem criar um novo arquivo.

Pra ficar mais fácil ainda meu brother Gimenez, bolou um script bash para executar processar o iconv para todos os arquivos a partir de uma pasta com filtro na extensão do arquivo.

#!/bin/bash

ICONVBIN='/usr/bin/iconv'

if [ $# -lt 3 ]
then
    echo "$0 from_charset to_charset extesion"
    exit
fi

for f in `find ./ -name "*.$3" -exec file --mime {} \; | grep $1 | cut -f 1 -d :`
do
    if test -f $f
    then
        echo -e "\nConvertendo $f"
        /bin/mv $f $f.old
        RETMV=$?
        if [ $RETMV -gt 0 ]; then
          echo -e "\n Atencao erro no mv"
          exit 1
        fi

        $ICONVBIN -f $1 -t $2 $f.old > $f
        RETICONV=$?
        if [ $RETICONV -gt 0 ]; then
          echo -e "\n Atencao erro no iconv"
          exit 2
        fi

        /bin/rm $f.old
        RETRM=$?
        if [ $RETRM -gt 0 ]; then
          echo -e "\n Atencao erro no rm"
          exit 3
        fi
    else
        echo -e "\nArquivo $f nao convertido";
    fi
done
 

A execução do script convert seria algo do tipo:
> convert iso-8859-1 utf8 java


@edermag
www.yaw.com.br

Thursday, July 21, 2011

Como foi o #TDC2011, um pequeno resumo

Novamente tenho a satisfação em escrever sobre o The Developer's Conference, um evento criado e realizado pela Globalcode. Vou resumir como foi a participação da YaW a 5a edição do The Developer's Conference, o TDC2011. Essa é a nossa 5a participação, nessa última edição colaborando na organização de 2 trilhas!

O evento seguiu a mesma estratégia do ano, organizado em diversas trilhas, com uma diferença: esse ano foram 25 trilhas dividas em 5 dias de evento, rolando muito conteúdo, networking, trabalho e diversão. O mix entre as 25 comunidades foi sensacional, com certeza esse é um dos principais diferenciais da conferência.


Primeiro dia do TDC2011: Coordenação

Trabalhei junto com o Neto Marin na coordenação/organização da trilha Android. Foram 8 palestras nos mais variados níveis, falando sobre arquitetura do Android; boas práticas e dicas de performance no desenvolvimento para Android; como devemos pensar em relação as interface gráfica tanto para smartphones quanto para os tablets; um pouco sobre desenvolvimento de Games em Android e até a integração de APIs para Android com redes sociais. Essa trilha contou com a presença de alguns palestrantes do Google, como o ilustre Tim Bray.



Ainda no primeiro dia do TDC2011 o Rafael Nunes atuou, também, na coordenação/organização na trilha Cloud, junto com o Bruno Souza (JavaMan). Nessa trilha além de uma boa visão sobre as tecnologias para desenvolvimento em Cloud, muito se falou sobre oportunidades de negócios para soluções em Cloud Computing.



Segundo dia do TDC2011: Palestra


Quinta-feira foi um dia mais que especial para nós da comunidade Java, nesse dia rolou o lançamento oficial do Java 7. O lançamento foi mundial, ocorreu simultaneamente em São Francisco,  Londres e em São Paulo durante o TDC2011.

Nesse dia participamos na trilha Java com a palestra do Wellington Pinheiro e o Marcelo Castro (instrutor da Globalcode Alphaville) sobre as novidades do Java 7, com vários exemplos das novidades que tornam o Java uma linguagem mais simples e relativamente menos verbosa. Estive nessa trilha como congressista.




Terceiro dia do TDC2011: Congressista


Na sexta-feira participei da trilha Mobile como congressista, assisti palestras com Roger Brinkley falando um pouco sobre o que a Oracle tem feito com o Java ME (Mobile & Embedded), assisti  palestras com o pessoal da Nokia, e Daniel Galpin do Google apresentando licenciamento e como fazer negócio no Android Marketing.

Tive a oportunidade de conhecer um pouco sobre o desenvolvimento da plataforma mobile da Microsoft, o Windows Phone, gostei do conceito de interface gráficas com metro, mas acho que eles tem muito a fazer pra chegar perto do Android e OS. No final do dia ainda assisti a ótima palestra do Felipe Rodrigues na trilha Ruby, falando sobre "Starting up", com foco empreendedor em fazer acontecer. Depois só diversão, happy hour com os amigos!


Quarto dia do TDC2011: Palestra

No sábado participei da trilha Java EE, que contou com a presença ilustre do Arun Gupta da Oracle. Apresentei a palestra "RichFaces 4: Desenvolvimento Web com JSF2 mais rico", demonstrando alguns componentes da suíte de componentes JSF da JBoss.


Último dia do TDC2011: Diversão

Domingão e eu ja estava bem cansado, nem por isso deixei de ir no dia mais "relax" do TDC2011, era a vez da trilha Arduíno e a trilha Games. Fiquei como congressista no auditório, participando da trilha Stadium, com um resumo das principais palestras do dia.


Pensa que acabou, não...

As manifestações no twitter foram constantes e bem interessantes, hashtag #TDC2011 bombou! A conta TheDevConf mantinha o timeline sempre atualizado com informações das palestras e feedback do evento. Outra característica genial do evento foi a transmissão GRATUITA via web, para quem não pode vir para Sampa. A Globalcode fez uma parceria com o Subway, em todos os dias os participantes podiam comer sem nenhum custo adicional dentro da Faculdade Anhembi Morumbi.

Muitas palestras foram filmadas, logo logo a Globalcode deve disponibilizar o acessos a esses vídeos.


Tem mais?

E agora é a vez do TDC2011 em Floripa que acontece nos dias 20 e 21 de Agosto. As trilhas foram definidas e já é possível submeter propostas de palestras. Nós da YaW estamos super motivados em participar!

Parabéns a Yara e Vinicius, a toda equipe da Globalcode, as empresas parceiras na organização do evento, os palestrantes e congressistas. Veja mais fotos do TDC2011 aqui.

@edermag
www.yaw.com.br

Thursday, July 14, 2011

Emissão de relatórios no Spring Roo e MVC com Jasper Reports

O Spring MVC é uma das tecnologias que mais gostamos e usamos na YaW. Quando uso o termo "gostar" na verdade me refiro a uma tecnologia que atendeu as nossas espectativas do ponto de vista de implementação e mais importante, supriu as necessidades e objetivos do nosso cliente. A nossa experiência com Spring MVC tem sido bem interessante, por isso faz parte de nosso portfólio de soluções.

Nesse post demonstro como intregrar uma aplicação Web desenvolvida pelo Spring MVC com o JasperReports para emissão de relatórios. A integração entre o Spring MVC e JasperReports não tem nenhuma relação com o Spring Roo, mas para facilitar a criação e o desenvolvimento do projeto vou assumir o uso do Spring Roo.

Dependências

Além da biblioteca do JasperReports, dependendo do caso precisamos de outras libs complementares:
  • Spring Support
  • iText (pdf)
  • POI  (xls)


A seguir o trecho do pom.xml (Maven) com configuração dos artefatos. No trecho abaixo também coloco as configurações para o plugin do Maven que automatiza a compilcação dos relatórios jrxml para o formato jasper, utilizado pelo JasperReports:

...
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>${spring.version}</version>
</dependency>
<dependency>
  <groupId>net.sf.jasperreports</groupId>
  <artifactId>jasperreports</artifactId>
  <version>4.0.0</version>
</dependency>
<dependency>
  <groupId>com.lowagie</groupId>
  <artifactId>itext</artifactId>
  <version>2.1.7</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>3.6</version>
  <scope>compile</scope>
  <optional>true</optional>
</dependency>
...
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>jasperreports-maven-plugin</artifactId>
  <configuration>
    <sourceDirectory>src/main/webapp/WEB-INF/reports</sourceDirectory>
    <outputDirectory>src/main/webapp/WEB-INF/reports</outputDirectory>
  </configuration>
  <executions>
    <execution>
      <goals>
        <goal>compile-reports</goal>
      </goals>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>jasperreports</groupId>
      <artifactId>jasperreports</artifactId>
      <version>3.5.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.log4j</groupId>
      <artifactId>com.springsource.org.apache.log4j</artifactId>
      <version>1.2.15</version>
    </dependency>
  </dependencies>
</plugin>
...

Próxima etapa é configurar no xml do MVC (webmvc-config.xml) o viewResolver do Spring que indica o properties com as configurações de cada relatório.

<bean id="viewResolver" 
  class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
  <property name="basename" value="relatorios"/>
</bean>

O arquivo relatorios.properties (na raiz do diretório de classes) armazena qual a classe que estipula o formato de geração do relatório, a url com o caminho do arquivo do relatório.

No exemplo estou usando o arquivo compilado, o .jasper, mas o Spring aceita a extensão jrxml. A propriedade reportKeyData (opcional) indica o apelido para o DataSource com os dados que o relatório depende. Já o valor relatorioPedidos usado como base das 3 chaves é o identificador do relatório, usamos no retorno do método da Controller que processa o relatório.

relatorioPedidos.(class)=
org.springframework.web.servlet.view.jasperreports.JasperReportsMultiFormatView
relatorioPedidos.url=/WEB-INF/reports/pedidos.jasper
relatorioPedidos.reportDataKey=pedidosDS

A classe JasperReportsMultiFormatView é indicada em relatórios que podem ser emitidos em mais de um formato, ou seja, o mesmo relatório gerado em xls e pdf. Outra alternativa seria utilizar JasperReportsPdfView, nesse caso a emissão ocorre só em pdf.

Pra fechar o método da Controller que processa os dados para emissão do relatório:

...
@RequestMapping("/report")
@Controller
public class ReportController {

  @RequestMapping(value ="/pedido/pdf", method = RequestMethod.GET)
  public String processaRelatorioPedidos(
     @RequestParam String de, @RequestParam String ate,
     ModelMap modelMap) 
  {
    JRBeanCollectionDataSource ds =
      new JRBeanCollectionDataSource(Pedido.findPedidosByDataGeracao(de, ate),false);
    modelMap.put("pedidosDS", ds);
    return "relatorioPedidos";
  }

}

A documentação oficial do Spring disponibiliza um capítulo sobre a integração do Spring MVC com o JasperReports.

@edermag
www.yaw.com.br

Tuesday, February 15, 2011

Spring: Como definir BasicDataSource usando arquivo properties

Definir um BasicDataSource usando as configurações do database definidas em arquivo properties é bem simples, basta definir um PropertyPlaceholderConfigurer.

Arquivo database.properties, com as configurações JDBC:
#usando mysql nesse exemplo
db.driver=com.mysql.jdbc.Driver
db.host=localhost
db.name=yawdb
db.username=yaw
db.password=yaw
db.port=3306
db.url=jdbc:mysql://${db.host}:${db.port}/${db.name}


spring-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" ...>
  <bean id="dbProperties"   
   class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="br/com/yaw/spring/database.properties" />
  </bean>

  <bean id="myDataSource"
   class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${db.driver}" />
    <property name="url" value="${db.url}" />
    <property name="username" value="${db.username}" />
    <property name="password" value="${db.password}" />
  </bean>
</beans>

Pronto!

@edermag
www.yaw.com.br

Monday, February 07, 2011

Habilitando conexão Https c/ Java 'ignorando' o certificado

Frequentemente escrevo um código para realizar requisições entre aplicativos, seja para WS/REST ou mesmo um simples HttpClient, usando Https com Java. Como fazer uma requisição SSL sem registrar o certificado na JVM, ou mesmo um 'bypass' em certificado desconhecido?

Aqui deixo um exemplo de como realizar um requisição Https com Java ignorando o certificado. Usando X509TrustManager [mais sobre X509Certificate] e HostnameVerifier de fachada. Na verdade o uso do HostnameVerifier seria pra evitar java.io.IOException: HTTPS hostname wrong: should be ..., já que o nome do certificado não bate com o domínio.

package br.com.yaw.client.ssl.main;

import java.security.cert.X509Certificate;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
//...

public class TestSecureRequest {

  public static void main(String[] args) throws Exception  {
    final X509TrustManager cert = new X509TrustManager() {
      public X509Certificate[] getAcceptedIssuers() {
        return null;
      }
      
      public void checkServerTrusted(X509Certificate[] certs,
        String authType)
      throws java.security.cert.CertificateException {
        return;
      }
      
      public void checkClientTrusted(X509Certificate[] certs,
        String authType)
      throws java.security.cert.CertificateException {
        return;
      }
    };

    //cria socket ssl
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, new TrustManager[] { cert }, null);

    //ativa o socket para a requisicao
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    
    final HostnameVerifier hv = new HostnameVerifier() {
      public boolean verify(String urlHostName, SSLSession session) {
        return true;
      }
    };

    HttpsURLConnection.setDefaultHostnameVerifier(hv);

    // daqui pra frente o codigo que acionar WS/REST, ou um simples HttpClient
    //...
  }
}

Peace of cake.

@edermag
http://www.yaw.com.br/

Thursday, January 20, 2011

Acessar properties a partir de uma classe no mesmo jar

Mais um post da série: "É melhor anotar! Afinal, vai que, você sabe...."

Como acessar um arquivo properties, ou qualquer tipo de arquivo, a partir de uma classe definida dentro do mesmo jar?


A estrutura do arquivo aplicacao.jar seria algo mais ou menos assim:

| META-INF/
| META-INF/conf.properties
| br/
| br/com/
| br/com/yaw/
| br/com/yaw/LeProperties.class

Simples, através do getResourceAsStream do ClassLoader da classe LeProperties:

public class LeProperties {
  static {
    ... 
    try {
      Properties p = new Properties();
      p.load(LeProperties.class.getClassLoader().getResourceAsStream("META-INF/conf.properties"));
    } catch (Exception e) {
      ...
    } 
  }

  ...

}

@edermag
http://www.yaw.com.br/

Tuesday, December 14, 2010

SpringRoo com Segurança e Repositório Usuários em BD Relacional

Apesar do Spring Roo não contar com nenhum add-on no módulo de segurança pra configurar um repositório de usuários em Banco de Dados Relacional, isso é muito simples de resolver.

Basta informar ao Spring que ele deve usar o DaoAuthenticationProvider como provedor de autenticação no Security. No applicationContext-security.xml:

    <authentication-manager alias="authenticationManager">
       <authentication-provider ref="daoAuthenticationProvider"/>
    </authentication-manager>

Depois é só definir o bean do DaoAuthenticationProvider, vincular o bean JdbcDaoImpl como service, com o DataSource e Queries mapeadas. No applicationContext.xml:

  <bean id="daoAuthenticationProvider" class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
    <property name="userDetailsService" ref="jdbcUserDetailsService"/>
  </bean>

  <bean id="jdbcUserDetailsService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">
    <property name="dataSource" ref="?"/>
    <property name="usersByUsernameQuery" value="?"/>
    <property name="authoritiesByUsernameQuery" value="?"/>
  </bean>

Na property dataSource informe respectivo DataSource do projeto, a query para busca de usuários em usersByUsernameQuery e a busca de perfis em authoritiesByUsernameQuery.


Veja também mais sobre Spring Roo no Globalcoders e aqui no blog.

http://twitter.com/edermag
http://www.yaw.com.br/

Monday, December 13, 2010

Aplicando Segurança no Spring Roo através do Spring Security

Como aplicar/habilitar mecanismo de segurança em aplicativo desenvolvido com Spring Roo? Ou melhor, como usar Spring Security com o Spring Roo? Esse post responde essas perguntas.

A instalação e configuração do Spring Security é a mesma de um aplicativo que já usa Spring Web MVC. MAS o pulo do gato é resolver isso através do shell do Spring Roo, com mais um comando esperto.

Comece definindo a estrutura do aplicativo no Spring Roo, depois execute o comando:

_> security setup


Altere o arquivo applicationContext-security.xml indicando o padrão de url que aciona o mecanismo de segurança segurança, por exemplo:
    <intercept-url pattern="/pastaProtegida/**" access="isAuthenticated()" /> 

Pronto! É só empacotar [perform package] e rodar a aplicação [mvn tomcat:run].


Mas... o que o Roo faz por trás das cortinas?

  • Primeiro configura a dependência do Spring Security (pom.xml);
  • Depois cria um arquivo xml com as diretrizes de segurança: applicationContext-security.xml
     <http auto-config="true" use-expressions="true">
        <form-login 
           login-processing-url="/resources/j_spring_security_check" 
           login-page="/login" 
           authentication-failure-url="/login?login_error=t"/>
        <logout logout-url="/resources/j_spring_security_logout"/>
       
        <!-- primeiro so admin, segundo qualquer autenticado, terceiro e quarto nao precisa de login -->
        <intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')"/>
        <intercept-url pattern="/restrito/**" access="isAuthenticated()" />
        <intercept-url pattern="/free/**" access="permitAll" />
        <intercept-url pattern="/**" access="permitAll" />
    </http>

    <!-- define o mecanismo de seguranca simples (estatico) com os usuarios: admin/admin e user/user -->
    <authentication-manager alias="authenticationManager">
        <authentication-provider>
            <password-encoder hash="sha-256"/>
            <user-service>
                <user name="admin" password="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" authorities="ROLE_ADMIN"/>
            <user name="user" password="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" authorities="ROLE_USER"/>
        </user-service>
        </authentication-provider>
    </authentication-manager>

  • Cria uma página com formulário de login:
Trecho de /WEB-INF/views/login.jspx
    ...
    <form action="/static/resources/j_spring_security_check" method="POST">
      <div>
        <label for="j_username">
          <spring:message code="security_login_form_name" />
        </label>
        <input id="j_username" type='text' name='j_username' />
    ...
      </div>
      <br />
      <div>
        <label for="j_password">
          <spring:message code="security_login_form_password" />
        </label>
        <input id="j_password" type='password' name='j_password' />
        ...
      </div>
      ...
    </form>
    ...

  • Configura a página de login no arquivo view.xml (usado pelo Tiles):
     <definition extends="public" name="login">
        <put-attribute name="body" value="/WEB-INF/views/login.jspx"/>
    </definition>  

  • Declara o filtro do Spring Security (springSecurityFilterChain) no web.xml:
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
         org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>

  • Configura a página de login no webmvc-config.xml:
    <mvc:view-controller path="/login"/>


Veja mais sobre Spring Security.
Veja também mais sobre Spring Roo no Globalcoders e aqui no blog.

Spring Roo: Mais agilidade com qualidade!

http://twitter.com/edermag
http://www.yaw.com.br/

Monday, September 20, 2010

Configurar DataSource [Hibernate + Oracle + Tomcat 6] aplicação c/ Spring Roo

Criar e configurar um aplicativo c/ Spring Roo para usar JPA c/ Hibernate no Oracle é muito simples. Pelo terminal no "prompt" do Roo, inicialmente, são 5 comandos:
$ mkdir projetoteste
$ cd projetoteste
$ roo    //assumindo que o roo ja estava instalado
$ project --toplevelPackage br.com.yaw
$ persistence setup --provider HIBERNATE --database ORACLE --username eder --password 123

Esse último comando vai gerar um warning com a informação de que não foi possível encontrar o jar do Oracle no repositório Maven, a instalação do driver será manual.

Na realidade o Roo define a conexão com o banco de dados dentro do aplicativo, veja os arquivos META-INF/spring/database.properties e META-INF/spring/applicationContext.xml.

Simples assim! Agora seria usar outros comandos para criar as entidades, controladores e as telas, executando por exemplo no Tomcat 6. Veja a demo do Roo.

Mas como utilizar um DataSource definido no Tomcat? Nesse wiki algumas dicas de como configurar o DataSource no Tomcat.

A forma mais dificil de configurar o DataSource no projeto é ir ao arquivo META-INF/spring/applicationContext.xml e substituir  a definição do bean dataSource [BasicDataSource] por:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="java:comp/env/jdbc/MeuOracleDS"/>
</bean>

Ou via "prompt" do Roo no comando persistence setup:
$ persistence setup --provider HIBERNATE --database ORACLE
   --username eder --password 123 --jndiDataSource jdbc/MeuOracleDS

http://twitter.com/edermag
http://www.yaw.com.br/

Tuesday, September 14, 2010

Consumir WebService com autenticação usando o wsimport

O wsimport é uma ferramenta bem simples, aquelas de linha de comando, disponibilizada no jdk. Sua função é criar a infra-estrutura necessária para "consumir" Web Services a partir do wsdl, sem muita dor de cabeça. Na realidade o wsimport gera o código baseado no JAX-WS resolvendo a burocracia para acionar o Web Service com o mínimo de esforço.

Um exemplo de como usar o wsimport:
wsimport -p br.com.yaw.ws -s src -d bin http://url.servico/xpto?wsdl

O parametro -p indica o pacote para a geração das classes java, -s o diretório dos fontes e -d conteúdo output (binário por exemplo). Por fim, o mais importante, a caminho do wsdl.

O código gerado não é complexo e depende só do jdk, sem a necessidade de outra API ou de algum container JEE. Simples assim, é só criar uma classe c/ main e com código acionando o webservice...

De forma geral o wsimport gera uma classe Service que representa o webservice no cliente, factory do Proxy que faz a comunicação c/ o EndPoint.
Um "pseudo-código" para consumir um catalogo de produtos seria:

CatalogoProdutosService service = new CatalogoProdutosService();
CatalogoProdutos proxy = service.getCatalogoProdutosPort();
List<Produtoto> produtos = proxy.getProdutos();

E se o EndPoint exige autenticação? Muito simples, o objeto Proxy (CatalogoProdutos é uma interface) também implementa BindingProvider que provê acesso ao protocolo e contexto vinculado. Através dela configuro o usuário e senha, o código ficaria:

CatalogoProdutosService service = new CatalogoProdutosService();
CatalogoProdutos proxy = service.getCatalogoProdutosPort();
//dados para o login 
((BindingProvider)proxy).getRequestContext()
     .put(BindingProvider.USERNAME_PROPERTY, "jose");
((BindingProvider)proxy).getRequestContext()
     .put(BindingProvider.PASSWORD_PROPERTY, "123");
List<Produtoto> produtos = proxy.getProdutos();

Para usar Web Service com Http(s) primeiro é necessário importar o certificado e alterar a url do wsdl.


http://twitter.com/edermag
http://www.yaw.com.br

Thursday, September 02, 2010

A participação da YaW no TDC2010

Nos dias 20, 21 e 22 de Agosto aconteceu a 4a Edição do The Developers Conference, o TDC2010, evento de desenvolvedores para desenvolvedores, organizado pela Globalcode. Nesse ano a Globalcode inovou trazendo variedade de assuntos com 13 trilhas, em parceria com outras Empresas/Grupos/Profissionais Independentes, aumentando o "menu" tornando o evento completo a um valor simbólico. E de quebra com transmissão online, favorecendo principalmente o pessoal fora de SP.

O evento foi incrível, uma mistura fantástica de assuntos e comunidades em uma vibe bem interessante com muita troca de informação e networking, além da chance de rever vários amigos, quem foi sabe o que estou falando. Pra quem não foi pode ter uma idéia do que rolou nos diversos posts resumindo o que rolou no TDC2010.

Um detalhe que tornou nossa (eu e o Rafael Nunes) participação ainda mais especial é que esse foi a nossa primeira participação como YaW. Apoiamos e participamos de várias palestras em diferentes trilhas como ouvintes e palestrantes trocando um pouco de nossa experiencia com a galera. Outro ponto foi que no TDC2010 apresentamos mais 10 demonstrações, afinal evento de desenvolvedores nada melhor que código.

Na sexta logo após a abertura do evento, apresentei a primeira palestra da Trilha de JavaEE falando sobre a evolução do JSF, melhorias e o amadurecimento da versão 2.0 com a possibilidade de adotar suítes de componentes customizadas. Fiz demonstrações com as suites PrimeFaces, RichFaces e ICEFaces todas incorporadas ao ScrumToys. Na sequência o Rafael apresentou como desenvolver com JSF no Google App Engine.


A tarde, na Trilha de Spring, apresentei palestra falando sobre opções de desenvolvimento RIA com o Spring Framework junto com o Rafael. Comentei sobre o GWT, pontos fortes e fracos, e de como ele poderia ser integrado ao Spring em mais de uma opção de arquitetura com uma demonstração usando GwtRPCController. O Rafael demonstrou como é possível integrar Adobe Flex com Spring MVC.


Depois disso, na Trilha Mobile, assisti a palestra do amigo Fernando Ribeiro contando um pouco dos desafios e as oportunidades desenvolvimento BlackBerry para o mercado Corporativo com muito bom humor e riqueza de conteúdo, característico do Fribeiro. Ainda na trilha Mobile, no fim do dia, rolou um painel com representantes das principais plataformas mobile e o ponto de vista de cada um em relação a oportunidades e inovação.

Já no sábado pela manhã, assisti algumas palestras na Trilha de NOSQL, como leigo no assunto estou naquela fase de descoberta e novidades. Valeu muito para adquirir um pouco mais de conhecimento além de pegar várias dicas e referências para estudo. Depois do almoço, na Trilha Java, apresentei uma palestra sobre JavaFX partindo de um ponto de vista divertido, aonde destrinchei um jogo de Quebra-Cabeças aonde as peças são montadas dinâmicamente a partir de uma imagem. Não poderia faltar algo mais "corporativo", demonstrei um CRUD puro com JavaFX, um outro exemplo de CRUD usando JPA reaproveitando uma estrutura em Java e por fim um exemplo de integração com serviço na Web no Google App Engine acessado via REST.


Depois assisti uma ótima palestra sobre linguagens dinâmicas na JVM, onde fui apresentado ao Quercus uma alternativa de integrar PHP com Java, apresentado pelo Jefferson Prestes. Pra fechar o dia uma passada rápida na Trilha de Ruby, e mais bate-papo com amigos que encontrei no evento.

Já no Domingo não estive presente fisicamente acompanhei o TDC2010 pelo twitter. Aliás a hash #TDC2010 foi um sucesso no twitter, ficamos até no TrendsBR, um ótimo foto on-line do evento outra oportunidade para quem não foi acompanhar o que estava rolando!

O TDC2010 foi único, gostei a definição/analogia que o Jorge Diz fez aqui. Deixou saudades!


http://www.yaw.com.br
http://twitter.com/edermag

Friday, June 18, 2010

i18n de Portlets em JSF e JSP com JSTL

Existem várias formas p/ internacionalizar labels no desenvolvimento de Portlets, no post comento sobre 2 alternativas: básico com JSP e JSTL, outra opção é JavaServer Faces.

No caso de JSP e JSTL é só usar as tags fmt:setBundle e fmt:message da taglib de formatação, da mesma forma que uma aplicação web comum (sem portlets).

E o JavaServer Faces?

O mecanismo nativo de i18n do JSF funciona para portlets, é só definir os idiomas suportados no faces-config.xml, usar a tag f:loadBundle e por fim outputText e/ou outputFormat indicando o bundle e chave da label.


Em ambas alternativas, JSF ou JSP/JSTL, existe uma limitação: o title do portlet, que normalmente é definido no descritor portlet.xml, não se encaixa nos modelos de i18n descritos.

A solução é bem simples, no caso do JSTL a alternativa que encontrei foi apelar para a própria API de Portlets. No portlet.xml mapeio como title a chave que corresponde ao título no arquivo de i18n, já no código java do portlet sobreescrevo o método getTitle (herança de GenericPortlet) pegando a informação do xml e na raça acessando o bundle indicando a chave, o código seria próximo a esse:

portlet.xml
<portlet-app ... >  
  <portlet>
      ...
    <portlet-info>
      <title>meu.portlet.titulo</title>
    </portlet-info>
  </portlet>
  ...
</portlet-app>

messages_pt_BR.properties:
...
meu.portlet.titulo=Testando i18n em Portlet c/ JSTL
...

trecho do código java do Portlet:
protected String getTitle(RenderRequest request) {
    String key = super.getTitle(request);
    try {
      ResourceBundle bundle = ResourceBundle.getBundle("messages",
          request.getLocale(),getClass().getClassLoader());
      return bundle.getString(key);
    } catch (Exception ex) {
      //log4j
      log.error("Valor ["+key+"] (i18n) p/ titulo nao encontrado", ex);
      return key;
    }
  }


A solução no JSF é mais simples! Coloque a chave javax.portlet.title com o respectivo valor dentro do arquivo de i18n do aplicativo. Mas existe um macete, no portlet.xml também é preciso indicar o arquivo i18n e os idiomas suportados. A seguir um exemplo de como isso é feito.

messages_pt_BR.properties:
...
javax.portlet.title=Testando i18n em Portlet c/ JSF
...

portlet.xml
<portlet-app ... >  
  <portlet>
    ...
    <supported-locale>pt_BR</supported-locale>
    <supported-locale>en_US</supported-locale>
    <resource-bundle>messages</resource-bundle>
  </portlet>
  ...
</portlet-app>

Importante: Sobre o que foi descrito em relação a JSF, o portlet roda no JBoss Portal com JBoss Portlet Bridge.


http://twitter.com/edermag
http://www.yaw.com.br

Wednesday, May 05, 2010

Aprendendo JSF 2.0 com ScrumToys na JavaMagazine - edição 78

Já esta nas bancas a Java Magazine edição numero 78 com artigo (da capa) JSF 2.0: Aprendendo JSF 2.0 com ScrumToys escrito por mim e pelo Vinicius Nunes, instrutor da Globalcode de Floripa.

A proposta do artigo é comentar sobre as mudanças do JSF 2, mas além disso uma preocupação nossa foi colocar conteúdo para quem ainda não teve contato com a tecnologia, seja profissional experinte ou iniciante. É que o artigo ficou um pouquinho grande (rs).

Para mostrar a implementação dos recursos do JSF utilizamos os fontes do ScrumToys, criado justamente para o aprendizado na tecnologia.

No blog da Globalcode fiz uma experiencia, usei o PrimeFaces com JSF 2. Na realidade configurei o PrimeFaces no ScrumToys e utilizei o datatable, fácil, simples e funcionou perfeitamente!



http://twitter.com/edermag
http://www.yaw.com.br

Sunday, April 25, 2010

Configurando o Hibernate 3.5 com Maven

No fim do mês de Março foi lançado o Hibernate 3.5 com novas funcionalidades e a partir dessa versão compatível a JPA2, agora um concorrente ao EclipseLink a implementação de referência. No ScrumToys - projeto da Globalcode exemplo no Netbeans 6.8 - utilizamos o EclipseLink como provider JPA.


O Maven simplifica bastante a vida do desenvolvedor java, isso é indiscutível afinal ficar controlando dependências na mão ficou fora de moda a um tempo. Mesmo quem esta começando usar Java pode tornar essa experiencia mais produtiva, mão na massa sem se preocupar com a burocracia dos jars.

A documentação do Hibernate mostra a configuração exemplo de projeto usando o maven, mas esse mapeamento não funciona por não definir a tag version na dependency, por isso montei um exemplo de pom.xml para utilizar o Hibernate 3.5:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>br.com.globalcode</groupId>
  <artifactId>hibernate-exemplo</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>hibernate-exemplo</name>
  <url>http://maven.apache.org</url>

  <repositories>
    <repository>
        <url>http://repository.jboss.com/maven2/</url>
        <id>hibernate-support</id>
        <layout>default</layout>
        <name>Repository for library Library[hibernate-support]</name>
    </repository>
  </repositories>

  <dependencies>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.5.0-Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.5.0-Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.5.0-Final</version>
    </dependency>

    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.8.0.GA</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.10</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.0.5</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
  </dependencies>
</project>

Agora é só mandar bala com recursos do hibernate.

http://twitter.com/edermag
http://www.yaw.com.br

Sunday, January 24, 2010

2009 passou voando! Mas relembrando...

O começo de 2009 foi um tanto quanto apreensivo, a expectativa sobre os impactos da crise econômica por aqui eram preocupantes. Ainda bem que as previsões mais pessimistas ficaram pra trás e de uma forma geral conseguimos passar por essa turbulência.

Pra mim 2009 começou com mudança de emprego, quem me conhece sabe que isso é um pouco difícil mim. Novos desafios, ambiente mais complexo, tecnologias diferentes, uma equipe de alto nível técnico entre outros, foram os motivadores para encarar essa nova jornada na Superbid.

Mão na massa, trabalhei com as seguintes tecnologias em diversos projetos:
  • Spring MVC
  • GWT
  • JBoss Portal
  • JBoss Bridge
  • JSF 1.2 c/ RichFaces
  • Python - Genshi
  • Alguns legados em PHP e PL-SQL.

Na Globalcode 2009 foi um ano incrível, repleto de realizações. Trabalhei c/ muitas turmas, conheci pessoas de diferentes perfis e espectativas em relação tecnologia Java. Foram turmas de Academia Java, Academia Web Developer, hands-on e vários minicursos.

A Globalcode promoveu vários eventos para comunidade Java, estive presente em todos em alguns apresentei algum tema:
  • Profissão Java: primeiro evento sobre carreira voltado ao profissional que trabalha ou quer trabalhar com Java, com palestrantes apresentando conteúdo de ponta (ex.: TV Digital) em alto nível para comunidade. Evento gratuito!
  • Open TDC: outro evento gratuito, que aconteceu em Sampa e Floripa! O evento contou com importantes figuras da comunidade de desenvolvimento, com palestras de diversos temas e qualidade de ponta. Apresentei junto com o Rafael Nunes e o Mauricio Leal uma Painel sobre opções RIA p/ Web: JavaFX, Adobe Flex e GWT. O Vinicius apresentou os projetos relacionados a Robótica da Globalcode, além do novo treinamento: Academia do Programador.
  • TDC : o maior e principal evento Java do país, trouxe em sua terceira edição palestrantes internacionais de peso da Sun, Oracle, Google e JBoss. Apresentei uma Lightning Talk sobre as tecnologias open da Google para desenvolvimento Java: GWT e Google Guice. Aqui um resumo do evento que foi fantástico! Em 2009 além de São Paulo e Floripa, o TDC teve sua versão Guanabara, a estreia no Rio de Janeiro.

A Globalcode retomou o Casual Class, que promove um bate-papo descontraído sobre tecnologia c/ Pizza + Cerveja + Vinho. Uma oportunidade de aproximar e fomentar a comunidade! Vários assuntos em pauta, como JavaOne 2009, Robótica, Java EE 6 e Cloud Computing.

Foi no Casual Class de Java EE 6 que fui apresentado ao Scrum Toys, projeto open source da Globalcode demo de JSF2 dentro Netbeans 6.8. Conversei com a Yara sobre algumas coisas interessantes que poderiam ser feitas no projeto como o suporte a bookmarkable, c/ seu apoio abracei a causa colaborando com algumas features. Foi uma experiência enriquecedora, mais detalhes sobre minha participação aqui.

Bastante coisa, mas ainda tem mais. Em 2009 tive a oportunidade de criar e apresentar 2 minicursos:
  • Introdução ao Google Web Toolkit: conteúdo necessário para quem quer saber o que é ou iniciar o desenvolvimento com essa ótima alternativa para Rich Internet Application criado pelo Google.
  • Introdução ao Google GO: apresentando características da nova linguagem do Google, explorando alguns recursos interessantes. O GO seria uma mistura de C++ e Python.

Ainda mais próximo da comunidade de desenvolvimento, foi lançado o Globalcoders, o blog do time Globalcode. Um espaço democrático para Informação + Colaboração + Discussão. Posts relacionados a tecnologia, num formato objetivo, claro e prático em uma linguagem de fácil compreensão. Bloguei sobre Facelets com um post para uso de templates e outro para criação de componentes. Outro post foi um pouco de como funciona o compilador (mágico) do GWT.

Uma dica bem legal é a lista do time Globalcode no twitter. Ótima oportunidade pra ficar pro dentro das novidades que estão rolando e no que estamos trabalhando.

A Globalcode disponibilizou um vídeo bem legal com um resumo, ou melhor uma retrospectiva 2009 e de quão intenso foi esse ano.

E pra encerrar iniciamos a realização de um projeto que há tempos vinhamos planejando, a YaW! Unidade da Globalcode no Grande ABC. Mas isso eu vou descrever em outro post.

Expectativas para 2010 são as melhores, muita determinação e vontade pra enfrentar mais desafios! Trabalho e tesão não faltam.


http://twitter.com/edermag
http://www.yaw.com.br

Sunday, December 06, 2009

Como Instalar Google GO no Ubuntu e Mac Os

Vou descrever quais são as etapas necessarias para instalação do Google GO, a nova linguagem de programação do Google, no Ubuntu 9.10 e no Mac OS 10.5 (Leopard).

Pré-requisitos para instalar e usar o GO:
  • Mercurial: ferramenta para controle de fontes (repositório) distribuído.
  • GCC: compilador C.

O Python é pré-requisito para o Mercurial.

Uma vez que essas ferramentas tenham sido instaladas, a proxima etapa seria configurar algumas variáveis de ambiente que o GO usa:
  • GOROOT: diretório raiz da instalação do GO.
  • GOBIN: diretório com conteúdo binário.
  • GOOS: sistema operacional.
  • GOARCH: indica qual arquitetura para compilação.
A próxima etapa seria baixar e compilar os fontes do GO, depois é começar a programar.


No Ubuntu 

Os comandos para instalação do Mercurial e GCC são:

$ sudo apt-get install mercurial
$ sudo apt-get install bison gcc libc6-dev ed make

Na sequencia é preciso criar a estrutura de diretórios e configurar as variáveis de ambiente (no arquivo ~/.bashrc):
$ mkdir $HOME/go
$ mkdir $HOME/go/bin
$ mkdir $HOME/go/src

export GOROOT=$HOME/go/src
export GOBIN=$HOME/go/bin
export GOOS=linux
export GOARCH=386
export PATH=$PATH:$HOME/go/bin

Para baixar os fontes do GO, use o seguinte comando:

$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT

Para compilar os fontes do GO (a partir do dirétorio src):
$ cd $GOROOT/src
$ ./all.bash 

Ambiente configurado no Ubuntu!


No Mac OS

Baixe o Mercurial aqui, e instale o dmg.
Caso ainda não tenha o xCode, baixe aqui para resolver o GCC.

A seguir a criação das pastas e configuração das variáveis de ambiente no arquivo .bash_profile:
$ mkdir $HOME/go
$ mkdir $HOME/go/bin
$ mkdir $HOME/go/src

export GOROOT=$HOME/go/src
export GOBIN=$HOME/go/bin
export GOOS=darwin
export GOARCH=386
export PATH=$PATH:$HOME/go/bin

Para baixar os fontes do GO, use o seguinte comando:

$ hg clone -r release https://go.googlecode.com/hg/ $GOROOT

Para compilar os fontes do GO (a partir do dirétorio src):
$ cd $GOROOT/src
$ ./all.bash

Pronto! Agora é só partir pro Hello World, veja um exemplo.

Saturday, November 21, 2009

The Developers Conference 2009 simplesmente incrivel!

Nos dias 06 e 07 de Novembro em São Paulo aconteceu The Developers Conference 2009, terceira edição do maior e melhor evento Java do Brasil promovido e organizado pela Globalcode. As 2 edições anteriores foram excelentes, mas esse ano o evento foi fantástico, com uma grade e palestrantes de altíssimo nível, como por exemplo Rod Johnson o pai/guru do Spring.

O TDC 09 foi realizado também na Guanabara prestigiando o galera do Rio de Janeiro (UFF), depois de passar por Florianópolis (V.Office).

Outra novidade foram os Lightning Talks, apresentações rápidas (+ ou - 15 minutos) com demonstrações práticas que aconteceram no decorrer das palestras. Tive a oportunidade de apresentar sobre GWT e Guice, bem introdutório mas focando no quanto o Google aposta na comunidade Java.

Falando um pouco mais sobre os palestrantes, além de Rod Johnson também tivemos a oportunidade de ver Mike Keith (Oracle) co-líder da especificação de JPA, Ed Burns (Sun) líder da especificação de JSF 2, Alejandro Guizer engenheiro de Software da Red Hat e Francisco da Google substituindo Chris Schalk, e outras personalidades da comunidade nacional. Foi uma oportunidade ímpar para fazer networking.

As palestras superaram as expectativas! No primeiro dia, Rod Johnson em seu Keynote comentou sobre o Futuro do Java EE como plataforma e as linguagens mais alto nível operando por cima, outra tendência é o Java como plataforma no universo Cloud Computing. Na sequência Ed Burns, Mike e Rod comentaram um pouco sobre o início de suas vidas profissionais, depois passaram valiosas dicas para quem esta começando a traçar carreira.

Na volta do almoço Mike Keith apresentou detalhes sobre o Java EE 6, a plataforma cada vez mais robusta, madura e simples para o desenvolvimento dia-a-dia. Ed Burns apresentou a padronização da nova forma de criar telas com JSF2 abusando de reutilização e composição, Composite Components. Na sequência Yara e Spock apresentaram o projeto demonstração do NetBeans e GlassFish mantido pela Globalcode, o Scrum Toys, uma case mostrando a força da comunidade brasileira!

Já no sábado fiquei muito empolgado com a palestra do Rod sobre o Spring 3.0, a evolução da consagrada suite de tecnologias para desenvolvimento, o que mais me chamou a atenção foi Spring Roo como uma alternativa para Rails. Depois do almoço Mike apresentou detalhes da especificação JPA 2.0, mostrou os novos recursos dessa JSR.

Francisco (Google) e Rafael apresentaram sobre a plataforma Cloud do Google o App Engine. Francisco comentando sobre a nova possibilidade de desenvolvimento de software com Cloud e um pouco da estratégia do Google nesse segmento. Rafael apresentou exemplo de como rodar JSF2 no Cloud, algo novo até então, outro ponto positivo pra comunidade brasileira!

Fechando o evento tivemos o Debate Cloud Computing na visão dos Players: Google (Francisco) + Oracle (Mike) + Sun (Ed) + Spring Source (Rod) + Yahoo (Bene) + JBoss Red Hat (Alejandro) mediado pelo Júlio (Globalcode). Esse bate-papo bem descontraído teve como objetivo mostrar do ponto de vista de cada um qual é a expectativa sobre o Cloud Computing, o que isso pode trazer como solução e/ou serviços para nós desenvolvedores.

Gostei muitos dos Lightning Talks, principalmente "Boas práticas com Spring" apresentado pelo Jun, "WebBeans/Context Dependency Injection na prática com Weld" - novo Seam - da JBoss e "Melhorando performance de JPA com Spring Web Flow" do Spock com dicas preciosas para o desenvolvimento com JSF.

Durante o evento o Vinicius Senger despertou o lado Prof. Pardal da galera, apresentando vários Robôs usando o Arduíno, mostrando um pouco do que a Globalcode pretende realizar: como pode ser simples e divertido usar robótica, fique por dentro no blog Elétron Livre!

O evento foi incrível, além de muito conteúdo, networking e diversão tive a oportunidade de rever velhos amigos e conhecer pessoalmente grandes figuras como o Bene (Benedicto Franco) da Yahoo. Conheci o pessoal do Rio (Universidade Federal Fluminense) e uma galera de Uberlândia. No ano que vem vou estar presente nas versões do TDC!

  • Vejas Fotos do Evento aqui
  • Site do Evento

Saturday, October 17, 2009

Client Subversion com Python

Existem vários clients e plugins disponíveis para acessar e manipular o respositório do subversion. Uma categoria de clients chamada Subversion Language Bindings permite o acesso ao svn via API, com suporte a linguagens como Java, Python, C++, veja mais detalhes aqui.

Abaixo um exemplo de código em Python usando o extensão pysvn que faz uso desse mecanismo e monta um relatório da quantidade de recursos manipulados agrupados por Desenvolvedor/Autor e por Data.

import sys, pysvn, re
from datetime import date
import datetime

def repos(work_path):
    "Get the svn repository url"
    info = pysvn.Client().info(work_path)

    if info.repos:
        return info.repos

    # special case - checked out the trunk
    if info.url.endswith("/trunk"):
        return re.sub(r"/trunk$", "", info.url)

    # default to the current dir's url
    return info.url

def arg(index):
    # find argument, if doesnt exists return None
    args = sys.argv[1:]
    try:
        return args[index]
    except IndexError:
        return None

def dayBeforeToday(d):
    try:
        diff = datetime.timedelta(days=int(d))
        return date.today() - diff
    except:
        return None

def query(repos, author, days):
    print "get in: "+repos

    logs = []
    for l in pysvn.Client().log(repos, discover_changed_paths=True):
        logs.append({"author": l["author"], "date": date.fromtimestamp(l["date"]), "changed_count": len(l["changed_paths"])})

    if not (author in [None, "-", "." ]):
        logs = list(filter_logs(logs, lambda k, v: k == "author" and v == author))

    dt = dayBeforeToday(days)
    if not (dt in [None, "-", ".",  "0"]):
        logs = list(filter_logs(logs, lambda k, v: k == "date" and v >= dt))

    return logs

def filter_logs(logs, where=lambda k, v: True):
    #apply filter in log results
    for l in logs:
        for k, v in l.items():
            if where(k, v):
                yield l

def format2cols(items):
    if len(items) == 0:
        return "\n"
    max_width = max(len(str(x)) for (x,y) in items)
    template = "%%%ds %%s" % max_width
    return "\n".join(template % (x, y) for (x, y) in items)

def sort_uniq_c(seq):
    "Duplicate unix's 'sort | uniq -c | sort -nr'"
    count_first = ((y,x) for (x,y) in histogram(seq, ["author", "date"]).items())
    return format2cols(sorted(count_first, reverse=True))

def histogram(logs, groupBy):
    result = {}
    for l in logs:
        k = ""
        for s in groupBy:
            k += str(l[s])+" "
        result.setdefault(k,0)
        result[k] += l["changed_count"]

    return result

if __name__ == "__main__":
    _author = arg(1)
    _days = arg(2)
    print sort_uniq_c(query(repos(work_path = "."), _author, _days))

Na realidade usei esse script python como base, nesse script além dos filtros por Autor e/ou Dias a contagem é realizada por resources no(s) commit, a saída é agrupada por autor e data de commit.