Mostrando postagens com marcador NetBeans. Mostrar todas as postagens
Mostrando postagens com marcador NetBeans. Mostrar todas as postagens

Yahoo OpenHack 2010 - YQL Console for Netbeans

terça-feira, 11 de outubro de 2011

Depois de muito tempo sem blogar, resolvi atualizar um pouco as coisas aqui.
O ano passado, teve o Yahoo Open Hack, onde mais uma vez, tive a oportunidade de participar. Para o evento, meu hack foi o YQL! Console for NetBeans and Meme Robot.
Apesar de não ter levado o prêmio, gostei muito do trabalho realizado, pois foi um verdadeiro hack, pois todas queries executadas pelo YQL Console no Netbeans, foram utilizando uma página do Yahoo, que descobri utilizando Wireshark.
O plugin chamou a atenção de Geertjan wielenga, que me convidou a escrever um artigo para a DZone.

Segue abaixo o texto, para acessar o artigo original, clique aqui, que foi copiado do DZONE,


Recently, Yahoo provided a nice API called YQL, which stands for "Yahoo! Query Language". It's an API that exposes an SQL-like syntax (from SHOW and DESC to INSERT and DELETE commands) that is very familiar to developers. It lets you make great things: with this language, developers can use a single language to query, filter, and join data across web services. You can even create your own open data table (see http://datatables.org) that can make your data YQL-accessible.

To test your queries and data tables, Yahoo created the YQL Console to help developers test their own queries and funcionalities, it's quite useful for YQL Developers.

This year (in March), Yahoo sponsored a contest called 'Yahoo Hack Day', an open contest for developers to create hacks using these Yahoo APIs. My contribution to this contest was the plugin "YQL Console for NetBeans", which is the YQL Console embedded into NetBeans IDE:


To make it work, I used wireshark to sniff the network to see what was happening. In that way, I was able to hack some Yahoo PHP pages that let me "clone" the console inside NetBeans IDE. I'm using some APIs like Bean Bindings and Swing Application Framework for the UI, Jakarta Commons HttpClient for accessing resources via HTTP, as well as RESTClient to format XML and JSon code, and a couple of NetBeans APIs, such as the Window System, Utilities, UI Utilities and Settings.

Bem, e isso ai, para download do plugin, conforme citado acima, acesse o link

http://plugins.netbeans.org/plugin/27552/yql-console-for-netbeans

Diversão Garantida!!!

Consumindo e Testando Clientes REST

terça-feira, 29 de dezembro de 2009



A especificação JAX-RS é uma ótima opção para criar web services REST e fornece meios de desenvolver componentes server-side, mas não descreve como os desenvolvedores devem desenvolver seus componentes client-side em Java, e essa já é uma das promessas para a próxima release do JAX-RS.

Pelo fato de nossos serviços RESTful serem URIs e a forma de acesso a estes serviços serem os próprios métodos HTTP, podemos trabalhar diretamente com requisições HTTP ou utilizar bibliotecas para facilitar este trabalho. Felizmente é relativamente fácil trabalhar diretamente com requests e responses HTTP, e as linguagens mais populares de programação possuem métodos/bibliotecas HTTP, como por exemplo, urllib2 e httplib em Python, libcurl em PHP, HTTPWebRequest em C#, open-uri em Ruby, e o pacote java.net.* e o projeto HttpClient da Apache para Java, entre outros. Mas para qualquer linguagem que seja feito a requisição ao serviço RESTful, temos que passar por alguns passos, conforme segue:
  1. Montar os dados que irão trafegar pelo requisição HTTP, como a URI, HTTP header (se houver), e o método HTTP desejado.
  2. Formatar estes dados como uma requisição HTTP, e enviá-lo para um servidor HTTP apropriado.
  3. Efetuar o parsing dos dados retornados (XML, JSON, etc..) para as estruturas de dados que o seu programa precisa.

Para facilitar a pesquisa, montamos um pequeno guia, para os desenvolvedores e estudiosos que querem aprender um pouco mais sobre REST, onde iremos apresentar algumas bibliotecas para teste e consumo de serviços RESTful.

cURL

Se o intuito for apenas testar os serviços REST desenvolvidos e validar o retorno, o mais simples é utilizar ferramentas existentes na web como é o caso da biblioteca cURL, que é uma ferramenta de transferência de arquivos entre cliente-servidor desenvolvida em C, e suporta protocolos como HTTP, HTTPS, FTP, FTPS, etc.
 A listagem 1 apresenta alguns exemplos de como fazer uma requisição GET e POST com uso da biblioteca cURL, como podemos ver, ela não possui uma interface gráfica, sendo uma ferramenta de linha de comando.
 Fazendo uma requisição (GET), passando como parâmetro de headerv tipo de conteúdo json, (-H "Accept:application/json")


// Fazendo uma requisição POST, passando como  query parameter name = JumboComLtda
$ curl -d name=JumboComLtda http://localhost:8080/Contatos/resources/customers/2/cliente/

// Excluindo um registro com DELETE, pelo parâmetro –X
$ curl -v –X DELETE http://localhost:8080/Contatos/resources/customers/99/


Registro excluído com sucesso !


Listagem 1: Uso da biblioteca cURL.
 

Referências:

RESTClient

 RESTClient é uma aplicação Java própria para auxiliar nos testes de serviços RESTful, complementar a isto, ela pode ser utilizada para testar Web Services POX (Plain Old XML) sobre HTTP. Para utilizar, basta efetuar o download do arquivo jar (com dependências) da ultima versão, no momento que escrevo este artigo, a versão mais recente é a versão 2.3, e vem com duas opções.

A versão GUI, é uma aplicação Swing com diversas opções, e bem conhecida de quem trabalha com o RESTClient desde suas primeiras versões, e a outra versão "cli" é para execução batch de arquivos .rcq. Para começar utilizar a versão em Swing, basta digitar o seguinte comando (A aplicação requer Java 6 para rodar):
$java -jar restclient-ui-2.3-jar-with-dependencies.jar
 
Após executar a aplicação, deverá ser apresentado a tela conforme ilustra a Figura 1.


Figura 01 - Interface Swing do RESTClient.

Pela aparência da interface gráfica, podemos deduzir facilmente o modo de utiliza-lá, basta digitar no campo URL o caminho desejado, selecionar algum método HTTP na aba Method, e executar a consulta clicando no botão [>>]. O resultado será apresentando no bloco HTTP Response.


Funcionalidades

 Com RESTClient, podemos fazer qualquer tipo de requisição HTTP (GET, PUT, POST, DELETE, HEAD, OPTIONS, TRACE), ainda existe o suporte a SSL e a possibilidade de adicionar parâmetros de Header adicionais.
É possível salvar as requests, responses, e o Response Body (atráves do menu File > Save Request, ou Save Response, Save Response Body), o que é útil para testes de regressão, que podemos utiliza-los posteriormente na versão de linha de comando.
RESTClient ainda vem com o Conteiner Jetty embutido, que possui um Servlet que imprime os detalhes das requisições submetidas a ele. Para iniciar o servidor basta acessar o menu Tools > Opção Start Trace Server (subirá na porta 10101).

E por fim, uma das funcionalidades mais interessantes é o seu suporte integrado para testes, que podem inclusive ser escritos em Groovy, o suporte a testes é baseado no JUnit 3.x e os tests são atachados a cada requisição. Para iniciar os testes, na aba "Test Script", clique o no botão Insert Template, RESTClient irá criar o código para você, conforme mostra a Listagem 02:
// The test class name should end with `Test'--this is a convention:
public class TemplateClassTest 
    extends org.wiztools.restclient.RESTTestCase{

  // Test method names should start with `test':
  public void testStatus(){
    if(response.getStatusCode() != 200){
      fail("This will fail the test!");
    }
  }
}
Listagem 2: Template de Test gerado pelo RESTClient.

