rich internet applications com clientes offline utilizando gears

51
Eduardo Cereto Carvalho Rich Internet Applications com clientes offline utilizando Gears Itatiba - São Paulo - Brasil Junho de 2009

Upload: eduardo-cereto-carvalho

Post on 24-Jun-2015

2.344 views

Category:

Technology


3 download

DESCRIPTION

“Aplicações Ricas da Internet” é o nome dado às aplicações Web que fazem uso pesado de Javascript para implementar uma interface dinâmica provendo uma experiência similar a das aplicações desktop convencionais. Este trabalho mostra um pouco da história das aplicações Web, e especula sobre o futuro, fazendo um estudo de tecnologias emergentes como o Gears que trazem novas possibilidades a essa plataforma.

TRANSCRIPT

Page 1: Rich Internet Applications com clientes offline utilizando Gears

Eduardo Cereto Carvalho

Rich Internet Applications com clientes offlineutilizando Gears

Itatiba - São Paulo - Brasil

Junho de 2009

Page 2: Rich Internet Applications com clientes offline utilizando Gears

Eduardo Cereto Carvalho

Rich Internet Applications com clientes offlineutilizando Gears

Monografia, apresentada à disciplina Trabalhode Conclusão de Curso II do curso de Engenha-ria da Computação da Universidade São Fran-cisco, sob a orientação do Prof. Rodrigo Cha-vez M. do Prado, como exigência parcial paraconclusão do curso de graduação.

Orientador:

Rodrigo Chavez M. do Prado

GRADUAÇÃO EM ENGENHARIA DA COMPUTAÇÃO

UNIVERSIDADE SÃO FRANCISCO

Itatiba - São Paulo - Brasil

Junho de 2009

Page 3: Rich Internet Applications com clientes offline utilizando Gears

i

Sumário

Lista de Figuras p. iii

Resumo p. iv

Abstract p. v

1 INTRODUÇÃO p. 1

1.1 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 3

1.1.1 Objetivos Específicos . . . . . . . . . . . . . . . . . . . . . . . . . . p. 3

2 ASPECTOS TEÓRICOS p. 4

2.1 Evolução das Aplicações Web . . . . . . . . . . . . . . . . . . . . . . . .. p. 4

2.1.1 Páginas Estáticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . p.4

2.1.2 Páginas com Conteúdo Multimídia . . . . . . . . . . . . . . . . . . .p. 4

2.1.3 Aplicações Ricas da Internet . . . . . . . . . . . . . . . . . . . . . .p. 5

2.1.4 Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 5

2.1.5 HTML5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 6

2.2 Javascript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p.7

2.2.1 Ajax e DOM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 7

2.3 Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 9

2.3.1 Módulos do Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 10

2.3.2 Arquitetura de Sistemas Baseados em Gears . . . . . . . . . . .. . . p. 10

3 METODOLOGIA p. 14

Page 4: Rich Internet Applications com clientes offline utilizando Gears

ii

3.1 Aplicação de anotações . . . . . . . . . . . . . . . . . . . . . . . . . . . .. p. 14

3.2 Aplicação em Django . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 14

3.2.1 Estrutura Básica de Sistemas Django . . . . . . . . . . . . . . . .. p. 15

3.2.2 Implementando Ajax . . . . . . . . . . . . . . . . . . . . . . . . . . p. 17

3.3 Implementação do Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . .p. 19

3.3.1 Implementação Modal ou Amodal . . . . . . . . . . . . . . . . . . . p. 20

3.3.2 Conteúdo Estático . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 20

3.3.3 Identificando Estado Online/Offline . . . . . . . . . . . . . . .. . . p. 22

3.3.4 Camada de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 23

3.3.5 Sincronização . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 24

4 CONCLUSÃO p. 28

4.1 Análise da Arquitetura Proposta . . . . . . . . . . . . . . . . . . . .. . . . p. 28

4.2 Contribuições . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p.28

4.3 Dificuldades Encontradas . . . . . . . . . . . . . . . . . . . . . . . . . .. . p. 28

4.4 Propostas de Extensão . . . . . . . . . . . . . . . . . . . . . . . . . . . . .p. 29

Referências Bibliográficas p. 30

Apêndice A -- Aplicação em Django utilizando Gears p. 31

A.1 Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p.31

A.2 Arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 33

A.2.1 Django . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 34

A.2.2 Gears . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 36

Page 5: Rich Internet Applications com clientes offline utilizando Gears

iii

Lista de Figuras

1 Arquitetura tradicional de aplicações Web . . . . . . . . . . . . .. . . . . . p. 11

2 Diagrama de sequência tradicional para aplicações Web . . .. . . . . . . . . p. 11

3 Arquitetura proposta pelo Gears . . . . . . . . . . . . . . . . . . . . . .. . p. 12

4 Diagrama de sequência para aplicações Web baseadas em Gears . . . . . . . p. 13

5 Confirmação para permitir que a aplicação use o Gears para guardar dados . . p. 19

6 Tela listando todas as notas. . . . . . . . . . . . . . . . . . . . . . . . . .. . p. 31

7 Tela mostrando uma determinada nota. . . . . . . . . . . . . . . . . . .. . . p. 32

Page 6: Rich Internet Applications com clientes offline utilizando Gears

iv

Resumo

“Aplicações Ricas da Internet” é o nome dado às aplicações Webque fazem uso pesado deJavascript para implementar uma interface dinâmica provendo uma experiência similar a dasaplicaçõesdesktopconvencionais.

Este trabalho mostra um pouco da história das aplicações Web, e especula sobre o futuro,fazendo um estudo de tecnologias emergentes como o Gears quetrazem novas possibilidades aessa plataforma.

Page 7: Rich Internet Applications com clientes offline utilizando Gears

v

Abstract

“Rich Internet Applications” is the name for the Web applications that make heavy useof Javascript to implement dynamic interfaces providing a user experience similar to a regularDesktop Application.

This work shows the history of Web applications, and discusses about the future of the Webas an application platform. Also it explores emerging technologies such as Gears that bring newfeatures to this platform.

Page 8: Rich Internet Applications com clientes offline utilizando Gears

1

1 INTRODUÇÃO

Nos últimos anos pudemos vivenciar a popularização dehardwaree Internet em todo o

mundo. É comum hoje em dia o indivíduo ter um computadordesktopem casa, umnotebook

para o trabalho e mais aquele computador da namorada que ele usa nos finais de semana. Seus

arquivos acabam espalhados em diversos computadores epen drives. Alguém distraído pode

facilmente se perder em meio às diferentes versões de arquivos que vão sendo criadas ao longo

do tempo. Agora imagine fazerbackupde tudo isso de uma maneira organizada. Pode-se pensar

em muitas soluções para estes problemas, dentre elas: criarum servidor FTP em um servidor

pago para centralizar tudo, usar umpen drivepara ter mobilidade e manterbackupsnos diversos

computadores ou ainda criar um elegante sistema de versões mantendo repositórios distintos que

iriam sendo mesclados usando uma ferramenta de controle de versões como o GIT. Cada uma

dessas soluções tem um problema, seja ele um ponto único de falha, um custo monetário mensal

ou um grau de complexidade elevado. Mas com certeza nenhuma delas é uma solução trivial o

suficiente para ser amplamente utilizada pelo usuário final.

A computação nas nuvens[Miller 2008] surge para resolver este problema. Esse novo

conceito de computação propõe que todos os dados e, às vezes,até mesmo as aplicações fiquem

na Internet. As empresas como o Google começam a oferecer muitos Giga Bytes grátis para

que o usuário possa guardar seus e-mails no Gmail ou documentos no GoogleDocs. Esses são

dois exemplos onde tanto os dados quanto a aplicação estão nas nuvens, ou seja, nos servidores

do Google. Tudo é facilmente acessível de um navegador, ondequer que o usuário esteja. É

fácil, é confiável, é seguro e é muito funcional.

Com a disseminação da computação nas nuvens o computador pessoal deixou de rodar as

aplicações e guardar os dados passando a ser apenas uma janela para a Internet. Na prática só

se precisa de um Sistema Operacional (SO) e um navegador parater acesso a um mundo de

aplicações como editores de imagem, planilhas eletrônicas, editores de texto, e-mail, etc. As

aplicaçõesdesktopficaram um tanto ameaçadas porque é improvável que elas consigam ofere-

cer em curto prazo as vantagens da computação nas nuvens. Porém as aplicações na Internet

