Professional Documents
Culture Documents
DEPARTAMENTO DE INFORMÁTICA
CURSO DE BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO
MARCOS D. PETRY
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 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
MVC Model-view-controller
ABSTRACT
1 INTRODUÇÃO
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 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)
2 CONCEITOS PRELIMINARES
• View: Gera a interface com usuário de modo que esta somente requisite o
processamento de eventos pelo Controller;
16
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.1 Atributos
2.3.1.2 Relacionamentos
2.3.1.3 Métodos
2.4.1 Exemplos
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.1 Exemplos
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
3 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
.
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:
3
404 Error. The Page Was Not Found
24
4 IMPLEMENTAÇÃO
• UML:Namespace.ownedElement
• UML:DataType
• UML:Class
• UML:Classifier.feature
• UML:Attribute
• UML:ModelElement.taggedValue
• UML:TaggedValue
• 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
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:
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]
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
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.
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.
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.
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)
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)
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”.
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
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
7 ANEXOS
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
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.