A partir da versão 2.3, RESTClient possui uma versão em linha de comando, está versão é utilizada para executar requisições de forma batch e armazenar o resultado dos testes.  Para executar está versão, basta na linha de comando executar:

$java -jar restclient-cli-2.3-jar-with-dependencies.jar -o /temp/diretorioResponse *.rcq

Esse comando, irá executar todos as requisições contidas nos arquivos de extensão (.rcq) no diretório de execução atual, e irá salvar as responses (na extensão .rcs) no diretório /temp/diretorioResponse. E por fim, o RESTClient, imprime um resumo da execução dos testes. 


Referências:

Testando Web Services RESTful no NetBeans.

 Para quem é usuário do NetBeans, uma outra opção para testar Web Services RESTful é utilizar o suporte do próprio IDE, com um projeto Web criado e os serviços RESTful devidamente configurados, é possível testá-los clicando com o botão direito do mouse em cima do projeto e selecionar a opção “Test RESTful Web Services” (Figura 02), lembrando que está opção só estará disponível, se o projeto WEB possuir serviços WEB.


Figura 02 -Suporte a REST no NetBeans.

Ao selecionar esta opção, será feito o build e o deploy da aplicação web, e ao final do processo será disponibilizado uma página de testes web, como mostra a Figura 03.



Figura 03 - Tela de testes de Web Services RESTful

Na página apresentada é possível testar todos os serviços disponíveis, criar novos parâmetros para a requisição (botão “Add Parameter”), e também é possível selecionar o tipo de método HTTP para teste e o tipo MIME de retorno.

Para iniciar o teste, basta clicar no botão “Test”, após a execução, dentro da seção Response, podemos analisar os dados de retorno, os dados do cabeçalho e o status da chamada.

Além disso, de acordo com os serviços criados, o NetBeans ainda gera o arquivo WADL, visível no canto superior esquerdo da Figura 03.
 
Referências:

JAXB

JAXB (Java Architecture for XML Binding) fornece a API, as ferramentas e um framework que automatiza o mapeamento entre documentos XML e objetos Java. Ou seja, fornece compiladores que compilam Schemas XML para objetos Java. Em tempo de execução podemos deserializar (unmarshal) o conteúdo de um arquivo XML para representações Java.

Além disso, podemos acessar, alterar e validar a representação Java contra regras de um Schema e por fim, podemos serializar (marshal) o conteúdo de um objeto Java em conteúdo XML. Veja sua arquitetura na Figura 04:




Figura 04 - Overview do JAXB.

Esta fora deste artigo um estudo mais aprofundado sobre o JAXB, mas apenas para conhecimento, a API JAXB acabou se tornando a forma padrão de mapeamento entre Java e XML, com JAXB temos anotações que nos permitem criar uma representação em Java de um Schema XML, estas anotações estão presentes no pacote javax.xml.bind.annotations, e possuem anotações associadas a pacotes Java (@XmlSchema, @XmlSchemaType, etc..), a classes Java (@XmlType, @XmlRootElement), a propriedades e campos (@XmlElement, @XmlAttribute), entre outras anotaçõe.

Para exemplificar, considere o exemplo da listagem 3, esta é uma classe POJO representando uma pessoa, com anotações JAXB.  Ao fazer um marshalling de uma instância da classe PessoaBinding para XML, teremos o resultado apresentado na listagem 04.

@XmlRootElement(name="pessoa")
@XmlType(name="", propOrder={"nome","idade","statusCivil"})
public class PessoaBinding {
/* Construtores e Setters omitidos */
    private String nome;
    private int idade;
    private String statusCivil;
    private String cpf;

    @XmlElement
    public String getNome() {
        return nome;
    }
    @XmlElement
    public int getIdade() {
        return idade;
    }
    @XmlAttribute(name="num_cpf")
    public String getCpf() {
        return cpf;
    }
    @XmlElement
    public String getStatusCivil() {
        return statusCivil;
    }
}
Listagem 03 - Classe PessoaBinding com anotações JAXB.

   
       Wagner
       29
       Casado
   
Listagem 04 - XML Gerado após marshalling de classe JAXB PessoaBinding.

A especificação do JAX-RS fornece alguns Entity Providers padrões, entre eles, provedores para JAXB, para quando o tipo de conteúdo trafegado for do tipo xml (application/xml, text/xml e application/*+xml), de modo que o programador não precisa criar código para converter um objeto Java em código XML e vice versa, facilitando muito nossa vida.


Ainda na classe PessoaBinding da  listagem 03, poderíamos então, no nosso exemplo, criar um serviço RESTful cujo retorno seja a classe JAXB PessoaBinding , neste caso a declaração do serviço seria similar ao método da listagem 05.

    @GET
    @Produces("application/xml")
    @Path("/NetFeijao/autor/{idPessoa}/")
    public PessoaBinding getPessoa(@PathParam("idPessoa") Integer id) {
         return dao.getPessoaAsBinding(id); // Retorna uma entidade Pessoa como PessoaBinding
    } 
Listagem 05 - Serviço RESTful cujo retorno é uma classe JAXB.

Ao fazermos o consumo deste serviço RESTful, vamos perceber que a conversão é feita automaticamente pelo entity provider padrão para XML (veja o teste na Figura 05, utilizando a ferramenta RESTClient). De maneira inversa poderíamos criar um serviço RESTful para receber requisições PUT e receber como parâmetro de entrada do método a classe PessoaBinding via HTTP Body.  Conforme apresenta a listagem 06:





Figura 05 - Retorno do serviço RESTful cujo retorno é uma classe JAXB.

    @PUT
    @Consumes("application/xml")
    @Path("/NetFeijao/")
    public void putPessoa(PessoaBinding pessoa) {
        // Operação de update
    } 
Listagem 06 - Convertendo código XML para objeto JAXB em chamada PUT com REST.



Referências:

JAKARTA COMMONS - HTTP CLIENT

HttpClient é um subprojeto open source da Jakarta Commons que se tornou independente em 2007, e que foi concebido para facilitar o desenvolvimento de aplicações que utilizam o protocolo HTTP.
 Ele é um projeto escrito totalmente em Java, e implementa todos os métodos HTTP (GET, POST, PUT, DELETE, HEAD, OPTIONS e TRACE).

Possui suporte ao protocolo HTTPS, suporte ao gerenciamento de conexões para uso em aplicações multi-thread, suporte a cookie, possui mecanismos de autenticação Basic, Digest e criptografia NTLM.

 Na listagem 07, demonstramos o uso da biblioteca HttpClient, onde consumimos dois serviços RESTful, um com uma chamada GET e outra com uma chamada PUT.

     public void testHTTPClient() {
        try {
            HttpClient client = new HttpClient(new MultiThreadedHttpConnectionManager());
            client.getHttpConnectionManager().getParams().setConnectionTimeout(30000);
            final String CONTENT_TYPE = "application/xml";
            final String CHARSET = "UTF8";

           /* Executando chamada com método HTTP GET */
        String getURI = "http://localhost:8080/ProjetoREST/NetFeijao/autores/Wagner/?idade=29";
        GetMethod get = new GetMethod(getURI);
        Header meuHeader = new Header("CPF","123456789");
        get.setRequestHeader(meuHeader);
        int statusCodeGET = client.executeMethod(get);
        String responseBody = get.getResponseBodyAsString();
        System.out.println("Chamada GET");
        System.out.println(" Status Code: "+statusCodeGET+" \nResponse Body:\n"+responseBody);

         /* Executando chamada com método HTTP PUT */
       String putURI = "http://localhost:8080/ProjetoREST/NetFeijao/autores/update/";
       PutMethod put = new PutMethod(putURI);
    StringRequestEntity requestEntity = new StringRequestEntity(responseBody, CONTENT_TYPE, CHARSET);
        put.setRequestEntity(requestEntity);
        int statusCodePUT = client.executeMethod(put);
        responseBody = put.getResponseBodyAsString();
        System.out.println("Chamada PUT");
        System.out.println(" Status Code: "+statusCodePUT+" \nResponse Body:\n"+responseBody);
    } catch (Exception ex) {/* OMITIDO */}
}
Retorno da chamada ao método.
Chamada GET
 Status Code: 200