Page 9: Rich Internet Applications com clientes offline utilizando Gears

2

têm a desvantagem de estar atreladas ao navegador e por isso ter certas limitações. Volta-se

a era dos terminais burros emainframes, com os dados e aplicações centralizadas na Internet

e os computadores fazendo o papel dos terminais burros. Os computadores de hoje são muito

superiores, em termos de recursos, aos terminais burros de antigamente, porém esses recursos

são muito mal utilizados nas aplicações Web. A falta de acesso direto ao SO não permite que

as aplicações acessem o sistema de arquivos ou façam algum processamento mais complexo

em paralelo. Todas estas aplicações estão presas ao protocolo HTTP que é simples e sem es-

tado [Tanenbaum e Steen 2007] além de linguagensscriptpara processamentoclient sidemuito

lentas se comparado a uma biblioteca nativa. Caso o usuário esteja em um local sem Internet

todos os seus documentos estão inacessíveis e seu computador passa a ser um peso de papel.

Além disso a questão da usabilidade é importante já que as interfaces das aplicações Web

são diferentes das interfaces de programasdesktopequivalentes, o usuário pode sentir difi-

culdade em se acostumar ao novo ambiente, o que pode gerar umaqueda de produtividade

expressiva [Krug 2005].

Algumas iniciativas vêm sendo tomadas para integrar as aplicações Web aodesktopa fim de

eliminar ou reduzir estas desvantagens das aplicações Web.Algumas empresas lançaram seus

produtos em caráter experimental usando suas próprias abordagens para o problema. A Adobe

criou o AIR que permite criar aplicações Web em Flash e ActionScript que rodam como se fos-

sem aplicações nativas, se aproveitando de recursos como aceleração 3D enquanto o Google,

com o seu Gears, teve uma abordagem diferente privilegiandoa possibilidade de guardar arqui-

vos no lado do cliente e fazer processamento Javascript em paralelo.

A integração tem um papel tanto de usabilidade, trazendo transparência no acesso à apli-

cação Web, quanto em termos de funções, já que as aplicaçõesdesktopnão estão presas ao

navegador especificamente. Por isso tem mais liberdade de acesso aos recursos da máquina.

Page 10: Rich Internet Applications com clientes offline utilizando Gears

3

1.1 Objetivos

O objetivo deste documento é fazer uma análise da evolução das aplicações Web e como o

Gears pode resolver limitações desta plataforma, introduzindo funcionalidades novas.

1.1.1 Objetivos Específicos

• Usar o Gears para contornar limitações das aplicações Web.

• Mostrar como o uso de um framework forte facilita a criação deaplicações mais ricas.

• Estudar os problemas mais comuns na implementação do Gears.

Page 11: Rich Internet Applications com clientes offline utilizando Gears

4

2 ASPECTOS TEÓRICOS

2.1 Evolução das Aplicações Web

De maneira geral a evolução das aplicações Web pode ser definida em 3 fases distin-

tas [Taivalsaari e Ingalls 2008].

• Páginas "clássicas", apenas com texto e imagens estáticas.

• Páginas multimídia, com animações e conteúdo multimídia com o uso de plugins.

• Rich Internet Applicationsou Aplicações Ricas da Internet.

2.1.1 Páginas Estáticas

Nos primórdios a Web era usada para manter arquivos HTML estáticos que possuíamlinks

entre eles. Era como um livro gigantesco, no qual o usuário tinha a opção de pular direto para a

seção que mais lhe interessava com facilidade.

Este modelo foi se modernizando e as páginas começaram a se tornar dinâmicas. Lingua-

gens simples eram usadas para gerar as páginas antes estáticas. Lentamente foram surgindo

linguagens eframeworksfocados na Web e a arquitetura dos sites foi se tornando cada vez mais

complexa.

2.1.2 Páginas com Conteúdo Multimídia

Mesmo com as páginas sendo geradas dinamicamente a interface do usuário ainda era está-

tica. O usuário clicava num link e isso acarretava num recarregamento da página. Com o tempo

foi surgindo a necessidade de adicionar dinamismo a interface do usuário.

Os Javaappletse o Flash deram essa possibilidade ao desenvolvedor. Os sites podiam ser

melhor customizados. Animações, som e vídeo abriam um novo leque de possibilidades para

Page 12: Rich Internet Applications com clientes offline utilizando Gears

5

oswebdesigners.

Este modelo exigia que o usuário instalasse um plugin proprietário no navegador, caso con-

trário este não conseguiria acessar o conteúdo. Porém não era mais preciso lidar com problemas

de incompatibilidade entre os navegadores, visto que todosusavam o mesmo plugin.

Essa metodologia trouxe novos problemas. O conteúdo em Flash, não era indexado pelos

mecanismos de busca, o que logo se tornou um grande problema amedida que os mecanismos

de busca se estabeleceram como a principal porta de entrada para a Web.

Além disso uma falta de padronização de interface trouxe dificuldades de usabilidade e

acessibilidade. Cada desenvolvedor criava interfaces ricas diferenciadas e que o usuário não

reconhecia de imediato [Krug 2005].

2.1.3 Aplicações Ricas da Internet

As Aplicações Ricas da Internet começaram a fazer uso mais intensivo das linguagens e

frameworksmodernos. Além disso houve o aparecimento do Ajax.

Ajax (Asynchronous Javascript and XML) é um conjunto de técnicas para alterar o conteúdo

de uma página Web depois dela ter sido carregada. Na prática ela permite que apenas uma parte

da página seja atualizada ao invés de fazer um novo carregamento. Por ser assíncrona essa

técnica permite que o usuário interaja com a página enquantoas informações são carregadas.

Esta funcionalidade existe nos navegadores desde o ano 2000, mas o termo Ajax surgiu apenas

em 2005 quando a tecnologia foi popularizada.

O Ajax trouxe um dinamismo novo às antigas páginas estáticasmelhorando a experiên-

cia do usuário drasticamente e permitindo aos desenvolvedores reinventar a Web como uma

plataforma para o desenvolvimento de aplicações.

O Flash deixou de ser a melhor opção para gerar interfaces ricas. E foi lentamente, sendo

rebaixada para a categoria de mídiaplayer para sites. Sites como o Youtube usam o Flash

apenas para exibir vídeos e áudio, enquanto que o Ajax predomina na interface.

2.1.4 Gears

As aplicações Web ficam centralizadas na nuvem. Isso significa que todos os códigos,

arquivos e dados ficam em servidores e não na máquina cliente,que serve apenas como uma

janela para enxergar essas aplicações.

Page 13: Rich Internet Applications com clientes offline utilizando Gears

6

Antes da aparição do Gears não existia uma maneira de guardarestes dados e arquivos. Os

cookiespodem guardar apenas uma quantidade limitada de dados, e sãogeralmente usados para

manter sessões de usuários, provendo uma funcionalidade não inclusa no HTTP. Não existe uma

maneira de guardar dados relacionais como os que são guardados nos bancos de dados do lado

do servidor.

Com o Gears o desenvolvedor tem uma nova opção. Pode armazenardados no computador

do usuário em um banco de dados local implementado dentro do navegador na forma de uma

extensão.

Isso cria um novo precedente no desenvolvimento de aplicações Web. Pode-se criar aplica-

ções Web seguras que nunca enviam os dados para a nuvem, ou acelerar aplicações existentes

trazendo os dados todos para o lado do cliente. Bem como tornaraplicações antes apenas aces-

síveis através da Internet completamenteoffline.

Aplicações Web contruídas desta forma podem deixar de ser dotipo thin-client/fat-servere

passar a serfat-client/thin-server. Exatamente como aplicaçõesdesktoptradicionais.

2.1.5 HTML5

A nova especificação do HTML, prevista para ser finalizada em 2010, inclui algumas funci-

onalidades análogas as providas pelo Gears. Como será uma funcionalidade padrão do navega-

dor pode-se antecipar que será utilizada por muitos desenvolvedores a medida que os usuários

começam a utilizar os navegadores que implementam o HTML5.

Além de contar com a funcionalidade de guardar dados localmente o HTML provêtags

multimídia para exibir videos ou sons, e uma API Javascript para controlar essas funcionalida-

des.

O Objetivo do HTML5 é introduzir funcionalidades antes providas apenas por extensões e

que provaram ser importantes para a construção de aplicações mais ricas baseadas na Web.

