You are on page 1of 45

UNIVERSIDADE DE CAXIAS DO SUL

DEPARTAMENTO DE INFORMÁTICA
CURSO DE BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO

MARCOS D. PETRY

UML2Django: Gerador de Código


para Framework Web MVC

Prof. João L. Tavares


Orientador

Caxias do Sul, Dezembro de 2008


“However, as every parent of a small child knows,
converting a large object into small fragments
is considerably easier than the reverse process.
— Andrew Stuart Tanenbaum
AGRADECIMENTOS

Agradeço a Deus por ter me dado forças para concluir este curso, me revitalizando
em todos os momentos de fraqueza.
Aos meus pais Ivan Luiz e Iana Fátima, por me entenderem a minha ausência
devido ao trabalho e aos estudo, não deixaram de estar do meu lado me apoiado
incondicionalmente.
Ao meu orientador, Professor João Luiz Tavares, pela paciência, sabedoria, pe-
las suas correções e incentivo durante a implementação do trabalho e redação da
monografia.
A Universidade de Caxias do Sul, e ao docentes do departamento de informática,
que durante os 7 anos de vida acadêmica nesta instituição, tive a honra de ser aluno.
Aos meus colegas de trabalho, que me ajudaram-me com meu TCC e na minha
carreira profissioal.
Agradeço aos amigos de minha cidade natal que me apoiaram em momentos que
precisei e me mostrando que a vida não é só trabalho e estudo.
Aos amigos que fiz na Universidade: Joel, Alexandre, Fran, Vinı́cius, Cristian,
Enor e muitos outros, por acompanharem minha trajetória acadêmica, e estarem
presentes em momentos complicados.
E por último, mas não menos importante, agradeço a minha querida e amada
namorada Letı́cia, por ter me ajudado onde podia e ter me apoiado e me entendido
em momentos difı́ceis com muito amor e carinho.
SUMÁRIO

LISTA DE ABREVIATURAS E SIGLAS . . . . . . . . . . . . . . . . . . . 6

LISTA DE FIGURAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

LISTA DE TABELAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

RESUMO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

ABSTRACT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

1 INTRODUÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1 Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2 Objetivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.3 Estrutura do Documento . . . . . . . . . . . . . . . . . . . . . . . . 13

2 CONCEITOS PRELIMINARES . . . . . . . . . . . . . . . . . . . . . . 15
2.1 Padrão de desenvolvimento MVC . . . . . . . . . . . . . . . . . . . 15
2.2 Ferramentas Gráficas de Modelagem . . . . . . . . . . . . . . . . . 16
2.3 UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.3.1 Digramas de Classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.4 Frameworks de desenvolvimento de aplicações . . . . . . . . . . . 18
2.4.1 Exemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
2.5 Linguagem de programação Python . . . . . . . . . . . . . . . . . 19
2.5.1 Exemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

3 DJANGO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.1 Caracterı́sticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.1.1 Persistência de dados (model) . . . . . . . . . . . . . . . . . . . . . . 22
3.1.2 Visualização de dados (view) . . . . . . . . . . . . . . . . . . . . . . . 22
3.1.3 Controle de dados (Controller) . . . . . . . . . . . . . . . . . . . . . . 23
3.2 Fluxo de Execução . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4 IMPLEMENTAÇÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.1 Arquitetura geral da implementação proposta . . . . . . . . . . . 25
4.2 Parâmetros XMI utilizados pelo Parser . . . . . . . . . . . . . . . 25
4.3 Mapeamento de objetos XMI - Django Model . . . . . . . . . . . 29
4.4 Análise léxico-sintática . . . . . . . . . . . . . . . . . . . . . . . . . 29
4.4.1 Extração do XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.5 Análise semântica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4.5.1 Algoritmo de geração . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

5 EXPERIMENTOS E RESULTADOS . . . . . . . . . . . . . . . . . . . 35
5.1 Diagramas com uma Classe . . . . . . . . . . . . . . . . . . . . . . 35
5.2 Diagramas com duas Classes sem relacionamento . . . . . . . . . 35
5.3 Diagramas com duas Classes relacionadas . . . . . . . . . . . . . 36
5.4 Teste de Herança . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
5.5 Teste múltiplo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

6 CONCLUSÃO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.1 Validação do projeto . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
6.2 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

7 ANEXOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

REFERÊNCIAS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
LISTA DE ABREVIATURAS E SIGLAS

DRY Don’t repeat yourself

GLC Gramática Livre-de-Contexto

HTML HyperText Markup Language

HTTP Hypertext Transfer Protocol

MVC Model-view-controller

OMG Object Management Group

PDF Portable Document Format

TCC Trabalho de Conclusão de Curso

UML Unified Modeling Language

URL Uniform Resource Locator

XML Extensible Markup Language

XMI XML Metadata Interchange


LISTA DE FIGURAS

Figura 1.1: Imagem gerada pelo editor UML . . . . . . . . . . . . . . . . . . 12

Figura 3.1: Estrutura do framework Django . . . . . . . . . . . . . . . . . . . 22


Figura 3.2: Fluxo de Execução do Framework Django . . . . . . . . . . . . . 24

Figura 4.1: Estrutura do parser XMI2Django . . . . . . . . . . . . . . . . . . 26


Figura 4.2: Diagrama de classes do sistema . . . . . . . . . . . . . . . . . . . 33

Figura 5.1: UML Representando uma classe . . . . . . . . . . . . . . . . . . . 35


Figura 5.2: UML Representando duas classes sem relacionamento . . . . . . . 36
Figura 5.3: UML representando duas classes relacionadas . . . . . . . . . . . 36
Figura 5.4: UML representando herança . . . . . . . . . . . . . . . . . . . . . 37
Figura 5.5: Uml representando várias classes . . . . . . . . . . . . . . . . . . 38
LISTA DE TABELAS

Tabela 4.1: Mapeamento de objetos XMI - Django Model . . . . . . . . . . . 30


RESUMO

O desenvolvimento de aplicações WEB cresce contantemente e, como conseqüência


disso, os recursos e as funcionalidades destas aplicações evolui. Portanto, desenvol-
ver aplicações de qualidade em um curto perı́odo de tempo é um requisito cada vez
mais valorizado.
Uma maneira de melhorar o processo de desenvolvimento e a qualidade das
aplicações é utilizando frameworks de desenvolvimento. Utilizando frameworks, o
desenvolvedor pode focar-se de fato, no objetivo principal do sistema, evitando as-
sim, o trabalho repetitivo de outras aplicações, como por exemplo a construção de
logins e controles de acesso. Um exemplo de framework que faz este trabalho é o
Django. Django constitui-se em um framework web de alto nı́vel, escrito em Python,
que visa estimular o desenvolvimento rápido. Apesar de suas inúmeras facilidades, o
Django não possui uma ferramenta de geração automática de código a partir de di-
agramas gráficos de modelagem, por exemplo. Esta funcionalidade auxiliaria muito
os desenvolvedores que, atualmente, precisam descrever manualmente a camada de
modelagem, dificultando também a documentação estruturada, como por exemplo
através de diagrama de classes e padronizações ao estilo UML.
Focado nestas limitações, inerentes a qualquer ferramenta de software livre que
inicia sua evolução no meio da produção de aplicações, este trabalho propõe uma fer-
ramenta que, aliada ao Django, tem a finalidade de gerar a camada de modelagem do
framework a partir de diagramas UML. Dessa forma o desenvolvedor consegue criar
o Model de forma mais rápida e fácil, ao mesmo tempo que mantém a documentação
de classes de seu sistema.

Palavras-chave: UML, VMC, Django, Framework, Python.


UML2Django: a code generator for Web MVC Framework

ABSTRACT

The development of the WEB applications grows constantly, and, as a conse-


