UNOCHAPECÓ - UNIVERSIDADE COMUNITÁRIA REGIONAL DE CHAPECÓ CENTRO TECNOLÓGICO CURSO DE BACHAREL EM CIÊNCIA DA COMPUTAÇÃO JACKSON LUIZ DE MARCO MODELAGEM E DESENVOLVIMENTO DE UM WEBSITE USANDO ZOPE Chapecó (SC), JUNHO DE 2006 JACKSON LUIZ DE MARCO MODELAGEM E DESENVOLVIMENTO DE UM WEBSITE USANDO ZOPE Trabalho de conclusão de curso de graduação, apresentado a UNOCHAPECÓ – Universidade Comunitária Regional de Chapecó como parte dos requisitos para obtenção do grau de bacharel em Ciência da Computação. Orientador: Jean Carlos Hennrichs Co-Orientador: Elton Luis Minetto Chapecó (SC), JUNHO DE 2006 JACKSON LUIZ DE MARCO MODELAGEM E DESENVOLVIMENTO DE UM WEBSITE USANDO ZOPE ESTA MONOGRAFOIA FOI JULGADA PARA OBTENÇÃO DO TÍTULO DE BACHAREL EM CIÊNCIA DA COMPUTAÇÃO, DA UNOCHAPECÓ, ÁREA DE SISTEMAS COMPUTACIONAIS E APROVADA PELO CURSO DE CIÊNCIA DA COMPUTAÇÃO, 2006. ORIENTADOR – Jean Carlos Hennrichs CO-ORIENTADOR – Elton Luis Minetto BANCA EXAMINADORA ----------------------------------------------------------------------Prof. Luciano Carlos Frosi - UNOCHAPECÓ -----------------------------------------------------------------------Prof. Ms. Sediane Carmem Lunardi - UNOCHAPECÓ AGRADECIMENTOS Agradeço à minha mãe e minhas irmãs que me apoiaram muito; Aos meus orientadores Jean e Elton; Aos meus amigos e colegas de trabalho por compreender o mau-humor causado pelo estresse do pouco tempo livre para esfriar a cabeça. SUMÁRIO Lista de Figuras....................................................................................................ix Lista De Tabelas e Quadros................................................................................xi Lista de Siglas e Abreviaturas...........................................................................13 Resumo ................................................................................................................14 Abstract................................................................................................................15 1 Introdução ...................................................................................................16 1.1 Objetivos Gerais............................................................................................16 1.2 Objetivos Específicos ...................................................................................17 1.3 Organização dos capítulos...........................................................................17 2 Framework...................................................................................................19 2.1 Características de Frameworks ...................................................................19 2.2 Tipos de framework ......................................................................................21 2.2.1 Como são utilizados.................................................................................................... 21 2.2.2 Onde são utilizados .................................................................................................... 21 3 Python ..........................................................................................................23 3.1 Sintaxe............................................................................................................24 3.1.1 Identificadores e Variáveis.......................................................................................... 24 3.1.2 Operadores ................................................................................................................. 25 3.1.2.1 Aritméticos............................................................................................................. 25 3.1.2.2 Atribuição............................................................................................................... 26 3.1.2.3 Comparação.......................................................................................................... 26 3.1.3 3.1.3.1 Estrutura If ............................................................................................................. 27 3.1.3.2 Estrutura While...................................................................................................... 28 3.1.3.3 Estrutura For.......................................................................................................... 28 3.1.4 3.2 4 Controle de Fluxo........................................................................................................ 27 Tratamento de Exceções............................................................................................ 29 Orientação A objetos ....................................................................................30 Zope..............................................................................................................31 4.1 Surgimento ....................................................................................................31 4.2 Servidor Web – ZServer................................................................................32 4.3 Zope Object Database - ZODB .....................................................................33 4.4 Interface de gerenciamento (Zope Management Interface – ZMI) ............36 4.5 Objetos ...........................................................................................................37 4.6 Aquisição .......................................................................................................38 4.7 Linguagens ....................................................................................................39 4.7.1 Document Template Markup Language - DTML ....................................................... 40 4.7.1.1 Tag dtml-var .......................................................................................................... 40 4.7.1.2 Tags dtml-if, dtml-else, dtml-elif............................................................................ 41 4.7.1.3 Tag dtml-unless..................................................................................................... 42 4.7.1.4 Tag dtml-in............................................................................................................. 42 4.7.1.5 Tag dtml-tree ......................................................................................................... 44 4.7.1.6 Tag dtml-with ......................................................................................................... 44 4.7.1.7 Tag dtml-let............................................................................................................ 45 4.7.1.8 Tag dtml-return...................................................................................................... 45 4.7.1.9 Tag dtml-call .......................................................................................................... 46 4.7.1.10 Tag dtml-raise ..................................................................................................... 46 4.7.1.11 Tag dtml-try ......................................................................................................... 47 4.7.1.12 Tag dtml-except................................................................................................... 47 4.7.1.13 Tag dtml-finally .................................................................................................... 47 4.7.2 5 Zope Page Templates – ZPT ..................................................................................... 48 4.7.2.1 Template Attribute Language – TAL .................................................................... 48 4.7.2.2 Expressões Path ................................................................................................... 49 4.7.2.3 Expressões Python ............................................................................................... 50 4.7.2.4 Expressões String ................................................................................................. 51 4.7.2.5 Modificador not...................................................................................................... 51 Engenharia Web..........................................................................................52 5.1 Web Applications – Webapps ......................................................................52 5.2 Modelo de Processo .....................................................................................54 5.2.1 Formulação, planejamento e análise ......................................................................... 55 5.2.2 Projeto ......................................................................................................................... 56 5.2.3 Implementação e Testes ............................................................................................ 59 5.2.4 Avaliação do Cliente ................................................................................................... 60 6 Protótipo ......................................................................................................62 6.1 Análise............................................................................................................62 6.1.1 Consulta ...................................................................................................................... 62 6.1.2 Cadastro de usuário.................................................................................................... 63 6.1.3 Cadastro das tabelas .................................................................................................. 64 6.1.4 Alteração de Preferências .......................................................................................... 65 6.1.5 Sugestão de Obras ..................................................................................................... 65 6.1.6 Cadastro de obras ...................................................................................................... 66 6.1.7 Empréstimo ................................................................................................................. 67 6.1.8 Devolução ................................................................................................................... 67 6.2 Projeto ............................................................................................................68 6.2.1 Armazenamento.......................................................................................................... 68 6.2.2 Conteúdo..................................................................................................................... 70 6.2.3 Interface e navegabilidade.......................................................................................... 71 6.3 6.3.1 Ferramentas utilizadas ............................................................................................... 71 6.3.2 Geração da base de dados ........................................................................................ 72 6.3.3 Criação das páginas ................................................................................................... 73 7 6.3.3.1 Menu dinâmico ...................................................................................................... 74 6.3.3.2 Cadastro de usuários e funcionários.................................................................... 75 6.3.3.3 Atualização das preferências................................................................................ 76 6.3.3.4 Sugestão de obras para leitura............................................................................. 79 6.3.3.5 Empréstimo e devolução ...................................................................................... 82 Conclusões..................................................................................................84 7.1 8 Implementação e testes................................................................................71 Trabalhos futuros..........................................................................................85 Referências..................................................................................................86 Anexo A – Script para geração da base de dados ..........................................89 LISTA DE FIGURAS Figura 1: diferenças entre um framework e uma classe...................................................................................20 Figura 2: framework horizontal. .......................................................................................................................22 Figura 3: framework vertical. ...........................................................................................................................22 Figura 4: fluxo de funcionamento do ZServer. .................................................................................................33 Figura 5: diagrama dos estados dos objetos no ZODB....................................................................................35 Figura 6: tela inicial da interface de gerenciamento do Zope. ........................................................................36 Figura 7: diferença entre os métodos de herança e aquisição.........................................................................39 Figura 8: complexidade de uma webapp em relação ao seu foco....................................................................52 Figura 9: etapas para o desenvolvimento de uma webapp. .............................................................................55 Figura 10: representação da estrutura linear...................................................................................................57 Figura 11: representação da estrutura de malha. ............................................................................................58 Figura 12: representação da estrutura hierárquica. ........................................................................................58 Figura 13: representação da estrutura interligada. .........................................................................................58 Figura 14: caso de uso – consultar obra ..........................................................................................................63 Figura 15: caso de uso – cadastro de usuário ..................................................................................................63 Figura 16: caso de uso – cadastro de tabelas...................................................................................................64 Figura 17: caso de uso – cadastro de preferências ..........................................................................................65 Figura 18: caso de uso – sugestões de literatura .............................................................................................66 Figura 19: caso de uso – cadastro de obras .....................................................................................................66 Figura 20: caso de uso – empréstimo de obra..................................................................................................67 Figura 21: caso de uso – devolução de obra ....................................................................................................67 Figura 22: diagrama entidade-relacionamento proposto ................................................................................69 Figura 23: assistente para geração das páginas de gerenciamento das obras ...............................................73 Figura 24: menu dinâmico conforme nível de usuário.....................................................................................74 LISTA DE TABELAS E QUADROS Tabela 1: operadores aritméticos da linguagem Python..................................................................................25 Tabela 2: operadores de comparação em Python. ...........................................................................................27 Quadro 1: controle da execução em Python é realizado pela endentação do código.....................................23 Quadro 2: exemplos válidos de nomes de identificadores em Python. ............................................................24 Quadro 3: palavras reservadas em Python.......................................................................................................24 Quadro 4: operadores de atribuição em Python. .............................................................................................26 Quadro 5: atribuição múltipla em Python. .......................................................................................................26 Quadro 6: exemplo da utilização da estrutura condicional if-elif-else em Python..........................................27 Quadro 7: exemplo da utilização da estrutura de repetição while em Python. ...............................................28 Quadro 8: estrutura do laço de repetição for em Python.................................................................................28 Quadro 9: exemplo da utilização da estrutura de repetição for em Python. ...................................................29 Quadro 10: exemplo da utilização do tratamento de exceções em Python......................................................29 Quadro 11: criação de uma classe em Python..................................................................................................30 Quadro 12: exemplo de instanciação de uma classe em Python......................................................................30 Quadro 13: exemplo da utilização da tag dtml-var. .........................................................................................41 Quadro 14: exemplo da utilização das tags de teste condicionais...................................................................42 Quadro 15: exemplo da utilização da tag dtml-in. ...........................................................................................44 Quadro 16: exemplo da utilização da tag dtml-tree. ........................................................................................44 Quadro 17: exemplo da utilização da tag dtml-with.........................................................................................45 Quadro 18: exemplo da utilização da tag dtml-let............................................................................................45 Quadro 19: exemplo da utilização da tag dtml-return. ....................................................................................46 Quadro 20: exemplo da utilização da tag dtml-call. ........................................................................................46 Quadro 21: exemplo da utilização da tag dtml-raise. ......................................................................................46 Quadro 22: exemplo da utiização das tags para tratamento de exceções. ......................................................47 Quadro 23: exemplo da utilização de uma expressão Path..............................................................................50 Quadro 24: exemplo da utilização de uma expressão Python..........................................................................51 Quadro 25: exemplo da utilização de uma expressão String. ..........................................................................51 Quadro 26: código-fonte do script de verificação da permissão de visualização ...........................................75 Quadro 27: Código-fonte do script de inserção de usuário .............................................................................75 Quadro 28: código-fonte do script de inserção de funcionário........................................................................76 Quadro 29: código fonte do script para inclusão de um objeto User ..............................................................76 Quadro 30: código fonte da alteração necessária para atualizar as preferências do usuário .......................77 Quadro 31: código fonte da alteração necessária para selecionar as preferências do usuário.....................78 Quadro 32: código-fonte do script LoggedUser ...............................................................................................78 Quadro 33: instruções SQL para selecionar as preferências do usuário ........................................................79 Quadro 34: script de agregação dos objetos ZSQL Method para preferências do usuário............................80 Quadro 35: código-fonte do objeto que seleciona obras de preferência do usuário.......................................82 Quadro 36: código-fonte da alteração para empréstimo de obras ..................................................................83 LISTA DE SIGLAS E ABREVIATURAS BBC British Broadcasting Corporation BMP Bitmaps CGI Common Gateway Interface CTO Chief Technical Officer DTML Document Template Markup Language EUA Estados Unidos da América FTP File Transfer Protocol GIF Graphics Interchange Format GPL General Public License HTML Hyper Text Markup Language HTTP Hyper Text Transfer Protocol JPEG Joint Photographic Experts Group ORB Object Request Broker PNG Portable Network Graphics SGBD Sistema Gerenciador de Base de Dados TAL Template Attribute Language TALES TAL Expression Sintax TCP Transfer Control Protocol WebDAV Web-based Distributed Authoring and Versioning WWW World Wide Web WYSIWYG What You See Is What You Get XML Extensible Markup Language ZMI Zope Management Interface ZODB Zope Object DataBase ZOPE Z Object Publishing Environment ZPT Zope Page Templates RESUMO Este trabalho enfoca o desenvolvimento de uma aplicação web para o gerenciamento do setor de empréstimos da Biblioteca Pública Municipal de Chapecó. Utilizando para este fim, o framework de desenvolvimento para aplicações web Zope e o software MySQL como banco de dados relacional. O protótipo oferece como adicional um módulo para sugestão de leitura, módulo este adaptado às preferências de leitura do usuário. Tendo como principal ferramenta o framework Zope, não deve-se deixar de tratar sobre framework e a linguagem Python na qual foi escrito o Zope. Este trabalho faz referência ao modelo de desenvolvimento para web criado por Pressman (2002) utilizado para a criação do protótipo. Palavras-Chave: Zope; Python; Biblioteca ABSTRACT This work focuses the development of na archetype of a web application for the management of the sector of loans of the Chapecó Municipal Public Library. Using for this end, framework of development for web applications Zope and MySQL software as relational data base. The archetype offers as additional a module for reading suggestion, module this adapted to the preferences of reading of the user. Having as main tool framework Zope, does not have to be left to treat on framework and the Python language in which was written the Zope. This work make references to the web development model created by Pressman (2002) used to create the archetype. Keywords: Zope, Python, Library. 1 INTRODUÇÃO A Biblioteca Pública, fundada em 18 de novembro de 1940, possui 12.910 usuários e um acervo com mais de 28.000 obras das quais 70 por cento são destinadas ao setor de empréstimos. O controle do setor de empréstimo é ainda totalmente manual, ficando fácil o extravio de obras do acervo bibliográfico por não haver um controle eficiente de quem emprestou uma obra específica. Se o usuário não vier devolver a obra, a biblioteca, muitas vezes, nem sabe que a mesma está emprestada e que não consta na prateleira. O cadastro dos usuários também é manual, o que torna dificultosa a manutenção e manuseio das fichas, ainda em papel. Se ocorrer o extravio de uma dessas e nela estiver alguma obra emprestada, acaba-se perdendo o controle de quem está com a referida obra. O protótipo contará com um módulo de sugestão de obras para leitura de acordo com as preferências do usuário, facilitando a escolha e até provendo um maior apreço pela leitura, diferenciando assim das sugestões limitadas oferecidas pelos funcionários, uma vez que o acervo que possui é muito extenso, impossibilitando o conhecimento completo por parte dos funcionários. Para o desenvolvimento, devido ao alto custo de uma ferramenta proprietária, optouse pela escolha do framework de desenvolvimento Zope, uma vez que possui todas as ferramentas necessárias para a criação de uma aplicação web, além de ser multiplataforma e de código aberto. 1.1 OBJETIVOS GERAIS Desenvolver um protótipo para o gerenciamento do setor de empréstimo da Biblioteca Municipal de Chapecó fazendo uso do framework Zope. Além dos módulos tradicionais de controle de empréstimo e de usuários, também foi desenvolvido um módulo para sugestão de leitura de obras para os usuários da biblioteca. 17 1.2 OBJETIVOS ESPECÍFICOS Para que o objetivo geral seja atingido, fazem-se necessárias as seguintes etapas: desenvolver a engenharia da aplicação web de acordo com o modelo de desenvolvimento de WebE sugerido por Pressman (2002); demonstrar a utilização do framework de desenvolvimento Zope; compreender a linguagem Python, para um maior aproveitamento do framework acima citado; desenvolver e disponibilizar um protótipo para os usuários da biblioteca, apresentando uma interface amigável; desenvolver um módulo para sugestão de leituras de acordo com as preferências do usuário. 1.3 ORGANIZAÇÃO DOS CAPÍTULOS O presente trabalho está disposto em seis capítulos organizados da seguinte forma: Capítulo 1, “Introdução”: tem por objetivo introduzir o assunto e contextualizar a escolha do tema; Capítulo 2, “Framework”: apresenta conceitos da tecnologia de frameworks para desenvolvimento de aplicações; Capítulo 3, “Python”: explana sobre a linguagem de programação orientada a objetos Python, descrevendo seu surgimento e sintaxe; Capítulo 4, “Zope”: apresenta o framework utilizado para o desenvolvimento do protótipo, identificando suas ferramentas e explanando sobre as mesmas; Capítulo 5, “Engenharia Web”: define o modelo para desenvolvimento de aplicações web proposto por Pressman (2002), identificando cada uma de suas etapas; 18 Capítulo 6, “Protótipo”: apresenta detalhadamente como se deu o desenvolvimento do protótipo proposto para este trabalho; Capítulo 7, “Conclusões”: apresenta as conclusões com o desenvolvimento deste, considerações finais e sugestões de trabalhos futuros. 2 FRAMEWORK Segundo Lloyd (2004) framework é: um conjunto de blocos de software pré-fabricados que os programadores podem usar, estender, ou customizar para sua aplicação. É um mecanismo de reuso orientado a objeto que permite ao desenvolvedor decompor uma aplicação em um conjunto interativo de objetos. Descreve as relações executadas pelos componentes da estrutura, pelo fluxo do controle entre estes componentes, e pelos contratos entre os componentes e o sistema. Sendo assim, um framework é um design reusável. Já mais especificamente em orientação a objeto, framework é um conjunto de classes com objetivo de reutilização de um design, provendo um guia para uma solução de arquitetura em um domínio específico de software. Ele se diferencia de uma simples biblioteca (toolkit), pois a biblioteca se concentra apenas em oferecer implementação de funcionalidades, sem definir a reutilização de uma solução de arquitetura (design). A seqüência deste capítulo foi totalmente baseada na obra de Sauvé (2002). 2.1 CARACTERÍSTICAS DE FRAMEWORKS As características de um framework são: deve ser reusável; bem documentado; fácil de usar; deve ser extensível, com funcionalidades abstratas a ser implementadas; deve ser de uso seguro; deve ser eficiente e completo (alcance o domínio do problema proposto). As vantagens de redução de custos e redução de tempo na programação se dão pelos seguintes motivos: maximização de reuso (análise, design, código, testes); desenvolvedores se concentram em adicionar valor em vez de reinventar a roda; 20 menos manutenção; fatoração de aspectos comuns a várias aplicações; estabilização melhor do código (menos defeitos) devido ao uso em várias aplicações. Entretanto se for feita uma análise mais aprofundada das vantagens e características de um framework descritas acima, pode-se chegar à conclusão de framework nada mais é do que a utilização de uma biblioteca de classes. No entanto esta é uma conclusão errônea, pois Sauvé (2002) demonstra as várias diferenças existentes entre um framework e uma biblioteca de classes através da figura 1: Fonte: (Sauvé,2002). Figura 1: diferenças entre um framework e uma classe Um framework impõe um modelo de colaboração (o resultado da análise e design) ao qual você deve se adaptar; Não se pode embutir conhecimento do domínio (análise + design) numa biblioteca de classes; O framework é usado de acordo com o Hollywood Principle ("Don't call us, we'll call you"), que significa não nos ligue, nós ligaremos para você. Explicitando assim o controle do fluxo de execução da aplicação. 21 Concluindo, o framework se diferencia de uma simples biblioteca de classes (toolkit), pois esta se concentra apenas em oferecer implementação de funcionalidades, sem definir a reutilização de uma solução de arquitetura (design). 2.2 TIPOS DE FRAMEWORK Os frameworks são classificados em duas dimensões: “como” e “quando” eles são utilizados. 2.2.1 Como são utilizados Os frameworks dessa dimensão definem de que forma estes serão utilzados. Esta por sua vez divide-se em três tipos. Inheritance focused (White Box): estende ou modifica funcionalidade pela definição de sub-classes com sobrecarga de métodos; Composition focused (Black Box): usa as funcionalidades já presentes no framework, não permitindo alterações dos componentes internos; Híbrido: a maioria dos frameworks se encaixa neste tipo, pois implementam um pouco de cada um dos tipos citados anteriormente. 2.2.2 Onde são utilizados Nesta dimensão os frameworks são divididos em três tipos: Suporte: provê serviços de nível de sistema operacional (e não de aplicação); Horizontal (aplicação): encapsula conhecimento aplicável à várias aplicações, resolvendo apenas uma parte do problema da aplicação, como é demonstrado pela figura 2; 22 Fonte: (Sauvé, 2002). Figura 2: framework horizontal. Vertical (domínio): encapsula conhecimento aplicável a aplicações pertencentes a apenas um domínio de problema, resolvendo boa parte da aplicação, demonstrado na figura 3; Fonte: (Sauvé, 2002). Figura 3: framework vertical. Mostrou-se neste capítulo sobre a tecnologia de framework, suas características e subtipos, além de apresentar as diferenças entre um framework e uma biblioteca de classes. No próximo capítulo será apresentada a linguagem de script Python, pois a tecnologia utilizada para a realização deste trabalho é baseada quase que em sua totalidade nesta linguagem. 3 PYTHON Segundo Neto e Borges (2004), o desenvolvimento da linguagem Python foi iniciado em 1989 pelo holandês Guido van Rossum, que inspirou o nome da linguagem no título da série de TV Monty Python's Flying Circus, originalmente exibida pela British Broadcasting Corporation (BBC) entre 1969 e 1974. O criador da linguagem Python queria desenvolver uma linguagem de altíssimo nível que agregasse características importantes de diversas linguagens e ainda mantivesse uma sintaxe clara e sólida. A portabilidade de Python também é importante ser destacada, atualmente ela trabalha em qualquer ambiente baseado em Microsoft (inclusive .NET), UNIX, Linux, MacOS. Segundo Rossum (2005), Python é uma linguagem orientada a objetos, interpretada e compilada em tempo de execução, possui suporte a tratamento de exceções e de erros, tipagem dinâmica e ampla documentação. Conta ainda com o amplo suporte a listas, uma sintaxe muito clara devido ao seu formato de agrupamento de códigos que é proporcionado somente pela endentação do código como se segue no exemplo do quadro 1: Quadro 1: controle da execução em Python é realizado pela endentação do código. def perm(l): # lista da permutações de l if len(l) <= 1: return [l] r = [] for i in range(len(l)): s = l[:i] + l[i+1:] p = perm(s) for x in p: r.append(l[i:i+1] + x) return r Python ainda possui licença compatível com a licença General Public License (GPL) da Free Software Foundation, tornando a linguagem independente de fornecedores exclusivos. 24 3.1 SINTAXE Será apresentado a seguir a sintaxe básica que a linguagem Python disponibiliza para um melhor entendimento da seqüência do presente texto. 3.1.1 Identificadores e Variáveis Segundo Brueck e Tanner (2001), a linguagem Python procede da mesma forma que a maioria das linguagens no que diz respeito à declaração de nomes de identificadores e variáveis. Devem iniciar com uma letra do alfabeto (A-Z, a-z) ou underline (_) seguidas por qualquer seqüência de números, letras ou underlines. Alguns exemplos válidos são demonstrados no quadro 2: Quadro 2: exemplos válidos de nomes de identificadores em Python. Frutas Flag Campo Texto1 Campo_do_texto1 Cabe salientar que na linguagem Python a declaração de variáveis é case sensitive, ou seja, a declaração da variável “Frutas” é diferente de “frutas”. Não há declaração de tipo de variável em Python, pois a cada atribuição de valor a variável é reiniciada e adaptada para o novo valor a ser atribuído. A linguagem oferece também inúmeros tipos de dados nativos, dentre os principais estão os numéricos (integer, long integer, float point, imaginary), string, list, tuple e dictionary. Existem também na linguagem Python as conhecidas palavras reservadas, as quais não podem ser utilizadas como nome de identificadores ou variáveis. A lista delas segue no quadro 3. and assert del elif Quadro 3: palavras reservadas em Python. for Is from lambda raise return 25 break class continue finnaly 3.1.2 else except exec in global if import print Not or pass try while def Operadores Para a construção de expressões em Python, sejam elas expressões de avaliação ou atribuição, devem ser utilizados símbolos conhecidos como operadores. 3.1.2.1 Aritméticos A linguagem disponibiliza vários operadores, tanto para dados aritméticos, quanto dados complexos. Os operadores aritméticos, conforme a tabela 1, são. Tabela 1: operadores aritméticos da linguagem Python. Operações unárias + ~ Operações binárias + * / % ** Operações binárias de bitwise & | ^ Operações de Shifting << >> Fonte: (BRUECK e TANNER, 2001). Positivo Negativo Inversão Adição Subtração Multiplicação Divisão Módulo (resto) Exponenciação E (AND) OU (OR) OU Exclusivo (XOR) Left bit-shifting Right bit-shifting 26 3.1.2.2 Atribuição Segundo Brueck e Tanner (2001), o principal operador de atribuição da linguagem é o sinal de igual (=), mas além deste a linguagem possui operadores de atribuição incrementais que combinam uma atribuição a uma operação binária em uma mesma declaração, ou seja, atribui o valor da direita ao valor da esquerda efetuando a operação representada pelo operador ao lado do sinal “=”. Os operadores de atribuição incrementais, conforme o quadro 4, são. Quadro 4: operadores de atribuição em Python. += -= *= /= %= **= >>= <<= &= |= ^= Fonte: (BRUECK e TANNER, 2001). Para demonstrar os operadores do quadro 4, supõe-se que o valor da variável “a” é 4 e quer-se acrescer um valor a esta variável. Uma maneira de se efetuar esta atribuição seria esta: a = a + 2. Já com o operador incremental a instrução ficaria desta forma: a += 2. Além das formas de atribuição acima citadas a linguagem possui a forma de atribuição múltipla como demonstrado através do quadro 5, onde três variáveis recebem valores diferentes com uma linha só de código. Quadro 5: atribuição múltipla em Python. a, b, c = 50, 5.5, 99 3.1.2.3 Comparação Python reconhece qualquer valor diferente de zero (0) como verdadeiro e somente zero como falso, sendo os operadores usados para efetuar comparações os que são apresentados na tabela 2. 27 Tabela 2: operadores de comparação em Python. Operadores de Comparação < Menor que > Maior que <= Menor ou igual a >= Maior ou igual a == Igualdade != Diferença Fonte: (BRUECK e TANNER, 2001). Para expressões compostas, a linguagem utiliza os operadores AND, OR e NOT, juntamente com os operadores de comparação e/ou operadores aritméticos. 3.1.3 Controle de Fluxo Segundo Brueck e Tanner (2001), para o controle de fluxo a linguagem utiliza-se das seguintes estruturas: if, for, while, contando ainda com o tratamento de exceções através da estrutura try-except-else. 3.1.3.1 Estrutura If Estrutura mais simples para controle de fluxo, existente em quase todas as linguagens, é utilizada para avaliar uma expressão condicional, podendo existir aninhamentos múltiplos e múltiplas opções com o uso das cláusulas elif e else como é demonstrado no quadro 6. Quadro 6: exemplo da utilização da estrutura condicional if-elif-else em Python. if nota >= 7 : print “Aprovado!” elif (nota < 7) and (nota >= 5) : if faltas > 25 : print “Reprovado sem chance!!” else : print “Tenta passar na G3!!” else : print “Reprovado sem chance!!!” 28 3.1.3.2 Estrutura While O laço de repetição while tem a função de repetir o bloco de código que está aninhado dentro dele, enquanto uma condição for verdadeira, através da seguinte estrutura demonstrada no quadro 7. Quadro 7: exemplo da utilização da estrutura de repetição while em Python. while (alunos != 0) : if nota >= 7 : print “Aprovado!” elif (nota < 7) and (nota >= 5) : if faltas > 25 : print “Reprovado sem chance!!” else : print “Tenta passar na G3!!” else : print “Reprovado sem chance!!!” 3.1.3.3 Estrutura For Esta estrutura como na maioria das linguagens, possibilita a execução de um bloco de código uma determinada quantidade de vezes. Mas ao contrário da maioria das linguagens não há um contador para esta estrutura, ela é apresentada como demonstrado no quadro 8: Quadro 8: estrutura do laço de repetição for em Python. for <variável> in <lista ou seqüência> (bloco de código a ser repetido) Para executar-se um bloco repedidas vezes usa-se das funções range(<inicial>[, <final>[, <passo>]]) e xrange(<inicial>[, <final>[, <passo>]]), que criam uma lista numérica, sendo que a única diferença entre elas é o acesso à memória que elas processam. O exemplo demonstrado no quadro 9, mostra a estrutura for, em suas três formas (lista, range e xrange): 29 Quadro 9: exemplo da utilização da estrutura de repetição for em Python. # imprimir nomes da lista for Nome in [“Paulo”, “José”, “Ana”] print Nome # imprimir números de 0 a 999999 for X in range(1000000) # isto irá ocupar uma memória considerável print X # imprimir números de 0 a 999999 for X in xrange(1000000) # isto irá muito menos memória que o código # acima print X Existem também cláusulas break, continue e else que funcionam respectivamente para parar com a execução do loop, continuar para a próxima iteração do loop e por último se não houver a execução da cláusula break é executada a cláusula else. Lembra-se ainda que a linguagem Python, diferentemente das outras linguagens, não possui a construção switch. 3.1.4 Tratamento de Exceções O tratamento de exceções na linguagem Python segundo Brueck e Tanner (2001) é realizado através das cláusulas try, exception e else, as quais respectivamente executam as tarefas de permitir o tratamento de exceções no bloco de código, efetuar o tratamento de exceções causadas no bloco de código e por último alocar blocos de código que são executados caso não haja acontecido uma exceção, um exemplo disso é apresentado no quadro 10: Quadro 10: exemplo da utilização do tratamento de exceções em Python. # Abrir um arquivo try: ArquivoNotas = open(“C:\Fac\Notas.dat”) # Caso não consiga abrir o arquivo except: # Mostra uma mensagem print “Arquivo não pode ser aberto...” else: ProcessaNotas(ArquivoNotas) #Processo para avaliar as notas 30 3.2 ORIENTAÇÃO A OBJETOS A orientação a objetos em Python segundo Brueck e Tanner (2001), funciona de forma prática e fácil. Criam-se as classes e as utiliza para instanciar os objetos. Sendo que estes objetos podem possuir um número qualquer de atributos, assim como um número qualquer de métodos. Ainda pode-se criar classes a partir da derivação de uma ou mais classes. Estas novas classes ou subclasses herdam os atributos e métodos de seus pais, mas podem sobrescrevê-los para que se adaptem ao que o sistema necessita. O quadro 11 demonstra um exemplo de como criar uma classe em Python: Quadro 11: criação de uma classe em Python. # Criar uma classe Carteira class Carteira: CarteiraCNT = 0 #Variável de classe, todas instâncias #compartilham def __init__(self, balance=0) self.balance = balance CarteiraCNT += 1 def printBalance(self) print “Balance of today is: %.2f” % self.balance Para instanciar a classe acima exemplificada, ou seja, criar um objeto Carteira, utiliza-se o seguinte código, como demonstrado no quadro 12: Quadro 12: exemplo de instanciação de uma classe em Python. # Criando o objeto carteira = Carteira(5000.52) # carteira criada como sendo um objeto # carteira com valor inicial de 5000.52 carteira.printBalance() # imprime o saldo que irá sair na tela como # demonstrado abaixo Balance of today is: 2500.00 Apresentou-se neste uma introdução à linguagem Python, bem como seu histórico e uma explanação sobre sua sintaxe e como é realizada a orientação a objetos nesta linguagem. A seguir será apresentado a tecnologia Zope, a qual será utilizada para a implementação da aplicação final. 4 ZOPE Z Object Publishing Environment (Zope), é segundo Santos (2002), “uma plataforma de desenvolvimento de aplicativos web dinâmicos com interface de administração via browser e orientada a objeto”. Segundo Latteier e Pelletier (2001), o Zope é considerado um framework, pois oferece suporte às principais ferramentas para criação de aplicações para web, como as apresentadas abaixo, as quais serão mais aprofundadas no decorrer do capítulo: servidor web; banco de dados transacional orientado a objetos; interface de administração via browser; linguagem de marcação própria, para geração de páginas dinâmicas; integração com bancos de dados relacionais, além de possuir uma versão simples para testes chamada Gadfly; separação da lógica e apresentação através da programação em linguagens como Python ou Perl. além de products (produtos), que funcionam como plugins para a extensão da plataforma; 4.1 SURGIMENTO Segundo Santos (2002), em 1996, Jim Fulton, o Chief Technical Officer (CTO) da empresa Digital Creations, atual Zope Corporation, e expert em Python, foi chamado para dar aulas de programação Common Gateway Inteface (CGI). Ele estudou a documentação existente sobre CGI no caminho para a sala de aula. Na volta, Jim pensou sobre o que não gostava dos ambientes de programação CGI existentes, e como ela expõe os detalhes do servidor. A partir disto, o núcleo do Zope foi escrito. A empresa Digital Creations liberou três pacotes de software de código aberto para suportar publicação via web, chamados Bobo, Document Template e BoboPOS. Estes 32 softwares foram escritos em Python. Eles evoluíram nos componentes base do Zope oferecendo o web Object Request Broker (ORB), a linguagem de script DTML e um banco de dados orientado a objeto. 4.2 SERVIDOR WEB – ZSERVER Na essência, o ZServer, segundo Feuer (2005), é um Server Medusa, criado por Sam Rushings, que tem como descrição em seu próprio site, uma arquitetura de servidor extensível e de alta performance que tem suporte atualmente para HTTP, FTP e WebDAV1 e outros protocolos de Internet e executa sob plataformas Windows e Unix (Linux, BSD, e afins). Foram somente efetuadas algumas modificações para suportar o banco de dados ZODB. A figura abaixo demonstra o fluxo de funcionamento do servidor ZServer. Fonte: (ZOPE – WPROWADZENIE, 2004) 1 WebDAV (Web-based Distributed Authoring and Versioning) Um conjunto de extensões para o HTTP (Hypertext Transfer Protocol) que permite que os usuários editem e gerenciam cooperativamente arquivos em servidores Web remotos (Fonte: Glossario: IBM HTTP SERVER, 2005). 33 Figura 4: fluxo de funcionamento do ZServer. Como demonstrado na figura 4, e segundo Santos (2002), o ZServer pode trabalhar só ou em conjunto com outros servidores web como Apache, IIS ou qualquer outro que suporte PCGI ou FastCGI. 4.3 ZOPE OBJECT DATABASE - ZODB ZODB, segundo Santos (2005) é um banco de dados orientado a objetos transacional tendo como principal objetivo, a transparência para o desenvolvedor que trabalha com Python, assim sendo ele torna-se uma ferramenta para a persistência dos objetos Python, não necessitando especificar como o objeto deve ser armazenado ou pesquisado no banco de dados. O ZODB efetua a persistência de objetos armazenando-os através de uma representação simples, formada pela classe do objeto e uma estrutura de dicionário que nas chaves contém as propriedades do objeto e nos valores de cada chave o valor que a propriedade possui. Esta representação simples é muito eficiente e permite que o meio de armazenamento tenha implementações alternativas como velocidade, tolerância a falhas, e até compatibilidade com modelos relacionais. Para o controle de concorrência o ZODB faz o uso de transações, subtransações em dois níveis e versões, e ao invés de bloqueios utiliza marcadores de tempo para evitar deadlocks2, ou seja, não tranca um registro para edição, simplesmente determina um tempo para o mesmo e se não houver alterações ele libera o marcador para outro usuário utilizar. As subtransações segundo Floriano (2005), durante o curso de uma única transação, parte do trabalho executado dentro da transação pode ser efetivado ou desfeito sem efetivar ou abortar a transação recipiente. Sendo isto conhecido como uma subtransação. Existem duas razões para o uso de subtransações: 2 Situação em que ocorre um impasse e o SO fica impedido de continuar suas atividades normais indefinidamente... ocorre com um conjunto de Processos e recursos não-preemptíveis, onde um ou mais processos desse conjunto está aguardando a liberação de um recurso por um outro processo que, por sua vez, aguarda a liberação de outro recurso alocado ou dependente do primeiro processo (Wikipédia, 2005). 34 Menos memória é utilizada, pois efetivar ações intermediárias permite aos objetos serem removidos da memória sem sacrificar a semântica transacional completamente; Recuperação de falhas parciais. Pode-se como em um jogo eletrônico usarse de savepoints através da efetivação de uma subtransação. A utilização de transações pelo editor do Zope acontece da seguinte forma, segundo Floriano (2005): No contexto de operação normal, o editor do Zope define uma transação como a extensão de uma simples requisição (request) da web. O editor faz uso do gerenciador de transações do ZODB para efetivar (commit) ou abortar (abort) a transação. Se a requisição é bem-sucedida, o gerenciador de transações é chamado com um ‘commit’, e todas as bases de dados participantes são efetivadas. Se uma requisição não é bem sucedida (por exemplo, se uma exceção for causada durante uma requisição), o gerenciador de transações é chamado com um ‘abort’, e todas as bases de dados participantes são revertidas (rolled back) para um estado anterior. Sem solicitação explícita feita por uma aplicação Zope, subtransações não são utilizadas dentro do contexto de uma requisição web. Os objetos Python possuem estados, graças à persistência. Quando em memória, segundo Floriano (2005) estes objetos possuem os seguintes estados: unsaved: o objeto criado pela primeira vez está em estado unsaved (nãosalvo). Um objeto unsaved pode deixar de existir como qualquer outro objeto Python. up-to-date: um objeto que foi salvo no banco de dados e que tem seu estado lido em memória está no estado up-to-date (pronto para atualização). Um objeto no estado up-to-date muda para o estado changed quando ele é modificado. Se um objeto up-to-date não foi usado por um longo período de tempo, o gerenciador de cache de objetos pode decidir desativar o objeto e liberar o estado do objeto passando assim o objeto para o estado ghost; changed: quando um objeto é alterado, ele entra no estado changed (alterado). Se a transação atual é efetivada, o estado do objeto é copiado para o banco de dados e as transições do objeto para o estado up-to-date. 35 Caso a transação atual for abortada, o objeto é desativado e muda para o estado ghost. ghost: um objeto no estado ghost (fantasma) existe em memória, mas não possui um estado lido. Se um atributo do objeto for acessado, então o estado do objeto é lido do banco de dados e o objeto entra no estado up-todate. Também é possível ajustar um atributo em um objeto que está no estado ghost, neste caso ele muda diretamente do estado ghost para o estado changed. Se um objeto no estado ghost for referenciado apenas pelo cache de objetos, então ele pode ser removido da memória. Para entender melhor o fluxo dos estados é apresentado através da figura 5 o diagrama dos estados dos objetos em ZODB. Fonte: (FLORIANO, 2005). Figura 5: diagrama dos estados dos objetos no ZODB. 36 4.4 INTERFACE DE GERENCIAMENTO (ZOPE MANAGEMENT INTERFACE – ZMI) Conforme Bernstein e Robertson (2002), a interface de gerenciamento padrão para o Zope, a ZMI, tem a mesma facilidade de navegação que um gerenciador de arquivos como o Windows Explorer da Microsoft. Isto se deve ao fato de ela estar dividida em três frames (quadros), apresentados a seguir segundo Latteier e Pelletier (2001): quadro superior: neste quadro é apresentado o logo do Zope que o leva diretamente à pagina principal do Zope, mostra com qual usuário está logado e uma lista suspensa com as opções de um tutorial para início rápido, preferências e logout; quadro da esquerda (Navegador): o navegador é utilizado para navegar pelo Zope como se estivesse navegando com seu gerenciador de arquivos. Neste quadro pode-se visualizar toda a estrutura do Zope desde a raiz. Quando desejar gerenciar um folder basta somente clicar nele que aparecerá no frame da direita as suas propriedades; quadro da direita (Área de Trabalho): este quadro apresenta os objetos que estão sendo gerenciados no momento. É dividido por abas que são usadas para executar diferentes funções para cada tipo de objeto. A figura 6 nos mostra como é a interface inicial do Zope. Fonte: (MATHDOGS, 2005). Figura 6: tela inicial da interface de gerenciamento do Zope. 37 Conforme Latteier e Pelletier (2001), o Zope é um sistema multi-usuário, suportando os seguintes tipos de usuário: emergence user (Usuário de emergência): utilizado quando você por algum motivo não consegue mais acessar o sistema, a única coisa que o usuário pode executar é criar novos usuários; manager (Administrador): é o usuário inicial do Zope e é com ele que devem ser executados a maioria das tarefas no sistema. É possível criar quantos administradores quiser; others (Outros): usuários criados para se encaixarem em uma role (função ou papel) pré-definida pelo administrador, ou seja, só irão poder executar uma função pré-determinada. 4.5 OBJETOS Segundo Bernstein e Robertson (2002), tudo o que for usado para se fazer um site em Zope é considerado um objeto, até mesmo os usuários. Os objetos têm propriedades em comum, sendo elas: podem ser identificados e acessados por uma Universal Resource Locator (URL)3, via HTTP, FTP, XML-RPC e WebDav como o endereço hipotético a seguir: http://bibliotecacco.com.br/consultas; mudanças são persistidas e armazenadas no ZODB; objetos podem adquirir atributos de seus contêiners, mesmo se eles não possuam estes atributos. Os principais objetos, conforme Bernstein e Robertson (2002), são: folder (Pasta): serve de contêiner para os outros objetos, incluindo outros objetos folder, e são similares aos diretórios de um gerenciador de arquivos; 3 URL (de Universal Resource Locator) em português significa (Localizador Uniforme de Recursos) é o endereço de um recurso (um ficheiro, uma impressora etc.), disponível em uma rede; seja a Internet, ou uma rede corporativa, uma intranet. Uma URL tem a seguinte estrutura: protocolo://máquina/caminho/recurso (WIKIPÉDIA, 2005) 38 DTML Documents (Documentos DTML): é o equivalente à uma página Web, eles podem conter informações textuais na forma de texto puro, HTML, Extensible Markup Language (XML) ou textos estruturados. Podem ser adicionados tags DTML para criar conteúdo dinâmico; DTML Methods (Métodos DTML): em uma visão geral methods e documents DTML são a mesma estrutura, pois são adicionados, editados e vistos da mesma forma, a única diferença está na sua utilização. Documentos foram feitos para conter e mostrar informação, enquanto os métodos são criados para adicionar dinamicidade à página. file (Arquivo): provêem um meio para adicionar arquivos binários à um site em Zope, através de um objeto File, pode-se adicionar qualquer arquivo que queira desde uma planilha até um arquivo de vídeo; image (Imagem): é um objeto File especial em Zope, pois quando é adicionado, já é definido a sua altura e largura nas suas propriedades. O Zope tem suporte aos mais comuns arquivos de imagem que trafegam na web dentre eles estão: 4.6 o Graphics Interchange Format (GIF); o Joint Photographic Experts Group (JPEG); o Bitmaps (BMP); o Portable Network Graphics (PNG). AQUISIÇÃO O Zope trabalha com o conceito de aquisição que segundo RamalhoOrg (2005), o mecanismo dos conceitos de herança e aquisição é parecido. A herança busca métodos na classe do objeto, e sucessivamente nas suas superclasses. A aquisição busca métodos no contexto do objeto, e sucessivamente nas pastas acima, até a pasta raiz da aplicação, como é demonstrado na figura 7. 39 Fonte: (RAMALHOORG, 2005). Figura 7: diferença entre os métodos de herança e aquisição. Conforme Ferri (2000, p. 16) cita, o conceito de aquisição é: 4 [...] a característica de subir níveis na pilha de namespaces ou árvore de objetos, na busca do objeto ou propriedade referenciado, pode ser vista como ortogonal em relação à generalização, que ocorre nas classes, é uma forma de facilitar o reuso, que é uma das características importantes do ZOPE. Ferri (2000) nos mostra os problemas que a aquisição pode gerar, como ocorre quando pretende-se chamar um objeto que está no topo da pilha de namespaces e por algum engano, houver um objeto com o mesmo nome antes do objeto que pretende-se chamar. Neste caso, este objeto será invocando não retornando o resultado esperado, ou até mesmo uma exceção. 4.7 LINGUAGENS O framework Zope conta com duas linguagens próprias, a Document Template Markup Language (DTML) e a Zope Page Templates (ZPT). 4 é uma lista de todos os nomes declarados nesse objeto, podendo ser atributos, métodos e até outros objetos nele contidos. Os namespaces são empilhados, do local que está sendo referenciada a estrutura dos objetos até o objeto raiz, formando assim uma pilha de namespaces. 40 4.7.1 Document Template Markup Language - DTML Segundo Ferri (2000), é uma linguagem script, tendo assim seu código interpretado e não compilado. Ela é oriunda da família das SGMLs, mas ao contrário da HTML que modela o texto do documento, sendo que para fazer qualquer alterações é necessário editar o documento, a DTML é dinâmica pelo fato de poder interagir com variáveis e acessar bancos de dados. Dessa forma as páginas são geradas conforme os valores dessas variáveis e bancos de dados. A sintaxe da linguagem DTML pode seguir três modelos conforme Ferri (2000): <dtml-var name=”title”> - sintaxe atual da DTML <!--#-var name=”title”--> - baseada em comentários, como o PHP. %(var name=title)s ou %(var title)s ou %(title)s - baseada em Python. A seguir serão apresentadas as principais tags da linguagem DTML de acordo com Ferri (2000). 4.7.1.1 Tag dtml-var A Tag dtml-var é utilizada para inserir no documento o resultado de uma expressão calculada, o conteúdo de um objeto ou o valor de uma propriedade. Possui atributos para controlar como o texto será inserido sendo os principais: name - insere o nome da variável; expr - insere uma expressão que calcula algum valor; fmt - especifica um formato de dados, que pode ser de uso geral ou formatado no estilo C; lower - converte todas a letras maiúsculas para minúsculas; upper - converte todas a letras minúsculas para maiúsculas; capitalize - converte o primeiro caractere inserido para maiúsculo; spacify - converte sublinhas "_", em valores inseridos, para espaços; html_quote - converte caracteres que possuem significado especial em HTML para 41 caracteres HTML "texto" reais; url_quote - converte caracteres que possuem significado especial em URLs para caracteres HTML reais, usando valores decimais; sql_quote - converte aspas simples para um par de aspas, isso é necessário para incluir valores corretos em strings SQL; newline_to_br - converte combinações de caracteres de nova linha, retorno de carro, e nova linha e retorno de carro para tags de quebra de linha HTML "<br>"; O quadro 13 nos mostra um exemplo do usa da tag dtml-var. Quadro 13: exemplo da utilização da tag dtml-var. <dtml-var standard_html_header> <h2><dtml-var title_or_id></h2> <p> This is the <dtml-var id> Document. </p> <dtml-var standard_html_footer> Fonte: (FERRI, 2000). 4.7.1.2 Tags dtml-if, dtml-else, dtml-elif A tag dtml-if é utilizada para realização de testes condicionais, pela avaliação de expressões ou variáveis, caso a avaliação seja verdadeira (true), o trecho de código dentro desta tag é executado. Esta deve ser fechada através de uma tag /dtml-if. A tag dtml-else é utilizada sempre em conjunto com a tag dtml-if. Ela define a execução de um bloco de código caso a avaliação da tag dtml-if não seja verdadeira. A tag dtml-elif é uma junção das tags dtml-if e dtml-else e também sempre é usada em conjunto com a tag dtml-if. Seu objetivo é executar uma outra avaliação caso a avaliação da tag dtml-if não seja verdadeira. 42 É possível também o encadeamento destas tags, ou seja, podem ser utilizadas várias tags dtml-elif dentro de uma tag dtml-if, bem como uma ou mais tags dtml-if aninhadas. Também sendo possível o uso das tags dtml-elif e dtml-else em conjunto. Para um melhor entendimento o quadro 14 mostrará um exemplo da utilização destas tags. Quadro 14: exemplo da utilização das tags de teste condicionais. <dtml-if "id == index_html"> <br>Esse documento é a sua Home Page. <dtml-elif “id == suporte_html”> <br>Esse documento é a sua Página de Suporte. <dtml-else> <dtml-if “id = web_html> <br>Esse documento não possui id, muito estranho... <dtml-else> <br>Esse é o <dtml-var id> documento. </dtml-if> </dtml-if> 4.7.1.3 Tag dtml-unless A tag dtml-unless é o oposto da tag dtml-if, pois ele executa o bloco de código se a avaliação for falsa e ao contrário da dtml-if, não permite o uso de else ou elif. 4.7.1.4 Tag dtml-in Tag similar ao “for” das linguagens de programação tradicionais, percorrendo os elementos de um conjunto informado executando o bloco de código uma vez para cada elemento. A condição de parada é quando não há mais elementos a percorrer no conjunto, e só executa se há elementos no conjunto. Pode ser usada a tag dtml-else no caso de não haver nenhum elemento no conjunto. Esta tag deve ser fechada com /dtml-in. Esta tag possui, em resumo os seguintes elementos: name - insere o nome da variável; expr - insere uma expressão que calcula algum valor; 43 mapping - normalmente os atributos dos itens são mostrados em seqüência, porém, alguns itens deveriam ser tratados como objetos mapeados; sort - ordena a iteração através do parâmetro passado; start - item de início da seqüência; size - tamanho da seqüência; skip_unauthorized - salta os itens que não possuem autorização para aquela operação, sem levantar exceção; orphan - declara o grupo de menor tamanho desejado para o final da seqüência; overlap - o número de linhas para sobrepor entre os grupos; previous - itens da seqüência anterior; next - itens da próxima seqüência. Para o controle de seqüência e como serão formatados e exibidos os textos pode-se fazer uso das seguintes variáveis: sequence-item - o item da vez na seqüência; sequence-key - a chave associada com o elemento em uma seqüência de itens; sequence-index - o índice dos elementos contidos na seqüência, iniciando em 0; sequence-start - é verdadeiro se o elemento da vez é o primeiro da seqüência; sequence-end - é verdadeiro se o elemento da vez é o último da seqüência. O quadro 15 nos mostra um exemplo da utilização das tags dtml-in e dtml-unless, além da utilização da variável sequence-end. 44 Quadro 15: exemplo da utilização da tag dtml-in. <(<dtml-in topicos> <dtml-var sequence-item> <dtml-unless sequence-end>, </dtml-unless> </dtml-in>)> Fonte: (FERRI, 2000). 4.7.1.5 Tag dtml-tree Esta tag trabalha de forma similar à tag dtml-in, contudo ela varre o objeto e todos os objetos contidos nele, ou seja, percorre a árvore do objeto. Esta tag deve ser fechada com /dtml-tree. O quadro 16 nos oferece um exemplo de sua utilização. Quadro 16: exemplo da utilização da tag dtml-tree. <dtml-tree> <dtml-var title> </dtml-tree> Fonte: (FERRI, 2000). 4.7.1.6 Tag dtml-with Esta tag resolve alguns problemas da aquisição, pois ela mapeia um namespace existente, possibilitando assim referenciar objetos ou propriedades de outros níveis, colocando-os no topo da pilha de namespaces. Para descer níveis da árvore deve-se aninhar tags dtml-with, sucessivamente até encontrar o nível desejado. Esta tag deve ser fechada com /dtml-with e possui somente um atributo: only: previne aquisições não desejadas. O exemplo no quadro 17 demonstra a utilização da tag dtml-with. 45 Quadro 17: exemplo da utilização da tag dtml-with. <dtml-with imagens> <dtml-with fotos_funcionarios> <dtml-in "objectValues(['Image'])" sort=id> <p> <dtml-var sequence-item> <dtml-var document_title> </p> </dtml-in> </dtml-with> </dtml-with> Fonte: (FERRI, 2000). 4.7.1.7 Tag dtml-let Esta tag trabalha quase da mesma forma que a tag dtml-with, só que ao invés de mapear um namespace já existente ela cria um novo, possibilitando assim a criação de variáveis internas que podem receber múltiplas atribuições e encadear várias tarefas. Os argumentos devem ser separados por uma nova linha e se o argumento tiver de ser calculado ele deve ser colocado entre aspas. Esta tag deve ser finalizada com /dtml-let e as variáveis criadas terão escopo somente dento desta tag. O quadro 18 nos mostra um exemplo de sua utilização. Quadro 18: exemplo da utilização da tag dtml-let. <dtml-in "1,2,3,4"> <dtml-let numero=sequence-item indice=sequence-index resultado="numero*indice"> (<dtml-var numero> * <dtml-var indice> = <dtml-var resultado>) </dtml-let> </dtml-in> Fonte: (FERRI, 2000). 4.7.1.8 Tag dtml-return Esta tag tem a função de retornar dados no formato de texto em um método DTML. Podemos ver sua utilização no quadro 19. 46 Quadro 19: exemplo da utilização da tag dtml-return. <dtml-in zoologico> <dtml-return sequence-item> <dtml-else> <dtml-return "Não há animais!"> </dtml-in> Fonte: (FERRI, 2000). 4.7.1.9 Tag dtml-call Esta tag tem o propósito de executar “ações”, ou melhor, invocar as ações a serem executadas, sem necessariamente produzir uma saída. O quadro 20 exemplifica a utilização desta tag. Quadro 20: exemplo da utilização da tag dtml-call. <dtml-call "debitaConta(conta)"> Fonte: (FERRI, 2000). 4.7.1.10 Tag dtml-raise Utilizada na verificação de uma variável ou expressão, serve para simplesmente repostar o erro que aconteceu através de uma tela padrão de erros do Zope. Deve ser finalizada com /dtml-raise e possui somente um atributo: type: especificar o tipo de erro que ocorreu. Esta tag é exemplificada através do quadro 21. Quadro 21: exemplo da utilização da tag dtml-raise. <dtml-if "balanco >= debito_total"> <dtml-call "debitoConta(conta)"> Sua conta, <dtml-var conta>, foi debitada. <dtml-else> <dtml-raise type=”Fundo Insuficiente"> Não há fundos suficientes para ao cliente <dtml-var conta>, para cobrir a quantia solicitada do débito. </dtml-raise> </dtml-if> Fonte: (FERRI, 2000). 47 4.7.1.11 Tag dtml-try A tag dtml-try, é utilizada para o tratamento de exceções, se ocorrer alguma exceção ela a detecta, interrompe a execução e gera uma mensagem de erro continuando após o bloco dtml-try que interrompeu a execução. Ela deve ser finalizada com /dtml-try. A tag dtmlelse pode ser usada para executar um bloco de código se não ocorrer nenhuma exceção. 4.7.1.12 Tag dtml-except É utilizada juntamente com a Tag dtml-try. Ela checa a exceção ocorrida e verifica se esta adapta-se ao seu tipo, a mensagem de erro informada será referente ao tipo tratado, com a descrição prevista. 4.7.1.13 Tag dtml-finally Utilizada juntamente com a tag dtml-try, esta tag é a responsável por desfazer o que a tag dtml-try executou no case de ocorrer uma exceção. Caso ocorra uma exceção tanto na tag dtml-try quanto na dtml-finally, as informações da exceção da primeira serão perdidas assim como o dado setado em uma tag dtml-return. O quadro 22 nos exemplifica a utilização das tags para tratamento de exceções. Quadro 22: exemplo da utiização das tags para tratamento de exceções. <dtml-try> <dtml-call AbrirTabela(BD1)> <dtml-except> Problemas no acesso ao banco de dados! <dtml-finally> <dtml-call FecharTabela(BD1)> </dtml-try> Fonte: (FERRI, 2000). 48 4.7.2 Zope Page Templates – ZPT Segundo Bax (2003), Zope Page Templates (ou linguagem de templates Zope) é um instrumento para a geração de páginas web dinâmicas em Zope. Ela torna fácil a colaboração entre designers e programadores aumentando a produtividade na criação de páginas web dinâmicas. Conforme Bernstein e Robertson (2002), ZPT foi criado para contornar alguns problemas da DTML, entre eles estão: as tags DTML não são amigáveis com editores HTML; as tags DTML não são renderizadas por editores WYSIWYG5, como Dreamweaver e Frontpage; a DTML encoraja a mistura de apresentação e lógica. Além de contornar estes problemas uma página em ZPT é de mais fácil compreensão e mais simples de utilizar que páginas DTML segundo Bax (2003). Para cumprir os objetivos a ZPT utiliza uma linguagem conhecida como Template Attribute Language (TAL), que conforme Bax (2003) consiste de vários atributos adicionados às tags já existentes do HTML e como a maioria dos editores HTML não reconhece estes atributos ele os deixa como estão, não afetando assim a apresentação da página. 4.7.2.1 Template Attribute Language – TAL A linguagem TAL possui declarações formadas da seguinte forma: tal:declaração=”expressão”. As declarações que a linguagem possui são segundo Santos (N/D) e também por Bernstein e Robertson (2002): content: preencher o conteúdo de uma tag com o resultado da avaliação da expressão contida na declaração; 5 WYSIWYG é a abreviação da expressão em inglês "What You See Is What You Get", que pode ser traduzido para "O que você vê é o que você tem". Trata-se de um método de edição no qual o usuário vê o objeto da edição na tela do computador já com a aparência final (WIKIPÉDIA, 2005). 49 replace: a diferença ente esta declaração e a content é que esta sobrescreve a tag com o resultado da expressão na tag; repeat: equivalente à tag dtml-in, serve para criarmos estruturas de repetição; define: é utilizado como a tag dtml-let, onde é criado um apelido para acessar mais facilmente o valor de uma expressão; attributes: atribui um valor dinâmico a um atributo da tag, ao contrário das expressões content e replace que atribuem valores ao conteúdo da tag; condition: utilizado para criar estruturas condicionais simples onde uma tag somente será processada se o valor da expressão for verdadeiro; omit-tag: faz o contrário da declaração content que preenche o valor da tag com o resultado de uma expressão. Essa declaração deixa como a tag como está se a expressão for verdadeira e substitui caso a expressão for falsa; on-error: provê o tratamento de erros, se não for encontrada uma declaração on-error no elemento onde aconteceu o erro é executada uma busca pela declaração através de seus elementos pais. Segundo Bernstein e Robertson (2002) TAL Expression Sintax (TALES) é a sintaxe da TAL para através de expressões acessar objetos e métodos Zope ou Python de uma forma compreensível. Ela possui três tipos de expressões: path, Python, string. Além disso possui o modificador de expressões not. 4.7.2.2 Expressões Path É indicado pelo flag opcional path:. Estas expressões são interpretadas como algum objeto no ZODB. O objeto é então retornado como resultado da expressão. Todo caminho deve começar com um nome, a TAL já provê alguns nomes embutidos são eles: nothing; default; options; 50 repeat; attrs; CONTEXTS. Mas como nós também queremos acessar objetos que estejam no ZODB, a TALES nos provê isso através dos seguintes nomes: root; here; container; template; request; user; modules. Um exemplo da utilização da expressão path é mostrado no quadro 23. Quadro 23: exemplo da utilização de uma expressão Path. <span tal:replace=”template/title”> O Título da Página</span> Fonte: (BAX, 2003). 4.7.2.3 Expressões Python Deve ser uma expressão válida em Python e ser prefixada com o flag python:. É uma ótima forma de passar parâmetros para os objetos, coisa que não é possível utilizando expressões path. Mas não se deve embutir a lógica nessas expressões isso deve ser feito em objetos script Python. Um exemplo da utilização deste tipo de expressão é demonstrado através do quadro 24. 51 Quadro 24: exemplo da utilização de uma expressão Python. <ul> <li tal:repeat=”list python: here.objectValues(‘Folder’)” tal:content=”list/id”>An ID</li> </ul> Fonte: (BAX, 2003). 4.7.2.4 Expressões String Este tipo de expressão é útil para substituições simples e pode conter múltiplas substituições. Deve ser precedido por string:. No quadro 25 temos um exemplo de sua utilização. Quadro 25: exemplo da utilização de uma expressão String. <p tal:content=”string: $here/title_or_id> Olá $user/getUserName, você está aqui: Fonte: (BAX, 2003). 4.7.2.5 Modificador not Pode prefixar qualquer das expressões anteriores, ele serve para forçar a interpretação da expressão como Booleana e inverter o resultado. A tecnologia do framework Zope bem como, seu histórico, suas características, ferramentas internas e as sintaxes das duas linguagens que o framework possui foram apresentadas neste capítulo. No próximo capítulo será discernido sobre engenharia para web (WebE), e o modelo proposto por Pressman. 5 ENGENHARIA WEB A Engenharia Web é apresentada muitas vezes pela sigla de WebE, e considerada por Engels (2005) como uma especialização da Engenharia de Software, no entanto, Carvalho e Chiossi (2001, p. 24) a definem como: [...] uma disciplina que reúne metodologias, métodos e ferramentas a ser utilizados, desde a percepção do problema até o momento em que o sistema desenvolvido deixa de ser operacional, visando resolver problemas inerentes ao processo de desenvolvimento e ao produto de sotware. A WebE tem o objetivo de auxiliar no processo da produção do software, oferecendo produtos de alta qualidade, produzidos mais rapidamente e com cada vez menos custos de desenvolvimento. 5.1 WEB APPLICATIONS – WEBAPPS Para Engels (2005) uma webapp é definida como um software baseado em tecnologias e padrões adotados pelo World Wide Web Consortium (W3C) que provê recursos como conteúdo e serviços através de uma interface de usuário, neste caso o navegador web. Segundo Locatelli (2003) a complexidade do desenvolvimento de uma webapp varia de acordo com o tipo do projeto a ser desenvolvido como demonstra a figura 8. Fonte: (LOCATELLI, 2003. p.23) Figura 8: complexidade de uma webapp em relação ao seu foco. 53 A figura 8 nos mostra, segundo Locatelli (2003), que a complexidade de uma webapp cresce exponencialmente em relação à interação com banco de dados e a comunicação com outros sistemas. Para uma melhor análise do tipo de projeto a ser desenvolvido, as webapps foram divididas em várias categorias como Engels (2005) define: centrada em documentos (Informacional): o conteúdo é somente leitura não havendo interação com os usuários, tendo como exemplos as páginas pessoais e uma radio web; interativa: usuários interagem de forma a enviar dados pra as aplicações. Tendo como exemplos páginas de busca e páginas dinâmicas; transacional: há uma interação muito alta com bancos de dados. Tendo como exemplos home-banking e compras on-line; baseadas em workflow: tem como pré-requisito um correto fluxo das atividades, suporta processos de negócios. Tendo como exemplos aplicações Business to Business (B2B) e aplicações e-Government. colaborativa: suporta cooperação no caso de fluxo não estruturados de atividades e um alto grau de comunicação como no caso de groupwares6. Tendo como exemplos sites wiki como a Wikipédia e ferramentas de eLearning; orientadas a portais: possui canais para outros conteúdos da web que não são do mesmo domínio da aplicação web. Tendo exemplos portais de serviço e portais empresariais; onipresente: serviços personalizados a qualquer hora em qualquer lugar, possuindo informações dependentes do contexto e são multiplataformas. Tendo como exemplo aplicações para aparelhos móveis como telefones celulares; 6 conjunto de ferramentas que tem por objetivo aumentar a produtividade do trabalho colaborativo, aumentando-lhes e eficiência e eficácia (WIKIPÉDIA, 2005). 54 semântica na web: tem como principal objetivo disponibilizar as informações na web para o entendimento humano e a manipulação automática. Tendo como exemplo aplicações de gestão do conhecimento. Para Pressman apud Breve (2002), as webapps apresentam, em sua maioria, as seguintes características: utilização intensiva dos recursos de rede, pois a webapp está em uma rede e deve atender as necessidades de diversos tipos de usuários; é dirigida a conteúdo, pois na maioria dos casos as aplicações tem como função primária utilizar hipermídia para apresentar textos, gráficos e vídeos; evoluem continuamente, pois ao contrário das aplicações convencionais que evoluem versionadamente, as webapps evoluem constantemente. 5.2 MODELO DE PROCESSO Conforme Pressman (2002) apud Oberderfer (2005), para quem se destina e qual a importância são as principais dúvidas no início do processo de desenvolvimento de uma webapp. Devem-se ter muito bem resolvidas as dúvidas iniciais para que se possa definir os seguintes itens: tecnologia que melhor se enquadra as necessidades da aplicação; níveis de qualidade em relação ao orçamento e prazos disponíveis; equipe que irá desenvolver a webapp; o público alvo desta aplicação. A figura 9 apresenta, de acordo com Pressman (2002) apud Oberderfer (2005), as etapas do processo para o desenvolvimento de uma webapp. 55 Fonte: Oberderfer (2005, p. 27). Figura 9: etapas para o desenvolvimento de uma webapp. 5.2.1 Formulação, planejamento e análise O ciclo do modelo incremental (Figura 9) inicia na fase de formulação, sendo nesta etapa que se definem as metas e objetivos da webapp. Segundo Pressman (2002) apud Oberderfer (2005). São formuladas as seguintes perguntas nesta fase: qual o objetivo principal da webapp a ser desenvolvida? qual será a utilidade a webapp? quais serão os usuários da webapp? Respondendo sucinta e diretamente as questões acima poderão ser identificadas as duas categorias de metas: metas de informação: objetiva fornecer a informação específica ao usuário. metas de aplicativo: as atividades executadas pela webapp. Para Oberderfer (2005), após as metas e os perfis de usuários estarem desenvolvidos, o ciclo passa para uma avaliação de riscos e estimativa de custos, ou seja, a fase de planejamento, onde também é realizado o escopo geral do sistema e um cronograma para realização das novas atividades. 56 O levantamento de requisitos técnicos e de conteúdo, junto com requisitos do projeto gráfico são definidos na fase de análise. Nesta fase encontram-se quatro diferentes tipos de análise conforme Pressman (2002) apud Oberderfer (2005). análise de conteúdo: identificação e organização do conteúdo que será disponibilizado na aplicação (textos, imagens, sons e vídeos...); análise de interação: seqüências de interação entre o usuário e a aplicação descrevendo casos de uso detalhados de alguns componentes; análise funcional: descrição detalhada de funções e operações; e análise da configuração: detalhes de ambientes e infra-estrutura na qual a aplicação irá residir. 5.2.2 Projeto Oberderfer (2005) cita que, a partir deste momento, as atividades entram na engenharia, onde estas dividem em duas linhas de tarefas paralelas: projeto de conteúdo e produção; projeto arquitetural, navegacional e de interface. Pressman apud Breve (2002) define que as etapas do projeto de conteúdo e da produção destinam-se à elaboração e aquisição de informações e objetos não técnicos. Atividades estas executadas por equipes de trabalho, que na maioria das vezes, não possuem vinculo com desenvolvimento técnico da aplicação. Segundo Pressman (2002) apud Oberderfer (2005), visando um projeto efetivo, fazse necessário o reuso de quatro elementos técnicos básicos: métodos e princípios de projeto: regras para uma alta coesão e baixo acoplamento no desenvolvimento de uma webapp devem ser aplicadas, assim como todos os métodos de projetos para sistemas orientados a objetos; regras de outro: aplicação de heurísticas no projeto de novas aplicações; 57 design patterns: padrões genéricos para resolução de problemas comuns que adaptam-se a problemas mais específicos; modelos (Gabaritos ou Templates): modelos que padronizam as interfaces de um aplicativo. Conforme as informações adquiridas na etapa do projeto de conteúdo, é definido, na fase do projeto navegacional, como será a estrutura navegacional da aplicação. Estrutura esta que definirá a forma como o conteúdo será percorrido e exibido ao usuário. O percurso que o usuário poderá percorrer e o que ele poderá ver dependerão de suas permissões junto ao sistema. Isso também é definido na fase do projeto navegacional. (PRESSMAN, 2002). Conforme Pressman (2002) apud Oberderfer (2005), existem quatro possíveis estruturas: Estrutura Linear: utilizada para visualizar opções diretas e inflexíveis, representando uma seqüência de interações previsíveis; Fonte: (OBERDERFER, 2005. p.34). Figura 10: representação da estrutura linear. Estrutura de Malha: representa uma estrutura de duas ou mais camadas. Utilizada para o cruzamento de informações destinadas a um mesmo fim. 58 Fonte: (OBERDERFER, 2005. p.35). Figura 11: representação da estrutura de malha. Estrutura Hierárquica: muito parecida com um grafo em árvore, com a diferença de que permite que haja comunicação entre as camadas irmãs; Fonte: (OBERDERFER, 2005. p.35). Figura 12: representação da estrutura hierárquica. Estrutura Interligada: proporciona uma alta flexibilidade pois permite que cada página comunique-se com qualquer outra página no sistema, mas tem uma alta probabilidade de confundir o usuário. Fonte: (OBERDERFER, 2005. p.34). Figura 13: representação da estrutura interligada. 59 Oberderfer (2005) cita que, a interface das webapps é a primeira impressão de um sistema ou organização na Internet, por isso a responsabilidade por manter as aparências é de suma importância. Para Nielsen (2000) apud Oberderfer (2005), a fim de se garantir uma boa interface pode-se seguir algumas recomendações simples: reduzir ao máximo os erros no servidor, pois estes podem fazer o usuário buscar informações em outra aplicação; tornar os textos objetivos, evitando que o usuário leia muito antes de poder utilizar a aplicação; evitar a utilização de avisos “Em desenvolvimento!” ou “Em Construção”, pois geram expectativa no usuário e podem decepcioná-lo; evitar o uso de barras de rolagem para mostrar as informações principais da aplicação, exibindo-as no topo da página; nunca contar somente com as funcionalidades do navegador. Projetar menus de navegação consistentes, permitindo uma completa navegação pelo usuário; manter bem expressiva as opções de navegação, não permitindo a busca inesperada de links dentro de uma página. 5.2.3 Implementação e Testes Segundo Oderberfer (2005), após a fase da engenharia é realizada a implementação dos itens levantados e planejados. Nesta fase, as páginas são criadas e seus conteúdos são revisados e testados. As atividades de testes em aplicações web seguem o mesmo objetivo que a engenharia convencional: encontrar erros. Pressman (2002) apud Oberderfer (2005) destaca algumas atividades, recomendadas para sistemas orientados a objetos, que podem auxiliar na detecção de erros: revisão do modelo de conteúdo: objetiva encontrar erros de digitação e gramática, consistência do conteúdo, representações gráficas, entre outros, relacionados ao valor das informações da webapp. 60 revisão de links e navegação: a fim de detectar erros em links, o sistema é exaustivamente navegado, com vários usuários, com diferentes permissões, não esquecendo também de verificar a visualização indevida de informações. processo de teste de unidades: teste individual das páginas, para procurar por erros de scripts, carregamento de imagens ou outras mídias. testes de integração: procura pela conectividade e comunicação entre as páginas da aplicação, verificando se a colaboração de funções auxiliares estão realmente sendo solicitadas e, se seus resultados permitem a real execução das tarefas desejadas. teste de funcionalidade geral e conteúdo fornecido: verifica a consistência dos dados gerados pelo sistema através de modelos reais, corrigindo erros de integridade das informações. teste de ambientes e configurações: procurar por erros associados a diferentes tipos de navegadores, plataformas, hardwares e conexões com a Internet. teste por população controlada: são simuladas interações de cada tipo possível de usuários no sistema, a fim de encontrar erros de conteúdo e navegação, desempenho e confiabilidade da webapp, bem como questões de usabilidade e compatibilidade. 5.2.4 Avaliação do Cliente Após a fase de implementação, é realizado o contato com o cliente, a fim de que se faça a avaliação da implementação e das atividades já executadas. Nesta fase do processo pode haver as seguintes atividades segundo Pressman (2002) apud Oberderfer (2005): a ocorrência de alterações no escopo; a confirmação ou alteração de usuários e suas permissões; a reedição da interface, bem como, do projeto navegacional. 61 Segundo Oberderfer (2005) “esses levantamentos deverão ser repassados novamente para fase de formulação, porém essa ação dependerá da disponibilidade tanto financeira como de prazos disponibilizados a esta aplicação”. Este capítulo abordou sobre a engenharia para web, enunciou o que são as webapps e apresentou o modelo proposto por Pressman em todas as suas fases. No capítulo seguinte será abordado a construção do protótipo do presente trabalho de conclusão de curso. 6 PROTÓTIPO O presente capítulo trata do desenvolvimento propriamente dito do protótipo proposto neste trabalho, sendo este dividido em três etapas: Análise: compreende as três primeiras fases do modelo proposto por Pressman (formulação, planejamento e análise), descrevendo entrevistas e os requisitos necessários para o desenvolvimento; Projeto: compreende as fases de projeto (conteúdo, produção, arquitetural, navegacional e de interface), que descreve os conteúdos e como devem ser mostrados ao visitante, bem como a navegabilidade da aplicação; Desenvolvimento: compreende as fases de implementação e testes do modelo de Pressman (2002), sendo aqui também efetuada a documentação do protótipo. 6.1 ANÁLISE Nesta primeira etapa foram realizadas entrevistas com usuários e funcionários da biblioteca para o levantamento de requisitos necessário ao desenvolvimento da aplicação, bem como para descrever casos de uso para o protótipo. Para demonstrar os requisitos levantados nesta fase se fará uso do diagrama de caso de uso do padrão UML. Os atores aqui levantados foram três: Anônimo, Usuário e Funcionário, sendo que cada um deles possui funções específicas dentro da aplicação. Através dos casos de uso a seguir serão descritos os requisitos que o protótipo deve abrangir. 6.1.1 Consulta Neste caso de uso são apresentados os três atores, pois todos devem poder efetuar consultas à base de dados de obras sem restrições como demonstra a figura 14. 63 Figura 14: caso de uso – consultar obra 6.1.2 Cadastro de usuário Este caso de uso reflete através da figura 15 o cadastro dos usuários, que deverá ser feito presencialmente com os devidos documentos para comprovação pelos funcionários. Além dos documentos o usuário irá atribuir uma senha a sua escolha para concluir o cadastro. Após a conclusão deste o usuário estará apto a efetuar empréstimos na biblioteca. Figura 15: caso de uso – cadastro de usuário 64 6.1.3 Cadastro das tabelas Para um funcionamento correto do sistema é necessário alimentá-lo com informações básicas, neste sentido, o funcionário deve adicionar informações que serão utilizadas pelos demais módulos do sistema. Estas informações básicas concentram-se em: tipo de aquisição das obras, autores, editoras, gêneros literários, idiomas e literaturas, como demonstra a figura 16. Somente após ter sido concretizado estes cadastros é que o sistema poderá efetuar cadastro de obras e as preferências do usuário. Figura 16: caso de uso – cadastro de tabelas 65 6.1.4 Alteração de Preferências É refletida neste caso de uso a alteração das preferências de leitura do usuário para o correto funcionamento do módulo de sugestão de leituras, no qual o usuário seta suas preferências através de cinco áreas de interesse, sendo elas: autores, gêneros literários, idiomas, literaturas e número de páginas, como demonstra a figura 17. Estas áreas de interesse foram elicitadas através de entrevistas informais com usuários da biblioteca, questionando sobre como é feita a escolha de uma obra para leitura. Figura 17: caso de uso – cadastro de preferências 6.1.5 Sugestão de Obras Este caso de uso demonstra, através da figura 18, a utilização do módulo de sugestão, onde após o usuário ter definido suas preferências de leitura, o sistema as consulta e retorna uma lista com as obras que se encaixam dentro das preferências do usuário conforme especificado no item 6.1.4. 66 Figura 18: caso de uso – sugestões de literatura 6.1.6 Cadastro de obras O cadastro de obras somente pode ser executado caso as tabelas básicas estejam cadastradas, conforme já relatado no item 6.1.3, pois a este caso de uso devem ser passados dados relativos às obras que se encontram nas tabelas básicas, realizando assim a interligação entre a obra e suas informações. Depois de efetuado o cadastro da obra deve ser executado o cadastro do autor dessa obra como demonstra a figura 19. Figura 19: caso de uso – cadastro de obras 67 6.1.7 Empréstimo Este caso de uso conta com dois atores, uma vez que o usuário solicita o empréstimo de uma obra e o funcionário após confirmar aprovação para empréstimo efetua o empréstimo definindo uma data de devolução, como é demonstrado pela figura 20. Figura 20: caso de uso – empréstimo de obra 6.1.8 Devolução Neste último caso de uso é efetuada a devolução da obra, onde o usuário solicita devolução e o funcionário, após verificar a data máxima para devolução e o estado da obra a ser devolvida, efetua a devolução, caso as duas condições citadas anteriormente sejam satisfatórias para a correta devolução da obra. Caso este demonstrado pela figura 21. Figura 21: caso de uso – devolução de obra 68 6.2 PROJETO Nesta segunda etapa, foram definidos os dados a serem armazenados pela base de dados, o conteúdo a ser apresentado aos usuários além da navegabilidade e interface da aplicação. 6.2.1 Armazenamento O sistema irá ser integrado a uma base de dados relacional MySQL, a qual tem por modelo ER a seguinte especificação de tabelas, efetuada através da análise dos casos de uso: Aquisição: código, descrição; Editora: código, nome, cidade, país, site, e-mail, telefone; Autor: código, nome, nascimento, naturalidade; Assunto: código, descrição; Língua: código, descrição; Literatura: código, descrição; Livro: código, título, subtítulo, ISBN, data de aquisição, ano da publicação, edição, número de páginas, resumo, exemplar; Empréstimo: código, data do empréstimo, data prevista para devolução, data da devolução; Usuário: ID, nome, endereço, bairro, complemento, telefone, celular, email, intervalo de páginas para avaliação da preferência; Funcionário: ID, nome. Após a identificação das tabelas e atributos necessários foi desenhado o diagrama de entidade-relacionamento, como pode ser visto na figura 22. 69 Figura 22: diagrama entidade-relacionamento proposto 70 6.2.2 Conteúdo Como mencionado nos casos de uso, para cada nível de usuário será exibido um conteúdo diferenciado, portanto nesta etapa identificou-se os conteúdos que devem ser exibidos para todos os usuários, bem como os que serão exibidos exclusivamente para cada grupo. Como o único recurso que todos os níveis de usuário compartilham é a consulta a obras, esta é a única que será exibida para todos os usuários no topo do menu de opções. Para cada tipo de usuário foram definidos os seguintes conteúdos a serem exibidos na interface: Anônimo o link para efetuar login como um usuário ou funcionário do sistema. Usuário o páginas para alteração de preferências (número de páginas, autores, gêneros literários, idiomas e literaturas), sendo uma página para cada um dos tipos; o link para sair do sistema. Funcionário o Páginas para cadastro das tabelas básicas (aquisições, autores, editores, gêneros literários, idiomas, literaturas), sendo uma página apara cada tabela; o Página para cadastro de novos usuários; o Página para cadastro de novos funcionários; o Página para cadastro de novas obras (sendo que os autores dessas obras devem ser cadastrados em uma página diferente); o Link para sair do sistema. 71 6.2.3 Interface e navegabilidade A interface gerada pelo sistema pode ser totalmente acessada por um browser (navegador) de Internet como Firefox, Netscape, Opera ou Internet Explorer. As cores utilizadas no sistema não estarão conforme um padrão de ergonomia, pois não é o propósito inicial deste trabalho. Toda a interface foi gerada pela ferramenta de desenvolvimento a ser utilizada (zetaDB), com exceção do menu que a ferramenta não tem possibilidade de geração dinâmica conforme o nível de usuário. A navegabilidade não depende das funcionalidades do browser, uma vez que o protótipo contará com botões que facilitam a navegação entre as páginas, além do próprio menu de acesso. O único pré-requisito que o protótipo necessita para funcionar é que esteja habilitado o javascript no navegador do usuário, pois o protótipo utiliza-os para validação das informações a serem enviadas, evitando assim a sobrecarga do servidor da aplicação web. 6.3 IMPLEMENTAÇÃO E TESTES Nesta etapa a base de dados e as páginas foram criadas e testadas, bem como foi realizada a documentação do código. Este capítulo está dividido em ferramentas utilizadas, geração da base de dados e criação das páginas. 6.3.1 Ferramentas utilizadas Para o desenvolvimento do protótipo, após estudos e verificações decidiu-se pela utilização das seguintes ferramentas: framework Zope 2.9.2, banco de dados MySQL 5.0, ArgoUML 0.2, CookieCrumbler 0.3, ZMySQLDA 2.0.9 e zetaDB 0.8.4. Zope: framework utilizado como servidor da aplicação web (utilza seu banco de dados interno ZODB para armazenar o conteúdo da aplicação como objetos), e suas linguagens script (DTML e ZPT) para criação das páginas. Obtido através do endereço http://www.zope.org; 72 MySQL: banco de dados relacional de alto desempenho e de código-fonte aberto, utilizado pelo protótipo para armazenamento dos dados. Obtida através do endereço http://www.mysql.com; ArgoUML 0.2: ferramenta case para desenvolvimento UML, utilizada para o desenho dos diagramas de caso de uso. Obtido através do endereço http://argouml.tigris.org; CookieCrumbler: ferramenta para efetuar login de usuários no protótipo utilizando autenticação via cookies. Obtida através do endereço http://www.zope.org/Members/hathawsh/CookieCrumbler; ZMySQLDA: adaptador de banco de dados para efetuar conexão com o banco de dados MySQL, requer a biblioteca MySQLdb que é biblioteca de conexão com MySQL para Python, ambas obtidas no endereço http://www.pastrytech.com/willy/zopemysql.html. Endereço este que traz um tutorial da instalação destes componentes no sistema operacional Windows XP; zetaDB: produto que adiciona funções ao Zope para desenvolvimento rápido de aplicações voltadas a banco de dados na web, pois ela efetua a geração de formulários, validações, consultas e inserções à base de dados para os bancos de dados PostgreSQL e MySQL. Obtido através do endereço http://zetadb.sourceforge.net/ 6.3.2 Geração da base de dados Para validação do protótipo foi necessário que o mesmo possuísse uma base de dados já implementada no SGBD. Para este caso foi gerado um script que criou esta base, através do utilitário de linha de comando do MySQL. O script criado está demonstrado no anexo 1 e foi executado com o comando: source <endereço>. 73 6.3.3 Criação das páginas A geração das páginas para o protótipo foi efetuada com a ferramenta zetaDB, a qual gera os formulários de acesso aos bancos de acordo com assistentes muito simples de usar, como no exemplo da figura 23 onde está sendo criada a página de cadastro de obras. Figura 23: assistente para geração das páginas de gerenciamento das obras A figura 23 demonstra a simplicidade da interface da ferramenta zetaDB para a criação das páginas com formulários de acesso aos dados. Através desta tela é possível adicionar os campos que devem aparecer nas telas de inclusão, listagem, visualização de registro, se o campo pode ser utilizado como campo de busca, entre outros. Além disso, é possível escolher qual campo deve ser mostrado no caso de referências a outras tabelas, como é o caso do campo Lit_Codigo, o qual está relacionado com a tabela de literaturas, sendo possível mostrar a descrição na tela de cadastro o que evita a criação de telas de pesquisa que retornem um código. Após a criação das páginas de cadastro básicas que não precisaram sofrer alterações no código gerado para estas, foram criadas as páginas mais complexas que requerem o usuário ativo, ou seja, o usuário que efetuou login no sistema, interação de baixo nível com o framework ou consultas a tabelas no banco de dados que a ferramenta não dá 74 suporte como é o caso das telas de empréstimo, devolução, cadastro de usuários e funcionários, preferências de leitura e sugestões de obras para leitura, além do menu de acesso, o qual foi alterado quase que em sua totalidade. Estas páginas por terem sido alteradas serão melhor detalhadas no decorrer to texto. 6.3.3.1 Menu dinâmico Como definido na fase de projeto o menu deve ser gerado dinamicamente para cada nível de usuário, sendo estas gerações demonstradas através da figura 24, onde aparecem em ordem os menus de usuário de nível Anônimo, Usuário e Funcionário. Figura 24: menu dinâmico conforme nível de usuário Para criação deste menu utilizou-se da alteração do menu criado pelo zetaDB, através da organização e gerenciamento da visualização das opções. Para este fim fora criado um script onde retorna a permissão de visibilidade do item a ser mostrado conforme o nível de usuário, como segue no quadro 26. 75 Quadro 26: código-fonte do script de verificação da permissão de visualização request = container.REQUEST return request.AUTHENTICATED_USER.has_permission('View', verobjeto) 6.3.3.2 Cadastro de usuários e funcionários Estas páginas têm que fazer comunicação a um nível mais baixo com o framework, pois uma vez que os usuários são controlados pelo framework deve-se cadastrá-los no controle de usuários do mesmo. Para esta finalidade foi criado um objeto script (Python) que efetua este cadastro no objeto userFolder do Zope. A fim de tornar isto possível, a página deve passar o parâmetro de usuário, senha e papel que o usuário irá ter. Os códigos a seguir demonstram o processo de envio de usuário e funcionário e a criação dos mesmos através dos quadros 27, 28 e 29 respectivamente, sendo que todos eles são objetos script (Python) onde os dois primeiros são alterações realizadas nos objetos criados pelo zetaDB e o terceiro é um objeto novo, com o objetivo de utilizar das funções nativas do framework para a criação de objetos User. Quadro 27: Código-fonte do script de inserção de usuário request = script.REQUEST #seta variáveis a apartir do request da aplicação Usu_ID = request['Usu_ID'] Usu_Senha = request['Usu_Senha'] Usu_Nome = request['Usu_Nome'] Usu_Endereco = request['Usu_Endereco'] Usu_Bairro = request['Usu_Bairro'] Usu_Complemento = request['Usu_Complemento'] Usu_Telefone = request['Usu_Telefone'] Usu_Celular = request['Usu_Celular'] Usu_EMail = request['Usu_EMail'] #se a inserção do usuário ocorrer sem problemas é feito o cadastro dos #dados no banco MySQL, exceto a senha if container.CreateUser(Usu_ID, Usu_Senha, 'Usuario'): container.insert_sql(p_Usu_ID=Usu_ID,p_Usu_Nome=Usu_Nome, p_Usu_Endereco=Usu_Endereco,p_Usu_Bairro=Usu_Bairro, p_Usu_Complemento=Usu_Complemento, p_Usu_Telefone=Usu_Telefone, p_Usu_Celular=Usu_Celular,p_Usu_EMail=Usu_EMail) request.RESPONSE.redirect('list_form') #caso contrário redireciona para uma página customizada de erro else: request.RESPONSE.redirect('existent_user') 76 Quadro 28: código-fonte do script de inserção de funcionário request = script.REQUEST #seta variáveis a partir do request da aplicação Fun_ID = request['Fun_ID'] Fun_Nome = request['Fun_Nome'] Fun_Senha = request['Fun_Senha'] #se a inserção do funcionário ocorrer sem problemas é feito o #cadastro dos dados no banco MySQL, exceto a senha if container.CreateUser(Fun_ID, Fun_Senha, 'Funcionario') == 1: container.insert_sql(p_Fun_ID=Fun_ID,p_Fun_Nome=Fun_Nome) request.RESPONSE.redirect('list_form') else: #caso contrário redireciona para uma página customizada de erro request.RESPONSE.redirect('existent_user') Quadro 29: código fonte do script para inclusão de um objeto User #importa a função html_quote da biblioteca standard from Products.PythonScripts.standard import html_quote request = container.REQUEST RESPONSE = request.RESPONSE #adiciona variáveis ao request da aplicação request.set('name',nome) request.set('password',chave) request.set('confirm', chave) request.set('roles', [papel]) #se o usuário estiver cadastrado retorna erro if nome in context.acl_users.getUserNames(): return 0 #caso contrário cadastra o usuário passando o request como uma lista de #parâmetros, retornando sucesso else: context.acl_users.manage_users('Add', request) return 1 6.3.3.3 Atualização das preferências Para elaboração destas interfaces fez-se necessária alteração dos objetos insert_action (script Python) que atualizam as preferências do usuário e os objetos select_sql (ZSQL Method) uma vez que o usuário conectado só pode alterar e ver as suas preferências. 77 Através dos quadros 30, 31 e 32, são demonstradas as alterações necessárias aos objetos, bem como o script que retorna o usuário que está conectado. Quadro 30: código fonte da alteração necessária para atualizar as preferências do usuário request = script.REQUEST #seta variável a partir do request da aplicação Lin_Codigo = request['Lin_Codigo'] #seta variável do usuário conectado User = container.LoggedUser() #repassa para o objeto ZSQL Method inserir na base de dados container.insert_sql( p_Lin_Codigo=Lin_Codigo, p_Usu_ID=User) request.RESPONSE.redirect('list_form') O quadro 30 demonstra a inclusão de um novo idioma de preferência do usuário, sendo que para todas as outras telas de inclusão de preferências a alteração é igual, alteração esta que está grifada em negrito, onde repassa o usuário conectado através da chamada ao script LoggedUser(). 78 Quadro 31: código fonte da alteração necessária para selecionar as preferências do usuário select coalesce(plinguas.Usu_ID, '') as "Usu_ID" ,coalesce(to_char(plinguas.Lin_Codigo, 'FM99999999990'), '') as "Lin_Codigo" from plinguas <dtml-sqlgroup where> Usu_ID = '<dtml-var expr="LoggedUser()">' <dtml-and> <dtml-sqltest p_Usu_ID column=Usu_ID op=eq type=nb optional> <dtml-and> <dtml-sqltest p_Lin_Codigo column=Lin_Codigo op=eq type=int optional> <dtml-and> <dtml-if p_search_filter_sql> <dtml-var p_search_filter_sql> </dtml-if> <dtml-and> <dtml-if p_program_filter_sql> <dtml-var p_program_filter_sql> </dtml-if> <dtml-and> <dtml-if p_where_sql> <dtml-var p_where_sql> </dtml-if> </dtml-sqlgroup> <dtml-if p_order_by> <dtml-var p_order_by> </dtml-if> Como no quadro 30, a alteração é igual para todas as telas de preferência do usuário, alteração esta que está em negrito, onde filtra pelo usuário conectado repassando o mesmo através da chamada ao script LoggedUser(). Quadro 32: código-fonte do script LoggedUser from AccessControl import getSecurityManager #return REQUEST.AUTHENTICATED_USER.getUserName() return getSecurityManager().getUser().getUserName() O script do quadro 32, tem a função de retornar o usuário conectado à aplicação, ele efetua a importação do objeto getSecurityManager da biblioteca AccessControl e retorna o nome do usuário. 79 6.3.3.4 Sugestão de obras para leitura Para a realização deste módulo foi necessária a criação de vários objetos ZSQL Method e um script Python que conseguisse agregar o retorno desses objetos ZSQL Method, para que a tela de consulta gerada pelo zetaDB obtivesse sucesso, sendo que ainda teve de ser efetuada uma alteração no objeto ZSQL Method criado pelo zetaDB. Estes objetos seguem demonstrados nos quadros 33, 34 e 35. Quadro 33: instruções SQL para selecionar as preferências do usuário select Aut_Codigo from PAutores where Usu_ID = <dtml-sqlvar Usuario type="string"> select Liv_Codigo from AutoresLivro where Aut_Codigo in <dtml-var Autores> select Ass_Codigo from PAssuntos where Usu_ID = <dtml-sqlvar Usuario type="nb"> select Lin_Codigo from PLinguas where Usu_ID = <dtml-sqlvar Usuario type="nb"> select Lit_Codigo from PLiteraturas where Usu_ID = <dtml-sqlvar Usuario type="nb"> select Usu_PgInicial, Usu_PgFinal from Usuario where Usu_ID = <dtml-sqlvar Usuario type="string"> Cada instrução contida no quadro 33, representa um objeto ZSQL Method, definido para selecionar as preferências do usuário conectado. 80 Quadro 34: script de agregação dos objetos ZSQL Method para preferências do usuário usu = container.LoggedUser() #pesquisa nas tabelas as preferências do usuários, retornando uma lista Autores = container.cPrefAutor(Usuario=usu) Idiomas = container.cPrefIdioma(Usuario=usu) Generos = container.cPrefGenero(Usuario=usu) Literaturas = container.cPrefLiteratura(Usuario=usu) PrefPg = container.cPrefPg(Usuario=usu) #inicializa variáveis inSQL = lstAutores = lstLivros = '' lstIdiomas = lstGeneros = lstLiteraturas = '' MinPg = MaxPg = 0 #se a lista não tiver vazia if Autores: lstAutores = '(' for i in range(len(Autores)): lstAutores = lstAutores + str(Autores[i].Aut_Codigo) + ', ' lstAutores = lstAutores[0:len(lstAutores) - 2] + ')' Livros = container.cPrefAutorLivro(Autores=lstAutores) if Livros: lstLivros = '(' for i in range(len(Idiomas)): lstLivros = lstLivros + str(Livros[i].Liv_Codigo) + ', ' lstLivros = lstLivros[0:len(lstLivros) - 2] + ')' if Idiomas: #cria o parâmetro do in SQL lstIdiomas = '(' for i in range(len(Idiomas)): lstIdiomas = lstIdiomas + str(Idiomas[i].Lin_Codigo) + ', ' lstIdiomas = lstIdiomas[0:len(lstIdiomas) - 2] + ')' if Generos: #cria o parâmetro do in SQL lstGeneros = '(' for i in range(len(Generos)): lstGeneros = lstGeneros + str(Generos[i].Ass_Codigo) + ', ' lstGeneros = lstGeneros[0:len(lstGeneros) - 2] + ')' if Literaturas: #cria o parâmetro do in SQL lstLiteraturas = '(' for i in range(len(Literaturas)): lstLiteraturas = lstLiteraturas + str(Literaturas[i].Lit_Codigo) + ', ' lstLiteraturas = lstLiteraturas[0:len(lstLiteraturas) - 2] + ')' if PrefPg: MinPg=PrefPg[0].Usu_PgInicial MaxPg=PrefPg[0].Usu_PgFinal #adiciona o tipo de conector para o SQL conector = ' ' + tipo + ' ' continua 81 continuação do quadro 34. #cria a condição where if (lstIdiomas + lstGeneros + lstLiteraturas + lstLivros != ''): if lstLivros: if inSQL: inSQL = inSQL + conector inSQL = inSQL + 'Liv_Codigo in ' + lstLivros if lstIdiomas: if inSQL: inSQL = inSQL + conector inSQL = inSQL + 'Lin_Codigo in ' + lstIdiomas if lstGeneros: if inSQL: inSQL = inSQL + conector inSQL = inSQL + 'Ass_Codigo in ' + lstGeneros if lstLiteraturas: if inSQL: inSQL = inSQL + conector inSQL = inSQL + 'Lit_Codigo in ' + lstLiteraturas pgSQL = '' if (str(MinPg) + str(MaxPg) != ''): if MinPg: pgSQL = pgSQL + 'Liv_Paginas >= ' + str(MinPg) if MaxPg: if pgSQL: pgSQL = pgSQL + ' AND ' pgSQL = pgSQL + 'Liv_Paginas <= ' + str(MaxPg) #monta a expressão SQL final exprSQL = '' if inSQL and pgSQL: exprSQL = '(' + inSQL + ')' + conector + '(' + pgSQL + ')' elif inSQL and not pgSQL: exprSQL = '(' + inSQL + ')' elif not inSQL and pgSQL: exprSQL = '(' + pgSQL + ')' #retorna a lista para ser processada pelo zSQL method return exprSQL O quadro 34 demonstra a manipulação dos resultados das consultas às preferências dos usuários chegando a um resultado que será enviado ao objeto ZSQL Method criado pelo zetaDB para exibição das preferências, resultado este sendo o filtro da expressão SQL, cujo código será demonstrado no quadro 35. 82 Quadro 35: código-fonte do objeto que seleciona obras de preferência do usuário <dtml-let prefs="PrefUsuario()"> select coalesce(livro.Liv_Codigo, '') as "Liv_Codigo" ,coalesce(livro.Liv_Titulo, '') as "Liv_Titulo" ,coalesce(livro.Liv_SubTitulo, '') as "Liv_SubTitulo" ,coalesce(livro.Liv_ISBN, '') as "Liv_ISBN" ,coalesce(to_char(livro.Liv_Edicao, 'FM99999999990'), '') as ,coalesce(to_char(livro.Edi_Codigo, 'FM99999999990'), '') as ,coalesce(to_char(livro.Liv_AnoPublicacao, 'FM99999999990'), "Liv_AnoPublicacao" ,coalesce(to_char(livro.Lin_Codigo, 'FM99999999990'), '') as ,coalesce(to_char(livro.Lit_Codigo, 'FM99999999990'), '') as ,coalesce(to_char(livro.Ass_Codigo, 'FM99999999990'), '') as from livro <dtml-sqlgroup where> <dtml-if prefs> <dtml-var prefs> </dtml-if> ... </dtml-let> "Liv_Edicao" "Edi_Codigo" '') as "Lin_Codigo" "Lit_Codigo" "Ass_Codigo" As partes grifadas em negrito do quadro 35 demonstram as alterações efetuadas no objeto, onde foi efetuada a criação de uma variável (prefs) através da nomeação de um novo namespace pela cláusula dtml-let. E caso a variável prefs seja verdadeira, ela é utilizada para a seleção das obras a serem sugeridas. 6.3.3.5 Empréstimo e devolução Para estes módulos houve a mesma alteração na parte de enviar o usuário que no caso das preferências de leitura, conforme quadro 31, pois deve ser informado qual funcionário aprovou o empréstimo da obra, portanto somente será demonstrada a alteração em um dos objetos, através do quadro 36. 83 Quadro 36: código-fonte da alteração para empréstimo de obras request = script.REQUEST Emp_Data = request['Emp_Data'] Liv_Codigo = request['Liv_Codigo'] Usu_ID = request['Usu_ID'] Emp_DataPrevista = request['Emp_DataPrevista'] User = container.LoggedUser() container.insert_sql(p_Emp_Data=Emp_Data, p_Liv_Codigo=Liv_Codigo, p_Usu_ID=Usu_ID, p_Emp_DataPrevista=Emp_DataPrevista ,p_Fun_ID=User) request.RESPONSE.redirect('list_form') Este capítulo apresentou o desenvolvimento do protótipo seguindo as definições do modelo proposto por Pressman (2002), detalhando os processos mais críticos do desenvolvimento do protótipo. O próximo capítulo trata das considerações finais acerca do presente trabalho. 7 CONCLUSÕES O presente trabalho teve como objetivo a criação de um protótipo para o gerenciamento do setor de empréstimos da Biblioteca Pública Municipal de Chapecó, através de uma aplicação web que ofereça uma interface amigável com o usuário, não menosprezando a funcionalidade da aplicação. Como o objetivo era a criação de um protótipo, foi necessário o aprendizado de um modelo de desenvolvimento para aplicações web, no caso o modelo escolhido foi o proposto por Pressman que compreende seis fases (formulação, planejamento, análise, projeto, implementação e testes e a última sendo a de avaliação com o cliente). A partir da escolha do framework Zope como ferramenta de desenvolvimento, um estudo mais aprofundado de suas ferramentas e técnicas de desenvolvimento, como a criação de objetos script e a separação da lógica da apresentação, fez-se necessário. Bem como o aprendizado da linguagem Python, uma vez que é a linguagem script nativa do framework. Para o inicio do desenvolvimento foi efetuado um estudo no ambiente onde o protótipo deveria ser aplicado, no caso a Biblioteca Municipal, onde foram efetuadas entrevistas de forma a levantar os requisitos para as primeiras fases do modelo de desenvolvimento, sendo estas realizadas com funcionários da instituição. Para o módulo adicional de sugestões de leituras, foram efetuadas entrevistas com os usuários levantando assim os requisitos que os motivam na escolha de uma obra para leitura, bem como sugestões para a interface de alteração das preferências pessoais. No decorrer do trabalho, pode se notar como é poderoso o framework Zope, sua classificação como um framework híbrido e horizontal, pois permite alterar suas características e ferramentas e é voltado para o desenvolvimento de qualquer tipo de aplicação. Foi constatado também a sua possibilidade de crescimento devido a adição de produtos para necessidades específicas como foi o caso dos produtos zetaDB que efetua um rápido desenvolvimento de aplicações voltadas para banco de dados na web, e o CookieCrumbler que efetua o controle de acesso através de autenticação via cookies. Cabe salientar que o objetivo proposto foi alcançado uma vez que o protótipo efetua um gerenciamento do setor de empréstimos, bem como efetua sugestões de obras para 85 leitura de acordo com as preferências do usuário, além de ser desenvolvido de acordo com o modelo proposto por Pressman. 7.1 TRABALHOS FUTUROS A implementação da webapp de acordo com os padrões ergonômicos para a web faz-se necessária, uma vez que não fez parte dos objetivos do trabalho. Um estudo sobre integração com outros servidores, tais como, Apache e IIS, pois sabe-se que a maioria dos servidores já contam com outros servidores web, não afetando assim a estrutura já existente. Uma comparação entre o framework Zope e outras ferramentas de desenvolvimento no mesmo nível que o Zope, para avaliar a real capacidade do mesmo. 8 REFERÊNCIAS BAX, Marcelo Peixoto. Zope Page Templates – Tutorial. Universidade Federal de Minas Gerais (UFMG). 2003. 15 p. BERNSTEIN, Michael R.; ROBERTSON, Scott. ZOPE BIBLE. WILEY, 2002. 613 P. BREVE, Fabricio Aparecido. Engenharia Para a Web. Universidade Federal de São Carlos (UFSCar). 2002. 25 p., BRUECK, David; TANNER, Stephen. Python 2.1 Bible. 34. ed. Hungry Minds INC., 2001. 732 p. CARVALHO, Ariadne M. B. Rizzoni; CHIOSI, Thelma C. Dos Santos. Introdução à Engenharia de Software. Campinas: Editora da UNICAMP, 2001. 148 p. CENTRO DE TECNOLOGIA XML. SGML (Standard Generalized Markup Language). Disponível em <http://www.centroxml.com.br/sgml.aspx>. Acessado em 12 de ago. 2005 ENGELS, Gregor. Web Engineering - Chapter I: Web Applications. Apresentação em slides: 2005. Disponível em: <http://wwwcs.uni-paderborn.de/cs/ag- engels/ag_dt/Courses/Lehrveranstaltungen/WS0506/WE/teachingMaterials.html>. Acessado em: 10 de nov. 2005. FERRI, Jean Rodrigo. DTML no Zope. Trabalho acadêmico da disciplina de Análise Comparativa de Linguagens: Unijuí. 2000. 35 p. FEUER, Adam. What is adzapper?. Disponível em <http://www.zaplet.org/adzapper/aboutadzapper.html>. Acessado em 15 de nov. 2005 FLORIANO, Amarílio Motta. Z OBJECT DATABASE. Disponível em: <http://www.tchezope.org/documentacao/publicacoes/zodb3>. Acessado em 20 de out. 2005 GLOSSARIO: IBM HTTP SERVER. Disponível em: <https://www2.rural.com.br/manual/ibm/9agloss.htm#w>. Acessado em: 25 de out. 2005 87 GLOSSARY OF WEB TERMS. Disponível em <http://www.epibiostat.ucsf.edu/epidem/wwwglossary.html>. Acesso em 20 de ago. 2005 LATTEIER, Amos; PELLETIER, Michel. Zope Book. 2001. 384 p. LLOYD, Douglas. EXPRESSO DEVELOPER'S GUIDE. Disponível em <http://www.jcorporate.com/expresso/doc/edg/edg_WhyUseFramework.html#N102F6>. Acesso em 20 de maio 2006. LOCATELLI, Marcio Henrique. Engenharia de Software para o Desenvolvimento de Webapps e as Metodologias OOHDM e WebML. Florianópolis: 2003. 57 p. Monografia (Conclusão do Curso de Pós-Graduação) - Universidade Federal de Santa Catarina. MAROLDI, Marcelo. Política de incentivo à leitura. Coluna semanal do autor para o site Digestivo Cultural publicada em 27/01/2005. Disponível em: <http://www.digestivocultural.com/colunistas/coluna.asp?codigo=1540>. Acesso em 08 de ago. 2005 MATHDOGS. Disponível em <http://www.mathdogs.com/people/mkc/python-talk/zope-if.jpg>. Acesso em: 01 de nov. 2005. NETO, Osvaldo Santana; BORGES, Luiz Eduardo. Python Apresentação. Artigo publicado em 15/11/2004 para a comunidade oficial de Python no Brasil. Disponível em < http://www.pythonbrasil.com.br/moin.cgi/PythonApresenta%c3%a7%c3%a3o>. Acesso em: 01 set. 2005 OBERDERFER, Saulo Bazzi. Engenharia De Webapp Para Um Grupo Escoteiro Utilizando O Método OOHDM. Chapecó: 2005. 113 p. Monografia (Conclusão do Curso de Ciência da Computação) - Universidade Comunitária Regional do Oeste. PRESSMAN, Roger S.Engenharia de Software. McGraw-Hill. 5 ed. 2002. 872 p. RAMALHOORG. Aquisição. Disponível em : <http://www.ramalho.org/wiki/index.php?title=Aquisi%C3%A7%C3%A3o>. Acessado em: 01 de nov. 2005 ROSSUM, Guido van. Python Reference Manual. Disponível em: <http://docs.python.org/ref/ref.html>. Acessado em 03 de set. 2005 88 SANTOS, Fabiano Weimar dos. Tutorial de Zope Page Templates – ZPT. 5 p. SANTOS, Fabiano Weimar dos. ZODB - Zope Object Database. Disponível em <http://www.tchezope.org/documentacao/publicacoes/zodb/document_view>. Acessado em 20 de out. 2005 SANTOS, Fábio. Programação para a Web utilizando ZOPE. Campinas: Unicamp, 2002. 32 p. SAUVÉ, Jacques Philippe. Projeto de Software Orientado a Objeto. Publicado em 2002 na página pessoal do autor. Disponível em <http://jacques.dsc.ufcg.edu.br/cursos/map/html/map2.htm>. Acesso em 10 de ago. 2005 WIKIPÉDIA – A enciclopédia livre. Disponível em <http://pt.wikipedia.org> ZOPE – WPROWADZENIE. Publicado em 08 de dez. 2004. Disponível em <http://www.extreme-is.com/technologia/plone_zope/zope_plone>. Acessado em 10 de out. 2005. ANEXO A – SCRIPT PARA GERAÇÃO DA BASE DE DADOS //Apagar as tabelas caso existam drop table IF EXISTS Multa; drop table IF EXISTS Emprestimo; drop table IF EXISTS PLiteraturas; drop table IF EXISTS PLinguas; drop table IF EXISTS PAssuntos; drop table IF EXISTS PAutores; drop table IF EXISTS AutoresLivro; drop table IF EXISTS Livro; drop table IF EXISTS Usuario; drop table IF EXISTS Funcionario; drop table IF EXISTS Literatura; drop table IF EXISTS Lingua; drop table IF EXISTS Editora; drop table IF EXISTS Autor; drop table IF EXISTS Assunto; drop table IF EXISTS Aquisicao; /*Criação das tabelas com seus respectivos relacionamentos devendo estas tabelas ser do tipo InnoDB, pois este é o único que suporta relacionamento*/ Create table Aquisicao ( Aqu_Codigo Int NOT NULL AUTO_INCREMENT, Aqu_Descricao Varchar(40) NOT NULL , UNIQUE (Aqu_Codigo), Index AI_Aqu_Codigo (Aqu_Codigo), Primary Key (Aqu_Codigo) ) TYPE = InnoDB; Create table Assunto ( Ass_Codigo Int NOT NULL AUTO_INCREMENT, Ass_Descricao Varchar(50) NOT NULL , UNIQUE (Ass_Codigo), Index AI_Ass_Codigo (Ass_Codigo), Primary Key (Ass_Codigo) ) TYPE = InnoDB; Create table Autor ( Aut_Codigo Float NOT NULL AUTO_INCREMENT, Aut_Nome Varchar(80) NOT NULL , Aut_Nascimento Date , Aut_Naturalidade Varchar(255) , UNIQUE (Aut_Codigo), Index AI_Aut_Codigo (Aut_Codigo), Primary Key (Aut_Codigo) ) TYPE = InnoDB; Create table Editora ( Edi_Codigo Int NOT NULL AUTO_INCREMENT, Edi_Nome Varchar(80) NOT NULL , Edi_Cidade Varchar(80) NOT NULL , 90 Edi_Pais Varchar(80) , Edi_Site Longtext , Edi_EMail Longtext , Edi_Telefone Char(30) , UNIQUE (Edi_Codigo), Index AI_Edi_Codigo (Edi_Codigo), Primary Key (Edi_Codigo) ) TYPE = InnoDB; Create table Lingua ( Lin_Codigo Int NOT NULL AUTO_INCREMENT, Lin_Descricao Char(50) NOT NULL , UNIQUE (Lin_Codigo), Index AI_Lin_Codigo (Lin_Codigo), Primary Key (Lin_Codigo) ) TYPE = InnoDB; Create table Literatura ( Lit_Codigo Int NOT NULL AUTO_INCREMENT, Lit_Descricao Char(20) NOT NULL , UNIQUE (Lit_Codigo), Index AI_Lit_Codigo (Lit_Codigo), Primary Key (Lit_Codigo) ) TYPE = InnoDB; Create table Funcionario ( Fun_ID Char(20) NOT NULL , Fun_Nome Char(50) NOT NULL , UNIQUE (Fun_ID), Primary Key (Fun_ID) ) TYPE = InnoDB; Create table Usuario ( Usu_ID Char(20) NOT NULL , Usu_Nome Varchar(50) NOT NULL , Usu_Endereco Varchar(80) NOT NULL , Usu_Bairro Varchar(50) NOT NULL , Usu_Complemento Varchar(20) , Usu_Telefone Char(20) , Usu_Celular Char(20) , Usu_EMail Varchar(50) , Usu_PgInicial Int , Usu_PgFinal Int , UNIQUE (Usu_ID), Primary Key (Usu_ID) ) TYPE = InnoDB; Create table Livro ( Liv_Codigo Char(20) NOT NULL , Aqu_Codigo Int NOT NULL , Lin_Codigo Int NOT NULL , Lit_Codigo Int NOT NULL , Ass_Codigo Int NOT NULL , Edi_Codigo Int NOT NULL , Liv_Titulo Varchar(100) NOT NULL , Liv_SubTitulo Varchar(50) , Liv_ISBN Char(20) , Liv_DataAquisicao Date NOT NULL , 91 Liv_AnoPublicacao Int NOT NULL , Liv_Edicao Int NOT NULL , Liv_Paginas Int NOT NULL , Liv_Resumo Mediumtext , Liv_Exemplar Int NOT NULL , UNIQUE (Liv_Codigo), Primary Key (Liv_Codigo), Index IX_LinguaLivro (Lin_Codigo), Foreign Key (Lin_Codigo) references Lingua (Lin_Codigo), Index IX_LiteraturaLivro (Lit_Codigo), Foreign Key (Lit_Codigo) references Literatura (Lit_Codigo), Index IX_AssuntoLivro (Ass_Codigo), Foreign Key (Ass_Codigo) references Assunto (Ass_Codigo), Index IX_EditoraLivro (Edi_Codigo), Foreign Key (Edi_Codigo) references Editora (Edi_Codigo), Index IX_AquisicaoLivro (Aqu_Codigo), Foreign Key (Aqu_Codigo) references Aquisicao (Aqu_Codigo) ) TYPE = InnoDB; Create table AutoresLivro ( Aut_Codigo Float NOT NULL , Liv_Codigo Char(20) NOT NULL , Primary Key (Aut_Codigo,Liv_Codigo), Index IX_AutorAutores (Aut_Codigo), Foreign Key (Aut_Codigo) references Autor (Aut_Codigo), Index IX_LivroAutores (Liv_Codigo), Foreign Key (Liv_Codigo) references Livro (Liv_Codigo) ) TYPE = InnoDB; Create table PAutores ( Aut_Codigo Float NOT NULL , Usu_ID Char(20) NOT NULL , Primary Key (Aut_Codigo,Usu_ID), Index IX_PrefAutores (Usu_ID), Foreign Key (Usu_ID) references Usuario (Usu_ID), Index IX_AutorPrefAutores (Aut_Codigo), Foreign Key (Aut_Codigo) references Autor (Aut_Codigo) ) TYPE = InnoDB; Create table PAssuntos ( Ass_Codigo Int NOT NULL , Usu_ID Char(20) NOT NULL , Primary Key (Ass_Codigo,Usu_ID), Index IX_PrefAssuntos (Usu_ID), Foreign Key (Usu_ID) references Usuario (Usu_ID), Index IX_AssuntoAssontos (Ass_Codigo), Foreign Key (Ass_Codigo) references Assunto (Ass_Codigo) ) TYPE = InnoDB; Create table PLinguas ( Lin_Codigo Int NOT NULL , Usu_ID Char(20) NOT NULL , Primary Key (Lin_Codigo,Usu_ID), Index IX_PrefLinguas (Usu_ID), Foreign Key (Usu_ID) references Usuario (Usu_ID), Index IX_LinguaLinguas (Lin_Codigo), Foreign Key (Lin_Codigo) references Lingua (Lin_Codigo) ) TYPE = InnoDB; 92 Create table PLiteraturas ( Lit_Codigo Int NOT NULL , Usu_ID Char(20) NOT NULL , Primary Key (Lit_Codigo,Usu_ID), Index IX_PrefLiteraturas (Usu_ID), Foreign Key (Usu_ID) references Usuario (Usu_ID), Index IX_LiteraturaLiteraturas (Lit_Codigo), Foreign Key (Lit_Codigo) references Literatura (Lit_Codigo) ) TYPE = InnoDB; Create table Emprestimo ( Emp_Seq Double NOT NULL AUTO_INCREMENT, Emp_Data Date NOT NULL , Liv_Codigo Char(20) NOT NULL , Usu_ID Char(20) NOT NULL , Fun_ID Char(20) NOT NULL , Emp_DataPrevista Date NOT NULL , Emp_DataDevolucao Date , UNIQUE (Emp_Seq), Index AI_Emp_Seq (Emp_Seq), Primary Key (Emp_Seq), Index IX_LivroEmprestimo (Liv_Codigo), Foreign Key (Liv_Codigo) references Livro (Liv_Codigo), Index IX_UsuarioEmprestimo (Usu_ID), Foreign Key (Usu_ID) references Usuario (Usu_ID), Index IX_FuncionarioEmprestimo (Fun_ID), Foreign Key (Fun_ID) references Funcionario (Fun_ID) ) TYPE = InnoDB; //Inserções após as criações das tabelas insert into aquisicao (Aqu_Descricao) values ('Doação'); insert into lingua (Lin_Descricao) values ('Portuguesa'); insert into editora (Edi_Nome, Edi_Cidade) values ('Atica', 'São Paulo'); insert into literatura (Lit_Descricao) values ('Espanhola'); insert into assunto (Ass_Descricao) values ('Poesia'); insert into usuario (Usu_ID, Usu_Nome, Usu_Endereco, Usu_Bairro, Usu_Complemento, Usu_Telefone) values ('jackfowl', 'Jackson Luiz De Marco', 'Joao', 'Centro', '', '33230007'); insert into funcionario (Fun_ID, Fun_Nome) values ('ana', 'Ana Paula')