O Gears provê hoje a habilidade de escrever aplicações que usam as algumas funcionali-

dades do HTML5 antes que este seja liberado. O Google anunciou recentemente uma camada

de abstração que permite o uso tanto do Gears como do HTML5, caso este esteja disponível,

através da mesma interface [Google 2009].

Page 14: Rich Internet Applications com clientes offline utilizando Gears

7

2.2 Javascript

O Javascript é um dialeto da especificação ECMAScript e é hoje alinguagem mais utilizada

para fazer programaçãoclient side. Por ser a única linguagem amplamente implementada por

todos os grandes navegadores, ela não tem muita concorrência.

A programaçãoclient sidefoi por muito tempo chamada de DHTML ouDynamic HTML,

pois a maior utilidade para o Javascript era adicionar dinamismo ao HTML. Este dinamismo, era

geralmente uma questão visual e não interferia em nada com o funcionamento das aplicações.

Uma das funcionalidade mais utilizada era para prover validação a formulários.

Com a popularização do Ajax o Javascript tornou-se parte integrante das aplicações. Uma

vez que a lógica das aplicações começou a ser escrita no lado do cliente a linguagem precisou

evoluir para suprir as necessidades dos desenvolvedores.

Hoje o Javascript é uma linguagem poderosa orientada a objetos e que faz uso extensivo de

eventos para capturar a interação do usuário com a página. É importante que o desenvolvedor

tenha um bom domínio dessas funcionalidades na hora de implementar grandes aplicações,

criando bibliotecas reutilizáveis e simples de manter [Keith 2005].

2.2.1 Ajax e DOM

O DOM ouDocument Object Model, é uma representação em árvore da estrutura HTML

de uma página Web. O DOM permite interações como consulta, adição, remoção ou alterações

dos nós desta árvore. O Javascript possui uma interface parauso do DOM permitindo alteração

dinâmica [Keith 2005].

O uso em conjunto do DOM e do Ajax é o que permite o carregamentode informação

adicionais dentro de uma página sem recarregar todo o conteúdo novamente.

Cada navegador implementa o Javascript em cima das especificação ECMAScript. Porém

as vezes há diferenças entre as implementações. Essas diferenças entre os navegadores sempre

foram uma dor de cabeça para os desenvolvedores. A medida queas aplicações crescem, e o

código Javascript cresce fica mais difícil encontrarbugse essa diferença entre os navegadores

não ajuda em nada os desenvolvedores.

Existem bibliotecas Javascript que padronizam a interfacede comandos Ajax e para inte-

ração com o DOM. Essas bibliotecas resolvem problemas como incompatibilidades com nave-

gadores e deixa tempo para o programador lidar com seus próprios bugs. Dentre as bibliotecas

Page 15: Rich Internet Applications com clientes offline utilizando Gears

8

mais utilizadas estão o jQuery, Prototype e Dojo.

As Aplicações Ricas de Internet geralmente fazem uso constante do DOM e Ajax, e por

este motivo é comum o uso de alguma destas bibliotecas.

Page 16: Rich Internet Applications com clientes offline utilizando Gears

9

2.3 Gears

O Gears é um projeto de código livre que possibilita a construção de aplicações Web mais

poderosas e integradas aodesktop, as chamadasRich Internet Applications.

O Gears foi idealizado pelo Google e lançado em maio de 2007 [Gears API 2008], atual-

mente está em sua versão 0.5.22.0 e é desenvolvido por funcionários do Google e membros

voluntários de uma comunidade de desenvolvedores que se formou ao redor do projeto.

O uso mais comum para Gears é fazer com que aplicações Web, ou pelo menos parte delas,

fiquem acessíveis mesmo que não haja acesso a Internet [Kilani 2007], ou para acelerar o fun-

cionamento da aplicação para que ela fique o mais parecido possível com o funcionamento de

uma aplicaçãodesktop.

Atualmente as plataformas suportadas são: Windows XP/Vista, Windows Mobile, Mac,

Android e Linux. O Gears é implementado como um extensão paraos navegadores Firefox,

Internet Explorer, Safari ou Chrome. O seu trabalho é fazer uma ponte entre a aplicação Web e

o SO, fornecendo os recursos do SO para a aplicação através deuma API em Javascript.

Entre os sistemas que já se beneficiam do Google Gears estão diversas aplicações do Google,

MySpace, Zoho, Remember the Milk [Kilani 2007], entre outras.

Page 17: Rich Internet Applications com clientes offline utilizando Gears

10

2.3.1 Módulos do Gears

O Gears é um sistema modular e a idéia é que no futuro mais e maismódulos sejam adicio-

nados permitindo flexibilidade enquanto mantém ocoredo Gears bem leve. Dentre os módulos

atualmente disponíveis estão:

Database Provê um banco de dados local no cliente para guardar dados e recuperá-los, pos-

sibilitando que esses dados possam ser utilizados mesmo semque haja conexão com a

Internet. No Gears esta camada faz uso do SQLite, um banco de dadosopen source

pequeno mas com muitas funcionalidades.

Desktop Fornece acesso aodesktopcomo por exemplo a possibilidade de criar ícones na má-

quina cliente facilitando o acesso a aplicação Web e tornando-a mais próxima de aplica-

ções locais.

Geolocation Permite que a aplicação Web acesse dispositivos da máquina cliente que infor-

mam a localização do usuário como um módulo GPS. Esse recursoé utilizado por exem-

plo em uma aplicação de mapas rodando em um celular para poderlocalizar a posição

exata em que o usuário se encontra em um mapa.

LocalServer Permite que requisições HTTP que normalmente seriam enviadas pela Internet

para um servidor remoto, sejam respondidas pela mesma máquina cliente num servidor

local. Este recurso acelera o funcionamento de uma aplicação Web e inclusive permite

que uma certa aplicação funcione sem acesso a Internet, e conseqüentemente ao seu ser-

vidor. Dentro do LocalServer existemResourceStoresque são utilizados para guardar

conteúdo estático.

WorkerPool Fornece recursos para fazer processamento Javascript em paralelo para evitar que

um script complexo interrompa a fluidez da aplicação.

2.3.2 Arquitetura de Sistemas Baseados em Gears

Como regra geral as aplicações Web são aplicações distribuídas do tipofat server/thin cli-

ent [Tanenbaum e Steen 2007], uma vez que o cliente oubrowseré responsável apenas por

renderizar a interface de usuário como mostra a Figura 1. Neste modelo cada vez que o usuário

realiza qualquer interação com a aplicação é feita uma requisição ao servidor e este retorna uma

página HTML que representa umsnapshotdo sistema como ilustrado na Figura 2.

Page 18: Rich Internet Applications com clientes offline utilizando Gears

11

Figura 1: Arquitetura tradicional de aplicações Web

Figura 2: Diagrama de sequência tradicional para aplicações Web

Page 19: Rich Internet Applications com clientes offline utilizando Gears

12

Figura 3: Arquitetura proposta pelo Gears

O Gears propõe uma arquitetura diferente [Gears API 2008]. Através dos módulos Local-

Server e Database, descritos na seção 2.3.1, o Gears tem o poder de prover páginas localmente

sem precisar contactar o servidor. Isso agiliza as chamadase possibilita o uso das aplicações

mesmo sem uma conexão a Internet. Nessa arquitetura as requisições passam primeiramente

por umdata switchque irá identificar se os dados devem ser requisitados para o servidor remoto

ou para o servidor local. Caso a requisição vá para o servidor remoto odata switchencaminha

a requisição para a camada de dados remotos, que por sua vez implementa a API para recuperar

os dados remotamente. Caso a requisição seja encaminhada para a camada de dados local, os

dados serão recuperados do banco de dados interno do Gears. Existe ainda uma camada op-

cional de sincronização responsável por sincronizar os dados do banco de dados local com os

dados do servidor remoto, essa sincronização normalmente éfeita por umWorker Poolsendo

assim executado em segundo plano. Esta arquitetura está ilustrada na Figura 3.

Na arquitetura do Gears nem sempre as requisições precisam passar pelo servidor, vide

Figura 4. Isto torna o processo todo bem mais rápido já que nãodepende da conexão com a In-

ternet. O próprio Gears trata de encaminhar as requisições que não podem ser feitas localmente

e sincronizar os dados remotos com os dados locais.

Page 20: Rich Internet Applications com clientes offline utilizando Gears

13

Figura 4: Diagrama de sequência para aplicações Web baseadas em Gears

