Applets ultrapassados? Ainda não!

Este blog deixou de ser mantido, mas o autor continua escrevendo aqui. Não deixe de assinar o novo feed!

JavaApesar de eu compartilhar a opinião de muita gente a respeito do FISL, alguns pontos interessantes merecem algum destaque, como o suporte a Comet no Glassfish e algumas curiosidades a respeito do projeto JavaDB.

Bom, estávamos (eu mais o pessoal do JavaFree) lá no FISL quando, do nada, começamos a puxar conversa com o Francois Orsini, um dos desenvolvedores principais do projeto JavaDB. Tirando a conversa afiada, ele nos mostrou uma aplicação bastante interessante que está preparando para o JavaOne… algo simples, mas bem legal. Na verdade, seria mais legal ainda se ele tivesse conseguido fazer o trem funcionar, mas a idéia não deixa de ser boa. :D

O projeto nada mais é do que uma aplicação web bem simples onde o banco de dados é embarcado, ou seja, roda internamente à aplicação. O detalhe é que a aplicação é composta basicamente de um arquivo HTML simples e um applet, sem nenhum application server ou servlet container rodando! O banco de dados em questão é, adivinhem, o JavaDB. Gastei alguns bons minutos para entender como o negócio funciona e estou escrevendo este post para compartilhar o conhecimento com você.

Mas, fique tranqüilo… não é nenhum bixo de sete cabeças. Mais importante que entender o código é tentar imaginar as situações onde tal arquitetura nos poderia ser útil. Bom, quem foi que disse que um applet só serve para que os bancos implementem seus teclados virtuais? :P

Baixando a aplicação

Primeiramente, baixe a aplicação de demonstração através deste link. Veja que o código é composto basicamente por três arquivos: o arquivo HTML e dois JARs (um com o código da aplicação e outro com o JavaDB).

Entendendo a interação entre o HTML e o applet Java

Vamos ver alguns trechos importantes do código HTML. Primeiramente, a declaração do applet:

  1.  
  2. <APPLET CODE="derby.embedded.ClientStoreService.class" CODEBASE="./Java" WIDTH=1 HEIGHT=1 NAME="ClientStoreService" ARCHIVE="demo.jar, derby.jar"></APPLET>
  3.  

O applet em questão poderá ser acessado através do elemento HTML document.ClientStoreService, como podemos ver em outros trechos do código:

  1.  
  2. <script language="JavaScript" type="text/javascript">
  3.   var needToConfirm = false;
  4.   var needToSave = false;
  5.   var dataSource = "DerbyTaxDB";    // DataSource to connect to
  6.   var userAuthenticated = false;
  7.  
  8.   // Login to the Store Service
  9.   function storeLogin(userName, password)
  10.   {
  11.  
  12.     var dbValues = document.ClientStoreService.login(userName, password, dataSource);
  13.      
  14.     …
  15.   }
  16. </script>
  17.  

Existe muito código JavaScript para interagir com o applet, como podemos ver no arquivo, entretanto, tudo o que tais métodos fazem é invocar os métodos no applet e obter as respostas (que são strings formatadas em XML).

O restante do código nada mais é do que um DHTML, usado para disparar as invocações de método no applet (que, por sua vez, interage com o banco de dados embarcado), formatar campos, habilitar/desabilitar campos e assim por diante.

Vale lembrar que o applet está oculto nesta aplicação… não se percebe sua presença, a não ser pelo delay que ocorre ao se iniciar a aplicação pela primeira vez, causado pelo download dos arquivos JAR. O applet só está ali para iniciar o banco de dados e fornecer uma interface entre este banco e o código JavaScript.

