terça-feira, 15 de março de 2011

Trabalhando com EXTJS

Senhores,

O caso de uso era simples: colocar um Grid dentro de um Accordion.

Criei o grupo do grid, no modo tradicional:

    // Variávl "Modelo de coluna", cria as colunas do grid.
    var clModel = new Ext.grid.ColumnModel(this.gridColumns);

    // Variável "Modelo de número de registros" cria as linhas do grid de acordo com a quantidade de registros 
    var rsModel = new Ext.grid.RowSelectionModel(this.gridSelection);
    rsModel.addListener('rowselect', function(obj, rowIndex, record){
        fmPanel.getForm().loadRecord(record);
        formataPopups(record);
    }, this);

    // Variável "Guardadora de dados do banco", esta variável será colocada dentro do rsModel para popular o grid
    var dtStoree = new Ext.data.Store({
        url: '<<local onde está o reposítório>>',
        reader: new Ext.data.JsonReader({
            successProperty: 'success',
            root: 'data',
            totalProperty: 'total'
        }, this.gridData)
    });
   
    dtStoree.addListener('load', function(store, records, options){
        initView();
    }, this);

    dtStoree.addListener('beforeload', function(store, records, options){
        var instruction = "dtStore.baseParams = { ";
        var cont = 0;
        if(tela.filterField1 != null){
            cont++;
            instruction += "\"" + tela.filterField1 + "\" : \"" + Ext.getCmp(tela.filterField1).getValue().split(' - ')[0] + "\",";
        }
        if(tela.filterField2 != null){
            cont++;
            instruction += "\"" + tela.filterField2 + "\" : \"" + Ext.getCmp(tela.filterField2).getValue().split(' - ')[0] + "\",";
        }
        if(tela.filterField3 != null){
            cont++;
            instruction += "\"" + tela.filterField3 + "\" : \"" + Ext.getCmp(tela.filterField3).getValue().split(' - ')[0] + "\",";
        }
        instruction += " }"
        if(cont>0){
            eval(instruction);
        }
    }, this);

    // Variável de montagem do painel do grid. Essa variável junta todos os componentes
    // e cria uma referencia ao grid pronto
    var gdPanel = new Ext.grid.GridPanel({
        layout: 'fit',
        autoWidth: true,
        height: 500,
        anchor: '100% 100%',
        autoScroll: true,
        // trecho a seguir redesenha o grid após a pesquisa dos dados
        view: new Ext.grid.GridView({
            forceFit:true
        }),
        cm: clModel,
        sm: rsModel,
        store: dtStoree,
        bbar: new Ext.PagingToolbar({
           pageSize: this.gridSize,
           store: dtStoree,
           displayInfo: true,
           displayMsg: 'Mostrando registros {0} - {1} de {2}',
           emptyMsg: "Nenhum registro para mostrar",
       })
    });

Logo após, coloquei a variável gdPanel dentro do construtor do Accordion:
Aqui é importante mencionar que fiz algo que não encontrei em nenhum exemplo por ai:
Ajuste de Grid dentro de Accordion em EXTJS.
Ao tentar arrumar o Grid dentro do Accordion, comecei tentando pelo próprio Grid, afinal, era este objeto que não tinha o comportamento que eu desejava.
Porém, por mais que eu tratasse o Grid, não havia como fazê-lo aparecer completo, com scroll, de forma satisfatória para o usuário final.
Então, suspeitei que o objeto do Accordion estivesse "espremendo" o Grid, não fornecendo lugar adequado para sua apresentação.
Mas o problema não foi no objeto do Accordion. Embora este tenha grupo "defaults", indicado para o conteúdo ser extendido por todos os items, o layout é controlado diretamente dentro de cada item do accordion.
O código do accordion ficou assim:

    // Variável de montagem do painel dde Accordion's. Essa variável junta todos os componentes
    // e cria uma referencia ao accordion pronto   
    var accordion = new Ext.Panel({
        title: 'Accordion Layout',
        layout:'accordion',
        defaults: {
            // Aplicado para cada painel
            bodyStyle: 'padding:15px'
        },
        layoutConfig: {
            // Configurações específicas do Grupo Accordion vão aqui
            titleCollapse: false,
            animate: true,
            autoWidth: true,
            autoHeight: 600
        },
        items: [{
            title: 'Panel 1',
            autoScroll: true,
            autoWidth: true,
            autoHeight: true,
            items: gdPanel
        }
,{
            title: 'Panel 2',
            html: '<p>Panel content!</p>'
        },{
            title: 'Panel 3',
            html: '<p>Panel content!</p>'
        }]
    });