quence of that, the resources and the functionalities of these applications evolves
too. Therefore, to develop applications of quality in a short period of time is a
requirement more and more valuable.
Development frameworks aid to improve the process of development and the qual-
ity of the applications. Using frameworks, the developer can actually be focused on
the main objective of the system, preventing some repetitive work on other applica-
tions, as for instance, the implementaion of logins and controls of access. Djando is
one of this kind of framework. Django consists in a high level web framework (writing
in Python) that aims to stimulate the fast development. Although its innumerable
easinesses, the Django does not possess a tool of automatic generation of code from
graphical diagrams of modeling, for instance. This functionality would very assist
the developers that, currently, need to describe the modeling layer manually, also
making it difficult the structuralized documentation, as for example through class
diagrams and standardizations in UML style.
Focused on those limitations, inherent to any tool of free software that initiates
its evolution in the production of applications, this work proposes a tool that, allied
to the Django, has the goal to generate the framework modeling layer from UML
diagrams. In this way, the developer is able to create the Model Layer in a faster
and easy way, at the same time that it keeps the class documentation of the system.

Keywords: UML, MVC, Django, Framework, Python.


11

1 INTRODUÇÃO

A cada dia que passa, a funcionalidade e os recursos dos sistemas produzidos


evolui, ao mesmo tempo em que é requerido uma maior agilidade no processo de
desenvolvimento dos mesmos. Desenvolver software em um curto perı́odo de tempo
sempre foi um requisito desejável para programadores e empresas.
Vários requisitos, padrões e técnicas são criados diariamente, com a finalidade
de aumentar a produção e melhorar o processo de construção de sistemas. Como re-
sultado, foram criados diversas ferramentas e frameworks, vários processos e rotinas
repetitivas foram automatizados por eles e o tempo gasto no processo de imple-
mentação de fato diminuiu. Em geral, um Framework, assim como web frameworks,
proporcionam uma infraestrutura de programação para aplicações, de forma que o
projetista possa se concentrar na escrita de código eficiente e de fácil manutenção.
Mas ainda há diversos pontos a melhorar, ou pelo menos para facilitar o processo de
produção de código de forma automatizada, como por exemplo geração automática
de código nativo de um framework a partir do esquema de um diagrama de classes.
Os frameworks utilizados atualmente, seguem o padrão MVC (LEFF AVRAHAM; RAY-
FIELD, 2001), que é um padrão de arquitetura de aplicações que visa separar a lógica
da aplicação (Model), da interface do usuário (View) e do fluxo da aplicação (Con-
troller). O uso deste tipo de framework permite que a mesma lógica de negócios
possa ser acessada e visualizada por várias interfaces. Neste trabalho adotamos o
framework Django1 (MAURER, 2006), que utiliza o padrão MVC e também sua
arquitetura de desenvolvimento estimula o desenvolvedor a aproveitar ao máximo o
código já feito, evitando a repetição.
Como o objetivo de melhorar o processo de desenvolvimento com Django, este
trabalho propõe-se a gerar camada Model do framework Django, através de códigos
XML’s gerados por editores de diagramas de classe, permitindo assim além de au-
mentar a velocidade de desenvolvimento de aplicações, a geração e documentação
básica do sistema.

1
http://www.djangoproject.com/
12

1.1 Motivação
O Framework escolhido, o Django, recentemente ganhou bastante notoriedade no
mundo do software livre, devido a sua praticidade no desenvolvimento de aplicações,
foi adotado em diversas empresas e instituições, como por exemplo o Google, Go-
verno Brasileiro e a Universidade de Caxias do Sul.
Django é um framework web de alto nı́vel escrito em Python que estimula o desen-
volvimento rápido e limpo, concentrando-se no máximo de automatização possı́vel,
aderindo ao princı́pio DRY (Don’t repeat yourself). Eliminando processos repetiti-
vos como criação e autenticação de formulários e também a geração automática de
interface de administração, mecanismos de cache e internacionalização.
Atualmente, o desenvolvimento de aplicações em Django não possui nenhuma
ferramenta que gere código a partir de ferramentas de modelagem, a camada de
modelagem é escrita manualmente. Desse modo, se a equipe necessitar de algum
tipo de documentação, como por exemplo um diagrama de classes, ela terá que
repetir o processo de construção.

1.2 Objetivos
O objetivo principal deste trabalho é o desenvolvimento de uma ferramenta para
a geração automática de código Python a partir da modelização de diagramas ge-
rados por ferramentas de modelagem UML. Esta ferramenta visa o aumento de
produtividade e também a diminuição da possibilidade de erros de codificação.
Nesta proposta, trataremos da implementação desta ferramenta, integrada ao
framework Django, com o objetivo de gerar a classe de modelagem do framework
web a partir dos diagramas de classes criados pela ferramenta de criação de modelos
UML.
Basicamente o processo desta geração segue os seguintes passos:

1. Construção dos diagramas de classes em uma interface gráfica (ex. ArgoUML,


Umbrello), Por exemplo, o projeto de um diagrama de classes com seus res-
pectivos componentes para definição de atributos, relacionamentos, cardinali-
dades, etc, conforme a Figura 1, abaixo:

Figura 1.1: Imagem gerada pelo editor UML


13

2. Geração do script XMI, padrão da OMG (grupo de gerenciamento de objetos)


(OMG, 2007), para troca de informações baseado em XML. O uso mais co-
mum é na troca facilitada de metadados entre as ferramentas de modelagem
(baseadas no UML). Um exemplo de um fragmento de script XMI é ilustrado
abaixo:

1 <?xml version = ’1.0’ encoding = ’UTF-8’ ?>


2 <XMI xmi.version = ’1.2’ xmlns:UML = ’org.omg.xmi.namespace.UML’
3 timestamp = ’Tue Sep 09 13:16:17 BRT 2008’>
4 <XMI.header> <XMI.documentation>
5 <XMI.exporter>ArgoUML (using Netbeans XMI Writer version 1.0)</XMI.exporter>
6 <XMI.exporterVersion>0.24(5) revised on $Date: 2006-11-06 19:55:22 +0100
7 (Mon, 06 Nov 2006) $ </XMI.exporterVersion>
8 &nbsp; </XMI.documentation>
9 &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;nbsp; <XMI.metamodel xmi.name="UML"
10 xmi.version="1.4"/></XMI.header>
11 <XMI.content>
12 <UML:Model xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000077B’
13 name = ’untitledModel’ isSpecification = ’false’ isRoot = ’false’ isLeaf = ’false’
14 isAbstract = ’false’>
15 <UML:Namespace.ownedElement>
16 .
17 .
18 .
19 </UML:Namespace.ownedElement>
20 </UML:Model>
21 </XMI.content>
22 </XMI>

3. Tratamento das informações do XML e geração de código no padrão do fra-


mework Django. O diagrama exemplificado na Figura 1 deverá produzir o
seguinte código Python no framework Django:

1 class Pessoa_Email(models.Model):
2 endereco = EmailField()
3
4 class Pessoa(models.Model):
5 nome = models.CharField()
6 cidade = models.CharField()
7 nascimento = models.DateField()
8 enviar_mail = models.BooleanField()
9 endereco = models.ForeignKey(Pessoa_Email)

1.3 Estrutura do Documento


O presente trabalho está dividido em 6 capı́tulos:.
O capı́tulo 1 apresenta uma introdução do trabalho, bem como a motivação, os
objetivos, ferramentas de apoio e a estrutura do documento.
No Capı́tulo 2, serão abordados alguns conceitos preliminares necessários para
um melhor entendimento trabalho, onde apresentamos o padrão de desenvolvimento
14

MVC, uma introdução básica sobre a linguagem python e frameworks de desenvol-


vimento.
O framework alvo da aplicação, o Django, será apresentado no capı́tulo 3, onde
serão descritos detalhes de seus componentes mais usuais e como o padrão MVC é
aplicado a ele.
No capitulo 4, apresentamos o trabalho desenvolvido, onde é focado o parser
implementado no projeto, a estrutura do sistema, os elementos relevantes do arquivo
XMI, a gramática utilizada para ler estes elementos e o processo de tradução para
a sintaxe da classe Django.
O capı́tulo 5 é destinado a apresentar os testes com o sistema, onde diversos
diagramas de classes serão traduzidos para código Python do Django através da
ferramenta implementada neste trabalho.
O Capı́tulo 6 é destinado à apreciação das conclusões final bem como das alter-
nativas de continuidade e trabalhos futuros da presente proposta.
15

2 CONCEITOS PRELIMINARES

Neste Capı́tulo, introduziremos alguns conceitos fundamentais necessários ao en-