Response Body:

  
       Wagner
       29
       Casado
  


Chamada PUT
 Status Code: 202
Response Body:

Bem vindo Wagner


Listagem 07: Consumindo serviços REST via GET e PUT com HTTPClient.

Primeiro, na linha 3 instanciamos a classe HttpClient que é o nosso agente HTTP que irá conter os atributos de persistência com cookies, e credenciais de autenticação através da classe HttpState. E também onde será armazenado uma ou mais conexões HTTP, cujo qual faremos chamadas aos métodos HTTP.

Na linha 4 atribuímos um timeout para a conexão de 30 segundos. Depois nas linhas 5, 6 e 9 declaramos as variáveis quer irão determinar o tipo de conteúdo, o character set e a URI de acesso ao serviço REST.

Na linha 10, instanciamos a classe GetMethod, que como o próprio nome indica representa o método GET, passando como parâmetro a URL do nosso serviço RESTful (getURI). Na linha 11 criamos um objeto Header, passando como parâmetro no construtor a chave e o valor que representam o parâmetro e o valor do cabeçalho, no nosso exemplo, passamos um número fictício de CPF. Na linha 12 atribuímos o objeto header para o objeto GetMethod.

 Na linha 13, fazemos a chamada ao serviço RESTful via HTTP GET, e armazenamos o código de status do retorno na variável statusCodeGET, na linha 14 extraímos os dados da Response como String para a variável responseBody. Pelo fato do retorno ser em XML, poderíamos facilmente utilizar JAXB para trabalhar o retorno como um objeto Java. Finalmente nas linhas 15 e 16 imprimimos no console o retorno da chamada a estes métodos.

A partir da linha 18, iniciamos o mesmo processo, mas agora para efetuar uma chamada via método PUT, as únicas diferenças, são o uso do método PutMethod, que implementa o método HTTP PUT e o uso da classe StringRequestEntity na linha  21,  com esta classe atribuímos uma entidade como String ao método PUT que será enviado junto a requisição.

Nas linhas 25 e 26 imprimimos o retorno da requisição PUT.

JavaScript:




Graças ao objeto XMLHttpRequest conseguimos nos comunicar com servidores de forma assíncrona,   desde então temos todas as vantagens do AJAX ao nosso dispor.  Para quem desenvolve interfaces WEB, este recurso resolveu grandes problemas no lado do cliente, mas vale lembrar que JavaScript não é Java, não possui threads, nem tipos, e possui uma grande gama de frameworks Ajax, como por exemplo Prototype, JQuery, Dojo, Script.aculo.us, Ext-JS, entre outros.

 Na listagem 08, temos um exemplo de uma função em JavaScript  que consume um serviço RESTful cujo retorno é um XML.




var xmlHttp;
function showCustomer(str){ 
    xmlHttp=GetXmlHttpObject(); // omitido código do método0
    if (xmlHttp==null) {
        alert ("Your browser does not support AJAX!");
        return;
    }
    var url='http://localhost:8080/Contatos/resources/customers/58/';
    xmlHttp.onreadystatechange=stateChanged;
    xmlHttp.open('GET',url,true);
    xmlHttp.send(null);
}

function stateChanged() { 
    if (xmlHttp.readyState==4){
        var xmlDoc=xmlHttp.responseXML.documentElement;
        document.getElementById("nome").innerHTML= 
        xmlDoc.getElementsByTagName("name")[0].childNodes[0].nodeValue;
    }
}
Listagem 08 - Consumindo um serviço RESTful (retorno XML) com Ajax.

Na listagem 08, vimos um exemplo de um serviço que retorna XML, mas uma das grandes vantagens dos serviços REST, é que podemos trabalhar com diversos formatos para troca de informação de um mesmo recurso. Entre eles JSON.

jQuery



JQuery é uma biblioteca JavaScript que vem chamando atenção por conta de sua facilidade de desenvolvimento, ela simplifica muito a manipulação dos elementos de um documento HTML, o tratamento de eventos e as interações Ajax para prover um desenvolvimento rápido de aplicações web, livrando o desenvolvedor de preocupações relacionadas a compatibilidade de navegadores e aderência a CSS.

A biblioteca jQuery fornece algumas funções para tratamento de requisições Ajax, ideais para o consumo de serviços REST, que reduzem muito a complexidade e a quantidade de linhas necessárias para consumir um serviço REST.  Com a função $.ajax() do jQuery, conseguimos um alto nível de controle nas requisições ajax.

A sintaxe do comando é $.ajax(options), onde o parâmetro options são as propriedades que passamos para controlar como a requisição é feita e retorno da chamada.
Na listagem 09, demonstramos o uso das funções $.ajax().
$.ajax({
    type: ‘DELETE’,
    url: "http://localhost:8080/ProjetREST/NetFeijao/autores/"+idAutor+"/",
    success: function(msg){
        $("#alert").html(msg);
    }
});
Listagem 09 - Consumindo um serviço REST com a função $.ajax().

Na listagem 09, usamos dois parâmetros na função $.ajax(), o parâmetro type para indicar o método HTTP que queremos executar e a url de chamada.

Para tratar tipos de retorno JSON, o jQuery oferece a função $.getJSON(), utilizada para carregar dados JSON mediante uma requisição HTTP GET.

Na listagem 10 mostramos um exemplo de uso da função $.getJSON() em um serviço REST do Flickr, nós fazemos uma chamada ao serviço REST e passamos o retorno da chamada ao método de callback. Dentro da função de callback criamos a tag passando como valor o endereço da foto retornada pelo serviço REST e a incluímos na div #foto. Note que a variável data, é um map chave-valor dos dados retornados pela função REST.
$.getJSON("http://api.flickr.com/services/rest/?method=flickr.photosets.getPhotos& photoset_id=72157614488723406&format=json&jsoncallback=?",
function(data){
    $.each(data.photoset.photo, function(i,item){
        if (item.title == foto){
            $("").attr("src", "http://farm"+item.farm+".static.flickr.com/"+item.server+"/"+item.id+"_"+item.secret+"_m.jpg").appendTo("#foto");
        }
    });
});
Listagem 10 - Uso da função $.getJSON para consumo de dados no formato JSON.

É isso aí, consumir serviços REST é diversão garantida !!! E a todos um Feliz Ano Novo repleto de código \o/ !!!

Entrevista para a Globalcode

quinta-feira, 10 de setembro de 2009

No mês de Junho, foi publicado uma entrevista minha para meus caros amigos da Globalcode, sobre carreira e oportunidades, para quem não viu vale a pena conferir. Segue abaixo as perguntas que estão disponíveis no próprio site da Globalcode. Para quiser ver o link da entrevista, clique aqui.

1. Poderia nos contar como começou a desenvolver plugins para o Netbeans ?

Comecei a desenvolver plugins através do "Desafio NetBeans", um campeonato de desenvolvimento de plugins para o NetBeans patrocinado pela Globalcode, Sun e o SOUJava, me lembro que antes de iniciar o campeonato participei de alguns minicursos gratuitos promovido pela Globalcode, contando inclusive com a participação de dois desenvolvedores do NetBeans (Tim Boudreau e Charlie Hunt).
Neste campeonato desenvolvi meu primeiro plugin para o Netbeans, mais especificamente um plugin para o Hibernate, onde a partir de tabelas selecionadas de um Banco de Dados, o plugin gera as entidades de persistência, o arquivo de configuração, com suporte a xDoclet (na época não havia annotations). Neste primeiro contato com a plataforma NetBeans tive a oportunidade de aprender várias coisas legais que me motivaram a continuar o aprendizado.