Page 21: Rich Internet Applications com clientes offline utilizando Gears

14

3 METODOLOGIA

Este capítulo mostra os passos principais no desenvolvimento de uma aplicação de anota-

ções em Django que faz uso do Gears.

3.1 Aplicação de anotações

A aplicação que foi desenvolvida é uma aplicação simples usada como base para imple-

mentar o Gears utilizando o Django como framework do lado do servidor.

Dentre as características da aplicação podemos citar:

• Criação de anotações com título e conteúdo.

• Possibilidade de visualizar as anotações mesmo sem acesso aInternet.

• Possibilidade de criar anotações mesmo sem acesso a Internet.

• Sincronização de anotações enquanto a aplicação está online, para enviar ao servidor as

anotações criadas em modo offline.

3.2 Aplicação em Django

O Django é umframeworkde código livre de alto nível que encoraja o desenvolvimento

rápido de aplicações Web com design limpo e pragmático utilizando a linguagem Python. A

linguagem Python por sua vez tem como principais características a rápida prototipação e o fato

de ter uma biblioteca básica muito completa.

O frameworkDjango se baseia nodesign patternMVC (Model View Controller) que pro-

põe uma divisão clara entre as camadas de modelo, visão e controle (representação de dados,

interface com usuário e lógica de negócio, respectivamente) da aplicação. Esta divisão facilita

Page 22: Rich Internet Applications com clientes offline utilizando Gears

15

a manutenção dos sistemas e a independência das camadas entre si e torna fácil a reestruturação

completa de uma dessas camadas com poucas ou nenhuma modificação nas outras camadas.

Os sistemas em Django são geralmente divididos em diversas aplicações Django. Cada

aplicação implementa uma ferramenta específica e estas são “plugáveis” no sistema como um

todo. Elas podem interagir entre si mas há uma separação clara de código. Este modelo mais

uma vez facilita a manutenção dos sistemas e estimula o reaproveitamento de código de maneira

muito prática.

3.2.1 Estrutura Básica de Sistemas Django

Esta seção visa exemplificar a estrutura geral de uma aplicação Django e como os diferentes

aplicativos são organizados e reutilizados. Bem como os pontos importantes para criar aplica-

ções em Ajax com Django. Este trabalho não pretende documentar todos os passos envolvidos

no desenvolvimento de aplicações Django. Uma análise mais detalhada pode ser encontrada na

bibliografia [Holovaty e Kaplan-Moss 2008] ou nahome pagedo projeto Django1.

Após usar o comandopython django-admin.py startproject project , o Django cria

uma pasta “project” com a seguinte estrutura.

project/

|-- __init__.py

|-- manage.py

|-- settings.py

‘-- urls.py

O arquivosettings.py possui configurações diversas como informações do banco de da-

dos, diretórios comtemplates, aplicações Django instaladas, entre outros. O arquivourls.py

possui o mapeamento de urls para “views”, em outras palavras indica qual função irá ser execu-

tada quando cada url for acessada. Já o arquivomanage.py disponibiliza uma extensa coleção

descriptsque gerenciam e automatizam a administração do sistema, pode-se usá-lo para criar

1http://www.djangoproject.com/

Page 23: Rich Internet Applications com clientes offline utilizando Gears

16

uma nova aplicação Django.

$ python manage.py startapp notes

$ ls

project/

|-- __init__.py

|-- notes

| |-- __init__.py

| |-- models.py

| ‘-- views.py

|-- manage.py

|-- settings.py

‘-- urls.py

Neste momento é criada uma pasta “notes” que irá agrupar os arquivos referentes a este

aplicativo e nele já existem os arquivosmodels.py e views.py que devem ser reescritos para

conter a descrição dos dados e lógica de negócio. O código utilizado neste documento pode ser

encontrado no Apêndice A.

Após escrever estas duas camadas o aplicativo pode ser “plugado” alterando a seguinte

sessão no arquivosettings.py .

INSTALLED_APPS = (

’django.contrib.auth’,

’django.contrib.contenttypes’,

’django.contrib.sessions’,

’django.contrib.sites’,

’project.notes’,

)

Desta forma o aplicativo “notes” éplugadono sistema. É perceptível que o Django já vem

com alguns aplicativos habilitados por padrão como por exemplo o “django.contrib.auth” que é

responsável por gerenciar usuários do sistema. Uma vez que amaioria dos sistemas Web tem

usuários, é natural que o Django já venha com esta aplicação,seguindo o modeloall under the

hooddo Python. Claro que esta aplicação pode ser desligada facilmente desabilitando o suporte

a usuários e permissões.

Page 24: Rich Internet Applications com clientes offline utilizando Gears

17

Após plugar a aplicação, pode-se invocar o comandopython manage.py syncdb para

que o Django crie no banco de dados as tabelas que refletem os modelos definidos no arquivo

models.py .

O Django provê uma interface orientada a objeto para acesso aos dados através da camada

de modelos. Desse modo não é preciso lidar comqueriesSQL, o que facilita o desenvolvimento

e cria uma independência do DBMS2.

3.2.2 Implementando Ajax

Uma boa prática no desenvolvimento de aplicações com Ajax, ése certificar de que a aplica-

ção continuará funcionando corretamente mesmo sem o Javascript [Keith 2005]. Uma estratégia

para atingir este objetivo é seguir os seguintes passos:

1. Construa uma aplicação sem Javascript utilizando links e formulários em HTML puro e

crie a lógia no servidor para responder a estas requisições.

2. Depois adicione Javascript para interceptar essas chamadas e submissões de formulário

realizando-as por Ajax e atualizando apenas parte da página.

Desta forma é fácil criar aplicações Ajax que são compatíveis com navegadores sem Javas-

cript, ou que continuem funcionando caso haja algum erro de Javascript.

A lógica em Javascript usada para interceptar as requisições na aplicação anotações, pode

ser encontrada no conteúdo do arquivonotes.js , na página 42 do apêndice A.2.2.

Após implementar a lógica para interceptar essas requisições em Javascript é importante

certificar-se que o servidor não irá responder da mesma formaas requisições simples e as re-

quisições em Ajax.

Felizmente o Django provê uma maneira simples de identificara origem da requisição

através da funçãorequest.is_ajax() dentro de uma “view”. Isso é possível graças ao jQuery

que insere um cabeçalho a mais na requisição HTTP facilitando sua identificação.

No caso de a requisição ser feita via Ajax, a “view” não precisa retornar a página completa,

apenas os dados que serão inseridos dentro da página. Estes dados podem ser retornados como

HTML, texto puro, XML ou Json. O Json tem a vantagem de ser um formato compatível com

um objeto Javascript e devido a isso o trabalho de extrair os dados se torna mais simples.

2Data Base Management System: Sistema gerenciador de bancos de dados

Page 25: Rich Internet Applications com clientes offline utilizando Gears

18

Neste exemplo utilizamos o Django para listar todas as notas, gerar Json caso a requisição

seja feita via Ajax e renderizar a página completa caso seja uma requisição normal.

def note_list(request):

n = Note.objects.all()

form = NoteForm()

if request.is_ajax():

response = HttpResponse(mimetype="application/json")

json_serializer = serializers.get_serializer("json")( )

json_serializer.serialize(n, ensure_ascii=False, stre am=response)

return response

else:

return render_to_response(’notes/note_list.html’,

{ ’object_list’ : n,’form’ : form},

context_instance=RequestContext(request))

Page 26: Rich Internet Applications com clientes offline utilizando Gears

19

3.3 Implementação do Gears

O Gears é flexível e a maneira como o desenvolvedor vai implementa-lo depende das ne-

cessidades da aplicação e da dificuldade de implementação. Odesenvolvedor deve ponderar a

quantidade de trabalho a ser realizado e o benefício para o usuário final. Na maioria das vezes

não faz sentido fazer com que toda aplicação esteja disponível offline[Gears FAQ 2008].

A medida que se acrescentam funcionalidadesofflinese torna necessário um mecanismo de

sincronização. Este provavelmente é o momento mais complexo e sujeito a erros na implemen-

tação do Gears.

Para inicializar o Gears sempre se deve usar o arquivogears_init.js que o Google dis-

ponibiliza. Este script torna disponível a variável globalgoogle dentro do Javascript caso o

Gears esteja instalado. Com isso podemos redirecionar o usuário para uma página de instalação