Por fim, utilizei o objeto do accordion para gerar um formField:

    // Objeto dos "Campos do Form". Ao invés de criá-los diretamente no painel, cria-se ou juntam-se os objetos aqui.
    // o nome da variável faz referência direta a todo grupo de elementos que aparecerão na tela.
    // neste caso em específico, criou-se um objeto de grid;
    // esse grid foi colocado dentro do objeto de accordion;
    // o accordion foi colocado dentro do formFields;
    // o formFields será utilizado dentro do fmPanel;
    // o fmPanel será um objeto do painel que será criado dentro do initView, objeto que cria, efetivamente, a tela.
    var formFields = [{
        autoScroll: true,
        layout: 'column',
        width: 465,
        heigth: 50,
        labelWidth: 1,
        items: [{
            layout: 'form',
            width: 350,
            labelWidth: 85,
            items: [ {
                xtype: 'textfield',
                id: 'id',
                title: 'id',
                fieldLabel: 'id',
                width: 244,
                scope: this,
                editable: false,
                allowBlank: false,
                tabIndex: 4,
                valueDto: null,
            }]
        },{
            layout: 'form',
            width: 115,
            labelWidth: 5,
            items: [{
                xtype: 'button',
                text: 'Botão',
                minWidth : 110,
                listeners:{
                    click:function(){
                        if ( Ext.getCmp('id').getValue() != '' && Ext.getCmp('id').getValue() != 'null') {
                            fmPanel.getForm().submit(searchAction);
                        } else {
                            Ext.Msg.alert('Atenção', 'Campo id em Branco.');
                        }
                    }
                }          
            }]
        }]
    },
    accordion
    ];

terça-feira, 15 de fevereiro de 2011

Iniciando com Hibernate 3 utilizando Annotations

Estava começando a escrever um tutorial "Aprenda Hibernate do Zero" e, pesquisando referencias, encontrei exatamente o que eu queria escrever.
Tutorial fácil, segui e funcionou perfeitamente, simples de ser ampliado.

Retirado daqui:
http://www.javaframework.org/portal/2010/03/17/iniciando-com-hibernate-3-utilizando-annotations/

-------------------------------------------------------------------

O Hibernate é um dos mais famosos frameworks de persistencia. Um framework de persistencia é uma ferramenta que ajudará a persistir, ou seja, salvar, os seus dados em algum local, um banco de dados por exemplo. O Hibernate faz o mapeamento das classes de sua aplicação em tabelas e colunas do banco de dados. Com isso é possível ler e salvar objetos no banco de forma transparente. Nesse tutorial aprenderemos a configurar um projeto básico com Hibernate e utilizaremos Annotations para fazer a configuração das classes.

O primeiro passo para fazermos um projeto com Hibernate, é definir qual é a estrutura de classes iremos utilizar. Depois, criaremos as tabelas de acordo com essas classes, e faremos o mapeamento no hibernate. Essas classes serão mapeadas em tabelas no banco de dados, o hibernate então fará a comunicação entre nossa aplicação e o banco de dados.
Iremos utilizar o hibernate para fazer o mapeamento de classes para tabelas em um banco de dados, então antes de trabalharmos na aplicação é necessário configurar algum SGBD para trabalhamos. Utilizaremos nesse tutorial o HSQLDB que é um banco de dados em memória escrito em Java e vai facilitar o nosso trabalho.

1. Baixando os pacotes necessários

Para esse tutorial precisaremos baixar vários arquivos:
  • Hibernate Core (3.3.2 GA): contém o núcleo do hibernate
  • Hibernate Annotations (3.4.0 GA): contém a API necessária para configurar as classes com annotations
  • SLF4J (1.5.x): sistema de log utilizado pelo hibernate
  • HSQLDB (2.0 RC 8): banco de dados que utilizaremos no nosso exemplo
Os arquivos podem ser baixados nas seguintes URLs
Hibernate Core:
http://sourceforge.net/projects/hibernate/files/hibernate3/3.3.2.GA/hibernate-distribution-3.3.2.GA-dist.zip/download
Hibernate Annotations:
http://sourceforge.net/projects/hibernate/files/hibernate-annotations/3.4.0.GA/hibernate-annotations-3.4.0.GA.zip/download
SLF4J:
http://www.slf4j.org/dist/slf4j-1.5.8.zip
HSQLDB:
http://sourceforge.net/projects/hsqldb/files/alpha_beta/hsqldb_2_0_0_rc8/hsqldb-2.0.0-rc8.zip/download
Se desejar baixar versões diferentes será necessário verificar a compatibilidade das versões das bibliotecas. No site do hibernate existe uma planilha com a compatibilidade de versões. A versão do HSQLDB não deve influenciar na compatibilidade. A versão do SLF4J deve ser a mesma do JAR contido no hibernate core.
Baixe todos os arquivos e extraia o conteúdo para uma pasta qualquer.