2. Desde então, quais plugins você já desenvolveu?

O segundo plugin que desenvolvi foi o módulo CodeGen, um plugin para sobrescrever os métodos equals() e hashcode() que na época (NetBeans 5.0) não existia no NetBeans, e existia no Eclipse. Existe até uma história engraçada por trás disso, me lembro de estar em um minicurso em que o Vinicius comentou que abria o Eclipse apenas para utilizar a função do equals e hashcode, o que me motivou a criar este projeto =D.
Depois desenvolvi alguns plugins corporativos, e depois de um tempo, a pedido do meu amigo Renato Bellia, criei o plugin Diamond Powder for NetBeans. No evento Yahoo Open Hack Day desenvolvi junto com o time Globalcode o plugin Blueprints Yahoo!, e mais recentemente estou colaborando na criação de um plugin para o framework SuperCRUD para o meu amigo Vinicius Senger.

3.Poderia comentar um pouco sobre o plugin que você desenvolveu no Yahoo Open Hack Day onde participou da equipe que ganhou o prêmio Bridging the Gap ?

Para mim foi uma grande alegria e honra participar do time Globalcode, onde ao todo foram desenvolvidos 4 hacks. Sobre o plugin desenvolvido para o Yahoo Open Hack Day, é um módulo que permite a criação de projetos (através de templates) com suporte ao Yahoo! Blueprint, uma tecnologia desenvolvida pela Yahoo que permite a criação de web sites para celulares com uso apenas de XML. O plugin oferece a criação de um esqueleto para um projeto Yahoo, criando os arquivos necessários para seu funcionamento (gallery.xml e config.xml). Além disso, o plugin vem com alguns samples (desenvolvidos pela Globalcode) dentro do NetBeans para os desenvolvedores que querem entender como funciona um projeto Blueprint. E possui suporte a Update Center, Help, e a inclusão do guia do Desenvolvedor em pdf no NetBeans.

4. Quais os conhecimentos necessários para um programador começar a criar módulos para o NetBeans ?

Além de ter conhecimentos sólidos de Java Standard Edition, para o programador iniciar a criação de módulos para o NetBeans, é importante entender como funciona o NetBeans e a sua arquitetura. Procurar enxergar além do IDE, rs.. o IDE NetBeans é construído sobre a Plataforma NetBeans, assim como vários outros produtos, como por exemplo a ferramenta VisualVM, quem utiliza nota a grande semelhança com o NetBeans.
Ao iniciar o desenvolvimento na plataforma NetBeans, já temos disponíveis várias funcionalidades / componentes prontos para o uso e toda esta infraestrutura pode ser manipulada via código através das APIs da Plataforma NetBeans. A plataforma dispõe de APIs para trabalhar com diversos tipos de categorias entre os quais podemos destacar como as Ações do Sistema (Actions), Ant, Paleta de objetos, Debug, Dialogs (para notificação), Sistema de Janelas, Sistema de Arquivos, Editores, Navegação, Loaders, entre outros.
O programador precisa somente entender como manipular estas APIs que ele pode praticamente fazer o que quiser com o NetBeans.

5. Sabemos que você andou fazendo testes com Zembly, poderia comentar um pouco sobre o que é Zembly e para que serve ?

A ideia do Zembly, é criar uma espécie de Wiki para aplicações sociais como o Facebook, ele fornece o ambiente no próprio site do Zembly para criação e edição de aplicações sociais, essa aplicação fica hospedada em uma nuvem do Zembly de maneira que podemos compartilhar nossa aplicação entre diversos sites, como se fossem widgets.
É algo extremamente interessante, pois no Zembly, temos um editor para o código HTML/XHTML para UI, um editor CSS para aplicar os estilos da aplicação e um editor JavaScript para a lógica do negócio, que pode ser utilizado bibliotecas JavaScript como jQuery, Prototype e podemos fazer inclusive integração com diversas APIs como FlickR, Yahoo API, Google Maps, entre outros.
Atualmente estou trabalhando no SOUJava para criar uma aplicação que seja compartilhada pelos sites de tecnologia, fóruns, blogs, de maneira que o SOUJava possa divulgar suas atividades de uma maneira muito mais ampla, pois estes sites deverão apenas incluir um pequeno trecho de código JavaScript em seus sites.

6. Poderia comentar um pouco sobre o Plugin que desenvolveu como colaboração para o SuperCRUD ?

Na verdade, este foi um trabalho relâmpago que montamos para o SuperCRUD e está em evolução, atualmente o plugin permite a criação de qualquer tipo de projeto (web, desktop, maven) com fontes existentes a partir de um servidor remoto, onde o desenvolvedor precisa informar a URL para o projeto (zipado).
Pelo que sei, o desenvolvedor cria um projeto no SuperCRUD, e ao final o próprio SuperCRUD gera uma bookmarkable URL que o programador cola e copia no NetBeans (no plugin), que por sua vez abre o projeto remotamente. Mas claro, sobre esta parte do SuperCRUD o Vinicius poderia dar maiores detalhes =D.

7. Poderia comentar um pouco sobre o Plugin que fez para o projeto Diamond Powder junto com o Renato Bellia?

O Diamond Powder é um framework open source para Java ME desenvolvido pelo Bellia, que acelera a criação de coletores de dados em aplicações MIDP. O framework permite a criação dos formulários, fields (datafield, stringitem, textfield, choicegroup, filter, etc..), definição do fluxo de navegação das páginas e as páginas de help de maneira declarativa, baseada em definições de pares de chave-valor com uso de um Hashtable, que descreve toda a sua organização por um objeto chamado Schema.
O "Schema" é o coração do framework, mas conforme a sua aplicação cresce, fica cada vez mais difícil dar manutenção no seu Schema, como adicionar novas páginas e campos, e é onde o plugin entra, ele facilita muito a criação e a manutenção do código do Schema (com refactoring ou criação de uma nova classe) através de um wizard e evita a digitação errada dos nomes das váriaveis, campos.
Tem a possibilidade de gravar os dados criados (páginas, campos, etc...) em um arquivo properties e reutilizá-los em outros projetos.

8. Você realmente achou um nicho de mercado muito interessante, onde pode colaborar com praticamente qualquer projeto Open Source, quais as dicas que você poderia dar para as pessoas que estão iniciando?

A melhor dica que posso dar é estudar, estudar e estudar. Porém, se você ficar cansado de estudar, estude mais um pouco, faça cursos de java, visite sites de tecnologia como InfoQ, TheServerSide, execute os samples disponíveis no NetBeans e analise o código fonte, participe das listas de discussão. Participe dos eventos, dos minicursos, inscreva-se em todos os feeds possíveis sobre tecnologia, blogs, participe de grupos de discussão, tire certificações e o mais importante, participe de projetos open source, além de aprender com profissionais renomados e compartilhar conhecimento, você estará fazendo networking, sem falar da possibilidade do seu trabalho ficar conhecido no mundo todo.

9. Poderia citar algumas referências para quem quer começar a desenvolver plugins para NetBeans ?

Para as pessoas que estão iniciando, recomendo o próprio site do NetBeans Platform que possui diversos tutoriais, screencasts, wikis, samples que demonstram como criar módulos para o NetBeans, recomendo também o blog do Geertjan, um dos desenvolvedores e evangelista do NetBeans, e existe um livro excelente chamado Plugging into the NetBeans Platform, que apesar de ser de 2007 demonstra em detalhes a criação de módulos para o NetBeans e o uso correto das APIs. E também recomendo meu artigo que foi publicado na edição 29 da revista Mundo Java sobre a Plataforma NetBeans ;).