caso o Gears não esteja instalado.

if (!window.google || !google.gears)

{

location.href = ’http://gears.google.com/?action=inst all&’ +

’message=Baixe o Google Gears para Continuar’ +

’&return=http://localhost/notes’;

}

Uma vez que o Gears esteja instalado é exibido para o usuário um diálogo de segurança

como o ilustrado na figura 5.

Figura 5: Confirmação para permitir que a aplicação use o Gearspara guardar dados

Page 27: Rich Internet Applications com clientes offline utilizando Gears

20

3.3.1 Implementação Modal ou Amodal

A primeira decisão a ser tomada é como o Gears será habilitadoe o usuário irá interagir

com ele. As opções são as seguintes [Kilani 2007]:

1. Modal: O usuário deve clicar em um botão na interface que troca parao modoofflinee de

volta para o modoonline. O Google Reader e o Remember the Milk, são dois exemplos

de aplicação que utilizam este sistema.

2. Amodal: O sistema entra em modooffline automaticamente caso a Internet não esteja

acessível. Este é o modelo de implementação usado no Gmail.

O modelo Modal é geralmente mais simples de implementar e dependendo da aplicação

pode ser o modelo ideal. A aplicação de anotações poderia serimplementada utilizando este

modelo, porém decidiu-se utilizar o modelo Amodal para fins de pesquisa.

3.3.2 Conteúdo Estático

Tornar o conteúdo estáticoofflineé uma operação relativamente simples no Gears. Por este

motivo este geralmente é o primeiro passo tomado pelos desenvolvedores. Além disso este é

um dos recursos que mais aceleram o funcionamento da aplicação para o usuário final. Como

todos os recursos estão alocados localmente a aplicação nãoprecisa acessar a Internet, ou então

acessa a Internet com muito menos frequência, e a velocidadese aproxima da velocidade de

uma aplicação desktop.

Este recurso usa o móduloLocalServer do Gears. Este módulo possui 3 classes, dessas

iremos abordar apenas 2 necessárias para capturar e prover os recursos estáticos em um site: A

classeLocalServer e a classeManagedResourceStore .

Com essas duas classes pode-se fazer ocachede arquivos estáticos como páginas HTML,

código Javascript, documentos CSS, imagens, etc.

Page 28: Rich Internet Applications com clientes offline utilizando Gears

21

Primeiro deve-se escrever um arquivomanifest.json com os arquivos que deverão ser

baixados. Exemplo de arquivomanifest.json :

{

"betaManifestVersion": 1,

"version": "v1",

"entries": [

{ "url": "/notes/"},

{ "url": "/media/notes/gears_init.js"},

{ "url": "/media/notes/jquery.js"},

{ "url": "/media/notes/notes.js"},

{ "url": "/media/notes/django_gears.js"},

{ "url": "/media/notes/datalayer.js"},

{ "url": "/media/notes/style.css"},

{ "url": "/media/notes/gears_icons.png"}

]

}

O Gears fica fazendo requisições repetidamente pelo arquivomanifest.json , essas geral-

mente são retornadas com o código HTTP 304 (“Not Modified”). Porém caso o arquivo seja

modificado ele recebe a nova versão. Caso um dos arquivos seja atualizado basta atualizar o pa-

râmetroversion do manifest para que as atualizações sejam buscadas. Caso contrário o Gears

irá sempre prover a versão local carregada anteriormente.

Esse mecanismo funciona analogamente ao mecanismo de cachedo HTTP, com a diferença

que ele não precisa checar as modificações para cada arquivo,o Gears apenas checa pelas

modificações no arquivomanifest.json .

Inicie o localserver em todas as páginas para ter certeza que sempre tem o ultimo

manifest.json .

localServer = google.gears.factory.create("beta.local server");

store = localServer.createManagedStore(’mystore’);

store.manifestUrl = ’http://localhost/media/notes/man ifest.json’;

store.checkForUpdate();

Page 29: Rich Internet Applications com clientes offline utilizando Gears

22

3.3.3 Identificando Estado Online/Offline

Caso o Gears seja implementado usando a forma Amodal, precisa-se descobrir o status da

aplicação. O Gears não possui uma interface simples para verificar se a aplicação estáonline

ouoffline, porém é fácil implementar em Javascript uma rotina que façaesta verificação.

Segue uma rotina que faz este procedimento:

var request = google.gears.factory.create(’beta.httpre quest’);

var online = false;

function pingSuccess() {

if(request.responseText.indexOf("ok") >= 0){

online = true;

} else {

online = false;

}

}

function isServerAvailable() {

var resource_to_test = "/media/notes/gears_test.txt";

var TIME_BETWEEN_PINGS = 3*1000;

var PING_TIMEOUT_SECONDS = 1*1000;

//parâmetro randômico para não receber arquivo em cache.

resource_to_test += "?q=" + Math.floor(Math.random() * 10 0000);

request.open(’GET’, resource_to_test);

window.setTimeout("pingSuccess()",PING_TIMEOUT_SECO NDS);

request.send();

window.setTimeout("isServerAvailable()",TIME_BETWEE N_PINGS);

}

isServerAvailable();

Esta rotina basicamente busca um arquivo no servidor a cada 3segundos. Este arquivo deve

existir dentro do servidor como um arquivo texto puro com o conteúdo “ok”. Dependendo da

resposta da requisição a rotina marca a variávelonlinepara refletir o estado da aplicação.

Pode ser importante ou não saber o estado da aplicação, dependendo da forma de sincroni-

zação que será utilizada.

No exemplo incluído nesta monografia a aplicação faz uso desta rotina para informar ao

Page 30: Rich Internet Applications com clientes offline utilizando Gears

23

usuário o estado atual, e para desativar a sincronização dosdados com o servidor.

3.3.4 Camada de Dados

A maioria das aplicações Web não possuem uma camada de dados bem definida. Isso

porque como a fonte de dados era apenas uma não fazia sentido criar esta abstração. Nestes

casos a implementação é mais complicada pois toda a aplicação deve ser reescrita para usar a

nova camada de dados.

A camada de dados é uma interface em Javascript para acesso aos dados da aplicação.

É importante a construção desta camada, pois uma vez que implementa-se o Gears os dados

poderão vir de duas origens distintas. O servidor ou banco dedados local.

Aplicações tradicionais fazem uma requisição ao servidor pedindo por um determinado

conjunto de dados. Dependendo da aplicação e implementação, esses dados podem vir em dife-

rentes formatos: texto puro, HTML, XML, Json, etc. Depois que esses dados são recuperados

a página é atualizada para mostrar os dados.

Porém uma vez que implementamos o Gears os dados que são recuperados do banco de

dados local vêm dentro de um GearsResultSet (classe do móduloDatabase ). Portanto tem-

se um retorno diferente dependendo da origem dos dados.

A camada de dados dentro de uma aplicação Web deve ser construída para normalizar os

dados que são passados para a aplicação. A seguir é apresentado como a aplicação de anotações

usa a camada de dados para fazer requisição de dados.

var dl = new datalayer;

dl.getNote(7,function(){

//mostra o titulo da Nota com id 7 em uma caixa de diálogo

alert(this.fields.title);

});

A classedatalayer irá verificar a existência do Gears. Caso este esteja instalado ela irá

buscar a nota no banco do Gears caso não esteja instalado, oDataLayer irá fazer uma requisição

Ajax ao servidor.

Page 31: Rich Internet Applications com clientes offline utilizando Gears

24

Exemplo de implementação de Camada de Dados:

function datalayer(){};

//Seleciona uma ou todas as notas do Gears ou da Web caso este n ão esteja disp.

datalayer.prototype.getNotes = function(id,callback){

try{

var sql = ’SELECT * FROM notes_note ’,

json_r = [];

if(id>=0){

sql += ’WHERE id = ’+id+’;’

}

//Já retorna um Json igual ao retornado pelo Django

json_r = dg.queryToObject(sql);

return cb(json_r);

}catch(e){

if(id>=0)

return $.getJSON(’/notes/’+id+’/’,cb);

return $.getJSON(’/notes/’,cb);

}

};

Percebe-se que independente de usar ou não o Gears o retorno ésempre um objeto Json

com os dados requisitados. Esta é a abstração desejada nestaimplementação.

O conteúdo dinâmico das páginas deve ser armazenado dentro do banco de dados local

utilizando a interface Javascript do móduloDatabase do Gears. Pode-se interagir com o banco

