sábado, 4 de dezembro de 2010

Arquitetura do ZK

Neste artigo, irei abordar sobre a arquitetura do ZK. Mas antes disso, gostaria de falar sobre alguns conceitos importantes:
  1.  POJO(Plain Old Java Objects) - São objetos Java que não dependem da herança de interfaces ou classes de frameworks externos. Outro link.
  2. JavaScript - Linguagem de script interpretada pelo borwser.
  3. DOM(Document Object Model) - Convenção criada peloa w3school, independente de plataforma e linguagem, para acessarem e manipularem elementos XML, HTML e XHTML através de objetos.
  4. AJAX(Asynchronous Javascript And XML) - Significa o uso de tecnologias como JavaScript e XML, providenciadas pelo navegador, para tornar as páginas Web mais interativas com os usuários, através de requisições assícronas.
Esse artigo foi baseado no texto do site do ZK: http://books.zkoss.org/wiki/ZK_Developer's_Reference/Architecture_Overview

Será abordado 2 perspectivas sobre o ZK: Aplicação e Componente. A primeira mostra uma visão a nível de aplicação, a segunda mostra uma visão a nível de componente.

Visão geral da arquitetura:

Visão do desenvolvedor da aplicação:

O ZK possui uma arquitetura server-centric(centrada no servidor), isso quer dizer que a aplicação ZK roda no servidor. Ela pode acessar os recursos backend, montar a interface com os componentes, ouvir a atividades do usuário, e então manipular componentes para atualizar a interface. Tudo é feito no lado do servidor. A sincronização dos estados dos componetes entre o browser e o servidor é feito automaticamente pelo ZK, e transparente pela aplicação.

Quando executada no servidor, a aplicação pode acessar a stack completa da tecnologia Java. Atividades do usuário são, incluindo AJAX e Server Push, abstraidas para objetos de eventos. A interface são compostas por componentes tipos POJO. Essa é a abordagem mais produtiva para desenvolver uma moderna aplicação web.

A partir do ZK 5, foi introduzido uma mundaça na arquitetura chamada de Server+Client Fusion. Assim a sua aplicação não para no servidor. É possível melhorar a interatividade de sua aplicação através da adição opicional de funcionalidades do lado do cliente(client-side), como o tratamento de evento pelo lado do cliente, efeitos visuais customizados, e até mesmo compor interfaces sem a codificação no lado do servidor. A versão 5 permite a fusão perfeita do servidor e cliente.Assim, voce pode ter o melhor dos 2 mundos: produtividade e flexibilidade.
Um artigo serã escrito mais tarde abordando o Server+Client Fusion.

Visão do desenvolvedor de componente:

Cada objeto de interface no ZK consiste de um componente e um widget. Um componente é um objeto Java sendo executando no servidor o qual representa um objeto de interface o qual pode ser manipulado por uma aplicação Java. Um componente possui todos os comportamentes de objeto de interface exceto a parte visual. Um widget é um objeto Javascript sendo executado no cliente. Esse objeto representa o objeto de interface o qual interage com o usuário. Por isso, um widget geralmente poussi uma aparencia visual, e manipula eventos ocorridos no cliente.

O relacionamento entre um componete e um widget é um um-pra-um. Mas, se um componente não é anexado a uma página, ele não possuirá um widgt correspondente no cliente. Por outro lado, é permitada a aplicação instanciar widgets no cliente diretamente sem o componente correspondente.

É função do componente sincronizar os estados e distribuir a carga. O ZK Client Engine and update Engine trabalham juntos para propocionar um elegante e robusto canal para simplificar a implementação.

Por exemplo, assuma que voce queira implementar um componente que permite o usuário clicar sobre um elemento DOM para mostrar alguma informação detalhada de um componente. Existe pelo menos 2 abordagens para essa implementação. Primeiro, nós podemos carregar a informação detalhada para o cliente quando o widget é instanciado, e então mostrar o detalhe via código client-side. Alternativamente, nós podemos preferir não carregar a informação do detalhe logo de começo, e então enviar uma requisição de volta ao servidor para preencher o detalhe quando o usuário clicar.