10. Poderia citar algumas referências para quem quer começar a estudar Zembly?

Para começar a estudar Zembly, o mais importante é conhecer bem JavaScript, (X)HTML e CSS, o resto é entender como funciona o ambiente do Zembly.
Uma ótima referência é o wiki do site, que possui diversos tutoriais de como criar aplicações a partir de templates, criação de aplicações para o Facebook, iPhone, Meebo, entre outros.

Diamond Powder for NetBeans

segunda-feira, 23 de março de 2009

Last year, i have created a NetBeans plugin to an interesting framework, called Diamond Powder, it was developed by a friend of mine, Renato Bellia .
To explain what Diamond Powder is, i´ve extracted a briefly introduction from his blog,

What is it ?

It's a Java ME framework to quickly build data collector forms. Further, it is able to manage the persistence of collected data into RMS records.

Data Collector ?

It is about user input.

Suppose you develop a MIDP application that helps car drivers to maintain records about fuel consume in his/her car: The driver stops by at the gas station and gets his mobile device to take note about odometer value, supplied fuel amount , price of fuel, gas station name, and the current date. Later on the driver needs to recover such data. This is a data collector, and Diamond Powder can help you to do so.

Your MIDP application could go further, doing some math with such data, plotting charts, sending it over the internet and the like, but this is up to you.

How does it work ?

Read this step-by-step and the glossary bellow:
  1. Define a Schema
  2. Create a Collector suppling with a display, a schema and a flow name
  3. Add regular LCDUI commands to the collector
    1. at least an OK Command, and a BACK Command
    2. other Commands can be provided
  4. Swicht the MIDlet display to the Collector
  5. At the end of Colletor´s job you may persist collected data with a StorageManager.
Glossary:

term

definition

Schema

A Hashtable that describes the data collector fields, and its organization.

A schema contains a name, a version number, and at least one Flow.

Flow

A sequence pages that the application user can browse through.

Page

A top level field container, to display to the user, as a data collector step.

Can be reused among flows.

Can be associated with a help screen.

Field

Regular LCDUI items: StringItem, TextField, DateField, ChoiceGroup

+ Filter : a special component to deal with huge ChoiceGroups

Collector

A collector manages the display of a Flow of Pages, and gathers all user input.

It extends LCDUI Form.

StorageManager

It is the Diamond Powder persistence component.

It helps to preserve user input data gathered by a Collector into RMS records.

It also helps to restore a Collector with previously saved RMS records.


NetBeans Plugin

Now, it´s time to talk about my collaboration in this project, if you get a look at this framework, you will realize that it simplifies a lot the development of a data collector on java me.

On the other hand, the heart of the framework, the "Schema", as stated in the glossary, it is a Hashtable that describes the data collector fields, flow, name and version of your application. Let´s see on listing 1, a snippet of the schema code from the hello world example, extracted from diamond powder blog.
public Hashtable getSchema() {
Hashtable schema = new Hashtable();

//schema declaration: name;version
schema.put("schema", "fuelControl;2");
//flow declaration: page1;page2;...
schema.put("flow.basicRecord", "numbers;extra");
//page declaration: title;field1;field2;...
schema.put("page.numbers", "The Numbers;date;odometer;fuelAmount;fuelPrice");
schema.put("page.extra", "Gas Station;gasStationName;gasStationBrand");
//help for page: help text
schema.put("help.numbers", "Enter the odometer mark, the supplied fuel amount and the fuel price");
schema.put("help.extra", "Enter the gas station name and brand");

//text field declaration: field type;label;size;mask
schema.put("field.odometer","textfield;odometer;6;numeric");
schema.put("field.fuelAmount","textfield;fuel amount;5;decimal");
schema.put("field.fuelPrice","textfield;fuel price;5;decimal");
// dateField;label;{date|time|date_time}"
schema.put("field.date","datefield;when;date_time");
schema.put("field.gasStationName","textfield;gas station;40;initial_caps_word");

//choice gorup declaration: field type;label;list model;mode
schema.put("field.gasStationBrand",
"choicegroup;brand;allBrands;exclusive");
//list model declaration: value1;label1;value2;label2;...
schema.put("listmodel.allBrands",
"999;undefined;1;Atlantic;2;Chevron;3;Esso;4;Texaco");

return schema;
}

Listing 1: Schema method example.

As you can see in the example, it can be a problem if you want a more complex application, as your schema evolves it can became inconvenient and error-prone, as you add more fields, or even new pages.
Diamond Powder for NetBeans it´s a plugin, that comes to fill this gap, and helps to create a Schema code, avoiding spelling error in variable names. Now let´s see how to install it.

Download and Installation

To install Diamond Powder for NetBeans, you can visit plugin Portal on NetBeans website, or you can download it directly from java.net site project. The easiest way to download it, is directly from NetBeans,
To install DP from NetBeans, select "Tools > Plugins", open the Setting category and click Add button, in Name field enter "Diamond Powder", and URL enter "https://diamond-powder.dev.java.net/files/documents/9072/108868/updates.xml", and click OK to create a new Update Center source.

Figure 1: Configuration of Update Centers.

Now, to install the plugin, select "Available Plugins" category and install the Diamond Powder plugin, during instalation it will generate a warning, stating that the module is not signed, but it´s ok..

Generating the Schema
There are two ways to create a schema, creating a new file, selecting "New File > MIDP > Diamond Powder - Schema Generator" from a Java ME Project, or you can invoke Diamond Powder wizard from the source code editor, selecting menu popup "Refactor > Diamond Powder - Schema Generator"..

Figure 2: Creating a new Schema file

Start by creating a Diamond Powder Schema file, as shown in Figure 3. Let´s create the schema defined in listing 1, so name the schema "fuelControl", set version 2 and click next to go the panel shown in Figure 4:
Figure 3: Naming the Schema file.

Here we can define our application fields, , let´s define the odometer, fuelAmount, fuelPrice, date, gasStationName and gasStationBrand. Note, that for gastStationBrand is a choicegroup field, to define our list values, click the Editor button, and create the list model defined in Figure 5.

Figure 4: Fields Configuration

Enter "allBrands" to List Model and click New Button, to include a value to the allBrands list model, select it in the list and click Add button, to cancel an item just click cancel, and to finish it, close the window.

Figure 5: List Model editor.

In the Pages Configuration step, let´s create our pages number and extra adding the related fields and entering the properly information like page name, title and help, like Figure 6.

Figure 6: Pages Configuration.


Click Next to our final step, now we going to define the sequence pages that our application will browse through. Enter basicRecord for Flow Name, and add the two pages created earlier (Figure 7).
Check the "Save to File?" option and click browser, this option will persist all fields created to an user defined file.

Figure 7: Flow Definition.

Note: You can retrieve these values, loading the file in the Fields Configuration step (see Figure 4).

Click Finish to generate the schema class. After generation, you should see the Java class, Schema, in the hello.schema package.

References:
Diamond Powder (java.net): https://diamond-powder.dev.java.net/
Diamond Powder Blog: http://diamond-powder.blogspot.com/
NetBeans Plugin: http://plugins.netbeans.org/PluginPortal/faces/PluginDetailPage.jsp?pluginid=17094
NetBeans: http://www.netbeans.org/

Try it !!

Yahoo! Hack Day 2008 Brasil - Bridging The Gap

terça-feira, 11 de novembro de 2008

In this weekend, we have celebrated the first Yahoo! Open Hack in Brazil, it was a great party in fact, the lunch was great, people were taking there time and having fun !!