2. Executando o HSQLDB

O HSQLDB, também conhecido como HyperSQL, é um banco de dados bem simples e não necessita instalação. Utilizaremos ele apenas para ser possível experimentar o hibernate. Antes de executar a aplicação que iremos montar será necessário ligar o banco de dados. Para ligar o banco de dados basta executar o arquivo runServer.bat que está dentro da pasta /hsqldb/bin. Nenhuma configuração é necessária.
Caso o banco de dados não esteja rodando quando executar a sua aplicação, um erro como o seguinte será lançado:
java.sql.SQLTransientConnectionException: java.net.ConnectException: Connection refused: connect

3. Criando um projeto e configurando as bibliotecas na aplicação

Crie um projeto no seu ambiente de desenvolvimento, é importante que seja um projeto Java 1.5 ou superior pois utilizaremos annotations. Copie e adicione ao classpath as bibliotecas das seguintes pastas dos arquivos baixados anteriormente:
\hsqldb-2.0.0-rc8\hsqldb\lib
        hsqldb.jar
\hibernate-distribution-3.3.2.GA
        hibernate3.jar
\hibernate-distribution-3.3.2.GA\lib\required (todas as bibliotecas)
        antlr-2.7.6.jar
        commons-collections-3.1.jar
        dom4j-1.6.1.jar
        javassist-3.9.0.GA.jar
        jta-1.1.jar
        slf4j-api-1.5.8.jar
\hibernate-annotations-3.4.0.GA
        hibernate-annotations.jar
\hibernate-annotations-3.4.0.GA\lib
        ejb3-persistence.jar
        hibernate-commons-annotations.jar
\slf4j-1.5.8
        slf4j-simple-1.5.8.jar
Totalizando 12 arquivos JAR.

4. Definindo a estrutura