Obviamente, a primeira abordagem requer mais largura de banda para a requisição inicial mas possui uma resposta rápida quando o usuário clicar. Porém, isso é geralmente transparente para o desenvolvedor da apicação, e a implementação do componente pode ser aperfeiçoada conforme a fase de desenvolvimento da aplicação.

Fluxo de Execução do carregamento de uma página:

  1. Quando um usuário digita uma URL ou clica num link no browser, uma requisição é enviada para o servidor web. Se a URL requisitada corresponde ao padrão de URL configurado do ZK(isso pode ser customizado), o ZK loader é então invocado para servir a essa requisiçáo.
  2. O ZK loader carrega a página especificada e interpreta-a para criar os componentes especificos de acordo com a página.
  3. Depois de interpretar a página toda, o ZK loader renderiza o resultado em uma página HTML. A página HTML é então enviada de volta ao browser acompanhada do ZK Client Engine.
  4. O ZK Client Engine renderiza os widgets em elementos DOM e insere os elementos DOM na árvore DOM do borwser para torná-los visíveis ao usuário.
  5. Logo, o ZK Client Engine fica no browser para servir as requisições feitas pelo usuário. Se ele vai para outra página, o fluxo de execução começa novamente. Se ele vai enviar uma requisição AJAX de volta, outro fluxo de execução começa conforme descito no próximo item.
O ZK Client Engine é escrito em JavaScript. Browsers irão fazer cache do Z Client Engine, logo ele é geralmente enviado apenas uma vez no primeiro acesso.

Fluxo de Execução ao servir uma requisição AJAX:

  1. O fluxo de execução é iniciado pelo widget ou pela aplicação; geralmente causado por uma atividade do usuário(ou requisitos da aplicação). Isso é geralmente feito por enviar uma evento do lado do cliente(Event) para um widget (Widget.fire(Event, int)).
  2. O evento é então propagado ao pai do widget, ao pai do pai, e finalmente ao ZK Client Engine(Um widget pode escolher parar essa propagação através de Event.stop(Map)).
  3. Se necessário, o ZK Client Engine envia uma requisição AJAX para o ZK Update engine no servidor( Do ponto de vista do servidor, uma requisição AJAX é apenas outra requisição HTTP).
  4. Ao receber uma requisição AJAX, o ZK Update Engine invoca o ComponentCtrl.service(AuRequest, boolean) para o tratamento da requisição.
  5. A manipulação é com o componente. Mas, geralmente é feita a atualização dos estados, se necessário, e então notifica a aplicação enviando eventos( Events.postEvent(Event)).
  6. Se algum evento for enviado, o ZK Update Engine processará eles um-por-um invocando os events listeners, se houver.
  7. O event listener, provido por uma aplicação, pode escolher atualizar os recursos de backend, atualizar os componentes ou postar outros eventos.
  8. Finalmente, o ZK Update Engine recolhe todas as atualizações de componentes, incluindo mudanças nos estados, attachment e detachment. Otimizá-os, e depois envia de volta uma coleção de comandos de volta ao cliente.
  9. O ZK Client Engine avalia cada um desses comandos para atualizar o widget de acordo com cada um. E, os widgets atualizarão a árvore DOM do browser para torná-los disponíveis para o usuário.

Quando enviar uma requisição AJAX:

Quando o ZK Client Engine recebe um evento propagado pelo lado do cliente(Event), ele decidirá se e quando enviar o mesmo de volta ao servidor para processamento adicional.
  1. Se existe um event listener não adiável(deferrable) registrado no servidor, o pedido é enviado imediatamente. Um event listener não adiável é um event listener (EventListener) que não implementa Deferrable. Por padrão, (sem implementar Deferrable) todo o evento é enviado imediatamente ao servidor quando ele é acionado no cliente.
  2. Se existe um event listener adiável registrado no servidor, a requisição será colocado numa fila no cliente e será enviada quando outro evento for acionado e um event listener não adiável for registrado por ele. Para tornar um listener adiável, voce deve implementar Deferrable e retornar true para isDeferrable().
  3. Se o widget declarar o evento o evento como importante(ComponentCtrl.CE_IMPORTANT), o evento será adicionado na fila para ser enviado depois também.
  4. Se não for nenhum dos casos acima ou o widget não tem nenhum componente corresponde no servidor, o evento é cancelado.