tendimento dos componentes utilizados no trabalho. Na seção 2.1 apresentamos uma
breve introdução sobre o padrão de desenvolvimento MVC. Introduzimos algumas
explicações sobre UML na seção 2.2. Na seção 2.3 serão abordados definições sofre
frameworks. Concluindo o capı́tulo, será feita uma breve explicação sobre Python,
a linguagem utilizada neste trabalho.

2.1 Padrão de desenvolvimento MVC


MVC é um padrão de arquitetura de aplicações que visa separar a lógica da
aplicação (Model), da interface do usuário (View) e do fluxo da aplicação (Control-
ler). Permite que a mesma lógica de negócios possa ser acessada e visualizada por
várias interfaces.
O MVC também é utilizado em padrões de projetos de software, entretanto, MVC
abrange mais da arquitetura de uma aplicação do que é tı́pico para um padrão de
projeto.
Em um projeto de software baseado no padrão MVC , define-se uma arquitetura
básica com 3 camadas possivelmente abstratas:

• Model: Implementa o modelo representando a estrutura de baixo nı́vel do


projeto, podendo ser o modelo objeto-relacional que implementa a camada de
dados. Um caso de MVC de Interface poderia guardar informações de estado
dos controllers, por exemplo;

• Controller: Implementa a camada responsável pelo gerenciamentos de eventos


no projeto, tais como cliques do usuário, chamando a camada Model para
processar os eventos. Também pode manter informações de estado do usuário
na aplicação;

• View: Gera a interface com usuário de modo que esta somente requisite o
processamento de eventos pelo Controller;
16

Segundo (BEZERRA, 2007), Model-view-controller (MVC) é um padrão de ar-


quitetura de software. Com o aumento da complexidade das aplicações desenvol-
vidas torna-se fundamental a separação entre os dados (Model) e o layout (View).
Desta forma, alterações feitas no layout não afetam a manipulação de dados, e estes
poderão ser reorganizados sem alterar o layout.
O model-view-controller resolve este problema através da separação das tarefas
de acesso aos dados e lógica de negócio, lógica de apresentação e de interação com o
utilizador, introduzindo um componente entre os dois: o Controller. MVC é usado
em padrões de projeto de software, mas MVC abrange mais da arquitetura de uma
aplicação do que é tı́pico para um padrão de projeto.”

2.2 Ferramentas Gráficas de Modelagem