de dados através dequeriesSQL, da mesma maneira com que se interage com um banco de

dados no servidor. Porém com tudo sendo executado do lado do cliente.

3.3.5 Sincronização

A sincronização dos dados locais com os dados remotos é um dospontos mais difíceis

na implementação do Gears. O desenvolvedor mais uma vez precisa ponderar que nível de

sincronização faz sentido dentro da sua aplicação.

O Gears não vem com nenhuma funcionalidade que implemente a sincronização automati-

camente. Ao invés disso o desenvolvedor deve criar um mecanismo de sincronização.

Page 32: Rich Internet Applications com clientes offline utilizando Gears

25

A seguir são apresentadas algumas estratégias de sincronização por ordem de complexidade

e comentários sobre a implementação de cada uma delas.

Apenas Leitura Offline

Neste modo baixa-se todo conteúdo, ou parte dele para o cliente. A partir daí sempre

que necessário, pode-se ler o conteúdo localmente, o que acelera muito o funcionamento da

aplicação. Quando alguma modificação é feita no servidor, descarta-se todo conteúdo local e

“baixa” o novo conteúdo.

Este é o modo mais fácil de usar o Gears para acelerar o acesso das aplicações aos dados e

permite que as aplicações sejam utilizadasofflineapenas para leitura.

A rede social MySpace utiliza esta estratégia com Gears paraacelerar as buscas no site.

Todos os contatos são baixados para a máquina do usuário, e asbuscas por Amigos são reali-

zadas localmente. Além de livrar o servidor da carga que existe por trás de uma busca do tipo

full-text-search, acelera a interface.

Leitura e Escrita Offline

Com uma aplicação implementando o modo somente leitura com o Gears, pode-se passar

para o próximo passo. Gravar as modificação localmente.

Ao invés de enviar as alterações para o servidor, fazer estasalterações diretamente no banco

de dados local, tornando desnecessário carregar todos os dados novamente a cada alteração de

registros.

Assim a aplicação fica disponíveloffline tanto para leitura como para edição, porém como

as modificações não são feitas no servidor perde-se uma das grandes vantagens das aplicações

nas nuvens que é a vantagem de poder acessar a aplicação de qualquer localidade. Deste modo

os dados vão estar sempre no cliente, e caso se mude de navegador se perde os dados.

O fato de os dados nunca irem para o servidor pode ser uma vantagem. Desta maneira é

possível a criação de sistemas em que os dados são apenas locais, introduzindo um nível de

segurança novo em aplicações Web. Pode-se imaginar, por exemplo, uma aplicação de controle

financeiro desenvolvida dessa maneira. A atualização do código da aplicação ainda pode ser

feita de modo remoto, porém toda a lógica e dados ficam na máquina do usuário e nunca são

enviadas para a Internet.

Page 33: Rich Internet Applications com clientes offline utilizando Gears

26

Sincronização Mono-usuário

Esta é uma estratégia para implementar a sincronizaçãoonline e offline, utilizando a pre-

missa de que um usuário nunca poderá estar logado mais de uma vez no sistema.

Num primeiro momento baixamos todos os dados do servidor localmente. Depois sempre

que uma gravação for efetuada nos dados locais ela será marcada com umaflag para que seja

enviada para o servidor assim que possível.

Uma rotina é executada periodicamente que verifica se existem modificações na base local

para que sejam enviadas para o servidor. Assim que a modificação é enviada para o servidor

marca-se a informação como enviada.

É interessante criar uma coluna de chave primária no banco dedados local, independente

da coluna de chave primária do servidor, para evitar problemas de conflito. Pode-se usar o

mesmo esquema do banco de dados do servidor dentro do Gears porém adicionando a coluna

id_server para manter uma referência ao “id” real do registro.

Sincronização Multi-usuário

Esta seria a estratégia mais completa, porém a mais complexade ser implementada.

Além de gravar as modificações feitas na base local e no servidor, precisa-se consultar o

servidor periodicamente para ter os dados mais atualizados.

Um evento de sincronização deve ser disparado periodicamente. Como a sincronização

pode se tornar um processo custoso, deve ser, de preferência, executada dentro de umWorkerPool ,

para que não interfira com o funcionamento da aplicação para ousuário.

A seguir é apresentada a rotina em Javascript da aplicação Anotações que busca as atuali-

zações na base de dados remota. Esta rotina usa uma tabela local notes_version que guarda

o timestampda última atualização, e requisita as notas alteradas depois dessetimestamp.

djGears.prototype.get_updates = function(){

var rs;

//set new updated time

this.query(’update notes_version set last_mod = datetime ("now");’);

//Only import the new ones

$.getJSON(’/notes/?xhr=1&last_mod=’+this.last_mod+’ ’,function(r){

for (var n in r){

Page 34: Rich Internet Applications com clientes offline utilizando Gears

27

if (r[n].pk === undefined){

continue;

}

dg.query(’insert into notes_note ’+

’(id_server,title, content,mod_date) values (?,?,?,?)’ ,

[r[n].pk, r[n].fields.title,

r[n].fields.content, r[n].fields.mod_date]);

}

});

rs = this.query(’select version,strftime("%s",last_mod ) ’+

’from notes_version’);

if(rs.isValidRow()){

this.version = rs.field(0);

this.last_mod = rs.field(1);

}

rs.close();

}

Este processo inclui um novo problema de implementação, queé a questão de conflitos. As

vezes modificações feitas no servidor e as modificações feitas localmente podem representar

um conflito. Neste caso temos que introduzir uma maneira de resolver este conflito. Algumas

opções ordenadas por dificuldade são:

• Substituir a versão local pela do servidor.

• Mostrar um diálogo ao usuário para que ele faça a resolução doconflito.

• Tentar fazer uma resolução de conflitos automaticamente.

Page 35: Rich Internet Applications com clientes offline utilizando Gears

28

4 CONCLUSÃO

Este capítulo apresenta os resultados obtidos pelo estudo desta arquitetura inovadora pro-

posta pelo Gears, bem como dificuldades encontradas duranteo projeto de desenvolvimento.

4.1 Análise da Arquitetura Proposta

As novas aplicações Web trazem a lógica cada vez mais para o lado do cliente. Isso faz com

que o código Javascript das aplicações se torne relativamente grande e complexo. É importante

conhecer bem as novidades dessa linguagem que tornam o desenvolvimento de grandes bases

de código mais amigável.

A arquitetura proposta pelo Gears demonstrada na seção 2.3.2 (página 10) cria um novo

paradigma para desenvolvimento de aplicações Web, introduzindo funcionalidades nunca antes

disponíveis nesta plataforma.

4.2 Contribuições

Este trabalho documenta a criação de uma aplicação rica da Web desenvolvida em Django

e utilizando o Gears para prover funcionalidadesoffline. Focando nos passos mais importantes

e nas decisões que devem ser tomadas pelo desenvolvedor que pretende implementar o Gears.

Outra contribuição é a análise da arquitetura proposta peloGears e como isso pode afetar o

futuro das aplicações Web.

4.3 Dificuldades Encontradas

As Aplicações Ricas da Internet são desenvolvidas em Python (ou qualquer outra linguagem

server side) e Javascript. O fato de ter que trabalhar com duas linguagens simultaneamente pode

Page 36: Rich Internet Applications com clientes offline utilizando Gears

29

causar confusão durante o desenvolvimento. Não só pelo fatode a sintaxe ser diferente, mas

também pelo fato de o Javascript ser uma linguagem que possuialguns paradigmas incomuns

como a orientação a eventos e o escopo baseado emclosures.

As aplicações Web podem ser difíceis de depurar. Uma das melhores ferramentas para fazer

debugé o FireBug, extensão para o Firefox que permite adicionarbreakpointse fazertracedo

código.

Pelo Gears ser uma tecnologia muito nova e com muitas possibilidades, é difícil encontrar

bom material de exemplo e bibliografia. Por sorte o Google provê uma boa documentação

da API [Gears API 2008] e de problemas comuns [Gears FAQ 2008]. Mesmo assim algumas

funcionalidades não são documentadas.

4.4 Propostas de Extensão

Dentre possíveis extensões para a continuidade deste trabalho estão:

• Estudo da arquitetura do Adobre AIR traçando um paralelo comas funcionalidades do

Gears.

• Estudo das novas funcionalidades do HTML5 e como essas funcionalidades complemen-

tam ou substituem as funcionalidades do Gears.