Os eventos adiáveis são usados para melhorar o desempenho, minimizando o tráfego entre o cliente e o servidor. É comumente usado por events listener que mantém estados da aplicação, ao invés de gerar respostas visuais.

Bem galera é essa é uma breve visão da arquitetura do ZK.. No próximo artigo irei falar de mais alguns conceitos importantes.

sexta-feira, 5 de novembro de 2010

Primeiros Passos

Com o nosso ambiente configurado no artigo anterior, vamos adicionar algums funcionalidades a nossa tela e ver como o ZK Studio funciona.

O Zk Studio permite auto-complete dentro de arquivos .zul e possui alguns recursos interessantes como drag-and-drop de componentes para os arquivos ZUL através do ZUL Palette, visualização em árvore dos componentes dentro do Outline, manipular as propriedades de um componente selecionado dentro do Properties, renderização do arquivo zul dentro do ZUL Visual Editor e uma vizualização das versóes instaladas e exemplos de códigos através do Sample Codes.

Sabendo um pouco melhor como o ZK Studio é estruturado, vamos começar a modificar o nosso exemplo.
Com o Eclipse aberto, vamos mudar a perspectiva para a do ZK. No canto superior direto, clique no botão "Open Perspective" e escolha a do ZK.

Feito isso sua tela deve estar parecida com essa:
Feito isso vamos abrir o arquivo index.zul e editar alguns coisas:

<?page title="Hello World"?>
<window title="Minha Primeira Janela" border="normal" width="200px">
<label value="Hello World!" />
</window>

Troquei o atributo title da pagina e da window, e o value de label.
Rode o servidor, e a tela gerada deve ficar assim:

Em ZK, voce escreve em ZUML(ZK User Interface Markup Language), linguagem essa baseada em XML.
Cada atributo alterado, altera cada propriedade de um componente.
Algumas propriedades do componente Window:

Propriedade Função Valor
title Define o título da janela qualquer texto
border Define o estilo de borda da janela normal ou none (padrão)
height Define a altura da janela numero de pixels (Ex: 100px)
width Define o comprimento da janela numero de pixels (Ex: 100px)
closable Define se ou não a janela pode ser fechada true ou false
sizeable Define se ou não a janela pode ser redimensionada true ou false
Vamos alterar a nossa janela pra ficar com um comprimento de 100px, ser redimensionável e fechada. Com as mudanças feitas, basta voce recarregar a pagina. Deve ficar assim:
Tente redimensionsar e/ou fechar a janela.

Agora vamos adicionar uma botão e um evento, ficando assim:

<?page title="Hello World"?>
<window title="Minha Primeira Janela" border="normal" closable="true"
sizable="true" width="200px">
<label value="Hello World!" />
<button label="sayHello" onClick='alert("Hello World!")' />
</window>

Ficando assim:

O evento onClick é acionado quando o botão é clicado, gerando, nesse caso, um alert com o valor "Hello World!". A função alert() é um função global que gera um alerta, similar a função alert() presente no Javascript. O ZK possui alguns objetos e funções globais, mas isso será abordado em outro artigo.
Mas essa não é a única maneira de descrever como o evento vai ser tratado. Eis uma outra maneira:

<?page title="Hello World"?>
<window title="Minha Primeira Janela" border="normal" closable="true"
sizable="true" width="200px">
<label value="Hello World!" />
<button label="sayHello" onClick="sayHello()" />
<zscript>
void sayHello() {
Messagebox.show("Hello World!");
}
</zscript>
</window>

Dessa vez eu escrevo o código Java dentro de um zscript. Esse tipo de tag significa que voce pode escrever scripts, mas em vez de serem processador no cliente serão processados no servidor. O zscript aceita mais de um tipo linguagens, basta voce dizer qual no atribute language, sendo Java o padrão.
Podemos observar que dessa vez eu utilizei uma outra maneira de criar um alert através do objeto Messagebox, similar ao JOptionPane, podendo passar vários parametros nas funções caso eu queira uma mensagem tipo alerta ou error.
Agora, se quisessemos, por exemplo trocar uma tributo o nome do nosso label?
Podemos fazer isso acessando o componente pelo id. Para cada componente é gerado um id automaticamentetem, mas eu posso definiar uma, e nesse caso foi o que eu fiz :