I can consider myself a luck guy, i was invited to join the Globalcode Team, with my friends Vinicius Senger, Yara Senger, Eder Magalhães, Rafael Nunes, Pedro Germano, and a couple of Globalcode classmates =) ..


Caption: NetBeans plugin presentation





We have divided the work into team groups and as a result we have produced FOUR incredible hacks, yes man, i said four great hacks.. See below:
---------------------------------------------

  1. NetBeans Plugin for Yahoo! Blueprint
  2. JSF Renderkit for Yahoo! Blueprint
  3. Mobile Planning Poker for distributed Teams
  4. Supercrud Mashup for Flickr








Caption: Eder presenting the Planning poker mobile



Obviously, my participation was related to the NetBeans plugin development =), it provides a template for Yahoo Blueprint Web Project, a sample application for Yahoo Blueprint, a JBlueprint librarie that encapsulates the Yahoo! Blueprint' API components (developed by Eder Magalhães), some Help Documents, an Update Center and the Developers Guide pdf file inside NetBeans.. =)




Caption: Award on "Bridging the Gap" Category

Our subject wasn't the prize only, our real intention was to build something useful for Java Developers, and make the work with Yahoo APIs easier with the NetBeans plugin and JSF Renderkit, we are planning open the code on java.net soon and attract new developers to this great platform. so stay tunned for more details !!!

Caption: Globalcode "Super" Team



Caption: Globalcode Team and some friends from São Carlos


Congratulations for all the winners. It’s really amazing to see these great and wonderful work .. you are the best !!

See more details at Yahoo! Developer Network blog by Chris Heilmann




Caption: NetBeans Plugin Presentation


One of the best moments, was the Puff Hacking Video,, see for yourself


Puff Hacking from fczuardi on Vimeo.


Cheers, and we see you again next year !!!!

Parabéns NetBeans !!!!

terça-feira, 21 de outubro de 2008


Como muitos já sabem o NetBeans está completando 10 anos de vida, e como homenagem, cantamos parabéns em grupo na época do Sun Tech Days.








Segue o mico, quer dizer o vídeo.




No vídeo gravado na churrascaria Jardineira Grill, estão presentes da esquerda para a direita, Renato Bellia e sua esposa, a esposa de um dos meus amigos, logo atrás dela eu e minha esposa, ao lado dela se encontra a minha grande amiga Janice Campbell, atrás dela, Jefferson Prestes e Michel Graciano, no centro Marcelo Castellani (de jaqueta preta), Mauricio "Maltron" Leal, atrás dele Vinicius Senger e Yara Senger, atrás deles, está Greg Sporar, e mais dois gringos da Sun, e logo após a esposa do Bruno com suas lindas filhas, atrás delas se encontra Henrique Meira e seu colega, e por último o JavaMan.

Fonte do Vídeo: http://www.netbeans.tv/on-the-road/Brazilian-Birthday-Song-400/


Outra dessa só daqui a 10 anos... =)

PARABÉNS NETBEANS !!!

SCSNI Study Group - Netbeans IDE Certification Exam

sábado, 18 de outubro de 2008

If you don´t know already, and to celebrate 10th NetBeans Birthday yeaahhh, Sun is planning to release a new certification for NetBeans IDE (Beta), if you are interested and would like to know more about it, or you are just looking for material to study, take a look at the SCSNI Study Group, the first study group to this certification, it has a plenty of related stuff.

You can help to increase the group providing mocks, articles, or even changing the site, if you wanna help, please let me know mailling me at wrsconsulting@gmail.com

As a beta tester, you officially test the test and will be able to provide Sun with valuable comments and technical feedback about the Netbeans IDE questions. The Sun beta exam counts towards official Sun Certified Specialist Netbeans IDE (SCSNI) Certification!