A escolha de ferramentas de Geração de Diagramas de classes foi definida tendo
como base dois critérios: ser software livre e possuir exportação para XMI. Foram
encontradas as seguintes ferramentas que possuem estes requisitos: ArgoUML1 e
Umbrello2 .
Umbrello UML Modeller permite a modelização de software através de diagramas
UML (Unified Modeling Language) originalmente para o ambiente KDE-Linux, com
extensões recentes para Windows e MAC. Umbrello manipula todos os tipos de
diagramas UML e é capaz de gerar código para algumas linguagens como Java,
C++, Python, PHP, entre outras. No entanto, o código Python gerado a partir
dos diagramas do Umbrello ainda não são compatı́veis com o framework Django,
necessitanto algumas adaptações manuais que, dependendo do tamanho do projeto,
pode tornar inviável sua execução.
ArgoUML é um software para modelagem UML escrito em Java. Possibilitando
ser instalado em qualquer plataforma com suporte a esta tecnologia. Possui suporte
completo para UML 1.4 padrão e oferece excelentes métodos para criação e mani-
pulação dos seus diagramas em UML. Oferece suporte para geração de código Java
nativo e outras linguagens (C++, C# e PHP) através de plugins disponibilizados
em seu site. Infelizmente, a exportação para código Python está somente nos planos
de seus desenvolvedores.
As ferramentas acima salvam o diagrama no formato padrão XMI (XML Meta-
data Interchange) (OMG, 2007), que segundo Eduardo Bezerra, define XMI como
sendo:

”um padrão baseado em XML para exportar modelos definidos em


UML. Esse padrão é importante, pois permite a interoperabilidade
1
http://argouml.tigris.org/
2
http://uml.sourceforge.net/
17

entre diversas ferramentas CASE: um diagrama produzido em uma


ferramenta A pode ser importado para uma ferramenta B de outro
fabricante, considerando que os fabricantes A e B são suporte ao
padrão XMI”(BEZERRA, 2007)

2.3 UML

A UML é uma linguagem visual para modelar sistemas orientados a objeto. Isso
quer dizer que a UML é uma linguagem que define elementos gráficos que podem
ser utilizados na modelagem de sistemas. Esses elementos permitem representar os
conceitos de orientação a objetos através dos diagramas criados. Seguindo a notação
UML, é possivel representar diversas perspectivas do sistema. Ainda segundo (BE-
ZERRA, 2007), cada elemento grafico da UML possui sintaxe e uma semântica.
A sintaxe de um elemento corresponde à forma predeterminada de desenhar o ele-
mento. A semântica define o que significa o elemento e com que objeto ele deve ser
utilizado. Tanto a sintaxe quanto a semântica dos elementos são extensı́veis. Essa
extensibilidade permite que a UML sejá adaptada às caracterı́sticas de cada projeto
de desenvolvimento.
Embora a UML possua diversos diagramas para representar o sistema (ativida-
des, casos de uso, colaboração, seqüência, entre outros) o sistema desenvolvido utiliza
somente diagramas de classe, pois é o diagrama mais indicado para o propósito do
mesmo.

2.3.1 Digramas de Classe

Um diagrama de classes basicamente descreve a estrutura de um sistema, mos-


trando as classes implantadas, seus atributos, e as relações entre as classes. Cada
classe do diagrama possui um conjunto de objetos: Nome da classe, atributos, rela-
cionamentos e métodos.

2.3.1.1 Atributos

Definição das caracterı́sticas da classe, cada elemento de sua lista de atributos


possui um nome e um tipo de dado.

2.3.1.2 Relacionamentos

Um relacionamento representa uma ligação entre classes, é uma ligação binaria


(com duas extremidades) onde cada extremidade é ligada a uma classe, através de
uma linha. Existem diferentes tipos de relacionamento: Agregação, composição,
Herança.
18

2.3.1.3 Métodos

Métodos são funções requeridas a um objeto ou seja, as ações que os objetos de


uma classe pode executar.

2.4 Frameworks de desenvolvimento de aplicações

Estamos em uma época onde as informações são recebidas rapidamente, notı́cias


de qualquer parte do mundo chegam às pessoas de forma quase instantânea. Grande
parte dessa informação é veiculada através da WEB. Para isso o desenvolvimento
de aplicações web é muito explorado.
Apesar da quantidade de ferramentas de desenvolvimento ser bastante grande,
implementar aplicações para Internet não é algo trivial. Construir uma aplicação
web totalmente funcional a algo bastante trabalhoso. Muitas tarefas são necessárias
para que tal feito seja completo: A Configuração e a criação de tabelas em base de
dados, criação de consultas e relacionamentos para as mesmas, geração de código
HTML, mapear as URL para ler os códigos, controle de usuários, e estes itens são
só a parte básica do desenvolvimento.
O desenvolvimento para WEB é muito repetitivo; os passos a serem seguidos
são praticamente os mesmos para cada nova aplicação a ser criada. Como tenta-
tiva de minimizar ao máximo estes repetitivos passos, foram criadas bibliotecas e
frameworks para facilitar o desenvolvimento de aplicações, fazendo com que o de-
senvolvedor focalize basicamente o objetivo do novo sistema, deixando a cargo do
framework manter as tarefas mais maçantes.
Um framework é uma camada de abstração na qual um determinado conjunto
de códigos implementa uma certa funcionalidade genérica, facilmente customizada
pelo usuário, criando assim um funcionalidade expecifica. É função do framework
também, validar o código criado pelo usuário.
Os frameworks para desenvolvimento web geralmente seguem o padrão de arqui-
tetura de sistema MVC para separar as camadas de negócio, persistência e interface.

2.4.1 Exemplos

A maioria das linguagens voltadas para o desenvolvimento WEB posuem fra-


meworks: Ruby possui um dos mais famosos framework WEB da atualidade, o
Ruby on Rails 3 . Python possui uma gama consideravel de ferramentas como o

3
http://www.rubyonrails.org
19

Django, TurboGears4 , Pylons5 , Zope6 /Plone7 , web2py8 entre outros. PHP9 que é
uma das mais utilizadas linguagens para peogramação WEB possui os frameworks
CakePHP10 , CodeIgniter11 , Prado12 , symfony13 , Zend14 , entre outros. Perl possui o
Catalyst15 , Maypole16 , Jifty17 , e a maioria deles segue o padrão MVC.

2.5 Linguagem de programação Python


Python18 é uma linguagem de programação de alto nı́vel, interpretada, intera-
tiva, orientada à objetos e de tipagem dinâmica e forte, lançada por Guido van
Rossum em 1991. Atualmente possui um modelo de desenvolvimento comunitário e
aberto gerenciado pela organização sem fins lucrativos Python Software Foundation.
Apesar de várias partes da linguagem possuı́rem padrões e especificações formais,
a linguagem como um todo não é formalmente especificada. O padrão de imple-
mentação é o CPython, o que significa que foi desenvolvida a partir da linguagem
C, mas existe também as variantes Jython e IronPython que são reimplementação
do Python produzidas em Java e .NET respectivamente.
A linguagem foi projetada com a filosofia de enfatizar a importância do esforço do
programador sobre o esforço computacional. Prioriza a legibilidade do código sobre a
velocidade ou expressividade. Combina uma sintaxe concisa e clara com os recursos
poderosos de sua biblioteca padrão e por módulos e frameworks desenvolvidos por
terceiros.

2.5.1 Exemplos

Através dos exemplo abaixo, é possivel verificar a simplicidade da linguagem:

2.5.1.1 Fibonacci
1 a =1
2 b =1
3 while a < 800:
4 print a ,

4
http://turbogears.org
5
http://pylonshq.com
6
http://www.zope.org
7
http://www.plone.org
8
http://mdp.cti.depaul.edu
9
http://www.php.net
10
http://www.cakephp.org
11
http://codeigniter.com
12
http://www.pradosoft.com
13
http://www.symfony-project.org
14
http://www.zend.com
15
http://www.catalystframework.org
16
http://maypole.perl.org
17
http://jifty.org
18
http://www.python.org
20

5 a,b = b,a+b

2.5.1.2 Números Primos


1 ehprimo = True
2 numero = input ( " Informe o numero : " )
3 i = 2
4 while i < numero :
5 if numero % i == 0:
6 ehprimo = False
7 break
8 i += 1
9 if ehprimo :
10 print " Primo : " , numero
11 else :
12 print numero , ’ possui fator ’ , i

2.5.1.3 Cálculo de Fatorial


1 n = int ( raw_input ( " Fatorial de : " ))
2 fatorial = 1
3 print " % d ! = " %n ,
4 i = n
5 while i > 0:
6 fatorial = fatorial * i
7 print " % d " %i ,
8 if i != 1: print " . " ,
9 i -= 1
21

3 DJANGO

Django (DJANGO, 2008) é um framework para desenvolvimento rápido para


web, escrito em Python, que utiliza o padrão MVC (model-view-controller). Foi
criado originalmente como sistema para gerenciar um site jornalı́stico na cidade de
Lawrence, no Kansas. Tornou-se um projeto de código aberto e foi publicado sob
a licença BSD1 em 2005. O nome Django foi inspirado no músico de jazz Django
Reinhardt.
Django utiliza o princı́pio DRY (Don’t Repeat Yourself), onde faz com que o
desenvolvedor aproveite ao máximo o código já feito, evitando a repetição.
Na seção 3.1, abordaremos as caracterı́sticas do framework, onde serão explicados
os componentes principais da ferramenta, tais como Controllers, Templates, Models,
Middlewares e URLDispacher. Na seção 3.2 será explicado o fluxo de execução de
uma requisição no Django.

3.1 Caracterı́sticas
Através do ORM2 do Django é definida a modelagem de dados através de classes
em Python, clamadas modelos. Com isso é possı́vel independente de qual banco
de dados escolhido, gerar suas tabelas e manipular seus dados sem necessidade de
utilizar linguagem SQL.
Os Models também possibilitam criar formulários automáticos e gerar uma inter-
face de administração praticamente completa e facilmente configurável e extensı́vel,
aumentando ainda mais o desenvolvimento das aplicações.
O Django possui uma linguagem de templates muito extensı́vel e amigável. Através
dela é possivel fazer a separação de design, conteúdo e código Python.
A figura 3.1 ilustra a estrutura global do Django, exibindo a ligação entre os
componentes principais do framework. Os componentes estão classificados em cores,
representando as camadas do sistema.
1
http://www.opensource.org/licenses/bsd-license.php
2
Object-Relational Mapping
22

Figura 3.1: Estrutura do framework Django

3.1.1 Persistência de dados (model)

A Classe de Modelagem é basicamente, a fonte de todos os registros no projeto.


Ele contém todos os campos essenciais e relações de tudo que é armazenado no
Banco de dados. Geralmente, cada modelo mapeia uma única tabela de dados.

3.1.2 Visualização de dados (view)

.
A visualização dos dados pelos usuários é feita através das views e dos templates.
São através deles que os dados recebidos pelos models são manipulados. Os acessos
aos dados são feitos através das views.
As views são as seções do site, onde os dados recebidos pela camada de per-
sistência são apresentados, criados, editados e deletados por scripts python. Por
exemplo, em uma aplicação de um blog, haveriam as seguintes views:

• Inı́cio - exibição das 5 últimas postagens;

• Postagem - página para uma única entrada;

• Postagem-Comentário - comentários de uma determinada postagem;

• Ano-arquivo - exibe todos os meses com as inscrições no ano determinado;


23

• Mês-arquivo - exibe todos os dias com entradas do mês em questão;

• Dia-arquivo - exibe todas as entradas em determinado dia;

O sistema de templates do django é um módulo que visa separar a apresentação dos


dados lógicos do site. O Template define certos espaços onde são definidos laços de
repetições, condicionais e outras funcionalidades do django para manipular variáveis
passadas pela view. Normalmente, os templates são utilizados para produzir docu-
mento HTML, mas os templates do Django são capazes de gerar qualquer formato
de tipo texto também.

3.1.3 Controle de dados (Controller)


Entre a camada de visualização e o usuário, há a camada de controle, responsável
pelo processamento de ações de requisições e resposta do usuário (HTTP Request e
HTTP Response). Para realizar este processamento o Django conta com Middlewa-
res e Url Dispatcher.
As middlewares são trechos de código que analisam requisições feitas pelo usuário.
Através dele é possı́vel enviar informações para view de forma transparente ao
usuário como, por exemplo, detalhes sobre seções e autenticação.
Depois de passar pelos middlewares, a requisição é analisada pelo URL Dispat-
cher, que verifica o endereço que o usuário acessa e verifica se o mesmo consta no
arquivo de URLs da aplicação. Cada URL está associada a uma view, se a URL
requisitada não se encontra no arquivo um erro do tipo 4043 é informado.

3.2 Fluxo de Execução


Através de um browser, o usuário faz uma requisição a um site Django, de acordo
com a URL informada. O Framework verifica se a mesma está nos seus registros
de URL. Após a localização da URL, uma view correspondente é invocada, a view
requisita informações à classe de modelagem que devolve os dados. Com os dados
recebidos da classe de modelagem, o Django armazena em variáveis e envia para um
template. O template recebe as variáveis da view e renderiza o template no formato
desejado (HTML, PDF). A página renderizada é exibida na tela para o usuário. O
processo detalhado pode ser visto na Figura 3.2.

3
404 Error. The Page Was Not Found
24

Figura 3.2: Fluxo de Execução do Framework Django


25

4 IMPLEMENTAÇÃO

Neste Capı́tulo abordamos a implementação da proposta de geração de código


python no framework Django a partir de modelos de diagramas de classes. Na seção
4.1 introduzimos a arquitetura geral do sistema proposto, mostrando seus compo-
nentes principais e seus relacionamentos. Na seção 4.2 mostramos a delimitação do
escopo dos elementos XMI tratados pelo nosso gerador.

4.1 Arquitetura geral da implementação proposta


A implementação do Parser XMI-DjangoModel foi feita inteiramente utilizando
Python, a mesma linguagem do Framework web Django. Não foi definida nenhuma
interface gráfica, pois não há necessidade para tal. Basicamente o script recebe
como parâmetro o arquivo XML e gera a classe de modelagem. A Figura 4.1 ilustra
a arquitetura geral do analisador XMI2Django proposta neste trabalho.
Os principais modeladores de gráficos UML possuem um método de exportação
em arquivo texto para que os diagramas criados possam ser acessados em outro
modelador. O método que resulta este texto, está escrito em padrão XMI, um
formato definido pela OMG para representação, intercâmbio e compartilhamento de
objetos, modelos e meta-modelos utilizando XML.
Teoricamente, os dados XMI exportados em um modelador, deverão ser lidos
em outro sem maiores problemas, logo o parser do trabalho em questão, irá gerar
o código Django independente da ferramenta de modelagem UML utilizada, desde
que ele exporte o arquivo XMI

4.2 Parâmetros XMI utilizados pelo Parser


Boa parte das tags contidas no XML gerado pelo editor UML não são utilizadas
no parser, pois muitas delas são geradas com a finalidade de exportações para outros
aplicativos (como por exemplo, outro editor UML). No trabalho em questão são
utilizadas, para uma geração correta da classe de modelagem do Django, os seguintes
elementos:
26

Figura 4.1: Estrutura do parser XMI2Django

• UML:Namespace.ownedElement

O elemento raiz do xmi, é onde todos os itens do diagrama em questão


estão inseridos;

• UML:DataType

Lista de tipos de dados (name, xmi.id);

• UML:Class

Classes do diagrama de classes (name, xmi.id);

• UML:Classifier.feature

Tag XMI que contém a tag UML:Attribute;

• UML:Attribute

Atributos da classe (name, xmi.id);

• UML:ModelElement.taggedValue

Tag XMI que contém a tag XML:TaggedValue;

• UML:TaggedValue

Lista de valores marcados;


27

• UML:TaggedValue.type
Tag XMI que contém a tag UML:TagDefinition;

• UML:TagDefinition
Apontador para o valor marcado (xmi.idref);

• UML:TaggedValue.dataValue
Valor do Valor Marcado (name);

• UML:StructuralFeature.type
Tag XMI que contém a tag UML:DataType;

• UML:DataType
Um apontador para um tipo de dado (xmi.idref);

• UML:Association
Lista de associações entre classes;

• UML:Association.connection
Tag XMI que contém a tag UML:AssociationEnd;

• UML:AssociationEnd
Tipo de associação (Composição, agregação, herança) (aggregation);

• UML:AssociationEnd.participant
Lista de objetos participantes da associação, para o parser, ele trata apenas
classes;

• UML:Class
Um apontador para a classe (xmi.idref);

• UML:AssociationEnd.multiplicity
Tag XMI que contém a tag UML:Multiplicity;

• UML:Multiplicity
Tag XMI que contém a tag UML:Multiplicity.range;

• UML:Multiplicity.range
Tag XMI que contém a tag UML:MultiplicityRange;

• UML:MultiplicityRange
Multiplicidade da associação (1 para n, 1 para 1) (lower, upper );
28

• UML:TagDefinition
Nome do Valor Marcado (name, xmi.id).

Abaixo está parte do código XMI gerado pelo editor UML que é utilizado pelo
parser. Nele está modelado o diagrama UML apresentado no capı́tulo de Introdução.
Duas classes, a primeira (Cidade) com um atributo (nome) e a segunda (Estado)
com dois atributos (Nome e Zona) e um relacionamento 1:n entre elas. O código
inteiro está nos anexos:
1 <UML:Namespace.ownedElement>
2 <UML:Class xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000077C’
3 name = ’Cidade’ visibility = ’public’ isSpecification = ’false’ isRoot = ’false’
4 isLeaf = ’false’ isAbstract = ’false’ isActive = ’false’>
5 <UML:Classifier.feature>
6 <UML:Attribute xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000077F’
7 name = ’nome’ visibility = ’public’ isSpecification = ’false’ ownerScope = ’instance’
8 changeability = ’changeable’ targetScope = ’instance’>
9 <UML:StructuralFeature.type>
10 <UML:DataType xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000786’/>
11 </UML:StructuralFeature.type>
12 </UML:Attribute>
13 </UML:Classifier.feature>
14 </UML:Class>
15 <UML:DataType xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000786’
16 name = ’CharField’ isSpecification = ’false’ isRoot = ’false’ isLeaf = ’false’
17 isAbstract = ’false’/>
18 <UML:DataType xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000787’
19 name = ’IntegerField’ isSpecification = ’false’ isRoot = ’false’ isLeaf = ’false’
20 isAbstract = ’false’/>
21 <UML:Class xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000792’
22 name = ’Estado’ visibility = ’public’ isSpecification = ’false’ isRoot = ’false’
23 isLeaf = ’false’ isAbstract = ’false’ isActive = ’false’>
24 <UML:Classifier.feature>
25 <UML:Attribute xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000795’
26 name = ’nome’ visibility = ’public’ isSpecification = ’false’ ownerScope = ’instance’
27 changeability = ’changeable’ targetScope = ’instance’>
28 <UML:StructuralFeature.type>
29 <UML:DataType xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000786’/>
30 </UML:StructuralFeature.type>
31 </UML:Attribute>
32 <UML:Attribute xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007AF’
33 name = ’zona’ visibility = ’public’ isSpecification = ’false’ ownerScope = ’instance’
34 changeability = ’changeable’ targetScope = ’instance’>
35 <UML:StructuralFeature.type>
36 <UML:DataType xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000786’/>
37 </UML:StructuralFeature.type>
38 </UML:Attribute>
39 </UML:Classifier.feature>
40 </UML:Class>
41 <UML:Association xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C2’
42 name = ’’ isSpecification = ’false’ isRoot = ’false’ isLeaf = ’false’ isAbstract = ’false’>
43 <UML:Association.connection>
44 <UML:AssociationEnd xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C3’
45 visibility = ’public’ isSpecification = ’false’ isNavigable = ’true’ ordering = ’unordered’
46 aggregation = ’composite’ targetScope = ’instance’ changeability = ’changeable’>
47 <UML:AssociationEnd.multiplicity>
29

48 <UML:Multiplicity xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C4’>


49 <UML:Multiplicity.range>
50 <UML:MultiplicityRange
51 xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C5’
52 lower = ’1’ upper = ’1’/>
53 </UML:Multiplicity.range>
54 </UML:Multiplicity>
55 </UML:AssociationEnd.multiplicity>
56 <UML:AssociationEnd.participant>
57 <UML:Class xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000077C’/>
58 </UML:AssociationEnd.participant>
59 </UML:AssociationEnd>
60 <UML:AssociationEnd xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C6’
61 visibility = ’public’ isSpecification = ’false’ isNavigable = ’true’ ordering = ’unordered’
62 aggregation = ’none’ targetScope = ’instance’ changeability = ’changeable’>
63 <UML:AssociationEnd.multiplicity>
64 <UML:Multiplicity xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007CA’>
65 <UML:Multiplicity.range>
66 <UML:MultiplicityRange
67 xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C9’
68 lower = ’1’ upper = ’-1’/>
69 </UML:Multiplicity.range>
70 </UML:Multiplicity>
71 &nbsp;&nbsp; </UML:AssociationEnd.multiplicity>
72 <UML:AssociationEnd.participant>
73 <UML:Class xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000792’/>
74 </UML:AssociationEnd.participant>
75 </UML:AssociationEnd>
76 </UML:Association.connection>
77 </UML:Association>
78 </UML:Namespace.ownedElement>

4.3 Mapeamento de objetos XMI - Django Model


O gerador proposto tem como objetivo traduzir elementos XMI em código Python
segundo o framework Django. A Tabela 4.1 ilustra os componentes (tags) XMI con-
siderados e sua respectiva tradução no framework Django. Cada linha da tabela
poderá ser gerada por uma ou várias regras de produção gramaticais aliadas à re-
gras semânticas para geração de código Python.

4.4 Análise léxico-sintática


O parser considerado neste projeto é um top-down descendente para gramáticas
do tipo LL1 . Considerando o escopo delimitado na seção 2.2, a gramática livre-de-
contexto (GLC) definida aqui compreende apenas a geração de produções relativas
aos componentes de representação de Classe, atributos e relacionamentos do padrão
XMI. Para tanto, limitamos nossa gramática a estas tags especı́ficas. Além disso,
não foi criada nenhuma validação da sintaxe do XMI, pois, partimos do pressuposto
1
Left-to-Right, Leftmost derivation com lookahead. Para isto, a gramática livre-de-contexto
deve estar livre de recursão a esquerda e deve estar fatorada.
30

Tag XMI Django


UML:Class Classe Django
UML:Attribute Atributo da Classe Django
UML:DataType Tipo do atributo
UML:Association, Geração de um atributo da classe
UML:AssociationEnd, Django que representará a associação, seja
UML:AssociationEnd.participant, ela chave Estrangeira ou um
UML:MultiplicityRange mapeamento N para N
UML:TagDefinition,
UML:TaggedValue.type, Parametros utilizados nos atributos da classe
UML:TaggedValue.dataValue

Tabela 4.1: Mapeamento de objetos XMI - Django Model

que a mesma esteja correta, pois foi gerada automaticamente através de um sistema
já consolidado.
Como a estrutura do XMI é basicamente uma estrutura em forma de árvore, a
gramatica utilizada no parser é bem simples. A seguir apresentamos a GLC proposta
em formato BNF:

1 <UML:Namespace.ownedElement> ::= <UML:DataType> <UML:Class> <UML:Association>


2 <UML:DataType> ::= name "=" "’" valor "’" xmi.id "=" "’" valor "’"
3 | xmi.idref "=" "’" valor "’"
4 <UML:Class> ::= UML:Classifier.feature name "=" "’" valor "’" xmi.id "=" "’" valor "’"
5 | xmi.idref = "valor"
6 <UML:Class> ::= UML:Class name "=" "’" valor "’" xmi.id "=" "’" valor "’" <UML:Classifier.feature>
7 <UML:Class> ::= UML:Class xmi.idref "=" "’" valor "’"
8
9 <UML:Classifier.feature> ::= <UML:Attribute>
10 <UML:Attribute> :: = UML:ModelElement.taggedValue UML:StructuralFeature.type"
11 name "=" "’" valor "’" xmi.id "=" "’" valor "’"
12 <UML:ModelElement.taggedValue> ::= "UML:TaggedValue"
13 <UML:TaggedValue> :: = "UML:TaggedValue.type" "UML:TaggedValue.dataValue"
14 <UML:TaggedValue.type> ::= "UML:TagDefinition"
15 <UML:TagDefinition> ::= xmi.idref "=" "’" valor "’"
16 <UML:TaggedValue.dataValue> ::= name "=" "’" valor "’"
17 <UML:StructuralFeature.type> ::= "UML:DataType"
18 <UML:Association> ::= "UML:Association.connection"
19 <UML:Association.connection> ::= "UML:AssociationEnd" "UML:AssociationEnd.participant"
20 "UML:AssociationEnd.multiplicity"
21 <UML:AssociationEnd> ::= aggregation "=" "’" valor "’"
22 <UML:AssociationEnd.participant> ::= "UML:Class"
23 <UML:AssociationEnd.multiplicity> ::= "UML:Multiplicity.range"
24 <UML:Multiplicity.range> ::= UML:MultiplicityRange
25 <UML:MultiplicityRange> ::= lower "=" "’" valor "’" upper "=" "’" valor "’"

Para auxiliar a extração de dados relevantes do XML, foi utilizado o pacote


padrão do Python, o xml.dom.minidom. Com ele foi possı́vel tratar os nomes de
tags e diferenças entre os atributos das mesmas. Embora existam outros parsers
31

XML escritos em Python, como por exemplo o ElementTree 2 e o BeautifulSoup 3 o


pacote padrão da linguagem foi o escolhido. A justificativa desta escolha se deve
ao fato do pacote padrão já fazer parte da distribuição atual do Python, sendo
assim, o sistema tende a manter uma maior compatibilidade com futuras versões do
interpretador.

4.4.1 Extração do XML


A extração dos dados é feita através do pacote xml.dom.minidom, como referido
acima, uma implementação mais leve da interface DOM4 . É uma implementação
mais simples que o DOM padrão e significativamente menor. O Minidom analiza
o código no arquivo XML e cria a estrutura DOM, sendo esta mais fácil para ma-
nipulação dos itens dos arquivos XML. Uma vez tendo o objeto DOM, é possivel
acessar partes de seu documento XML através das suas propriedades e métodos.
Estas propriedades são definidas na especificação DOM5 . A principal propriedade
do objeto é a documentElement, responsável pela extração das tags expecı́ficas do
XML. O exemplo pode ser visto abaixo:

>>> from xml.dom import minidom


>>> dom = minidom.parseString("<myxml>Some data</myxml>")
>>> dom.documentElement.nodeValue
>>> print dom.documentElement.tagName
u’myxml’

Também foi criada uma função em Python chamada finditem com a finalidade
de buscar e retornar uma lista de itens-filho, de uma tag expecı́fica, de acordo com
o nome enviado por parâmetro:
1 def findItem(raiz,item):
2 return [x for x in raiz.childNodes if x.nodeName == item]

A busca dos elementos principais do diagrama (classes, tags, tipo de dados e


associações) é feita através do item raiz (UML:Namespace.ownedElement):

1 def findItem(raiz,item):
2 return [x for x in raiz.childNodes if x.nodeName == item]
3
4 raiz = doc.documentElement.getElementsByTagName(’UML:Namespace.ownedElement’)[0] #elemento raiz
5
6 xmi_tipos = findItem(raiz,"UML:DataType") #lista de tipos
7 lst_tipos = TipoDados(xmi_tipos)
8

2
http://effbot.org/zone/element-index.htm
3
http://www.crummy.com/software/BeautifulSoup/
4
Document Object Model interface
5
http://www.w3.org/DOM/
32

9 xmi_tags = findItem(raiz,"UML:TagDefinition") #valores marcados


10 lst_tags = TipoTags(xmi_tags)
11
12 xmi_classes = findItem(raiz,"UML:Class") #lista de classes
13 xmi_associacoes = findItem(raiz,"UML:Association") #lista de associaç~
oes
14 xmi_herancas = findItem(raiz,"UML:Generalization") #lista de herancas
15 classes = ListaClasses(xmi_classes,lst_tipos,lst_tags,xmi_associacoes,xmi_herancas)

Para cada classe encontrada no XMI, é feita a extração do nome de identificador


da classe e também é realizada a busca dos atributos da mesma.
1 def findItem(raiz,item):
2 return [x for x in raiz.childNodes if x.nodeName == item]
3
4 for classe in xmi_classes:
5 nome = classe.attributes.get(’name’).value
6 container = findItem(classe,’UML:Classifier.feature’)[0]
7 xmi_atributos = findItem(container,’UML:Attribute’)

A cada atributo encontrado, é extraı́do o nome e o identificador do tipo do


atributo. O nome do tipo do atributo é buscado na lista de tipos, extraı́da anteri-
ormente:
1 xmi_atributos = findItem(container,’UML:Attribute’)
2 for att in xmi_atributos:
3 container_tipo = findItem(att,’UML:StructuralFeature.type’)[0]
4 container_tipo2 = findItem(container_tipo,’UML:DataType’)[0]
5 nome = att.attributes.get(’name’).value
6 valor= lst_tipos.get_nome(container_tipo2.attributes.get(’xmi.idref’).value)

4.5 Análise semântica


A tradução para código Django, utiliza uma estrutura intermediária de dados,
utilizando programação orientada à objeto escrita em Python, para assim gerar o
código Django. A figura 4.5 representa o diagrama desta estrutura intermediária.
De acordo com os dados contidos no arquivo XML, é feita a busca de elementos
e extraı́do os dados relevantes. Estes dados são armazenadas em forma de objetos
python de acordo com a Figura 4.5. Quando a leitura estiver completa, os objetos
python são lidos e escritos na tela, já no padrão de modelagem da camada Model do
Django.

4.5.1 Algoritmo de geração


A geração das classes é realizada através da busca das classes do objeto Klasse
(Figura 4.5), onde o objeto possui uma variavel que informa se a classe herda de
outra ou não, pois o código traduzido de uma classe herdada é diferente.
33

Figura 4.2: Diagrama de classes do sistema

1 for cl in self.classes.lista:
2 if cl.herda_de:
3 yield ’class %s(%s):’ % (cl.nome,cl.herda_de)
4 else:
5 yield ’class %s(models.Model):’ % cl.nome

Para cada classe, é verificado se a mesma possui atributos, cada atributo é escrito
como uma variável da classe recebendo como valor, o tipo de campo Field do Django.
É verificado também se o atributo possui valores marcados, se possuir, estes são
escritos como parâmetros do Field.

1 yield ’class %s(models.Model):’ % cl.nome


2 for att in cl.atributos:
3 extra = ""
4 if len(att.extras):
5 for ex in att.extras:
6 extra+="%s=%s," %(ex[’nome’],ex[’valor’])
7 yield ’ %s = models.%s(%s)’ % (att.nome, att.valor,extra[:-1])

As Associações da classe são geradas de forma semelhante aos atributos, pois são
escritas também como variáveis da classe. Além da verificação de valore marcados,
é verificado o tipo de cardinalidade. Se a cardinalidade for “um para muitos” (1:n)
é gerado um campo ForeignKey, se for uma relação “muitos para muitos” (n:n) é
gerado um campo ManyToMany.

1 for rel in cl.associacoes:


2 extra = ""
34

3 if len(rel.extras):
4 for ex in rel.extras:
5 extra+=", %s=’%s’" %(ex[’nome’],ex[’valor’])
6 if rel.cardinalidade[0] == ’*’ and rel.cardinalidade[1] == ’*’:
7 yield ’ %s = models.ManyToManyField(%s%s)’ % \
8 (str.lower(str(rel.classe)), rel.classe, extra)
9 for rel in cl.associacoes:
10 extra = ""
11 if len(rel.extras):
12 for ex in rel.extras:
13 extra+=", %s=’%s’" %(ex[’nome’],ex[’valor’])
14 if rel.cardinalidade[0] == ’*’ and rel.cardinalidade[1] == ’*’:
15 yield ’ %s = models.ManyToManyField(%s%s)’ % \
16 (str.lower(str(rel.classe)), rel.classe, extra)
17 else:
18 yield ’ %s = models.ForeignKey(%s%s)’ % \
19 (str.lower(str(rel.classe)), rel.classe, extra)
35

5 EXPERIMENTOS E RESULTADOS

As classes criadas pelo Parser, foram testadas no Django. Foram criados diversos
diagramas, contendo uma grande variedade de tipos de dados, atributos, agregações
e herança. Em todos os casos abaixo foram gerados códigos, sendo estes perfeita-
mente aplicados no framework.

5.1 Diagramas com uma Classe


Primeiro teste feito com o Parser, e o mais simples, verifica a classe “Pessoa”
contida no XML e lista os atributos (nome) e (nascimento), conforme a figura 5.1.

Figura 5.1: UML Representando uma classe

O código gerado corresponde a Classe do Django com o nome “Pessoa” e com


as variáveis (nome) e (nascimento) representando seus atributos, conforme o quadro
abaixo:
1 # coding: utf-8
2 # Este ~
A c um modulo de auto gera~
A§~
A£o de classes django.
3
4 from django.db import models
5
6 class Pessoa(models.Model):
7 nome = models.CharField(max_length=15)
8 nascimento = models.DateField()

5.2 Diagramas com duas Classes sem relacionamento


Basicamente o mesmo teste que o anterior, criado para testar várias classes. Nele
são geradas duas classes, a classe “Cidade”, com um atributo (nome) e a Classe
“Estado” com dois atributos (nome) e (zona)
36

Figura 5.2: UML Representando duas classes sem relacionamento

O código gerado contém duas classes Django com os nomes “Cidade” e “Estado”.
A classe “Cidade” possui o atributo (nome) e a classe “Estado” possui os atributos
(nome) e (zona), conforme o quadro abaixo:

1 ## coding: utf-8
2 # Este ~
A c um modulo de auto gera~
A§~
A£o de classes django.
3
4 from django.db import models
5
6 class Cidade(models.Model):
7 nome = models.CharField(max_length=15)
8
9 class Estado(models.Model):
10 nome = models.CharField(max_length=25)
11 zona = models.CharField(max_length=2)

5.3 Diagramas com duas Classes relacionadas


O mesmo teste que o anterior, agora testando associações entre classes. Neste
caso foi utilizado um relacionamento 1:n, este relacionamento é representado pelo
atributo do tipo ForeignKey da classe Django

Figura 5.3: UML representando duas classes relacionadas

Neste caso o código gerado é semelhante ao do teste 5.2, mas, como pode ser
visto na linha 12, foi acrescentado uma variável do tipo ForeignKey representando
um relacionamento.

1 ## coding: utf-8
2 # Este ~
A c um modulo de auto gera~
A§~
A£o de classes django.
3
4 from django.db import models
5
37

6 class Cidade(models.Model):
7 nome = models.CharField(max_length=15)
8
9 class Estado(models.Model):
10 nome = models.CharField(max_length=25)
11 zona = models.CharField(max_length=2)
12 cidade = models.ForeignKey(Cidade)

5.4 Teste de Herança

O teste abaixo foi realizado para representar as heranças de classes Django. São
representadas três classes, uma classe principal chamada “Pessoa”, e outras duas
classes que descendem da classe anterior, “Fisica” e “Jurı́dica”.

Figura 5.4: UML representando herança

No código gerado, o parser gerou a Classe “Pessoa” herdando da classe Django


e as classes “Fisica” e “Jurı́dica” herdando de “Pessoa”.

1 # coding: utf-8
2 # Este ~
A c um modulo de auto gera~
A§~
A£o de classes django.
3
4 from django.db import models
5
6 class Pessoa(models.Model):
7 nome = models.CharField(max_length=45)
8
9 class Fisica(Pessoa):
10 cpf = models.IntegerField()
11
12 class Juridica(Pessoa):
13 cnpj = models.IntegerField()
38

5.5 Teste múltiplo


Este exemplo ilustra um sistema real, contendo várias classes e vários tipos de
campos e associações.

Figura 5.5: Uml representando várias classes

O código gerado pode ser visto no quadro a seguir:

1 # coding: utf-8
2 # Este ~
A c um modulo de auto gera~
A§~
A£o de classes django.
3
4 from django.db import models
5
6 class Estado(models.Model):
7 nome = models.CharField(max_length=10)
8 zona = models.IntegerField()
9
10 class Usuario(models.Model):
11 username = models.CharField(max_length=10)
12 password = models.CharField(max_length=20)
13
14 class Cidade(models.Model):
15 nome = models.CharField(max_length=30)
16 estado = models.ForeignKey(Estado)
17
18 class Pessoa(models.Model):
19 nome = models.CharField(max_length=40)
20 cidade = models.ForeignKey(Cidade)
21 usuario = models.ForeignKey(Usuario, unique=’True’)
39

22 fotos = models.ManyToManyField(Fotos)
23
24 class Fotos(models.Model):
25 foto = models.ImageField(upload_to=’/upload/teste/’)
26 data = models.DateField(auto_now_add=True)
27
28 class PessoaFisica(Pessoa):
29 rg = models.IntegerField()
30 nascimento = models.DateField()
31
32 class PessoaJuridica(Pessoa):
33 cnpj = models.IntegerField()
34
40

6 CONCLUSÃO

6.1 Validação do projeto


O principal objetivo deste trabalho foi alcançado. O objetivo central de gerar
uma classe Django a partir de um diagrama de classes foi completamente atingido.
Praticamente todos os elementos Model que o Django suporta (Classes, atributos,
Valores de atributos, Chaves estrangeiras, relacionamentos N:N e herança) foram
extraidos com sucesso.
Com a utilização do gerador de código, a criação da camada lógica do sistema
ficou muito mais fácil de ser desenvolvida, pois agora o usuário possui uma visua-
lização gráfica de todo o sistema, facilitando a visualização da estrutura do sistema
a ser desenvolvido.
Apesar do sistema conseguir extrair perfeitamente os dados do XMI, os testes
mais profundos da ferramenta foram feitos utilizando o modelador ArgoUML, por
isso, a compatibilidade com outros modeladores, como por exemplo o Umbrello, não
está completamente garantida.

6.2 Trabalhos Futuros


A intenção é que os trabalhos com o parser possam continuar, através da criação
de outros testes utilizando diferentes modeladores UML e comparando seu resultado
com o desenvolvido até o momento.
Há interesse em disponibilizar o parser como software livre, tendo como principal
meta, a evolução do sistema adicionando novas funções, melhorias de performance
no código e no gerador, uma atualização do mesmo com possı́veis mudanças da
estrutura de modelagem do framework Django
Atualmente há uma projeto de implementação de máquina de workflow em
django chamado GoFlow 1 . Uma das possibilidades de trabalho futuro, seria a
integração de diagramas de estados com uma máquina de workflow. A proposta se-
ria de a partir de diagramas de estado serem gerados rotinas de workflow, da mesma
1
http://code.google.com/p/goflow/
41

forma que hoje são geradas classes a partir de diagramas de classe.


42

7 ANEXOS

1 <?xml version = ’1.0’ encoding = ’UTF-8’ ?>


2 <XMI xmi.version = ’1.2’ xmlns:UML = ’org.omg.xmi.namespace.UML’ timestamp = ’Tue Sep 09 13:16:17 BRT 2008’>
3 <XMI.header> <XMI.documentation>
4 <XMI.exporter>ArgoUML (using Netbeans XMI Writer version 1.0)</XMI.exporter>
5 <XMI.exporterVersion>0.24(5) revised on $Date: 2006-11-06 19:55:22 +0100 (Mon, 06 Nov 2006) $ </XMI.exporterVersio
6 </XMI.documentation>
7 <XMI.metamodel xmi.name="UML" xmi.version="1.4"/></XMI.header>
8 <XMI.content>
9 <UML:Model xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000077B’
10 name = ’untitledModel’ isSpecification = ’false’ isRoot = ’false’ isLeaf = ’false’
11 isAbstract = ’false’>
12 <UML:Namespace.ownedElement>
13 <UML:Class xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000077C’
14 name = ’Cidade’ visibility = ’public’ isSpecification = ’false’ isRoot = ’false’
15 isLeaf = ’false’ isAbstract = ’false’ isActive = ’false’>
16 <UML:Classifier.feature>
17 <UML:Attribute xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000077F’
18 name = ’nome’ visibility = ’public’ isSpecification = ’false’ ownerScope = ’instance’
19 changeability = ’changeable’ targetScope = ’instance’>
20 <UML:StructuralFeature.multiplicity>
21 <UML:Multiplicity xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007BF’>
22 <UML:Multiplicity.range>
23 <UML:MultiplicityRange xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007BE’
24 lower = ’1’ upper = ’1’/>
25 </UML:Multiplicity.range>
26 </UML:Multiplicity>
27 </UML:StructuralFeature.multiplicity>
28 <UML:StructuralFeature.type>
29 <UML:DataType xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000786’/>
30 </UML:StructuralFeature.type>
31 </UML:Attribute>
32 </UML:Classifier.feature>
33 </UML:Class>
34 <UML:DataType xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000786’
35 name = ’CharField’ isSpecification = ’false’ isRoot = ’false’ isLeaf = ’false’
36 isAbstract = ’false’/>
37 <UML:DataType xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000787’
38 name = ’IntegerField’ isSpecification = ’false’ isRoot = ’false’ isLeaf = ’false’
39 isAbstract = ’false’/>
40 <UML:Class xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000792’
41 name = ’Estado’ visibility = ’public’ isSpecification = ’false’ isRoot = ’false’
42 isLeaf = ’false’ isAbstract = ’false’ isActive = ’false’>
43 <UML:Classifier.feature>
44 <UML:Attribute xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000795’
45 name = ’nome’ visibility = ’public’ isSpecification = ’false’ ownerScope = ’instance’
43

46 changeability = ’changeable’ targetScope = ’instance’>


47 <UML:StructuralFeature.multiplicity>
48 <UML:Multiplicity xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C1’>
49 <UML:Multiplicity.range>
50 <UML:MultiplicityRange xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C0’
51 &nbsp; lower = ’1’ upper = ’1’/>
52 </UML:Multiplicity.range>
53 </UML:Multiplicity>
54 &nbsp; </UML:StructuralFeature.multiplicity&amp;amp;gt;
55 &amp;nbsp;&nbsp; <UML:StructuralFeature.type>
56 <UML:DataType xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000786’/>
57 </UML:StructuralFeature.type>
58 </UML:Attribute>
59 <UML:Attribute xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007AF’
60 name = ’zona’ visibility = ’public’ isSpecification = ’false’ ownerScope = ’instance’
61 changeability = ’changeable’ targetScope = ’instance’>
62 <UML:StructuralFeature.multiplicity>
63 <UML:Multiplicity xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007BD’>
64 <UML:Multiplicity.range>
65 <UML:MultiplicityRange xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007BC’
66 lower = ’1’ upper = ’1’/>
67 </UML:Multiplicity.range>
68 </UML:Multiplicity>
69 </UML:StructuralFeature.multiplicity>
70 <UML:StructuralFeature.type>
71 <UML:DataType xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000786’/>
72 </UML:StructuralFeature.type>
73 </UML:Attribute>
74 </UML:Classifier.feature>
75 </UML:Class>
76 <UML:Association xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C2’
77 name = ’’ isSpecification = ’false’ isRoot = ’false’ isLeaf = ’false’ isAbstract = ’false’>
78 <UML:Association.connection>
79 <UML:AssociationEnd xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C3’
80 visibility = ’public’ isSpecification = ’false’ isNavigable = ’true’ ordering = ’unordered’
81 aggregation = ’composite’ targetScope = ’instance’ changeability = ’changeable’>
82 <UML:AssociationEnd.multiplicity>
83 <UML:Multiplicity xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C4’>
84 <UML:Multiplicity.range>
85 <UML:MultiplicityRange xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C5’
86 lower = ’1’ upper = ’1’/>
87 </UML:Multiplicity.range>
88 </UML:Multiplicity>
89 </UML:AssociationEnd.multiplicity>
90 <UML:AssociationEnd.participant>
91 <UML:Class xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:000000000000077C’/>
92 </UML:AssociationEnd.participant>
93 </UML:AssociationEnd>
94 <UML:AssociationEnd xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C6’
95 visibility = ’public’ isSpecification = ’false’ isNavigable = ’true’ ordering = ’unordered’
96 aggregation = ’none’ targetScope = ’instance’ changeability = ’changeable’>
97 <UML:AssociationEnd.multiplicity>
98 <UML:Multiplicity xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007CA’>
99 <UML:Multiplicity.range>
100 <UML:MultiplicityRange xmi.id = ’127-0-1-1--2d55673f:11c47d175d4:-8000:00000000000007C9’
101 lower = ’1’ upper = ’-1’/>
102 </UML:Multiplicity.range>
103 </UML:Multiplicity>
104 &nbsp;&nbsp; </UML:AssociationEnd.multiplicity>
44

105 <UML:AssociationEnd.participant>
106 <UML:Class xmi.idref = ’127-0-1-1--2d55673f:11c47d175d4:-8000:0000000000000792’/>
107 </UML:AssociationEnd.participant>
108 </UML:AssociationEnd>
109 </UML:Association.connection>
110 </UML:Association>
111 </UML:Namespace.ownedElement>
112 </UML:Model>
113 </XMI.content>
114 </XMI>
45

REFERÊNCIAS

BEZERRA, E. Princı́pios de Análise e Projeto de Sistemas com Uml. [S.l.]:


Campus, 2007.

DJANGO. Django — the web framework for perfectionists with deadlines.


http://www.djangoproject.com/.

LEFF AVRAHAM; RAYFIELD, J. T. Web-Application Development using the Mo-


del/View/Controller Design Pattern. , v.1, n.1, 2001.

MAURER, I. Python Web Frameworks, part 1: Develop for the Web with Django
and Python. , v.1, n.1, july 2006.

OMG. Object manager group - MOF 2.0/XMI Mapping, Version 2.1.1. , v.1, n.1,
2007.

You might also like