<?page title="Hello World"?>
<window title="Minha Primeira Janela" border="normal" closable="true"
sizable="true" width="200px">
<label id="mylabel" value="Hello World!" />
<button label="sayHello" onClick="change()" />
<zscript>
void change() {
mylabel.value = "ZKBrasl";
}
</zscript>
</window>


Depois de o botão ter sido clicado:
O label foi alterado, sem muita dificuldade, com uma chamada de evento paracida com Java mas que por trás roda AJAX. :)
Veja que estamos alterando o atributo value do componente, mas poderiamos ter feito isso através do método setValue. Isso pode ser feito porque cada componente ZK é formado por uma parte visual e uma parte Java. Isso será abordado melhor mais em outro artigo.

O ZK tem suporte a EL (Express Language) através da sintaxe ${exp}. Vamos agora, definiar que o valor de um botão será o mesmo de um outro botão:

<?page title="Hello World"?>
<window title="Minha Primeira Janela" border="normal" closable="true"
sizable="true" width="200px">
<button id="button1" label value="sayHello" />
<button id="button2" label="${button1.label}" />
</window>

EL Será abordado melhor em outro artigo.

Até agora escrevemos os nosso códigos de tratamento de evento dentro de um arquivo .zul, mas e se quisesemos escrever em outro lugar?
Claro que podemos! O ZK tras um bom suporte ao padrão MVC, nesse caso voce deve implementar uma classe java para tratar os eventos. A classe deve estender GenericComposer.


<?page title="Hello World"?>
<window title="Minha Janela" border="normal" width="200px"
apply="view.MyComposer">
<button label="say Hello" forward="onSayHello" />
</window>

view.MyComposer

public class MyComposer extends GenericComposer {
public void onSayHello(Event evt) {
evt.getTarget().appendChild(new Label("Hello"));
}
}

Depois de o botão ter sido clicado:



Vimos um pouco mais como o ZK funciona, e como o ZK trata eventos de uma maneira simples e rápida.
Vimos alguns componentes simples, mas exitem vários outros.

Voce pode consultar uma demo dos componentes aqui:  http://www.zkoss.org/zkdemo/
No próximo artigo veremos um pouco mais de como o ZK funciona por dentro.


ATUALIZAÇÃO - 04/12/2010
Uma outra maneira mais simples na hora de tratar eventos e que eu costumo usar é fazer com que a minha classe onde eu trato os meus eventos estenda de GenericForwardComposer. Assim o nosso exemplo fica assim:


 

view.MyComposer

public class MyComposer extends GenericForwardComposer {

 Window win;
 
 public void onClick$btn(Event evt) {
  win.appendChild(new Label("Hello"));
 }
}


Dessa forma retiramos o atributo forward de button, colocamos um id nele e em window também.
Na classe, declaramos uma variável com nome similar ao id de window e do tipo Window. Dessa forma forma o ZK vai saber que aquela várial está se ligando a Window na parte de visão cujo id bate com o nome da variável e tipo também. O nome do método agora segue uma convenção de nomes para tratamentos de eventos: "event_name$component_id". Dessa forma quando o evento for disparada e redirecionado para essa classe, ele vai comparar o tipo de evento e depois o id do componente o qual  disparou o evento. Dessa forma o código fica mais limpo e máis fácil de manter.

Em geral os exemplos postados no blog irá utilizar uma abordagem mais parecida com essa.

terça-feira, 2 de novembro de 2010

Configurando o ZK

Neste artigo irei abordar a configuração do Eclipse e o ZK Studio, plugin pro Eclipse, para trabalhar com o ZK.

Ferramentas necessárias:
  1. JDK 6
  2. Eclipse Helios Java EE
  3. Tomcat 7
  4. Algum browser, recomendo o Firefox.
  5. ZK 5.0.5, versão da data deste artigo.
  6. ZK Studio
Após a instalação do JDK, baixe o Eclipse, e descompacte no local que preferir. 
No meu caso foi escolhido o caminho C:\Java\eclipse, com worspace em C:\Java\workspace.
Feito isso, baixe o tomcat 7 e descompacte para C:\Java\tomcat.
Abra o Eclipse. No menu navegue para Window -> Show View -> Other... , 
ou no canto inferior esquerdo clique no botão "Show View as fast view", e procure por Servers.
Com a janela aberta, clique com o botão direito dentro da janela e vá para New -> Server.
Nessa janela escolha o Tomcat v7.0 Server e clique next.