• Desenvolvimento de aplicação para facilitar a criação de mecanismos de sincronização

no Gears.

Page 37: Rich Internet Applications com clientes offline utilizando Gears

30

Referências Bibliográficas

[Gears API 2008]GEARS API. [S.l.], 2008. Documentação da APIdo Google Gears. Disponí-vel em:<http://code.google.com/apis/gears/design.html>. Acesso em: 30/05/2009.

[Gears FAQ 2008]GEARS FAQ. [S.l.], 2008. Perguntas e Respostas Frequentes sobre o GoogleGears. Disponível em:<http://code.google.com/apis/gears/gears_faq.html>. Acesso em:30/05/2009.

[Google 2009]GOOGLE.Web Storage Portability Layer: A Common API for WebStorage. [S.l.], 2009. Anúncio do WSPL do Google. Disponível em:<http://google-opensource.blogspot.com/2009/05/web-storage-portability-layer-common.html>. Acessoem: 31/05/2009.

[Holovaty e Kaplan-Moss 2008]HOLOVATY, A.; KAPLAN-MOSS, J. The Definitive Guide todjango: Web development done right. 1. ed. [S.l.]: Apress, 2008. ISBN 978-1590597255.

[Keith 2005]KEITH, J. DOM Scripting: Web design with javascript and the documentobject model. Friends of ED, 2005. 368 p. ISBN 978-1-59059-533-6. Disponível em:<http://www.friendsofed.com/book.html?isbn=1590595335>.

[Kilani 2007]KILANI, O. Taking web applications offline with gears. 2007. Disponí-vel em: <http://code.google.com/apis/gears/articles/take_app_offline.html>. Acesso em:04/12/2008.

[Krug 2005]KRUG, S.Don’t Make Me Think: A common sense approach to web usability. 2.ed. [S.l.]: New Riders Press, 2005. ISBN 978-0321344755.

[Miller 2008]MILLER, M. Cloud Computing: Web-based applications that change the way youwork and collaborate online. [S.l.]: Que, 2008. ISBN 978-0789738035.

[Taivalsaari e Ingalls 2008]TAIVALSAARI, A.; INGALLS, D. Web browser as an applicationplatform: The lively kernel experience. 2008.

[Tanenbaum e Steen 2007]TANENBAUM, A.; STEEN, M. V.Sistemas Distribuídos: Princí-pios e paradigmas. 2. ed. São Paulo, SP: Pearson, 2007. 416 p.ISBN 978-8576051428.

Page 38: Rich Internet Applications com clientes offline utilizando Gears

31

APÊNDICE A -- Aplicação em Django utilizando

Gears

Neste Apêndice está documentada uma aplicação simples de anotações utilizando Django

e disponibilizando todas as funcionalidadesofflinecom o Gears.

A.1 Interface

Telas da aplicação de Anotações.

Figura 6: Tela listando todas as notas.

Page 39: Rich Internet Applications com clientes offline utilizando Gears

32

Figura 7: Tela mostrando uma determinada nota.

Page 40: Rich Internet Applications com clientes offline utilizando Gears

33

A.2 Arquivos

Nesta seção estão documentados os arquivos principais da implementação da aplicação de

anotações.

project

|-- __init__.py

|-- db.sqlite <-- Banco de dados do lado do Servidor

|-- manage.py <-- Arquivo do django de gerenciamento de proj etos e aplicações

|-- notes <-- Aplicação django

| |-- __init__.py

| |-- admin.py <-- Configura interface de Administração do d jango

| |-- app_media <-- Arquivos estáticos

| | ‘-- notes

| | |-- datalayer.js <-- Camada de abstração de dados

| | |-- django_gears.js <-- Funções de sincronização e setup do Gears

| | |-- gears_icons.png

| | |-- gears_init.js <-- Arqivo padrão para inicializar o Ge ars

| | |-- gears_test.txt <-- Usado para testar se o cliente esta online

| | |-- jquery.js <-- Biblioteca que facilita o uso do DOM e Aja x

| | |-- manifest.json <-- manifest do Gears

| | |-- notes.js <-- Biblioteca que faz alterações na interfa ce

| | ‘-- style.css

| |-- forms.py

| |-- models.py <-- Define modelo de dados

| |-- templates <-- django templates, usados pelas views

| | ‘-- notes

| | |-- base.html

| | |-- note_detail.html

| | ‘-- note_list.html

| |-- urls.py <-- Faz mapeamento de urls e views para esta apli cação

| ‘-- views.py <-- Lógica de negócio

|-- settings.py <-- Configuração do django

‘-- urls.py <-- Mapeamento de urls do projeto

Page 41: Rich Internet Applications com clientes offline utilizando Gears

34

A.2.1 Django

Arquivos mais relevantes na implementação do Django da aplicação.

models.py

from django.db import models

from datetime import datetime

class Note(models.Model):

mod_date = models.DateTimeField(’date modified’)

title = models.CharField(max_length=200)

content = models.TextField()

def __unicode__(self):

return self.title

def get_absolute_url(self):

return "/notes/%i/" % self.id

def save(self, force_insert=False, force_update=False) :

self.mod_date = datetime.utcnow()

super(Note, self).save(force_insert, force_update)

urls.py

from django.conf.urls.defaults import *

from notes.models import Note

urlpatterns = patterns(’notes.views’,

(r’^$’, ’note_list’),

(r’^add/$’, ’note_add’),

(r’^(?P<id>\d+)/$’, ’note_detail’),

(r’^sync/$’, ’sync’),

)

views.py

from django.http import HttpResponse, HttpResponseRedir ect

from django.core import serializers

from django.shortcuts import get_object_or_404, render_ to_response

from notes.models import Note

Page 42: Rich Internet Applications com clientes offline utilizando Gears

35

from django.template import RequestContext

from notes.forms import NoteForm

from datetime import datetime

def note_list(request):

form = NoteForm()

if request.GET.has_key("last_mod") and request.GET[’la st_mod’].isdigit():

#recuperando notas alteradas apenas a partir de certa data

n = Note.objects.filter(mod_date__gt=datetime.fromtim estamp(

int(request.GET[’last_mod’])))

else:

n = Note.objects.all()

if request.is_ajax() or request.GET.has_key("xhr"):

response = HttpResponse(mimetype="application/json")

json_serializer = serializers.get_serializer("json")( )

json_serializer.serialize(n, ensure_ascii=False, stre am=response)

return response

else:

return render_to_response(’notes/note_list.html’,

{ ’object_list’ : n,’form’ : form},

context_instance=RequestContext(request))

def note_detail(request, id):

n = get_object_or_404(Note, pk=id)

if request.is_ajax() or request.GET.has_key("xhr"):

n = Note.objects.filter(id=id)

response = HttpResponse(mimetype="application/json")

json_serializer = serializers.get_serializer("json")( )

json_serializer.serialize(n, ensure_ascii=False, stre am=response)

return response

else:

return render_to_response(’notes/note_detail.html’, { ’object’:n},

context_instance=RequestContext(request))

def note_add(request):

if request.method == ’POST’:

form = NoteForm(request.POST)

Page 43: Rich Internet Applications com clientes offline utilizando Gears

36

if form.is_valid():

form.save()

return HttpResponseRedirect(’/notes/’)

else:

return HttpResponseRedirect(’/notes/’)

def sync(request):

if request.method == ’POST’:

for deserialized_object in serializers.deserialize("js on",

request.POST[’data’]):

obj = deserialized_object.object

deserialized_object.save()

if(obj.pk):

return HttpResponse(obj.pk)

assert(False)

return HttpResponse(’ERROR’)

A.2.2 Gears

Arquivos mais relevantes na implementação do Gears na aplicação.

django_gears.js

function djGears(){

this.STORE_NAME = "offline_notes";

this.MANIFEST_FILENAME = "/media/notes/manifest.json" ;

this.online=false;

this.setup_store();

this.db = google.gears.factory.create(’beta.database’ );

this.db.open(’db’);

try {

var rs;

rs = this.query(

’select version,strftime("%s",last_mod,"utc") from not es_version’);

console.log(rs);

console.trace();

this.version = rs.field(0);

Page 44: Rich Internet Applications com clientes offline utilizando Gears

37

this.last_mod = rs.field(1);

rs.close();

} catch (e) {

console.error("DB needs setup: "+ e.message);

this.setup_db();

}

this.get_updates();

}