Exam Testing Objectives
    Section 1: IDE Configuration
    • 1.1 Demonstrate the ability to configure the functionality available in the IDE, including using enabling and disabling functionality and using the Plugin Manager.
    • 1.2 Explain the purpose of the user directory and the netbeans.conf file and how these can be used to configure the IDE.
    • 1.3 Demonstrate the ability to work with servers in the IDE, such as registering new server instances and stopping and starting servers.
    • 1.4 Describe how to integrate external libraries in the IDE and use them in coding and debugging your project.
    • 1.5 Demonstrate knowledge of working with databases in the IDE, including registering new database connections and tables running SQL scripts.
    • 1.6 Describe how to integrate and use different versions of the JDK in the IDE for coding, debugging, and viewing Javadoc documentation.
  • Section 2: Project Setup
    • 2.1 Describe the characteristics and uses of a free-form project.
    • 2.2 Demonstrate the ability to work with version control systems and the IDE. (Which VCS's are available, which ones you need an external client for, how to pull sources out of a repository, view changes, and check them back in).
    • 2.3 Describe the ways in which you can change the build process for a standard project, such as configuring project properties and modifying the project's Ant build script.
    • 2.4 Configure your project to compile against and run on a specific version of the JDK.
  • Section 3: Java SE Development
    • 3.1 Demonstrate the ability to create NetBeans projects from the source code of an existing Java SE program.
    • 3.2 Describe how to manage the classpath of a Java SE project, including maintaining a separate classpath for compiling and debugging.
    • 3.3 Demonstrate the knowledge of the NetBeans GUI Builder and the ability to lay out and hook up basic forms using it.
    • 3.4 Demonstrate the ability to package and distribute a built Java Desktop project for use by another user.
  • Section 4: Java EE Web Development
    • 4.1 Describe how to create a NetBeans project from the source code of an existing Web application.
    • 4.2 Distinguish between a visual web application and web application.
    • 4.3 Demonstrate knowledge of which web frameworks are available in NetBeans IDE and how they are added to and used in a web application.
    • 4.4 Describe how to monitor HTTP requests when running a web application.
    • 4.5 Demonstrate a knowledge of basic tasks related to building and deploying web applications to a server, such as changing the target server and undeploying an application.
  • Section 5: Editing
    • 5.1 Describe the purpose and uses of refactoring and demonstrate the ability to perform basic refactoring on Java source code.
    • 5.2 Describe how to use the Options window to change the default appearance and behavior of the Source Editor.
    • 5.3 Describe the ways that the IDE highlights errors in source code and the tools the IDE offers for correcting those errors.
    • 5.4 Demonstrate the ability to use editor hints, such as implementing all the methods for an implemented interface.
    • 5.5 Demonstrate the ability to use live code templates such as automatic generation of constructors, try/catch loops, and getters and setters.
  • Section 6: Testing, Profiling, and Debugging
    • 6.1 Demonstrate the ability to work with JUnit tests in the IDE, such as creating JUnit tests and interpreting JUnit test output.
    • 6.2 Describe how to debug a local (desktop) application, including setting breakpoints and stepping through code.
    • 6.3 Describe the difference between local and remote debugging and describe how to debug a remote (web) application.
    • 6.4 Describe the purpose of profiling applications and how to profile a local desktop application in the IDE.

References:

Official Site: http://www.sun.com/training/certification/netbeans.html
Study Group: http://sites.google.com/site/netbeansscsni/
NetBeans 10th Birthday: http://www.netbeans.org/birthday/logos.html

NetBeans Rocks, The only IDE you need !!!

[JavaEE 6] EJB 3.1 no GlassFish V3 e NetBeans

segunda-feira, 15 de setembro de 2008


Esta semana saiu nas bancas a edição 31 da revista Mundo Java com o título "Futuro do Java Corporativo", com um artigo meu sobre o mesmo tema.
Para quem quer saber o que vai rolar na próxima especificação do Java EE 6, está edição está um prato cheio, portanto compre uma edição e aproveite...
Não vou entrar em muitos detalhes da matéria, mas vou descrever aqui melhor a demo que está na revista, onde apresento uma aplicação utilizando Session Bean da especificação de EJB 3.1 no GlassFish V3.

Instalando o GlassFish V3 e o conteiner EJB

No site do GlassFish baixe o arquivo zip e descompacte em um diretório da sua escolha, a partir deste momento vamos chamar apenas de GLASSFISH_HOME\bin e execute o updatetool (Figura 1).
Na opção available addons, selecione glassfishv3-ejb e clique em Install, esta ação irá instalar o container EJB no Glassfish.

Instalando o plugin GlassFish V3 no NetBeans

Agora inicie o NetBeans (de preferência a versão 6.1 ou 6.5) e instale o plugin do GlassFish V3 para o NetBeans em Ferramentas | Plugins, selecione em plugins disponíveis "Glassfish JavaEE Integration" e clique em instalar.
Após instaldo o plugin, na aba Serviços, adicione um novo servidor, selecione a opção GlassFish V3 e siga os passos apontando o diretório GLASSFISH_HOME de instalação e finalizar.



Vamos explorar agora uma funcionalidade no NetBeans para a criação de CRUD, crie uma nova Aplicação Web na categoria Web e clique em Próximo.
Neste passo digite "DEMO_EJB31" e clique em Próximo, na opção servidores selecione o servidor GlassFish V3 T2 recém instalado e clique em Próximo. No último passo selecione o framework JavaServer Faces e clique em Finalizar.

Agora vamos criar uma aplicação CRUD completa baseada em uma entidade de banco de dados, para isso clique em Arquivo | Novo Arquivo, na categoria Persistence selecione a opção "Classes de entidade do banco de dados" e clique em Próximo.
OBS: Antes de fazer o passo abaixo, inicie o banco de dados Derby na guia Serviços do NetBeans, clique com o botão direito do mouse em Java DB e clique em "Iniciar Servidor".

Neste segundo passo, na lista Fonte de Dados selecione a opção "Nova Fonte de Dados", no campo "Nome JNDI" digite jndi/TesteEJB e na lista "Conexão de banco de dados" selecione o banco "jdbc:derby://localhost:1527/vir" já existente e clique em OK.

Se tudo ocorreu de maneira correta será apresentada uma lista de tabelas disponíveis. Selecione a tabela Employee, clique em Adicionar e em seguida clique em Próximo.

No campo nome do pacote digite br.com.netfeijao.entities e por fim clique no botão "Criar unidade de persistência". Mantenha os valores default clique em Criar e depois clique em Finalizar. Esta ação irá criar a classe persistente Employee no pacote informado.

Agora vamos utilizar um recurso no NetBeans para a criação de um CRUD com páginas JSF baseado em entidades JPA, no caso a classe Employee que acabamos de criar. Acesse o menu Arquivo | Novo Arquivo, na pasta categoria Persistence selecione "Páginas JSF de classes de entidade" e clique em próximo. Adicione a única classe persistente (Employee) existente (ver figura 1), clique em Próximo e a seguir clique em Finalizar.
Execute a aplicação pressionando o botão F6 e faça testes, perceba que o NetBeans criou uma aplicação completa "a lá Ruby on Rails" com apenas alguns cliques.

public class EmployeeController {
private Employee employee = null;
private List employees = null;
@Resource
private UserTransaction utx = null;
@PersistenceUnit(unitName = "DEMO_EJB31PU")
private EntityManagerFactory emf = null;

public EntityManager getEntityManager() {
return emf.createEntityManager();
}
public int batchSize = 5;
private int firstItem = 0;
private int itemCount = -1;

public SelectItem[] getEmployeesAvailableSelectMany() {
return getEmployeesAvailable(false);
}

public SelectItem[] getEmployeesAvailableSelectOne() {
return getEmployeesAvailable(true);
}

private SelectItem[] getEmployeesAvailable(boolean one) {
List allEmployees = getEmployees(true);
int size = one ? allEmployees.size() + 1 : allEmployees.size();
SelectItem[] items = new SelectItem[size];
int i = 0;
if (one) {
items[0] = new SelectItem("", "---");
i++;
}
for (Employee x : allEmployees) {
items[i++] = new SelectItem(x, x.toString());
}
return items;
}

public Employee getEmployee() {
if (employee == null) {
employee = getEmployeeFromRequest();
}
if (employee == null) {
employee = new Employee();
}
return employee;
}

public String listSetup() {
reset(true);
return "employee_list";
}

public String createSetup() {
reset(false);
employee = new Employee();
return "employee_create";
}

public String create() {
EntityManager em = getEntityManager();
try {
utx.begin();
em.persist(employee);
utx.commit();
addSuccessMessage("Employee was successfully created.");
} catch (Exception ex) {
try {
if (findEmployee(employee.getId()) != null) {
addErrorMessage("Employee " + employee + " already exists.");
} else {
ensureAddErrorMessage(ex, "A persistence error occurred.");
}
utx.rollback();
} catch (Exception e) {
ensureAddErrorMessage(e, "An error occurred attempting to roll back the transaction.");
}
return null;
} finally {
em.close();
}
return listSetup();
}

public String detailSetup() {
return scalarSetup("employee_detail");
}

public String editSetup() {
return scalarSetup("employee_edit");
}
..
}
Listagem 1 - Parte da Classe EmployeeController gerado pelo NetBeans

Perceba que o NetBeans gerou o código de persistencia em uma classe controller, vamos melhorar um pouco isto, tirando o código de acesso aos dados e isolando isto em uma classe DAO, depois vamos transformar esta classe em um EJB sem interface,

OBS> Cuidado, o uso de um EJB DAO deve ser restrito, pois dependendo do seu uso, isso pode ser um Anti-Pattern

Vamos criar uma nova classe Java acessando o menu Arquivo | Novo Arquivo. Nomeie a classe como EmployeeDAO no pacote br.com.mundojava.dao. Nesta classe vamos colocar todos os métodos de acesso ao banco utilizados na classe EmployeeController e inclui-los na classe recém criada. Veja parte do código na Listagem 18.

Vamos criar uma nova classe Java acessando o menu Arquivo | Novo Arquivo. Nomeie a classe como EmployeeDAO no pacote br.com.mundojava.dao.
Adicionalmente vamos criar uma classe para tratamento de Exceptions, crie uma classe e nomeie de DatabaseException, na classe DAO vamos encapsular os erros de acesso a banco nesta classe.

Criada a classe DAO, vamos colocar todos os métodos de acesso ao banco utilizados na classe EmployeeController. Feito isto, transforme esta classe EmployeeDAO em um EJB colocando a anotação Stateless em cima da declaração da classe. Veja parte da classe criada na Listagem 2.

@Stateless
public class EmployeeDAO {

public static final int PROCESSADO = 1;
public static final int JA_EXISTE = 2;
public static final int ERRO = 3;

@PersistenceUnit(unitName = "DEMO_EJB31PU")
private EntityManagerFactory emf;

private EntityManager getEntityManager() {
  return emf.createEntityManager();
}

  public Employee getEmployeeFromRequestParam(Object employee) {
    EntityManager em = getEntityManager();
     try{
       Employee o = em.merge((Employee) employee);
       return o;
     } finally {
       em.close();
     }
  } 

  public int create(Employee employee) throws DatabaseException{
    EntityManager em = getEntityManager();
    try {
      em.getTransaction().begin();
      em.persist(employee);
      em.getTransaction().commit();
      return EmployeeDAO.PROCESSADO;
    } catch (Exception ex) {
      try{
       int opt = 0;
       if (getEmployee(employee.getId()) != null) {
         opt = EmployeeDAO.JA_EXISTE;
       } else {
         opt = EmployeeDAO.ERRO;
         throw new DatabaseException("A persistence error occurred.");
       }
       em.getTransaction().rollback();
       return opt;
      }catch(Exception sup){
        throw new DatabaseException("An error occurred attempting to roll back the transaction.");
      } finally {
        em.close();
      }
    }
  }

public void edit(Employee employee) throws DatabaseException {
EntityManager em = getEntityManager();
try {
em.getTransaction().begin();
em.merge(employee);
em.getTransaction().commit();
} catch (Exception ex) {
try {
em.getTransaction().rollback();
throw new DatabaseException(ex.getLocalizedMessage());
} catch (Exception e) {
throw new DatabaseException("An error occurred attempting to roll back the transaction.");
}
} finally {
em.close();
}
}
...
}
Listagem 2 - Parte da classe EmployeeDAO recém criada.

Fica um desafio para o leitor do blog, criar os métodos
public void destroy(Employee employee);
public List getEmployees(boolean all, 
                         int batchSize, 
                         int firstItem); 
public List getEmployees(boolean all,  
                         int batchSize,  
                         int firstItem); 
public Employee getEmployee(Integer id); 
public int getItemCount();
Por fim, na classe EmployeeController vamos fazer algumas alterações para consumir o EJB sem interface. Primeiro declare uma variável do tipo EmployeeDAO, e vamos injetar com a referência do EJB, e troque todas as referências ao código de acesso ao banco para apontar para o nosso EJB DAO, veja como ficou na classe EmployeeController na Listagem 3.

public class EmployeeController {
private Employee employee = null;
private List employees = null;
public int batchSize = 5;
private int firstItem = 0;
private int itemCount = -1;
@EJB
EmployeeDAO dao;

public SelectItem[] getEmployeesAvailableSelectMany() {
return getEmployeesAvailable(false);
}

public SelectItem[] getEmployeesAvailableSelectOne() {
return getEmployeesAvailable(true);
}

private SelectItem[] getEmployeesAvailable(boolean one) {
List allEmployees = getEmployees(true);
int size = one ? allEmployees.size() + 1 : allEmployees.size();
SelectItem[] items = new SelectItem[size];
int i = 0;
if (one) {
items[0] = new SelectItem("", "---");
i++;
}
for (Employee x : allEmployees) {
items[i++] = new SelectItem(x, x.toString());
}
return items;
}

public Employee getEmployee() {
if (employee == null) {
employee = getEmployeeFromRequest();
}
if (employee == null) {
employee = new Employee();
}
return employee;
}

public String listSetup() {
reset(true);
return "employee_list";
}

public String createSetup() {
reset(false);
employee = new Employee();
return "employee_create";
}

public String create() {
int resultado = dao.PROCESSADO;
try {
resultado = dao.create(employee);
if (resultado == dao.PROCESSADO) {
addSuccessMessage("Employee was successfully created.");
} else if (resultado == dao.JA_EXISTE) {
addErrorMessage("Employee " + employee + " already exists.");
}
} catch (Exception ex) {
ensureAddErrorMessage(ex, ex.getLocalizedMessage());
}
return listSetup();
}

public String detailSetup() {
return scalarSetup("employee_detail");
}

public String editSetup() {
return scalarSetup("employee_edit");
}

private String scalarSetup(String destination) {
reset(false);
employee = getEmployeeFromRequest();
if (employee == null) {
String requestEmployeeString = getRequestParameter("jsfcrud.currentEmployee");
addErrorMessage("The employee with id " + requestEmployeeString + " no longer exists.");
String relatedControllerOutcome = relatedControllerOutcome();
if (relatedControllerOutcome != null) {
return relatedControllerOutcome;
}
return listSetup();
}
return destination;
}

public String edit() {
EmployeeConverter converter = new EmployeeConverter();
String employeeString = converter.getAsString(FacesContext.getCurrentInstance(), null, employee);
String currentEmployeeString = getRequestParameter("jsfcrud.currentEmployee");
if (employeeString == null || employeeString.length() == 0 || !employeeString.equals(currentEmployeeString)) {
String outcome = editSetup();
if ("employee_edit".equals(outcome)) {
addErrorMessage("Could not edit employee. Try again.");
}
return outcome;
}
try {
dao.edit(employee);
addSuccessMessage("Employee was successfully updated.");
} catch (DatabaseException ex) {
String msg = ex.getLocalizedMessage();
if (msg != null && msg.length() > 0) {
addErrorMessage(msg);
}else if (getEmployeeFromRequest() == null) {
addErrorMessage("The employee with id " + currentEmployeeString + " no longer exists.");
return listSetup();
} else {
addErrorMessage("A persistence error occurred.");
}
return null;
}
return detailSetup();
}

public String destroy() {
employee = getEmployeeFromRequest();
if (employee == null) {
String currentEmployeeString = getRequestParameter("jsfcrud.currentEmployee");
addErrorMessage("The employee with id " + currentEmployeeString + " no longer exists.");
String relatedControllerOutcome = relatedControllerOutcome();
if (relatedControllerOutcome != null) {
return relatedControllerOutcome;
}
return listSetup();
}
try {
dao.destroy(employee);
addSuccessMessage("Employee was successfully deleted.");
} catch (DatabaseException ex) {
ensureAddErrorMessage(ex, ex.getLocalizedMessage());
return null;
}

String relatedControllerOutcome = relatedControllerOutcome();
if (relatedControllerOutcome != null) {
return relatedControllerOutcome;
}
return listSetup();
}
...
}

Listagem 3 - Classe EmployeeController refatorada para utilizar o EJB DAO sem interface

Perceba que na expressão "@EJB EmployeeDAO dao" estamos referenciando ao EJB, sem interface para atrapalhar, claro que não é possível criar uma instância utilizando a palavra reservada new ainda, na verdade estamos trabalhando com um proxy, mas se quisermos podemos fazer um lookup utilizando JNDI também.
Vou deixar o restante dos métodos para o leitor resolver, é apenas trocar a referencia pela classe dao conforme os métodos acima.


Compile e faça o deploy, rode a aplicação, se tudo deu certo você irá ver a sua aplicação rodando (ver figura 2) com um EJB sem interface, e o melhor, o EJB está dentro de um arquivo .war, já estamos implementando o empacotamento simplificado.






Veja como ficou o empacotamento do nosso projeto na Figura 3.



Para maiores informações sobre o futuro do Java Corporativo, leia a edição 31 da Mundo Java, que ainda traz ótimos artigos como:

  • EJB 3.1:Conheça as Novidades do Futuro do Java Corporativo.
  • Autor:Wagner Roberto dos Santos
  • Grizzly e Comet - Ajax Reverso com Escalabilidade.
  • Autor: Pedro Cavalero
  • Usando o Mavem para melhorar a Qualidade dos seus Projetos.
  • Autor:Márcio Varchavsky
  • Criando Software mais próximo do Cliente com Domain-Drivgen Design.
  • Autor:Sérgio Lopes
  • Setembro: Mês de Java.
  • Autor:Mauricio Leal
  • Testes de unidades Avançadas com JMock 2
  • Autor:Eduardo Guerra
  • Gerenciamento de Conteúdo Web com OpemCMS -Customização de Sites.
  • Autor:Rodrigo Cunha de Paiva
  • Tirando o Máximo dos Interceptors no Struts2.
  • Autor: José Yoshiriro Ajisaka Ramos
  • Tendências em Foco:Ganhando com Open Source
  • Autor:Cezar Taurion
  • Jogo Rápido
  • Autor:Charbel Symanski e Rodrigo Barbosa Cesar
  • Mundo OO: Requisitos Executáveis com FIT
  • Autor:Rodrigo Yoshima
  • SOA na Pratica:Iniciando Projetos SOA.
  • Autor:Ricardo Ferreira









Diversão Garantida !!!