Na Janela seguinte, procure pelo diretório do Tomcat 7 e clique em finish.
Feito isso vamos baixar o ZK Studio. navegue até Help -> Install New Software....
Nessa Janela voce clicar em Add..., para adicionar uma nova url de busca de plugins para o Eclipse.
Em Name, coloque o nome de ZK Studio e Location o url para download descrita no site.
Feito isso, o Eclipse irá buscar o plugin. Escolha o plugin ZK Studio e instale.

Antes de criar um projeto vá em Window -> Preferences, escolha o item ZK e depois ZK Packages. Voce notará que a versão utilizada é a 3.6.3. Baixe a última versão do ZK, na janela anterior escolha clique em Add File/ Directory..., depois em File Import. Escolha o local onde está o arquivo .zip da versão do ZK e depois em finish. Marque a opção da versão mais nova. O ZK Studio não atualiza a versão do ZK sozinho, então a cada nova versão que voce deseja instalar voce deve realizar esse procedimento, É permitido que voce tenha projetos ZK com versão diferentes basta voce configurar cada projeto separadamente. A cada novo projeto, o Eclipse irá gerar com a versão escolhida aqui
Clique em apply e depois finish.
Voce pode notar que no Project Explorer existe as 2 versões das libs:
Feito isso, vamos criar um novo projeto ZK. Vá em File -> New -> Other... e escolha ZK Project.
O nome do nosso projeto vai ser HelloWorld:
Note que ele mostra a versão do ZK utilizada e o servidor a ser utilizado, podendo ser configurado antes de cada projeto.
Lembre-se de selecionar a versão 2.5 do Dynamic web module, e clique em Finish.
Feito isso vamos analisar melhor o projeto gerado:
Em Java Resources ficam as classes Java, arquivos XML, arquivos texto, etc.
Dentro de WebContent fica os arquivos que irão serão responáveis pela vista como os arquivos ZUL. No projeto gerado temos 2 : index e o timeout.
Quando um url é enviada para o servidor, o servidor irá processar e devolver o arquivo index por padrão, mas isso pode ser configurado para enviar outro arquivo. Como estamos trabalhando com uma aplicação AJAX, existe um tempo de resposta para a pagina. Quando tenta-se acessar um componente e é gerado um evento mas o tempo de resposta acabou, o servidor processa e devolve a pagina timeout com uma resposta, também podemos configurar a mensagem de timeout e o tempo de resposta.
Nessa pasta podemos ter outras pastas, contendo outros arquivos .zul, .html, .css, .js, imagens, entre outras coisas.
Dentro da pasta WEB-INF temos todas as libs usadas no projeto e os arquivos web.xml e zk.xml, usados para configurar nossa aplicação. Se precisarmos adicionar alguma lib extra, basta adicionar na pasta lib.

Agora vamos iniciar a aplicação. COm o botão direito na projeto, seleciona Run As -> Run on Server.
Irá aparecer uma tela pra voce escolher o servidor o qual voce deseja rodar a apicação. No nosso caso o tomcat já está selecionado, então basta clicar em Finish. Voce pode marcar uma opção que permite que ele sempre rode dentro do servidor selecionado, se preferir.
Feito isso temos, nossa primeira aplicação funcioando:

ATUALIZAÇÃO - 03/12/2010
Na imagem de criação de projeto ZK aparece um warning dizendo que precisa do JDK instalado.
Para resolver isso basta ir em Window->Preferences e depois navegue para Java -> Installed JREs.
Escolha a versão da jre instalada e clique em edit. Em JRE home basta colocar o caminho do JDK, no meu caso está em C:\Java\jdk1.6.0_20. Se quiser renomear o nome de jre para jdk fique a vontade.
Feito isso não vai mais aparacer aquele warning.



segunda-feira, 1 de novembro de 2010

O que é o ZK?

Inicio a minha série de postagens falando mais sobre o que o ZK:

O ZK é um framework orientado a eventos para desenvolvimento web baseado em AJAX de código aberto. Permitindo o desenvolvimento de interfaces ricas para aplicações web com pouca programação e um custo de desenvolvimento reduzido, tal como as antigas aplicações desktop. 
O ZK utiliza uma linguagem de meta-definição baseada em XML (ZUML) para definir a interface do usuário traduzindo para código HTML quando a página é solicitada pelo cliente.
O ZK foi o primeiro projeto AJAX + mobile no SourceForge.net, acumulou 1.500.000 downloads, e foi referenciado por mais de 4.000 web sites desde o lançamento da primeira versão em 2005.


O ZK possui quase tudo feito de bandeja:
  • Diversos componentes prontos: Tabbox, grid, listbox, tree, menu, combobox, bandbox, datebox, chart, hbox, vbox, window, slider, paging, audio, image, timer, include, iframe, etc
  • Drag-and-drop suportado por todos componentes
  • Menu de Contexto e Tooltips customizaveis suportado por todos componentes
  • Ordenação Customizada de listbox, grid etc
  • Auto-preenchimento para combobox
  • “Load on demand” sem escrever nenhuma linha de código
  • “Live data” ou “Load on demand” para listbox
  • Todos componentes são clonáveis e serializáveis
  • Validação e formatação para componentes de entrada de dados, com suporte completo a uso de expressões regulares e $#,##0
  • 100% API Java para os componentes Google Maps, FCKeditor, DOJO e Timeline
  • Componente Tree com paginação
  • Server push, chamado de reverse-ajax, permite o servidor enviar dados para clientes ativos, ou seja, facilmente é capaz de se desenvolver sistema de CHAT.
  • Em adição, componentes TreeModel, Timebox e Flash
  • Modelo server-side e baseado em eventos
  • Mais de 20 eventos suportados; onChange, onChanging, onScroll, onSelect, on Show, onZIndex, etc
  • Todos os eventos são processados no servidor
  • Todos os eventos estão sincronizados. Não possui problema de “Racing Condition”
  • Scripting usando expressões EL. Inclui, mas não limitado, a Java, Javascript, Ruby, Groovy e Python
  • Mudanças noa interface do usuário sem necessidade de restarting da aplicação
  • Anotações que permite uma página acessar a base de dados sem escrever código Java
  • Macro componentes
  • Facilidade em encapsular componentes puramente clientes como componentes do ZK usando 100% a API Java
  • Dialogos Modais verdadeiramente server-side
  • Internacionalização
  • MVEL plug-in

Facilidade de utilização
Simplicidade é um dos valores de base do ZK. Outra facilidades que se encontra nesse framework, é a disponibilidade com que a sua equipa de desenvolvedores está disposta a ajudar.
A criação de novos/customizados componentes é bastante simples e a documentação é muito boa e bem detalhada.


Independência de plataforma
O ZK Mobile possui vários componentes já de bandeja: listbox, listitem, textbox, image, label, command, datebox, decimalbox, intbox, frame
O ZK suporta os seguintes browsers: Internet Explorer 6/7+, Firefox 1+, Safari 2+, Mozilla 1+, Opera 9+ and Camino 1+. Escreve uma vez e rode em todos os browsers sem problemas de compatibilidade.
Roda em qualquer web Server que suporta Servlet 2.3+ e JVM 1.4+



Licença
A licença padrão do ZK é LGPL. No entanto, existem licenças pagas os componentes mais avançados que segue o mesmo padrão do famoso MySQL.


Integração com outros frameoworks
Possui integração com outros frameworks, como Spring, Hibernate, JSP, JSF. ExtJs, Google Maps, FCKeditor, DOJO e Timeline.


Enfim, muitas coisas ficaram por analisar. 
Com muitos componentes já prontos, AJAX imbutido, integração com frameworks populares, suporte da comunidade e open-source, torna o ZK uma exelente escolha para o desenvolvimento de aplicações web.


    sábado, 18 de setembro de 2010

    Primeiro Post...

    Olá a todos!
    Assim estreio a minha participação no meu primeiro Blog! rs
    Esse blog tem como objeto falar sobre o framework RIA ZK, coisas relacionadas a Java e desenvolvimento de software.
    Espero abordar tanto o basico quanto o avançado na parte de desenvolvimento web com o ZK.

    That's all folkes!