Vamos ver agora um trecho do código do applet ClientStoreService:

  1.  
  2.  
  3. // package e imports…
  4.  
  5. public class ClientStoreService extends Applet implements Runnable {
  6.  
  7.     // Dados de conexão
  8.     static final String framework = "embedded";
  9.     static final String driver = "org.apache.derby.jdbc.EmbeddedDriver";
  10.     static final String protocol = "jdbc:derby:";
  11.  
  12.     public void init() {
  13.         log("ClientStoreService: init() was called");
  14.  
  15.         try {
  16.             storeSetup();
  17.         } catch (Exception e) {}
  18.     }
  19.  
  20.     public String login(String userName, String password, String dbName) throws Exception {
  21.  
  22.         try {
  23.             Connection c = ds.getConnection();
  24.             Statement s = c.createStatement();
  25.  
  26.             ResultSet rs = s.executeQuery("SELECT * FROM DerbyTax");
  27.  
  28.             xml = Util.toXML(rs);
  29.             return xml;
  30.     }
  31.  
  32.     public void shutdown() {
  33.  
  34.         try {
  35.             DriverManager.getConnection("jdbc:derby:;shutdown=true");
  36.         }
  37.         catch (Exception e) {}
  38.         System.gc();
  39.     }
  40.  
  41.     private void storeSetup() throws Exception {
  42.  
  43.         ds = new EmbeddedDataSource();
  44.  
  45.         // We attempt to create a database named "DerbyTaxDB"
  46.         ds.setCreateDatabase("create");
  47.         ds.setDatabaseName("DerbyTaxDB");
  48.  
  49.         try {
  50.          c = ds.getConnection();
  51.         } catch (Exception e) {}
  52.  
  53.         // create some data in the database
  54.     }
  55. }
  56.  

Novamente avisando, este código é meramente ilustrativo e é apenas um pequeno trecho do código real, que nos servirá para entender um pouco do que esse applet faz.

O método init() e o shutdown(), assim como outros métodos que foram suprimidos, são métodos de ciclo de vida do applet. Esses dois métodos em particular servem, respectivamente, para iniciar e fechar a conexão com o banco de dados.

O método login(), serve para verificar se um determinado usuário está cadastrado no banco antes de conceder acesso ao sistema. Existe também uma classe utilitária que serve para formatar o retorno do método em XML, que é processado pelo código JavaScript.

Veja que, apesar de ser um applet, trata-se de um aplicativo Java como qualquer outro. A diferença é que este irá rodar “dentro do browser”.

O que está acontecendo neste código?

Vamos por partes. Imagine que você tenha acessado a aplicação pela primeira vez. Então, os arquivos JARs serão baixados e o applet será carregado.

Quando o applet é carregado, um novo banco de dados JavaDB é criado com algumas informações. Esse banco de dados fica então disponível para o código JavaScript, que utiliza os métodos do applet para gravar as informações digitadas no banco de dados. Perceba pelo código DHTML que o banco de dados é gravado sempre que um campo no HTML é modificado, o que permitirá que as informações digitadas não sejam perdidas ao se fechar o browser.

Finalmente, quando a aplicação é encerrada (o browser fechado, por exemplo), a conexão com o banco de dados também é encerrada. Como já era de se esperar, mesmo ao se fechar o browser, os arquivos JAR e o banco de dados criado pelo applet permanecem gravados na máquina. Então, quando a aplicação for iniciada posteriormente, os mesmos dados digitados anteriormente estarão disponíveis.

Conclusões

Antes que você diga alguma coisa, não se atente ao fato de que estamos manipulando um banco de dados diretamente através de um código JavaScript. A aplicação foi feita visando a demonstração do recurso e não para demonstrar boas práticas de desenvolvimento.

Em vez disso, vamos ir um pouco além… pergunte a si mesmo: no que isso me poderá ser útil? Em um monte de coisas! Como Francois disse em sua palestra, não são todas as aplicações que precisam estar “online” o tempo todo!

Imagine só como seria legal se você pudesse entrar no GMail “offline” para organizar os e-mails e contatos, durante uma viagem de avião. Então, ao se conectar no GMail “de verdade”, todas as modificações feitas na aplicação “local” são sincronizadas com a aplicação remota. Loucura? Não precisamos ir muito longe para perceber que algo semelhante pode ser feito com a maioria dos serviços que utilizamos no nosso dia-a-dia! A maior prova disso é que já utilizamos uma abordagem bastante parecida com nossos Palmtops e PCs, onde o PC seria a versão “online” da aplicação e o Palmtop seria a versão “offline”. :P

Quem ganha com isso? Os usuários. Damos a eles a opção de recorrer à internet somente em situações onde o uso da mesma é realmente necessário, possibilitando o uso de algumas partes das aplicações sem que ele precise sair à caça de um link de internet.

Mas essa é a minha opinião. Qual é a sua?

UPDATE: O exemplo do GMail era um exemplo hipotético. Agora, o pessoal da Google lançou o Google Gears, que permite que aplicações (como o GMail) funcionem “offline”. O conceito é, de certa forma, parecido com o que foi mostrado aqui.

Foto por: Scott Schram

Tags: , , , , , , ,