Vamos criar apenas uma classe nessa aplicação, para ver como o hibernate funciona. Crie uma classe Produto conforme o exemplo:
package org.javaframework.persistencia;
import static javax.persistence.GenerationType.*;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Produto {

    @Id @GeneratedValue(strategy=SEQUENCE)
    Integer id;
    String nome;

    public Produto(Integer id, String nome) {
        this.id = id;
        this.nome = nome;
    }
    public Produto(){
    }

    public Integer getId() {
        return id;
    }
    public String getNome() {
        return nome;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
}

Essa classe produto possui dois atributos. O primeiro é o id, o id será utilizado apenas como a chave primária do produto, não terá utilidade na nossa aplicação. Mas para o hibernate trabalhar, precisamos definir esse atributo na classe. Escolhemos a classe Integer para o atributo id, pois utilizaremos um sequencial numérico para os registros do banco. O outro atributo é o nome do produto. Repare que foi criado um construtor sem nenhum parâmetro, esse construtor é obrigatório (caso crie um outro construtor com vários argumentos, como no exemplo).
A configuração dessa classe está nas anotações que utilizamos. A anotação @Entity define uma entidade, e deve ser utilizada em todas as classes que forem mapeadas pelo hibernate. A anotação @Id define o campo que será o primary key no banco de dados. E a anotação @GeneratedValue indica que deve ser gerado um valor quando for salvar um novo produto a estratégia utilizada é a SEQUENCE, que criará um novo sequencial para cada produto. Dependendo do banco de dados utilizado podem ser utilizadas outras estratégias, consulte a documentação do hibernate para mais informações.
Atenção para o pacote da anotação @Entity, deve ser utilizado o pacote javax.persistence. Existe outra anotação com o mesmo nome no pacote org.hibernate.annotations mas não servirá para mapear a classe, apenas para adicionar informações extras. Se utilizar a anotação do pacote errado o hibernate lançará exceções dizendo que a classe não foi mapeada.

5. Configurando o hibernate

Existem duas formas de configurar o hibernate, através de um XML ou de um arquivo de properties. Por sem mais simples, utilizaremos o arquivo de properties. Crie um arquivo chamado hibernate.properties na sua aplicação, ele deve ficar na raiz dos fontes (SRC no eclipse por exemplo) e deve estar na raiz do classpath quando executar sua aplicação (se estiver utilizando um editor, basta colocar o arquivo na pasta raiz dos fontes). O arquivo deve ficar assim:
hibernate.connection.driver_class=org.hsqldb.jdbcDriver
hibernate.connection.url=jdbc:hsqldb:hsql://localhost
hibernate.connection.username=sa
hibernate.connection.password=

# Echo all executed SQL to stdout
hibernate.show_sql=true

# Drop and re-create the database schema on startup
hibernate.hbm2ddl.auto=update

Nesse arquivo temos nas quatro primeiras linhas as informações de conexão JDBC com o banco de dados. Configuramos também a exibição de queries e que o hibernate deve criar a estrutura do banco de dados automaticamente.
Com esse arquivo o Hibernate estará configurado. Caso você nao coloque o arquivo no lugar certo com o nome correto um erro como o seguinte pode acontecer: Exception in thread "main" org.hibernate.HibernateException: ‘hibernate.dialect’ must be set when no Connection avalable.
Vamos agora criar uma classe que utilizará o hibernate.

6. Executando um programa com o Hibernate

Crie na sua aplicação a seguinte classe para podermos testar o hibernate:
package org.javaframework.persistencia;
import java.util.List;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.classic.Session;

public class HelloWorldHibernate {
    public static void main(String[] args) {
        AnnotationConfiguration config = new AnnotationConfiguration();
        config.addAnnotatedClass(Produto.class);
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        inserirProduto(session);
        listarProdutos(session);
        session.close();
        sessionFactory.close();
    }

    private static void inserirProduto(Session session) {
        Produto produto = new Produto();
        produto.setNome("Shampoo");
        Transaction tx = session.beginTransaction();
        session.persist(produto);
        tx.commit();
        System.out.println("Produto inserido");
    }

    private static void listarProdutos(Session session) {
        List<Produto> produtos = session.createQuery("from Produto").list();
        for (Produto p: produtos) {
            System.out.printf("%4d \t %s %n", p.getId(), p.getNome());
        }
    }

}
A classe HelloWorldHibernate é apenas para efeito didádico, é interessante você estruturar a sua aplicação de maneira mais elegante.
Nesse código criamos um AnnotationConfiguration que permite a configuração de classes anotadas no Hibernate. Adicionamos a classe Produto para ser adicionada a configuração. O arquivo hibernate.properties será lido automaticamente. Com essa configuração construimos um SessionFactory. Um SessionFactory serve para criamos sessões do hibernate. Devemos ter apenas um SessionFactory na aplicação mas podemos ter vários Sessions (geralmente um para cada thread, ou um por requisição no caso de aplicações web). Um SessionFactory é como um DataSource e um Session é como um Connection.
Temos dois métodos bastante simples, um é o inserirProduto, que salva um novo produto no banco de dados, inclusive utilizando uma transação. E um método listarProdutos que lista todos os produtos encontrados no banco de dados.
Se executarmos o programa veremos algo semelhante ao seguinte:
Hibernate: call next value for hibernate_sequence
Hibernate: insert into Produto (nome, id) values (?, ?)
Produto salvo
Hibernate: select produto0_.id as id0_, produto0_.nome as nome0_ from Produto produto0_
  10      Shampoo

Pronto! Já pode agora utilizar o hibernate nos seus projetos. Veja a documentação de referencia no site http://www.hibernate.org para mais exemplos de consultas, operações e mapeamentos.

sexta-feira, 11 de fevereiro de 2011

Aplicação SOA

Caso de Uso:

Tínhamos que buscar alguns dados de tabelas diferentes para utilizarmos em nosso aplicativo.
Para isso, fizemos um barramento SOA (que não vou postar por motivo de sigilo da empresa...) e conectamos este cliente a ele.

Problemas resolvidos com este código:
Swing: Utilização de tabelas dentro de abas, sem a utilização de containers.
Popular tabelas com array bidimensional de strings

SOA: Transportar strings entre o barramento e o Cliente.


-----------------------------------------------------------------------------------------------------------------



-----------------------------------------------------------------------------------------------------------------
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.encoding.XMLType;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class Unitizacao implements ActionListener{
   
    JFrame tela = new JFrame();
    JTextField TfOdex;
    JTable tbData1, tbData2, tbData3, tbData4, tbData5;
    JTextArea area6 = new JTextArea();
       
    public static void main(String args[]){
       
        // Cria o Objeto para tirar o swing de um método static
        Unitizacao u = new Unitizacao();
        u.run();
    }
   
    public void run(){
       
        // Tenta utilizar uma biblioteca de aparencia para o Swing
        try{
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        }catch(Exception e){
            area6.setText(e.getMessage());
        }
       
        // Layout null para posicionamento manual dos itens
        tela.setLayout(null);
       
        // INÍCIO GRUPO DE OBJETOS DO CABEÇALHO
       
        // Objeto do texto Odex
        JLabel LbOdex = new JLabel("ODEX");
        // Objeto Font para ajustar o tipo, estilo e tamanho da fonte
        Font t = new Font("Arial", Font.BOLD, 20);
        // Atribuindo o Objeto Font ao Objeto do texto Odex
        LbOdex.setFont(t);
     // ajustar posição do elemento no JPanel: (coluna, linha, largura, altura)
        LbOdex.setBounds(10, 40, 60, 30);
               
        // Objeto da caixa de diálogo
        TfOdex = new JTextField("");
        // ajustar posição do elemento no JPanel: (coluna, linha, largura, altura)
        TfOdex.setBounds(80, 40, 370, 30);
               
        // Objeto do botão Consultar
        JButton consulta = new JButton("Consultar");
        consulta.setBounds(480, 40, 120, 30);
        // Adiciona o listner ao Botão
        consulta.addActionListener(this);
        // Determina o comando que o listener recebe ao clicar no Botão
        consulta.setActionCommand("consultar");
       
        // Objeto do botão Sair
        JButton sair = new JButton("Sair");
        sair.setBounds(630, 40, 120, 30);
        sair.addActionListener(this);
        sair.setActionCommand("sair");
       
        // FIM DO GRUPO DE OBJETOS DO CABEÇALHO
       
        // INÍCIO DO GRUPO DE OBJETOS DE ABAS
       
        // Cria o Objeto do conjunto de Abas
        JTabbedPane tabelaDePaineis = new JTabbedPane(JTabbedPane.TOP);
        tabelaDePaineis.setBounds(0, 100, 800, 500); 
       
        // ABA 1
        // Objeto da Aba 1
        JPanel painel01 = new JPanel(null);
       
        // Objeto da Tabela
        tbData1 = new JTable();
        tbData1.setBounds(5,5,685,360);
        tbData1.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
       
        // Crio o objeto do Scroll e coloco a tabela dentro dele.
        JScrollPane sc = new JScrollPane(tbData1);
        sc.setBounds(5,5,780,430);
        // Indica que a scroll bar vertical é necessária
        sc.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        // Indica que a scroll bar horizontal é necessária
        sc.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
       
        // Adiciona a Scroll (com a tabela dentro) no objeto da primeira aba.
        painel01.add(sc);
     
        // ABA 2
        JPanel painel02 = new JPanel(null);
       
        tbData2 = new JTable();
        tbData2.setBounds(5,5,685,360);
        tbData2.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
       
        JScrollPane sc2 = new JScrollPane(tbData2);
        sc2.setBounds(5,5,780,430);
        sc2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
        sc2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
               
        painel02.add(sc2);
       
        // ABA 3
       
        JPanel painel03 = new JPanel(null);
       
        tbData3 = new JTable();
        tbData3.setBounds(5,5,685,360);
        tbData3.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
       
        JScrollPane sc3 = new JScrollPane(tbData3);
        sc3.setBounds(5,5,780,430);
        sc3.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
        sc3.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
               
        painel03.add(sc3);
       
        // ABA 4
       
        JPanel painel04 = new JPanel(null);
        tbData4 = new JTable();
        tbData4.setBounds(5,5,685,360);
        tbData4.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
       
        JScrollPane sc4 = new JScrollPane(tbData4);
        sc4.setBounds(5,5,780,430);
        sc4.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
        sc4.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
               
        painel04.add(sc4);
       
        // ABA 5
       
        JPanel painel05 = new JPanel(null);
        tbData5 = new JTable();
        tbData5.setBounds(5,5,685,360);
        tbData5.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
       
        JScrollPane sc5 = new JScrollPane(tbData5);
        sc5.setBounds(5,5,780,430);
        sc5.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
        sc5.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
               
        painel05.add(sc5);
       
        // ABA 6 - LOG
       
        JPanel painel06 = new JPanel(null);
       
        area6.setBounds(5,5,685,360);
         
        JScrollPane sc6 = new JScrollPane(area6);
        sc6.setBounds(5,5,780,430);
        sc6.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
        sc6.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
       
        painel06.add(sc6);
       
        // adiciona as abas no objeto de abas
        tabelaDePaineis.addTab("Informações",painel01);
        tabelaDePaineis.addTab("Detalhes",painel02);
        tabelaDePaineis.addTab("MaterialUC",painel03);
        tabelaDePaineis.addTab("MaterialCOM",painel04);
        tabelaDePaineis.addTab("Serviços",painel05);
        tabelaDePaineis.addTab("Log",painel06);
       
        // ADICIONANDO OS OBJETOS AO FRAME
       
        tela.add(LbOdex);
        tela.add(TfOdex);
        tela.add(consulta);
        tela.add(sair);
        tela.add(tabelaDePaineis);
               
        // SETANDO DETALHES DO FRAME
        tela.setTitle("Unitização"); 
        tela.setSize(800, 600);
        tela.setBounds(100,100, 800, 600);
        tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        tela.setResizable(false);
        tela.setVisible(true);   
    }
   
    public void actionPerformed(ActionEvent e){
        if(e.getActionCommand().equals("consultar")){
           
            String[][] resposta = null;
           
            // chama o método de conexão, passando o método que será invocado.
            resposta = conecta("Informacoes");
            // ajusta a tabela com o array retornado pela conexão.
            tbData1.setModel(new DefaultTableModel(resposta, new String[]{"1","2","3","4","5","6","7","8","9","10","11","12","13"}));
           
            resposta = conecta("Detalhes");
            tbData2.setModel(new DefaultTableModel(resposta, new String[]{"1","2","3","4","5","6","7","8","9","10","11","12","13"}));
           
            resposta = conecta("MaterialUC");
            tbData3.setModel(new DefaultTableModel(resposta, new String[]{"1","2","3","4","5","6","7","8","9","10","11","12","13"}));
           
            resposta = conecta("MaterialCOM");
            tbData4.setModel(new DefaultTableModel(resposta, new String[]{"1","2","3","4","5","6","7","8","9","10","11","12","13"}));
           
            resposta = conecta("Servicos");
            tbData5.setModel(new DefaultTableModel(resposta, new String[]{"1","2","3","4","5","6","7","8","9","10","11","12","13"}));

        }  
        if(e.getActionCommand().equals("sair")){
            System.exit(0);
        }
    }
   
    public String[][] conecta(String operacao){
       
        String[][] resposta = null;
        Service  service  = new Service();
        Call call;
        String odex = TfOdex.getText();
       
        try {

            call = (Call) service.createCall();
           
            // Atribuindo a URL do Servico
            // Importante: é necessário um serviço SOA para conexão
            call.setTargetEndpointAddress(new java.net.URL("<<INSERIR AQUI A URL DO BARRAMENTO SOA IMPLEMENTADO>>"));

            // Definindo o metodo a ser invocado
            call.setOperationName(operacao);

            // Definindo os parametros de entrada
            call.addParameter("odex", XMLType.XSD_STRING, ParameterMode.IN);

            // Definindo o tipo do parametro de retorno
            call.setReturnType(org.apache.axis.encoding.XMLType.SOAP_ARRAY);
           
            // Invocando o servico
            resposta = (String[][]) call.invoke(new Object[] {odex});

        } catch (Exception ex) {
           
            String a = "Serviço "+operacao+" "+ex.getMessage();
            area6.setText(a);
        }
        return resposta;
    }
}

quarta-feira, 9 de fevereiro de 2011

Executável JAVA via Eclipse:

JAVA é legal, as aplicações podem ficar poderosas e lindas...


Mas uma coisa incomoda: como gerar um executável?


Agora é simples, no Eclipse, tente isso:

1º - Clique com o botão direito do seu mouse em seu Projeto.

2º - Clique na opção Export.

3º - Após clicar em Export, surgirá uma outra janela, na qual você deverá clicar em Jar File.

4º - Após selecionar Jar File, clique em Next para abrir a proxima "ABA", então você ira verificar que seu projeto estara marcado com um 'vzinho' na parte que está escrito Select the resources to export... logo a sua direita existe outro quadro, neste quadro desmarque todas as opções, pois são "lixos".

5º - Na mesma aba onde está escrito: Select the export destination, coloque o local onde está a sua classe main (ali aparecerá o Ícone).

6º - Pronto, clicando em next 2 vezes, ira aparecer a ultima tela.. no qual você escolhe seu ManifestFile. Clique em Generate the manifest file. Com isso na parte de baixo da tela, irá abrir a opção Main Class, clique em browser e escolhe sua classe principal, ou seja, onde fica seu main.

Então, na pasta da main class, estará pronto seu .jar.

Obs: Caso ele execute e não abra clicando 2 vezes com o mouse, no mesmo local crie um arquivo "*.txt" e nele coloque o comando:

java -jar nomedoseujar.jar



A, e para criar um .bat, é simples.. renomei um arquivo .txt para .bat.



Tanto o .jar quanto o .bat podem ser "enviados para área de trabalho", e ter o seu ícone alterado.



Pronto.

segunda-feira, 17 de janeiro de 2011

SOA TomCat-Axis


 Guia para implementação de WebServices em Container TomCat:

Introdução:

O objetivo deste guia é mostrar – passo a passo – como implementar um webService, com servidor e cliente, funcional, em ambiente TOMCAT.
Um WebService é qualquer aplicação que é dividia em cliente e servidor.
            O Servidor: É a parte do sistema responsável pelo processamento dos dados, CRUD e encaminhamento dentro da rede.
            O Cliente pode coletar (do usuário ou de outros aplicativos ou bancos), enviar e/ou receber dados do servidor e/ou apresentar os dados enviados pelo servidor (a usuários ou encaminhar a outras aplicações).
Através dos estudos de caso, notou-se que o Container Tomcat serve para publicar páginas e aplicações web, mas não possui muito suporte sobre o processamento dos serviços. Isso porque, pelo menos para JAVA, o TomCat não disponibiliza API’s necessárias para referência nas aplicações. Assim, o princípio do servidor, de processar dados, não pode ser alcançado pela falta de capacidade de interpretação de componentes necessários.
Foi aferido que existem outros Container’s que mostram mais suporte às aplicações, como o GlassFish e o JBossESB. Destes dois, em específico, o GlassFish mostrou-se o mais simples, apresentando pouco mais que as API’s básicas para uma aplicação CRUD convencionais. O Container JBossESB, por sua vez, além de suportar aplicações JAVA, estende-as com API’s específicas para implementação de barramentos web, auxiliando desde o processo de codificação (ampliando a gama de extensões suportadas pelo Eclipse com JbossTools, por exemplo), passando por automações na comunicação entre clientes e servidores chegando a oferecer até um ambiente gráfico mais eficiente para manipulação dos arquivos que participam do webService. Claro que cada facilidade apresentada por estes outros Container’s implica em tamanho maior do Container e demora significativa no tempo de execução das aplicações.

Ambiente de Trabalho:

O TomCat, sozinho, não possui capacidade de implementar webServices.
Por isso, a Apache disponibiliza um complemento chamado Axis.

Executável TomCat:

Zip com a pasta Axis:

Complemento xerces:
 
1 – Instale o TomCat normalmente;
2 – Descompacte o zip do Axis;
3 – Mova a pasta "Axis", que encontra-se dentro do diretório webapps do arquivo, para a pasta webapps do TomCat;
4 – Descompactar o zip do xerces;
5 – Mover os arquivos “xercesImpl.jar” e “xml-apis.jar” da pasta xerces para a pasta axis\lib\ (do próprio diretório Axis, descompactado anteriormente).
6 – Criar as seguintes variáveis de ambiente:
(Criar as JAVA, caso ainda não estejam criadas, também.)

AXIS_HOME=C:\axis

AXIS_LIB=%AXIS_HOME%\lib

AXISCLASSPATH=%AXIS_LIB%\wsdl4j-1.5.1.jar;%AXIS_LIB%\axis.jar;%AXIS_LIB%\commons-discovery-0.2.jar;%AXIS_LIB%\commons-logging- 1.0.4.jar;%AXIS_LIB%\jaxrpc.jar;%AXIS_LIB%\saaj.jar;%AXIS_LIB%\log4j-1.2.8.jar;%AXIS_LIB%\xml-apis.jar;%AXIS_LIB%\xercesImpl.jar;%AXIS_LIB%\jaxrpc.jar

7 – Mover o arquivo tools.jar da pasta lib do JAVA para a pasta lib do Axis, dentro do TomCat.

8 - Pode-se testar se o ambiente está ok abrindo o navegador e digitando a seguinte URL:


Se aparecer a tela do servidor Axis, estará tudo ok.

Desenvolvimento do Servidor:

1 - Abra a IDE e crie a seguinte classe JAVA:

/*
 * Esta classe foi desenvolvida para ser referencia de teste para implementação de SOA.
 * Este é um arquivo de servidor webService.
 * Recebe duas variáveis Inteiras do cliente e devolve a soma delas para o cliente
 */

public class Calculadora {
      public int somar( int a, int b ) {
            return a + b;
      }
}

2 – Salve o arquivo do servidor;
3 – Copie o arquivo do seu contexto para a pasta:
C:\Arquivos de programas\Apache Software Foundation\Tomcat 7.0\webapps\axis\

4 – No Browser, digite a seguinte URL:

Aparecerá a seguinte tela:



Clicando no Link, você verá o arquivo WSDL:


 Agora, o servidor TomCat/Axis já possui o arquivo de comunicação pronto, aguardando o envio de dados pelo cliente.


Desenvolvimento do Cliente:

1 – Certifique-se que a IDE possui as Lib’s do Axis.
No Eclipse, para incluir as Lib’s, Basta clicar o botão direito sobre a pasta do projeto -> Propriedades.
JavaBuildPaths -> Libraries -> Add External JAR’s
Selecione todas as JAR’s da pasta LIB do Axis -> OK.

2 – Abra a IDE e crie o seguinte arquivo:

import javax.swing.*;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;
import javax.xml.rpc.ParameterMode;

public class Cliente {
     
      public Cliente(){
           
      }
     
         private void invocaServico(String endpointURL, int mensagem1, int mensagem2){

                  int resposta = 0;
                  Service  service  = new Service();
                  Call call;

                  try {

                     call = (Call) service.createCall();
                    
                     // Atribuindo a URL do Servico
                     call.setTargetEndpointAddress(new java.net.URL(endpointURL));

                     // Definindo o metodo a ser invocado
                     call.setOperationName("somar");

                     // Definindo os parametros de entrada
                     call.addParameter("a", XMLType.XSD_INT, ParameterMode.IN);
                     call.addParameter("b", XMLType.XSD_INT, ParameterMode.IN);

                     // Definindo o tipo do parametro de retorno
                     call.setReturnType(org.apache.axis.encoding.XMLType.XSD_INT);

                     // Invocando o servico
                     resposta = (Integer) call.invoke(new Object[] {mensagem1, mensagem2});

                     // Imprimindo a resposta
                     JOptionPane.showMessageDialog(null, "Servico invocado...\n" + resposta);

                  } catch (Exception ex) {
                     ex.printStackTrace();
                  }
               }
        
         public static void main(String args[]){
             args= new String[3];
             // Aqui é colocado o caminho que está indicado no arquivo WSDL.
             args[0]="http://localhost:8080/axis/Calculadora.jws?wsdl";
             args[1]="4";
             args[2]="4";
            
            
            String endpointURL = null;
            int mensagem1   = 0;
            int mensagem2   = 0;

            if (args.length < 3){
               System.out.println("Sintaxe errada. \nInforme a URL e a Mensagem");
               System.out.println("Ex: java ClientHelloWorld http://localhost:8080/axis/HelloWorld.jws \"Ola mundo\"");
               System.exit(0);
            }

            try {
               //Obtendo a URL do Servico Web
               endpointURL = args[0];

               //Obtendo a mensagem 1
               args[1] = JOptionPane.showInputDialog("Digite o primeiro fator da Soma:");
               mensagem1 = Integer.parseInt(args[1]);
              
               //Obtendo a mensagem 2
               args[2] = JOptionPane.showInputDialog("Digite o segundo fator da Soma:");
               mensagem2 = Integer.parseInt(args[2]);
              
            } catch (Exception ex) {
               ex.printStackTrace();
            }

            //Criando uma instancia da classe ClientHelloWorld
            Cliente client = new Cliente();

            //Invocando o metodo 'invocaServico'
            client.invocaServico(endpointURL, mensagem1, mensagem2);
         }
}
 
3 – Compile e Rode.


Conclusão

1 – O cliente vai solicitar dois números para o usuário;
2 – O usuário irá fornecer e clicar “OK” para cada número;
3 – O cliente irá estabelecer uma conexão através do caminho do arquivo WSDL;
3 – O cliente irá enviar dois parâmetros para o servidor: número 1 e número 2;
4 – O servidor irá receber os parâmetros, efetuar a soma e devolver o resultado;
5 – O cliente irá receber a resposta e mostrar na tela a resposta para sua solicitação.

Esta é uma aplicação básica, podendo apenas trabalhar com:
1 – Sempre precisamos ter o fonte Java disponível;
2 – A classe não pode fazer parte de nenhum pacote;
3 – Não pode utilizar outros tipos, senão os básicos do Java (primitivos, wrappers e String).

Mesmo assim, este modo de aplicação pode muito bem ser utilizada como base para vários clientes enviando e recebendo informações para um servidor com vários métodos de controle, que reenvia para os clientes corretos as informações necessárias.