segunda-feira, 13 de agosto de 2012

Criando meu próprio Framework (Parte 1)


Introdução (que não tem nada a ver com Java)
Amigos leitores, eu fiquei alguns meses sem postar nada aqui. Mudei de empresa! Ai já viu né? Dei um gás inicial no meu novo emprego, zerei alguns jogos de Playstation 2 (ICO, Resident Evil 4, Shadow of Collossus, etc), voltei a tocar guitarra, enfim... acabei ficando sem tempo pra postar. Agora que já estou mais tranquilo aqui no emprego, já satisfiz meus vícios de nerd e de rockeiro, e voltei a escrever.
Ahhh, só pra constar, esse site aumentou um pouco o número de visitantes nesses últimos meses – alcançou a incrível marca de 1 visitante por hora (hehehehe... putz). Não é nenhum Google da vida, mas agente chega lá.
 
Introdução (de verdade agora)
Como sempre, gosto de postar tópicos associados às situações corriqueiras do dia de analista. Recentemente mudei de emprego (como disse acima) e algumas de minhas bibliotecas Java ficaram na empresa antiga. Resultado: tive que programar as mesmas coisas novamente. Eu tinha iniciado um projeto (www.linubr.org - acho que já saiu do ar o site) de framework geral para aplicações simples, mas infelizmente não pude continuar o projeto. Esse projeto já estava bem adiantado, mas incompleto. Alguns de seus recursos só fariam sentido quando uma versão razoável estive pronta. Mas isso não ocorreu.
 
Resolvi então deixá-lo de lado e iniciar uma construção de elementos simples para um framework de auxílio (um projeto menos audacioso que o linubr.org original). E é exatamente disso que trato nesse tutorial. Estou disponibilizando aqui uma biblioteca simples, que trata de Exceções e LOG. Pra não ter que ficar programando essa mesma solução sempre. Aqui no meu novo emprego já estou adotando-a.
 
Entendo a biblioteca
Clique aqui para verificar a API. Essa biblioteca simplesmente serve para criar Exceções para sistemas corriqueiros e já criar o LOG para essas Exceções automaticamente. Veremos então um exemplo simples e um exemplo aprimorado de como usar esses recursos.
 
Exemplo Simples
Nesse exemplo, criamos algumas classes internas para simular a construção de uma aplicação com camadas EAO, BO e View.
 
package br.com.linu.test;
 
import br.com.linu.util.exception.BOException;
import br.com.linu.util.exception.EAOException;
import br.com.linu.util.exception.ExceptionFacade;
import br.com.linu.util.exception.SEViewException;
 
 
public class MainTest {
 
      public class MyEAO {        
            public void metodoQualquer() throws EAOException {
                  ExceptionFacade.throwEAO( "Ocorreu um erro de acesso aos dados." );
            }          
      }
     
      public class MyBO {         
            public void metodoQualquer() throws BOException {
                  try {
                        MyEAO eao = new MyEAO();
                        eao.metodoQualquer();
                  } catch (EAOException e) {
                        ExceptionFacade.throwBOWithLOG( "Não foi possível acessar os dados." );
                  }
            }          
      }
     
      public class MyView {       
            public void metodoQualquer() throws SEViewException {
                  try {
                        ( new MyBO() ).metodoQualquer();                    
                  } catch (BOException e) {
                        ExceptionFacade.throwSEView( e );
                  }
            }          
      }
     
      public class MyGeneralProgram {         
            public void metodoQualquer() {
                  try {
                        ( new MyView() ).metodoQualquer();                  
                  } catch (SEViewException e) {
                        ExceptionFacade.showMessage(null, e);
                  }
            }          
      }
     
      public static void main(String[] args) {
 
            MainTest test = new MainTest();
            ( test.new MyGeneralProgram() ).metodoQualquer();
 
      }
 
}
 
Observe que em todos os casos foram utilizados os métodos estáticos da ExceptionFacade. Não entrarei em detalhes profundos da utilização dos exceptions em si, pois através dessa fachada podemos utilizar todos os recursos de exceção com ou sem LOG, inclusive com possibilidade de mostrar a mensagem JOptionPane em sistema SE. Por opção, não implementei a exception padrão para sistema EE (para não precisar agregar o pacote JSF nessa jar), mas você pode implementar essa classe facilmente (baseando-se na classe SEViewException).
 
Exemplo Complexo
Nesse exemplo vou demonstrar como usar esses recursos porém com definição dos Consoles onde os LOGs serão gerados. Por default (no caso simples acima, por exemplo) é gerado um arquivo de LOG no diretório da aplicação e no prompt de saída onde a aplicação foi executada. Podemos definir quantos Consoles quisermos para nossa aplicação. Foram definidos os seguintes tipos: PromptConsole, FileConsole e TextAreaConsole.
 
package br.com.linu.test;
 
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
 
import br.com.linu.util.logging.LogManager;
import br.com.linu.util.logging.LoggingSingleton;
import br.com.linu.util.logging.console.FileConsole;
import br.com.linu.util.logging.console.PromptConsole;
import br.com.linu.util.logging.console.TextAreaConsole;
 
public class MainTestFrame extends JFrame {
 
      private static final long serialVersionUID = -7834252451139464178L;
      private JTextArea textArea;
     
      public MainTestFrame() {
            super( "Teste de Framework" );
            setLayout( new BorderLayout() );
            setSize( 600 , 200 );
            setLocation( 100 , 100 );
           
           
            JPanel buttonPane = new JPanel();
            FlowLayout flowLayout = new FlowLayout( FlowLayout.CENTER );
            buttonPane.setLayout( flowLayout );                 
            JButton button = new JButton("Clique-me");
            buttonPane.add( button );         
            button.addActionListener(
                        new ActionListener() {                        
                             @Override
                             public void actionPerformed(ActionEvent event) {
                                   MainTest test = new MainTest();
                                   ( test.new MyGeneralProgram() ).metodoQualquer();
                             }
                        }
            );
           
            textArea = new JTextArea();
            textArea.setEditable( false );
            textArea.setFont( new Font( Font.MONOSPACED , Font.PLAIN , 12 ) );
            JScrollPane scrollPane = new JScrollPane( textArea );           
           
            getContentPane().add( scrollPane );
            getContentPane().add( buttonPane , BorderLayout.SOUTH );
           
            configLog();
            setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
            setVisible( true );
      }
     
      private void configLog() {
            LogManager logManager = new LogManager();
            FileConsole file = new FileConsole("/home/guilherme", "meuArquivoLog.log");
            TextAreaConsole textAreaConsole = new TextAreaConsole( textArea );
            logManager.addConsole( new PromptConsole() );
            logManager.addConsole( file );
            logManager.addConsole( textAreaConsole );
            LoggingSingleton.setLogManager(logManager);
      }
     
      public static void main(String args[]) {
            new MainTestFrame();
      }
     
}
 
Neste exemplo, o método configLog() cria um novo LogManager e adiciona três tipos de Console: um console padrão de Prompt, um de arquivo (que salvará o arquivo no diretório /home/guilherme com o nome meuArquivoLog.log) e um JTextArea utilizado no JFrame da aplicação. Este é um típico caso de configuração de LOG.
Para exemplificar o restante da lógica, utilizei a MainTest() criada no exemplo simples.
 
Download
 
Conclusão
Bom, conforme disse, eu estou criando esse material para uso próprio e para manter uma documentação auto-explicativa sobre a biblioteca. Mais recursos serão acrescentados em breve.
 
Valeu pela leitura galera.

Nenhum comentário:

Postar um comentário