djGears.prototype.setup_db = function(){

try{

//Create tables

this.query(’BEGIN’);

var sql = ’CREATE TABLE IF NOT EXISTS "notes_note" (’+

’ "id" integer NOT NULL PRIMARY KEY,’+

’ "id_server" integer,’+

’ "mod_date" datetime NOT NULL,’+

’ "title" varchar(200) NOT NULL,’+

’ "content" text NOT NULL’+

’);’+

’CREATE UNIQUE INDEX IF NOT EXISTS "notes_note_id_server" ’+

’ON "notes_note" ("id_server");’;

this.query(sql);

sql = ’CREATE TABLE IF NOT EXISTS notes_version ’+

’("version" integer not null primary key, "last_mod"’+

’ datetime not null);’;

this.query(sql);

this.query(’COMMIT’);

this.query(’INSERT INTO notes_version VALUES (1,0);’);

} catch (ex) {

console.error(’Could not create database: ’ + ex.message) ;

}

};

djGears.prototype.query = function(sql, arr){

var ret;

Page 45: Rich Internet Applications com clientes offline utilizando Gears

38

try{

console.info(sql,arr);

return this.db.execute(sql,arr);

}catch(e){

console.error("query error:" + e.message +":" +sql+arr);

throw e;

}

};

djGears.prototype.queryToObject = function(sql, args) {

var rs = this.query(sql, args);

try {

var rv = [], h;

if (rs && rs.isValidRow()) {

while (rs.isValidRow()) {

h = {fields: {}};

h.pk = rs.fieldByName(’id’);

h.model = ’notes.note’;

for (i = 0; i < rs.fieldCount(); i++) {

h.fields[rs.fieldName(i)] = rs.field(i);

}

rv.push(h);

rs.next();

}

}

} catch (e) {

throw e;

} finally {

rs.close();

return rv;

}

}

djGears.prototype.setup_store = function(){

if(!window.google || !google.gears) {

location.href = "http://gears.google.com/?action=inst all" +

"&return=localhost/notes/";

Page 46: Rich Internet Applications com clientes offline utilizando Gears

39

}else{

localServer = google.gears.factory.create("beta.local server");

this.store = localServer.createManagedStore(this.STOR E_NAME);

this.store.manifestUrl = this.MANIFEST_FILENAME;

this.store.checkForUpdate();

}

};

djGears.prototype.get_updates = function(){

try{

var rs;

//Only import the new ones

$.getJSON(’/notes/?xhr=1&last_mod=’+this.last_mod+’ ’,function(r){

for (var n in r){

if (r[n].pk === undefined){

continue;

}

dg.query(’insert into notes_note ’+

’(id_server,title, content,mod_date) values (?,?,?,?)’ ,

[r[n].pk, r[n].fields.title,

r[n].fields.content, r[n].fields.mod_date]);

}

});

//set new updated time

this.query(’update notes_version set last_mod = datetime ("now");’);

rs = this.query(

’select version,strftime("%s",last_mod,"utc") from not es_version’);

if(rs.isValidRow()){

this.version = rs.field(0);

this.last_mod = rs.field(1);

}

rs.close();

} catch (ex) {

console.error(’Import error: ’ + ex.message);

Page 47: Rich Internet Applications com clientes offline utilizando Gears

40

}

}

djGears.prototype.send_updates = function(){

try{

var obj;

if(this.tsend){

clearTimeout(this.tsend);

}

//get new rows

obj = this.queryToObject(

’select id,title,content,mod_date from notes_note ’+

’where id_server is null limit 1;’);

if(typeof obj[0] == ’undefined’ || typeof obj[0].pk == ’und efined’){

console.log(’App atualizada’);

return false;

}

if(!this.online){

this.tsend = window.setTimeout("dg.send_updates()",9* 1000);

console.log(’Aplicação offline remarcando send_updates ’);

return false;

}

this.get_updates();

//Export

$.post(’/notes/sync/’,’data=’+JSON.stringify(obj),f unction(text){

var id = parseInt(text);

if(id && id>=0){

dg.query("update notes_note set id_server = ? ’+

’where id = ? ",[id,obj[0].pk]);

dg.send_updates();

}

});

}catch (ex){

console.error(’Export error: ’ + ex.message)

}

}

Page 48: Rich Internet Applications com clientes offline utilizando Gears

41

//Check if Online

if(window.google && google.gears) {

var request = google.gears.factory.create(’beta.httpre quest’);

var dg = new djGears();

function pingSuccess() {

if(request.responseText.indexOf("ok") >= 0){

$("#gears").attr(’class’, ’online’);

$("#gears_status").text("Online");

dg.online=true;

} else {

$("#gears").attr(’class’, ’offline’);

$("#gears_status").text("Offline");

dg.online=false;

}

}

function isServerAvailable() {

var resource_to_test = "/media/notes/gears_test.txt";

var TIME_BETWEEN_PINGS = 3*1000;

var PING_TIMEOUT_SECONDS = 1*1000;

resource_to_test += "?q=" + Math.floor(Math.random() * 10 0000);

request.open(’GET’, resource_to_test);

window.setTimeout("pingSuccess()",PING_TIMEOUT_SECO NDS);

request.send();

window.setTimeout("isServerAvailable()",TIME_BETWEE N_PINGS);

}

isServerAvailable();

}

datalayer.js

function datalayer(){};

/**

* Get all or one object from local database or, if not possible , from the web

*/

datalayer.prototype.getNotes = function(id,cb){

try{

Page 49: Rich Internet Applications com clientes offline utilizando Gears

42

var sql,

json_r = [];

sql = ’SELECT * FROM notes_note ’;

if(id>=0){

sql += ’WHERE id = ’+id+’;’

}

json_r = dg.queryToObject(sql);

return cb(json_r);

}catch(e){

return $.getJSON(’/notes/?xhr=1’,cb);

}

};

/**

* Funcao deve ser passada para o contexto de um formulario

*/

datalayer.prototype.postNote = function(e,cb){

var event = e || window.event;

var el = event.target || event.srcElement;

try{

var sql,arr;

sql = ’INSERT INTO notes_note (title,content,mod_date) ’+

’VALUES (?,?,datetime("now"))’;

arr = [el.title.value, el.content.value]

dg.query(sql,arr);

cb();

dg.send_updates();

}catch(e){

$.post($(el).attr(’action’),$(el).serialize(),cb);

}

};

var dl = new datalayer();

notes.js

Funções responsáveis por invocar o datalayer e fazer modificações na interface do usuário.

Faz uso de instruções da biblioteca jQuery.

Page 50: Rich Internet Applications com clientes offline utilizando Gears

43

function loadNotes(event){

dl.getNotes(-1,function(data){

$("#notas").empty();

$("#notas").append(document.createElement(’ul’));

$.each(data, function(){

$("#notas").children(":first").append(’<li>’+

’<a href="/notes/’+this.pk+’/">’+this.fields.title+’ </a></li>’);

});

$(’<form id="add_nota" method="post" action="/notes/ad d/">’+

’<p><label for="id_title">Title:</label> <input type=" text" maxlength=’+

’"200" name="title" id="id_title"/></p><p><label for=" id_content">’+

’Content:</label> <textarea name="content" cols="40" ro ws="10" ’+

’id="id_content"/></p><input type="submit" value="Sub meter"/></form>’)

.appendTo(’#notas’);

$("#add_nota").submit(NovaNota);

RegisterListEvents();

});

if (event) {

event.preventDefault();

}

}

function NovaNota(event){

dl.postNote(event,function(){

loadNotes();

});

event.preventDefault();

}

function RegisterListEvents(){

$("#notas li>a").unbind(’click’);

$("#notas li>a").click(function(event){

var pk = /.*\/notes\/(\d+)\//.exec($(this).attr("href" ))[1];

dl.getNotes(parseInt(pk), function(data){

$("#notas").empty();

Page 51: Rich Internet Applications com clientes offline utilizando Gears

44

$.each(data,function(){

$(’#notas’).append(’<h2>’+this.fields.title+’</h2>’ );

$(’#notas’).append(’<pre>’+this.fields.content+’</p re>’);

});

event.preventDefault();

});

});

}

function RegisterSidebarEvents(){

$("#note_menu").unbind(’click’);

$("#note_menu").click(loadNotes);

}

$(document).ready(function(event){

RegisterListEvents();

RegisterSidebarEvents();

loadNotes();

});