drawcode: um plugin do eclipse para a geraÇÃo...

102
UNIVERSIDADE REGIONAL DE BLUMENAU CENTRO DE CIÊNCIAS EXATAS E NATURAIS CURSO DE CIÊNCIAS DA COMPUTAÇÃO – BACHARELADO DRAWCODE: UM PLUGIN DO ECLIPSE PARA A GERAÇÃO DE CÓDIGO A PARTIR DE DIAGRAMAS DE CLASSE E DIAGRAMAS N-S ANDRÉ HENKELS BLUMENAU 2007 2007/2-04

Upload: trandang

Post on 13-Oct-2018

215 views

Category:

Documents


0 download

TRANSCRIPT

UNIVERSIDADE REGIONAL DE BLUMENAU

CENTRO DE CIÊNCIAS EXATAS E NATURAIS

CURSO DE CIÊNCIAS DA COMPUTAÇÃO – BACHARELADO

DRAWCODE: UM PLUGIN DO ECLIPSE PARA A GERAÇÃO

DE CÓDIGO A PARTIR DE DIAGRAMAS DE CLASSE E

DIAGRAMAS N-S

ANDRÉ HENKELS

BLUMENAU 2007

2007/2-04

ANDRÉ HENKELS

DRAWCODE: UM PLUGIN DO ECLIPSE PARA A GERAÇÃO

DE CÓDIGO A PARTIR DE DIAGRAMAS DE CLASSE E

DIAGRAMAS N-S

Trabalho de Conclusão de Curso submetido à Universidade Regional de Blumenau para a obtenção dos créditos na disciplina Trabalho de Conclusão de Curso II do curso de Ciências da Computação — Bacharelado.

Prof. Maurício Capobianco Lopes, MEng - Orientador.

BLUMENAU 2007

2007/2-04

DRAWCODE: UM PLUGIN DO ECLIPSE PARA A GERAÇÃO

DE CÓDIGO A PARTIR DE DIAGRAMAS DE CLASSE E

DIAGRAMAS N-S

Por

ANDRÉ HENKELS

Trabalho aprovado para obtenção dos créditos na disciplina de Trabalho de Conclusão de Curso II, pela banca examinadora formada por:

______________________________________________________ Presidente: Prof. Mauricio Capobianco Lopes, MEng – Orientador, FURB

______________________________________________________ Membro: Prof. Everaldo Artur Grahl, MEng – FURB

______________________________________________________ Membro: Prof. José Roque Voltolini da Silva – FURB

Blumenau, 07 de dezembro de 2007

Dedico este trabalho a toda minha família, em especial a dona Maurina que infelizmente pode acompanhar apenas o começo desta caminhada. Dedico também aos meus amigos, especialmente aqueles que me ajudaram diretamente na realização deste.

AGRADECIMENTOS

A minha noiva Luciane, pelo apoio que recebi durante toda a graduação. A sua

compreensão, principalmente durante a realização deste onde não lhe dei toda a atenção que

desejava.

Ao meu pai Floriano, pelo seu apoio e incentivo, indispensáveis durante toda esta

caminhada.

Ao meu irmão e herói Tarcisio, pelo apoio e companheirismo, principalmente pelas

madrugadas sem dormir, abrindo mão da sua família para me ajudar.

Aos irmãos Juliano e Susane e demais familiares, muito obrigado pelo carinho e apoio.

A todos os meus amigos da graduação, em especial Gustavo e Fabio, pelo

companheirismo durante toda esta caminhada.

Ao meu orientador Mauricio, que embora tivesse ficado com receio sobre o tema no

início, acreditou na conclusão deste trabalho. Obrigado pelo apoio, conhecimento e

experiência, compartilhados durante o andamento deste.

Ao professor Roque, pela idéia sobre o tema do trabalho e ajuda durante o andamento

do mesmo.

A professora Joyce pelas dicas sobre o motor de template e o analisador léxico.

A todos os demais professores, muito obrigado por todo o conhecimento que adquiri

com vocês durante todos estes anos da graduação.

Aos meus amigos de trabalho da Benner que seguraram as pontas para mim quando eu

desapareci da empresa para garantir o termino deste trabalho.

A todos os demais que eu possa ter esquecido, meu muito obrigado.

O valor das coisas não está no tempo que duram, mas na intensidade com que acontecem. Por isso existem momentos inesquecíveis, coisas inexplicáveis e pessoas incomparáveis.

Fernando Pessoa

RESUMO

Este trabalho apresenta o Drawcode, um plugin para o ambiente de desenvolvimento Eclipse cujo objetivo é a edição de diagramas de classe, diagramas N-S e geração de código a partir da associação destes dois tipos de diagramas. Depois de criados os diagramas é possível associar um método de uma classe a um diagrama N-S e gerar código para a linguagem Java das classes definidas, incluindo os atributos e corpo dos métodos associados a um diagrama N-S. Em ambos os diagramas a representação visual é atualizada a cada alteração para ajustar o tamanho dos elementos visuais dinamicamente conforme a necessidade. Para a geração dos gráficos e interatividade do usuário foi utilizado o Graphical Editing Framework (GEF), um subprojeto da Eclipse Foundation para facilitar a criação de plugins para o ambiente com interfaces visuais mais amigáveis. Para a geração de código foi utilizado o motor de templates Velocity.

Palavras-chave: Geração de código. Algoritmos. Diagramas N-S. Orientação a objetos. Diagramas de classe. Eclipse.

ABSTRACT

This work presents the Drawcode, a plug-in for Eclipse development environment. It’s purpose is to allow editing of the class diagrams, N-S diagrams and code generation from the association of these two types of diagrams. After the creation of diagrams, it’s possible to associate a method from a class to one N-S diagram and generate code to the Java language of the defined classes, including attributes, methods and body method when associated with one N-S diagram. In both diagrams, the visual representation is updated for every change to adjust the size of the visual elements. For the generation of graphics and user control was used Graphical Editing Framework (GEF), a subproject of the Eclipse Foundation to facilitate the creation of plug-in for the environment with more friendly visual interfaces. For code generation was used engine templates Velocity.

Key-words: Code generation. Algorithms. N-S diagrams. Object orientation. Class diagrams. Eclipse

LISTA DE ILUSTRAÇÕES

Figura 1- Exemplo de diagrama de classes simples .................................................................21

Figura 2 – Exemplos de representação de algoritmos ..............................................................23

Figura 3 - Exemplo de um comando de atribuição...................................................................25

Figura 4 - Exemplo de um comando de decisão.......................................................................25

Figura 5 - Exemplo de uma estrutura de seleção......................................................................25

Figura 6 - Exemplo de um comando de repetição ....................................................................26

Figura 7 - Exemplo de um bloco de comandos ........................................................................26

Figura 8 - Exemplo de uma estrutura de paralelismo...............................................................26

Figura 9 – Componentes de um compilador.............................................................................28

Figura 10 – Representação do funcionamento de um motor de templates ...............................31

Figura 11 – Diagrama de seqüência da ativação do plugin ......................................................33

Figura 12 – Visão geral do GEF...............................................................................................35

Figura 13 – Tela do aplicativo NSD Editor..............................................................................36

Figura 14 – Tela do aplicativo Structorizer ..............................................................................37

Figura 15 – Tela principal do plugin Jupe................................................................................39

Figura 16 – Editor de diagrama de classe do plugin TOPCASED...........................................40

Figura 17 - Requisitos funcionais do plugin.............................................................................41

Figura 18 - Requisitos não funcionais do plugin ......................................................................42

Figura 19 - Diagrama de casos de uso do plugin......................................................................42

Figura 20 - Classe principal do Drawcode ...............................................................................45

Figura 21 - Diagrama de classe do editor de diagramas de classe ...........................................46

Figura 22 - Diagrama de classes do editor de diagramas N-S..................................................49

Figura 23 - Diagrama de classe da manutenção do modelo e representação gráfica ...............52

Figura 24 – Diagrama de classe da geração de código.............................................................55

Figura 25 – Diagrama de seqüência da inclusão de um elemento no diagrama N-S ...............60

Figura 26 – Seqüência de inicialização da classe NSDiagramEditor.......................................61

Figura 27 – Diagrama de atividades do processo de inserção de elementos no modelo..........63

Figura 28 – Exemplo de representação gráfica de uma instrução simples...............................64

Figura 29 – Exemplo de representação gráfica de uma instrução de decisão ..........................64

Figura 30 – Exemplo de representação gráfica de uma instrução “for”...................................64

Figura 31 – Exemplo de representação gráfica de uma instrução “while”...............................65

Figura 32 – Exemplo de representação gráfica de uma instrução “repeat-until” .....................65

Figura 33 – Exemplo de representação gráfica de uma instrução de seleção...........................65

Figura 34 – Exemplo de representação gráfica de um diagrama N-S e sua lista de comandos66

Figura 35 – Diagrama de seqüência do processo de atualização gráfica do modelo................67

Figura 36 – Diagrama de atividades do processo de cálculo dos elementos visuais................69

Figura 37 – Seqüência para a geração de código do diagrama N-S .........................................70

Figura 38 – Seqüência de geração de código para o diagrama de classe .................................71

Figura 39 – Exemplo de template VTL de decisão com anotações..........................................72

Figura 40 – Iniciando o ambiente Eclipse: definir pasta de trabalho .......................................77

Figura 41 – Informações sobre os plugins instalados no ambiente ..........................................77

Figura 42 – Tela principal do ambiente Eclipse .......................................................................78

Figura 43 – Edição do diagrama de classe: incluindo uma classe com atributos e métodos....79

Figura 44 – Edição do diagrama N-S: definindo o algoritmo ..................................................80

Figura 45 – Associar um algoritmo representado por diagrama N-S para o método da classe 81

LISTA DE QUADROS

Quadro 1 – Exemplo de utilização da VTL..............................................................................32

Quadro 2 – Estrutura do arquivo plugin.xml .....................................................................34

Quadro 3 – Detalhes do caso de uso: editar diagrama de classe ..............................................44

Quadro 4 – Detalhes do caso de uso: editar diagrama N-S ......................................................44

Quadro 5 – Código completo da classe IfCommand..............................................................57

Quadro 6 – Conteúdo da interface ICommandVisitable ..................................................58

Quadro 7 – Conteúdo da interface ICommandVisitor .......................................................58

Quadro 8 – Parte da classe NSDiagramHandler ................................................................62

Quadro 9 – Método responsável por retornar a posição do elemento ......................................68

Quadro 10 – Template escrito na VTL para elemento de decisão gerando código Java..........71

Quadro 11 - Esquema representando o resultado do processamento de um elemento de decisão

...............................................................................................................................72

Quadro 12 – Implementação do método processChilds ..................................................73

Quadro 13 – Implementação do método processSingleCommand .................................74

Quadro 14 – Template criado com a tabela de tradução para a condição dos elementos.........75

Quadro 15 – Definições regulares criadas na ferramenta GALS .............................................76

Quadro 16 – Definições de tokens criados na ferramenta GALS.............................................76

Quadro 17 – Resultado da geração de código a partir do diagrama de classe..........................82

Quadro 18 – Comparativo entre Drawcode e seus correlatos ..................................................83

Quadro 19 - Template para a lista principal do diagrama N-S .................................................91

Quadro 20 - Template para os comandos simples, atribuições e chamadas de sub-rotinas .....91

Quadro 21 - Template para o comando de seleção...................................................................91

Quadro 22 - Template para as opções do comando de seleção ................................................91

Quadro 23 - Template para o comando de repetição com condição no final do laço de

repetição.................................................................................................................91

Quadro 24 - Template para o comando de repetição com número de repetições definido.......91

Quadro 25 - Template para o comando de repetição com condição no inicio do laço de

repetição.................................................................................................................92

Quadro 26 - Template para o comando de decisão...................................................................92

Quadro 27 - Template para a lista de comandos verdadeiros e falsos do comando de decisão92

Quadro 28 - Template para o lista de classes do diagrama de classes......................................93

Quadro 29 - Template criado para o elemento classe...............................................................93

Quadro 30 - Template criado para a lista de atributos da classe...............................................93

Quadro 31 - Template criado para o elemento atributo ............................................................93

Quadro 32 - Template criado para o elemento método ............................................................93

Quadro 33 - Template criado para lista de métodos da classe..................................................93

Quadro 34 - Template contendo a tabela de mapeamento para os comandos do tipo instrução

...............................................................................................................................94

Quadro 35 - Template com a tabela de mapeamento para as condições dos elementos do

diagrama N-S .........................................................................................................94

Quadro 36 – Operações das classes apresentadas na Figura 23 .............................................101

LISTA DE SIGLAS

DAS – Departamento de Automação e Sistemas

EA – Enterprise Architect

ECF – Ecole Centrale Paris

GALS – Gerador de Analisadores Léxicos e Sintáticos

GEF – Graphical Editing Framework

IBM – International Business Machines

MVC – Model View Controller

UML – Unified Modeling Language

VTL – Velocity Template Language

XML - eXtensible Markup Language

SUMÁRIO

1 INTRODUÇÃO..................................................................................................................15

1.1 OBJETIVOS DO TRABALHO ........................................................................................17

1.2 ESTRUTURA DO TRABALHO ......................................................................................18

2 FUNDAMENTAÇÃO TEÓRICA....................................................................................19

2.1 ORIENTAÇÃO A OBJETOS ...........................................................................................19

2.2 DIAGRAMA DE CLASSES.............................................................................................20

2.3 ALGORITMOS.................................................................................................................22

2.4 DIAGRAMAS N-S ...........................................................................................................24

2.5 GERADORES DE CÓDIGO ............................................................................................27

2.6 MOTORES DE TEMPLATES ...........................................................................................30

2.7 AMBIENTE DE DESENVOLVIMENTO ECLIPSE.......................................................32

2.7.1 Estendendo o ambiente de desenvolvimento ..................................................................32

2.7.2 Editores gráficos no ambiente Eclipse ............................................................................34

2.8 TRABALHOS CORRELATOS........................................................................................35

2.8.1 NSD Editor......................................................................................................................36

2.8.2 Structorizer......................................................................................................................37

2.8.3 Jupe .................................................................................................................................38

2.8.4 Topcased .........................................................................................................................39

3 DESENVOLVIMENTO DO PLUGIN.............................................................................41

3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO.......................41

3.2 ESPECIFICAÇÃO ............................................................................................................42

3.2.1 Diagrama de casos de uso ...............................................................................................42

3.2.2 Diagrama de classes do Drawcode..................................................................................45

3.2.2.1 Diagrama da principal classe do plugin ........................................................................45

3.2.2.2 Diagrama de classe do editor de diagrama de classes ..................................................46

3.2.2.3 Diagrama de classe do editor de diagrama N-S............................................................48

3.2.2.4 Diagrama de classes do gerador de código...................................................................54

3.3 IMPLEMENTAÇÃO ........................................................................................................55

3.3.1 Técnicas e ferramentas utilizadas....................................................................................56

3.3.1.1 Entendendo o modelo criado ........................................................................................56

3.3.1.2 Manutenção dos modelos de dados ..............................................................................59

3.3.1.3 Representação gráfica do diagrama N-S.......................................................................63

3.3.1.4 Geração de código ........................................................................................................69

3.3.2 Operacionalidade da implementação ..............................................................................76

3.4 RESULTADOS E DISCUSSÃO ......................................................................................82

4 CONCLUSÕES..................................................................................................................85

4.1 EXTENSÕES ....................................................................................................................86

REFERÊNCIAS BIBLIOGRÁFICAS .................................................................................88

APÊNDICE A – Templates criados na linguagem VTL para o diagrama N-S.................91

APÊNDICE B – Templates criados na linguagem VTL para o diagrama de classes .......93

APÊNDICE C – Relação dos templates da tabela de tradução...........................................94

APÊNDICE D – Relação de métodos das classes apresentadas na Figura 23 ..................95

15

1 INTRODUÇÃO

Os computadores vêm evoluindo constantemente desde a sua concepção: maior poder

de processamento e maior capacidade de armazenamento são apenas alguns exemplos na

parte de hardware. Porém, isto não vem ocorrendo apenas com hardware, pois aliado ao

aumento da capacidade computacional, os softwares vêm crescendo tanto em quantidade

como em complexidade, para os mais variados fins.

Basicamente um computador é uma máquina que executa instruções previamente

definidas, ou seja, apenas executa o que foi previamente programado para fazer, sendo que

assim é necessário organizar quais são e em que ordem o computador deve executar essas

instruções. Para atingir esta organização de instruções é necessário entender o problema e

organizá-lo de maneira que o computador possa executar sua resolução. Este processo é

dividido em várias etapas: analisar e entender o problema, criar a solução do problema em

uma determinada linguagem e transformar esta linguagem em instruções para o computador.

Este processo de transformação vem evoluindo constantemente, sendo que várias

linguagens e ferramentas estão sendo criadas com o objetivo de facilitar e ajudar a mapear o

conteúdo sobre determinada área do conhecimento de forma que o computador possa executar

instruções onde o resultado seja usado de alguma maneira pelo usuário do recurso

computacional, seja ele um humano, ou ainda outro computador.

O que motiva a construção de um programa é a necessidade do cliente. Para se

desenvolver um programa, o cliente indica o que o programa deve contemplar e executar por

meio de especificações chamadas de requisitos. No desenvolvimento, os requisitos do cliente

são traduzidos em especificações técnicas de software pelos analistas de sistema ou

engenheiros de software (SOUZA et al., 2005, p. 2).

Uma das preocupações da indústria de software é a necessidade de criar software e sistemas corporativos muito mais rapidamente e a um custo mais baixo. Para fazer bom uso da crescente potência dos computadores, precisamos de um software de maior complexidade. Ainda que mais complexo, esse software também precisa ser mais confiável. A alta qualidade é fundamental no desenvolvimento de software. (MARTIN; ODELL; 1996, p. 3).

Martin e Odell (1996, p. 5) afirmam que para atingir tal qualidade e rapidez é

necessária uma combinação de técnicas e ferramentas. Uma das técnicas mais utilizadas

atualmente é a orientação a objetos, que permite ter uma visão mais natural do problema nas

fases de análise e programação da solução. Tal técnica agrupa as informações conforme suas

características e comportamentos, possibilitando uma visão mais parecida com o mundo real

16

onde todas as coisas podem ser consideradas objetos, podendo ser formados por outros

objetos menores, distribuindo a responsabilidade da resolução do problema.

O software construído no estilo Orientado a Objetos (OO) pode ser descrito com a

ajuda da Unified Modeling Language (UML), que segundo Fowler (2005, p. 25) é uma

família de notações gráficas que ajudam na descrição e no projeto de sistemas de software. A

UML é formada por diversos diagramas, dentre os quais o diagrama de classes que descreve

os tipos de objetos presentes no software e os relacionamentos entre eles. Um dos elementos

presentes no diagrama de classes são as operações que a classe possui, ou seja, são os

problemas que a classe sabe resolver (FOWLER, 2005, p. 33).

Para determinar como a operação de uma classe chega à solução do problema é

possível construir um algoritmo. Um algoritmo é um conjunto de regras finito, numa

determinada ordem de execução, onde cada regra tem determinado significado segundo

alguma convenção (uma linguagem de programação, por exemplo). A associação destas

regras permite a solução de um problema computacional qualquer (SOUZA et al. 2005, p. 4).

É possível representar algoritmos de várias maneiras. Souza (2000, p. 21) cita:

fluxogramas, português estruturado, pseudocódigo, diagrama de Nassi-Shneiderman (N-S) e

diagrama de ações. Alguns são representações textuais e outras gráficas. A representação

visual facilita a estruturação do raciocínio e, consequentemente, minimiza o esforço para

obtenção da solução do problema (SOUZA, 2000, p. 9).

Uma das notações para representação gráfica do algoritmo é o diagrama N-S, que

apresenta como vantagens domínio funcional bem definido e claramente visível,

impossibilidade de transferência de controle arbitrária, escopo dos dados facilmente

determinado e a recursividade é bem representada.

Definido o algoritmo para a solução do problema e representado através do diagrama

(N-S), é preciso codificar a solução de maneira que o computador possa tratar os dados e

processar a solução, escrevendo a solução em alguma linguagem de programação para

posterior compilação e geração de instruções que o computador possa executar. Geralmente

esta etapa é feita manualmente, entretanto, Martin e Odell (1996, p. 7) afirmam que sempre

que possível, os programas devem ser gerados utilizando técnicas de geração de código que

permitem produzir código sem nenhum erro de sintaxe a partir do projeto.

Herrington (2003, p. 15) afirma que técnicas de geração de código podem trazer

benefícios como: consistência ao definir um padrão para nomes de variáveis, produtividade

para o desenvolvimento de programas onde classes são geradas rapidamente e qualidade, pois

o código gerado é uniforme e superior ao criado numa codificação manual. Tal técnica

17

também possibilita abstração em nível de linguagem, sendo possível gerar programas em

outras linguagens de programação utilizando templates, sem comprometer a lógica envolvida.

Assim, este trabalho propõe a criação de uma ferramenta que possibilite a edição de

diagramas de classes, permitindo definir um algoritmo para as operações das classes criadas

usando diagramas N-S e possibilitando ainda gerar código para a linguagem Java, utilizando

para isso a técnica de templates1. No diagrama de classes serão editados apenas o nome da

classe, os atributos e métodos, não sendo tratados as demais representações deste tipo de

diagrama como associações, agregação, herança, entre outros, que serão tratados como

extensões do mesmo.

1.1 OBJETIVOS DO TRABALHO

O objetivo deste trabalho é desenvolver uma ferramenta gráfica e interativa que

possibilite a edição de atributos e métodos em diagramas de classe, permitindo criar para cada

método/operação das classes do diagrama de classes, um diagrama N-S, que vai representar o

algoritmo para alcançar o resultado planejado para este método. A partir desta associação de

um diagrama N-S para cada o método da classe, será gerado o código para a classe, incluindo

a assinatura, os atributos e o corpo do método.

Os objetivos específicos do trabalho são:

a) permitir que o usuário possa criar diagramas de classe;

b) permitir que o usuário possa criar diagramas N-S;

c) gerar código na linguagem Java para o corpo dos métodos utilizando templates;

d) utilizar a técnica de plugins2 para o ambiente Eclipse3.

1 Template é uma técnica que consiste em montar um texto com algumas anotações especiais, onde determinado programa vai processar este texto, substituindo tais anotações por outra informação. 2 Plugin é um programa de computador que serve normalmente para adicionar funções a outros programas maiores, provendo alguma funcionalidade especial ou muito específica (PLUGIN, 2007). 3 Eclipse é um ambiente de desenvolvimento de código aberto para a construção de programas de computador (ECLIPSE FOUNDATION, 2007a).

18

1.2 ESTRUTURA DO TRABALHO

Este trabalho está divido em quatro capítulos. O primeiro capítulo apresenta uma

introdução sobre o contexto que o plugin está envolvido. Já no segundo capítulo é apresentada

a fundamentação teórica envolvida na idealização do mesmo, assim como algumas

ferramentas correlatas. O terceiro capítulo apresenta detalhes sobre o desenvolvimento,

informações sobre como o problema foi modelado e dividido e quais técnicas foram utilizadas

na sua construção. No quarto capítulo são apresentadas algumas discussões sobre os

resultados, comparações com seus correlatos, limitações existentes e extensões futuras.

19

2 FUNDAMENTAÇÃO TEÓRICA

Neste capítulo são apresentados os principais assuntos relacionados ao

desenvolvimento deste projeto, sendo: orientação a objetos, diagramas de classe, algoritmos,

diagramas N-S, geração de código, motores de templates, ambiente de desenvolvimento

Eclipse e alguns trabalhos correlatos.

2.1 ORIENTAÇÃO A OBJETOS

A orientação a objetos é um paradigma4 de análise, projeto e programação de sistemas

baseado na composição e interação entre diversas unidades de software chamadas de objetos

(ORIENTAÇÃO A OBJETO, 2007).

Em outras palavras, o objetivo é identificar e classificar as informações que fazem

parte do software e organizá-las em grupos, conforme suas características e comportamentos,

apresentando quais objetos fazem parte do software. Neste modelo um software pode ser

descrito como vários objetos distintos que interagem entre si. A interação entre estes objetos

será o resultado final do software.

Mas, o que é um objeto? Tonsig (2003, p. 166) apresenta a seguinte definição de

objeto: “Objeto é a representação de elementos físicos do mundo real, que sob o ponto de

vista do problema a ser resolvido, possuem atributos e métodos comuns”. Portanto, um objeto

é composto por atributos que representam suas características e métodos que são suas

atividades. Normalmente um software é composto por uma grande quantidade de objetos, que

são agrupados em classes de objetos. Uma classe representa um conjunto de objetos com as

mesmas características e comportamentos (TONSIG, 2003, p. 167).

Para ajudar a entender estas classes de objetos e como elas se relacionam no contexto

do software a UML prevê alguns diagramas (PILONE, PITMAN, 2006, p. 5), os quais são

exemplos:

a) diagramas de classes: apresentam as classes existentes no software e de que

maneira elas se relacionam;

20

b) diagrama de componentes: mostram a organização e as dependências envolvidas

na implementação do sistema. Agrupam elementos menores como as classes em

elementos maiores;

c) diagrama de estruturas compostas: demonstram a ligação entre os diagramas de

classe e os diagramas de componentes;

d) diagramas de pacote: são tipos especiais de diagramas de classe, utilizando a

mesma notação, porém com foco em como classes e interfaces estão agrupadas;

e) diagramas de objetos: utilizam a mesma sintaxe do diagrama de classe e tem como

objetivo demonstrar o relacionamento entre elementos em determinado momento

da execução do software;

f) diagrama de atividade: demonstram o fluxo de comportamento de determinada

classe de objetos;

g) diagrama de comunicação: demonstram as mensagens trocadas entre os objetos

que compõem o software;

h) diagrama de seqüência: apresentam os elementos envolvidos, o tipo e a ordem das

mensagens enviadas entre os elementos durante a execução do software.

Neste trabalho será dada ênfase ao Diagrama de Classes.

2.2 DIAGRAMA DE CLASSES

O diagrama de classes representa os objetos presentes no sistema, seus

atributos/propriedades, suas operações e os relacionamentos existentes entre os objetos

utilizados na construção do software. Ele demonstra atributos e operações, apresentando sua

visibilidade, indicando se podem ser acessados de fora da classe ou apenas internamente. Um

exemplo de diagrama de classes pode ser visto na Figura 1, onde também é apresentado o

significado das notações utilizadas no diagrama.

4 Um paradigma de programação fornece e determina a visão que o programador possui sobre determinado software e mostra como este software está dividido (PARADIGMA DE PROGRAMAÇÃO, 2007).

21

Fonte: adaptado de Fowler (2005, p. 53).

Figura 1- Exemplo de diagrama de classes simples

No diagrama apresentado na Figura 1 são descritas sete classes. É possível visualizar o

relacionamento de agregação entre a classe Pedido e a classe ItenPedido, representado por

um losango mais próximo a classe Pedido. É possível ainda observar que existe uma

associação entre as classes Pedido e Cliente indicando também a multiplicidade existente

nesta associação onde um cliente pode ter vários pedidos, porém um pedido pode pertencer a

apenas um cliente.

Neste mesmo diagrama ainda é possível visualizar uma generalização envolvendo as

classes Cliente, ClienteCorporativo e ClientePessoal, onde a classe Cliente possui as

características comuns aos dois tipos de cliente corporativo e pessoal. Pode ser observado

também que a classe ClienteCorporativo além de herdar da classe Cliente alguns

atributos e operações, possui seus próprios atributos e operações.

Neste trabalho é explorada apenas a representação das classes e seus atributos e

métodos. Nenhum tipo de relacionamento entre as classes é tratado.

22

2.3 ALGORITMOS

Segundo Carboni (2003, p. 12-24), existem várias formas de descrever a lógica para

solução de um problema e uma das mais utilizadas é o algoritmo, com suas formas de

representação. O algoritmo pode ser considerado uma seqüência de procedimentos finitos que

serão executados em determinada ordem para atingir certo objetivo.

O nível de complexidade do algoritmo varia de acordo com o tamanho do problema

que este visa resolver. Problemas simples são facilmente representados num fluxograma, em

contrapartida algoritmos com um nível de complexidade maior necessitam de algum tipo de

divisão do problema em problemas menores. Souza (2000, p. 15) afirma que para minimizar a

complexidade utiliza-se o conceito de abstração considerando apenas os dados que são

realmente relevantes para a solução do problema atual, e o método de refinamentos sucessivos

onde o problema é decomposto em problemas menores, caracterizando algoritmos formados

por outros algoritmos menores.

Existem duas técnicas principais adotadas para o desenvolvimento de algoritmos,

sendo elas a abordagem estruturada e a orientada a objetos. A abordagem estruturada visa

decompor o problema inicial em problemas menores, utilizando um conjunto de construções

lógicas simples, onde qualquer algoritmo possa ser elaborado. A abordagem orientada a

objetos trata o problema como um conjunto de objetos que interagindo entre si vão chegar à

resolução do problema, onde cada objeto agrupa seus respectivos dados e funções (SOUZA,

2000, p. 17-19).

A pesquisa na literatura e a prática em universidades brasileiras demonstraram ser a metodologia de Resolução Estruturada de Problemas aquela mais utilizada para elaboração dos algoritmos. Por outro lado, conclui-se também que a Resolução Orientada a Objetos pode fazer uso da metodologia Resolução Estruturada para especificação dos métodos da classe, visto que aquela não apresenta técnica específica para elaboração dos algoritmos que os formam. (SOUZA, 2000, p. 42).

Souza (2000, p. 20) afirma que as técnicas de diagramação estruturada ajudam os

desenvolvedores de algoritmos a manipularem um grande número de detalhes gerados durante

o processo de elaboração da solução de um problema. Existem ferramentas para a criação e

representação de algoritmos, sendo as mais utilizadas:

a) fluxogramas: foi um dos primeiros e mais usados métodos para diagramação,

tendo sido utilizado pela maioria dos programadores e analistas de sistemas antes

do surgimento dos métodos de resolução estruturada;

23

b) português estruturado: é uma ferramenta hierarquicamente estruturada, que utiliza

margens para demonstrar a estrutura e apresenta forma análoga à linguagem

escolhida para implementação do algoritmo. Utiliza palavras-chave para formalizar

o algoritmo e apresenta como vantagem, a facilidade para elaboração;

c) pseudocódigo: utiliza as mesmas diretrizes do português estruturado, porém faz

uso de uma notação mais formal, orientada a profissionais da informática, enquanto

o português estruturado é mais bem compreendido por usuários;

d) diagrama de ações: são ferramentas que utilizam recursos visuais e foram

projetadas para relacionar ações ao modelo de dados. Pode apresentar uma visão

mais geral ou mais detalhada do algoritmo desenvolvido, demonstrando sua

estrutura hierárquica;

e) diagrama N-S: apresenta uma estrutura hierárquica e fornece a visão detalhada do

algoritmo. Apresenta como estrutura básica o retângulo, a partir do qual as demais

estruturas são desenhadas.

O diagrama é uma forma visual de representação do conhecimento. Com o aumento da

complexidade dos programas criados, o processo de criação de software necessita de

ferramentas que auxiliem na representação do problema, com o intuito de amenizar a

complexidade de mesmo, sendo que os diagramas visam facilitar o entendimento do

problema.

Na Figura 2 são apresentadas duas representações distintas para o mesmo algoritmo.

Um algoritmo que soma três valores, calcula a média e se o resultado é maior que seis, tem

como resultado a string “aprovado”. Caso contrário, tem como resultado a string “reprovado”.

Na primeira representação é apresentado o algoritmo na forma de um diagrama N-S. Já na

segunda forma, o mesmo algoritmo é representado na linguagem Java.

Figura 2 – Exemplos de representação de algoritmos

24

2.4 DIAGRAMAS N-S

O diagrama N-S foi apresentado em 1973 por Isaac Nassi e Ben Shneiderman (NASSI;

SHNEIDERMAN, 1973). Segundo eles, os programas de computador passam por várias

fases: entendimento do problema, formulação e definição da solução e codificação do

software. Nestas fases um fluxograma ou diagrama pode ser criado para ajudar no

entendimento do problema abstraindo fases posteriores da solução do problema como a

codificação em uma linguagem de programação, por exemplo.

Conforme Martin e Mcclure (1991, p. 256), “Diagramas de I. Nassi e B. Shneiderman

(N-S) representam estruturas de programas que tem um ponto de entrada e um ponto de saída

e são compostos pelas estruturas básicas de controle de seqüência, seleção e repetição.” Esse

diagrama é formado por um retângulo que representa o algoritmo para a solução de

determinado problema utilizando estruturas de seleção, repetição e a ordem das ações a serem

executadas.

Os diagramas N-S são melhores para representar a solução estruturada de um

algoritmo que os fluxogramas, pois esses dão uma visão não estrutural do problema e tendem

a apresentar muitos saltos. “Enquanto é difícil mostrar o embutimento e a recursividade com o

fluxograma tradicional, é fácil mostrá-los com um diagrama N-S. É fácil, também, converter

um diagrama N-S em código estruturado” (MARTIN; MCCLURE, 1991, p. 256).

Nassi e Shneiderman (1973) citam as seguintes vantagens do diagrama N-S sobre os

fluxogramas:

a) escopo das iterações é bem definido e visível;

b) escopo dos comandos de decisão são bem definidos e visíveis, apresentando em

destaque a condição de decisão;

c) escopo de variáveis globais e locais é facilmente observado;

d) não existe transferência de controle arbitrária;

e) a recursividade tem uma representação muito simples.

Conforme Souza (2000, p. 25) os diagramas N-S apresentam como desvantagem o

problema do dimensionamento das estruturas, que normalmente obriga o desenvolvedor a

redesenhá-lo novamente, consumindo muito tempo na sua elaboração.

Porém é possível eliminar, ou ao menos minimizar este problema utilizando-se de

ferramentas computacionais que automaticamente redimensionem o diagrama conforme a

necessidade.

25

O diagrama N-S é formado por seis elementos básicos, sendo eles: processo, decisão,

repetição, bloco, paralelo e seleção. Basicamente todos os elementos são representados por

retângulos, sendo que cada um deles apresenta particularidades no seu interior.

O símbolo de processo serve para indicar uma ação a ser executada, a qual pode ser um

método a ser invocado ou uma atribuição. É basicamente um retângulo com o seu respectivo

comando dentro. Um exemplo deste símbolo pode ser visto na Figura 3.

Fonte: adaptado de Nassi e Shneiderman (1973).

Figura 3 - Exemplo de um comando de atribuição

O símbolo de decisão serve para indicar uma expressão lógica a ser verificada para

desviar o fluxo de execução do algoritmo em duas possibilidades. Se a expressão for

verdadeira uma coluna de execução é seguida, caso contrário, outra coluna de execução é

seguida. Um exemplo deste símbolo pode ser visto na Figura 4.

Fonte: adaptado de Nassi e Shneiderman (1973).

Figura 4 - Exemplo de um comando de decisão

Outro símbolo que faz parte do diagrama N-S é o que representa a seleção. Este

símbolo representa para o algoritmo que com base no valor de determinada variável, uma das

colunas de execução será seguida. Cada uma das colunas de execução tem um valor que a

representa. Caso o valor da variável definida para ser analisada não seja igual a uma das

colunas, uma coluna de execução padrão é seguida. Um exemplo deste símbolo pode ser visto

na Figura 5.

Fonte: adaptado de Nassi e Shneiderman (1973).

Figura 5 - Exemplo de uma estrutura de seleção

26

O símbolo de repetição serve para indicar um grupo de comandos a serem executadas

até que determinada expressão lógica deixe de ser verdadeira. São de dois tipos, sendo que no

primeiro tipo a expressão fica antes da lista de comandos e o segundo é quando a expressão

fica depois da lista de comandos. Desta maneira quando a condição está depois da lista de

comandos, isto significa que aquela lista vai ser executada pelo menos uma vez. Um exemplo

deste símbolo com a expressão lógica antes da lista de comandos pode ser visto na Figura 6.

Fonte: adaptado de Nassi e Shneiderman (1973).

Figura 6 - Exemplo de um comando de repetição

O símbolo de bloco serve para agrupar uma lista de comandos a serem executados

formando um bloco, sendo que existe uma marcação para o início do bloco e outra para

indicar o final do bloco. Um exemplo deste símbolo pode ser visto na Figura 7.

Fonte: adaptado de Nassi e Shneiderman (1973).

Figura 7 - Exemplo de um bloco de comandos

Por último existe o símbolo de paralelismo, indicando que o algoritmo em determinado

ponto vai ter mais de uma linha de execução. Indica que novas linhas de execução serão

criadas e serão seguidas ao mesmo tempo, retornando a uma única no término de cada uma

das linhas. Um exemplo deste símbolo pode ser visto na Figura 8.

Fonte: Nassi e Shneiderman (1973).

Figura 8 - Exemplo de uma estrutura de paralelismo

27

2.5 GERADORES DE CÓDIGO

O desenvolvimento de um programa torna-se mais fácil se a linguagem utilizada para

sua criação estiver mais próxima do problema a ser resolvido, ou seja, se a linguagem

apresenta construções que refletem a terminologia e/ou elementos usados na descrição do

problema. Este tipo de linguagem é chamada de linguagem de alto nível, porém computadores

apenas entendem sua própria linguagem de máquina, chamada de linguagem de baixo nível,

que geralmente é formada por uma seqüência de zeros e uns (PRICE; TOSCANI, 2001, p. 1).

Para que se tornem operacionais para os computadores, programas escritos em

linguagens de alto nível devem ser traduzidos para linguagem de máquina. Esta tradução é

realizada por programas especializados nesta tarefa, chamados de compiladores ou

interpretadores. Estes têm como entrada uma representação textual do algoritmo, tendo como

saída o mesmo algoritmo expresso em outra linguagem (PRICE; TOSCANI, 2001, p. 1).

A complexidade envolvida neste processo determina a divisão em processos menores

interconectados, exigindo vários componentes para a sua formação, os quais são:

a) analisador léxico: analisa a seqüência de caracteres de entrada e traduz em tokens

da linguagem alvo, que serão utilizados pelo analisador sintático (SOUZA 2000, p.

53);

b) analisador sintático: verifica se a estrutura gramatical do programa criado está

correto conforme as regras gramaticais definidas para a linguagem de programação

utilizada na construção do programa (SOUZA 2000, p. 53);

c) analisador semântico: faz a verificação dos tipos utilizados no programa. Checa se

cada operador recebe os operandos permitidos conforme a especificação da

linguagem (AHO; SETHI; ULLMAN, 1995, p. 4);

d) gerador de código intermediário: gera uma representação intermediária do

programa fonte (AHO; SETHI; ULLMAN, 1995, p. 7);

e) otimizador de código: atua sobre o código intermediário, com o objetivo de

melhorá-lo, tendo como resultado ao final de todo o processo, código de máquina

mais otimizado (AHO; SETHI; ULLMAN, 1995, p. 7);

f) gerador de código: responsável por gerar o código alvo (AHO; SETHI; ULLMAN,

1995, p. 7);

g) gerenciador de tabela de símbolos: responsável por manter uma tabela com os

símbolos encontrados no programa fonte e demais informações necessárias. É

28

utilizado pelos outros componentes do processo de compilação (SOUZA 2000, p.

53);

h) manipulador de erros: responsável por tratar os erros encontrados por cada um dos

componentes da compilação (SOUZA 2000, p. 53).

A Figura 9 apresenta uma representação dos componentes presentes no compilador.

Fonte: Souza (2000, p. 54).

Figura 9 – Componentes de um compilador

A geração de código pode ou não estar precedida de todas as etapas anteriores,

dependendo do tipo de geração de código que se deseja fazer. Um gerador de código pode ser

um simples formatador de código ou uma ferramenta que gere uma aplicação a partir de

modelos abstratos. De acordo com Herrington (2003, p. 3), as vantagens de se utilizar

geradores de código para o desenvolvimento de software são:

a) qualidade: código escrito manualmente tende a ter um nível de qualidade muito

irregular visto que, durante o desenvolvimento da aplicação, podem ser propostas

melhores abordagens para solucionar os problemas, além de depender da

experiência e boas práticas de programação do programador;

b) produtividade: quando são usados geradores no projeto de software, o volume de

29

código produzido manualmente é bem menor se comparado a outro projeto sem o

uso dessas ferramentas. Sendo assim, tem-se mais tempo para outras etapas do

projeto;

c) abstração: a definição de templates é bem mais simplificada que o código alvo.

Com o uso de templates pode-se corrigir erros do projeto ou incluir novas

funcionalidades apenas reescrevendo os templates. Além disso, o gerador pode ser

facilmente reprojetado para outras linguagens ou tecnologias.

Herrington (2003, p. 61-94) apresenta 5 tipos de geração de código, sendo:

a) formatação de código (code munger): é o mais simples dos modelos de geradores,

tendo como entrada um código fonte escrito em alguma linguagem de alto nível, e

apresenta na saída um ou mais arquivos que podem ser documentação, ou ainda

uma extensão do código;

b) expansão de código (inline code expander): permite simplificar o código fonte.

Tem como entrada um código fonte em uma linguagem de alto nível anotado com

algum tipo de marcação que, na execução do gerador, será substituído por código

da linguagem fonte. A saída é código fonte na mesma linguagem da entrada. O

código não pode ser compilado antes da execução do gerador;

c) geração mista (mixed code generator): é uma implementação mais prática que o

modelo de expansão de código. Tem como entrada código fonte em uma

linguagem de alto nível, com marcações feitas utilizando comentários. Tem como

saída código na mesma linguagem de entrada. O código de entrada e o código de

saída podem ser diretamente compilados;

d) geração parcial de classes (partial class generator): este tipo constrói código a

partir de modelos abstratos. Ele tem como entrada uma descrição abstrata dos

requisitos de código e constrói um conjunto de classes que deve ser estendido com

a implementação dos métodos ou subclasses (classes derivadas) para criar a

aplicação completa;

e) geração de camadas de aplicação (tier generator): este tipo de geração constrói

todo o código necessário para um camada da aplicação. Tem como entrada uma

definição abstrata de toda a informação necessária para criar o código completo de

uma camada da aplicação. Utilizando a definição abstrata com um conjunto de

templates, a saída é criada.

Depois de definido qual tipo de gerador é o mais apropriado para a solução, existem

passos a serem observados para a construção do gerador de código sendo (HERRINGTON,

30

2003, p. 93):

a) escrever o código alvo manualmente: determinar qual será a saída do gerador;

b) projetar o gerador: determinar como será a entrada do gerador, como a entrada será

analisada e como o código de saída será gerado;

c) desenvolver a entrada: implementar como as informações de entrada do gerador

serão extraídas;

d) desenvolver a saída: implementar o processamento dos dados de entrada e criar a

saída conforme apresentado na primeira etapa.

A geração de camada de aplicação faz uso do conceito de template. Um template é

basicamente um arquivo texto com marcações especiais. Tais marcações devem ser feitas

levando em consideração o motor que vai ser utilizado, por que o arquivo de template

unicamente não é utilizado. Ele deve ser usado em conjunto com um motor de templates.

2.6 MOTORES DE TEMPLATES

O motor de template é um artefato de software que possibilita a junção de um conjunto

de informações a um arquivo de template. O resultado da ação do motor será a união do

código dinâmico com o código estático. Código estático é o que está definido de forma fixa

no template e código dinâmico são as variáveis que o motor vai tratar e substituir por valores

que recebeu como entrada.

A Figura 10 apresenta uma representação gráfica do funcionamento de um motor de

templates.

31

Fonte: Template Processor (2007).

Figura 10 – Representação do funcionamento de um motor de templates

Segundo Rocha (2005), os motores de templates são mecanismos que permitem

desenvolver geradores de código independentes do código alvo já que este está externo à

aplicação. Deve existir um programa responsável por instanciar o motor, carregar os valores

das variáveis e blocos especiais.

Cada motor implementa sua própria linguagem através da qual os templates deverão

ser escritos. Esta linguagem define os tipos de blocos especiais e como referenciar variáveis e

varia bastante em nível de complexidade, podendo ser definida apenas com estruturas básicas

para substituição de valores de variáveis ou até ter estruturas de controle mais complexas

como loops e comandos condicionais (ROCHA, 2005).

Um dos motores de templates existentes é o Velocity da Apache Software Foundation.

Foi escrito na linguagem Java, sendo um projeto de código aberto. Suas indicações são as

seguintes (APACHE SOFTWARE FOUNDATION, 2007a):

a) aplicações web: criar páginas com informações dinâmicas;

b) geração de código: pode gerar código baseado em modelos;

c) geração automática de correio eletrônico: corpo padrão da mensagem é

armazenado em template e as demais informações são geradas dinamicamente;

d) transformação XML: permite ler diretamente arquivos XML e fazer a

transformação necessária conforme descrito no template.

Ele provê um objeto chamado de contexto, sendo que o mesmo é na verdade uma

32

tabela de objetos, que é utilizado para mesclar as informações estáticas presentes no arquivo

de template com as informações dinâmicas fornecidas ao Velocity pelo programa que fez sua

inicialização (APACHE SOFTWARE FOUNDATION, 2007a).

Os arquivos de template, criados para serem utilizados junto ao Velocity, devem ser

escritos conforme a Velocity Template Language, ou simplesmente VTL. A VTL provê

comandos para controlar o funcionamento do motor no momento do processamento do

arquivo de template. Existem comandos para laços de repetição, condições a serem analisadas

pelo motor, ou ainda a definição de variáveis. O Quadro 1 mostra a construção de uma

condição utilizando a VTL. No momento que o motor processa o arquivo de template, se a

variável foo for igual a variável bar, é produzido como saída “it’s true!”, caso contrário “it’s

not!” (APACHE SOFTWARE FOUNDATION, 2007b).

#if( $foo == $bar)it's true!#{else}it's not!#end Fonte: Apache Software Foundation (2007b).

Quadro 1 – Exemplo de utilização da VTL

Mais informações sobre a VTL podem ser encontradas na guia de referência da VTL,

no site da Apache Software Foundation (APACHE SOFTWARE FOUNDATION, 2007b).

2.7 AMBIENTE DE DESENVOLVIMENTO ECLIPSE

O Eclipse é um projeto de código fonte aberto com o objetivo de criar uma plataforma

de desenvolvimento composto de várias partes extensíveis e ferramentas para apoiar a

construção, implantação e todo o ciclo de desenvolvimento de programas. Foi originalmente

criado pela International Business Machines (IBM) e a partir de janeiro de 2004 se tornou

uma fundação sem fins lucrativos a fim de apoiar a criação de comunidades de

desenvolvimento em torno do projeto Eclipse (ECLIPSE FOUNDATION, 2007c).

2.7.1 Estendendo o ambiente de desenvolvimento

O Eclipse foi projetado para ser amplamente extensível, assim o mesmo provê alguns

mecanismos que permitem serem adicionadas funcionalidades ao ambiente de

desenvolvimento. Estas partes criadas para serem conectadas ao ambiente são chamadas de

33

plugins.

Basicamente, um plugin é um conjunto de funcionalidades a ser integrada ao Eclipse.

Esse deve ser criado acompanhado de um arquivo plugin.xml, que define como deve ser tal

integração. Esse arquivo define desde informações básicas (como nome, fornecedor) até

dados importantes para a integração com o Eclipse (extensões, pontos de extensão). O plugin

por sua vez costuma conter um conjunto de classes Java (para criar um editor, por exemplo),

mas pode conter também outros tipos de arquivo, como páginas html (para estender a Ajuda)

ou simples arquivos de dados (BARROS et al., 2003).

Quando o ambiente é inicializado, o mesmo carrega todos os arquivos plugin.xml do

diretório plugins e os mantém em memória durante todo o tempo de execução e havendo

necessidade, as classes de ativação de cada plugin são carregadas. O diagrama de seqüência

apresentado na Figura 11 demonstra de que forma o plugin é ativado.

Figura 11 – Diagrama de seqüência da ativação do plugin

O arquivo plugin.xml traz as principais informações sobre o funcionamento do plugin

para o ambiente Eclipse. Um exemplo deste arquivo pode ser verificado no Quadro 2.

34

<plugin> <extension point="org.eclipse.ui.editors"> ->ponto de extensão utilizado <editor ->definição de um novo editor class="NSDiagramEditor" ->classe responsável extensions="nsd" ->extensão de arquivo a ser usado icon="icons/drawcode/graphics/nsd.png" id="NSDiagramEditor" name="N-S Diagram Editor"> ->nome do editor </editor> </extension> <extension point="org.eclipse.ui.popupMenus"> ->ponto de extensão utilizado <viewerContribution ->definição de uma nova contribuição visual id="NSCodeGeneration" targetID="NSDiagramEditor"> <action class="NSCodeGeneration" ->classe responsável definitionId=" NSCodeGeneration" icon="icons/drawcode/codegeneration2.png" id=" NSCodeGeneration" label="Generate from NS-Diagram" menubarPath="additions"> </action> </extension> </plugin>

Quadro 2 – Estrutura do arquivo plugin.xml

O ambiente oferece um grande número de pontos de extensão já existentes que

possibilitam incluir menus e opções praticamente em todas as suas partes. Além disso, é

possível criar os seus próprios pontos de extensão para serem utilizados por outros plugins.

Mais informações sobre os pontos de extensão existentes e seu funcionamento podem ser

encontradas diretamente no site da Eclipse Foundation (ECLIPSE FOUNDATION, 2007a).

2.7.2 Editores gráficos no ambiente Eclipse

Um dos sub-projetos da Eclipse Foundation é o Graphical Editing Framework, ou

simplesmente GEF. O GEF é um framework cujo objetivo é permitir que os desenvolvedores

criem aplicações mais ricas graficamente a partir dos seus modelos. É baseado no padrão de

projeto Model, View, Controler (MVC) e fornece funcionalidades para controlar alterações no

modelo, criar uma representação gráfica do mesmo e permitir que alterações feitas na

representação visual sejam propagadas para o modelo e vice-versa.

Internamente o GEF utiliza-se ainda de outro framework, o Draw2d que provê a parte

gráfica, como o desenho de linhas ou círculos e quadrados e as estruturas gráficas básicas para

a criação da representação visual de algum elemento do modelo.

35

A Figura 12 demonstra uma visão geral do GEF, onde o mesmo pode ser definido

como a região central. O framework provê a ligação entre o modelo da aplicação e sua

visualização, onde as ações executadas pelo usuário são tratadas e transformadas em eventos e

comandos. Estes eventos e comandos são usados para encapsular as interações do usuário e

seus efeitos junto ao modelo (ECLIPSE FOUNDATION 2007d).

Fonte: ECLIPSE FOUNDATION (2007d). Figura 12 – Visão geral do GEF

2.8 TRABALHOS CORRELATOS

Para o desenvolvimento deste trabalho foram pesquisadas algumas ferramentas

correlatas que possibilitam a edição de diagramas de classe e N-S, assim como a geração de

código. Serão apresentadas duas ferramentas que possibilitam a edição de diagramas N-S e a

geração de código do mesmo. Serão apresentadas também duas ferramentas que permitem

editar diagramas de classe e posteriormente gerar código para o mesmo.

Durante a pesquisa não foram encontradas ferramentas criadas na forma de plugin para

o ambiente Eclipse que possibilitassem a edição de diagramas N-S e/ou geração de código.

Assim foram pesquisadas as ferramentas NSD Editor e Structorizer.

Para a edição de diagramas de classe as ferramentas pesquisadas são plugins para o

ambiente Eclipse e ambas com o código aberto, sendo elas Jupe UML Plugin for Eclipse e o

36

TopCased.

2.8.1 NSD Editor

Kalt (1996) apresenta o NSD Editor, sendo um editor de diagramas N-S criado no

ambiente Borland Delphi. Dá suporte às instruções de chamada de sub-rotina, atribuição,

decisão e laços de repetição. Permite salvar os diagrama em disco e posteriormente abri-los.

Redimensiona os elementos visuais conforme a necessidade automaticamente e permite gerar

código para as linguagens C e Pascal.

A Figura 13 mostra a tela principal do aplicativo. Nela é possível clicar num novo

elemento a ser inserido no diagrama e arrastar em cima do diagrama e soltar o novo elemento.

Conforme é movimentado o mouse o aplicativo vai sinalizando o ponto exato da inserção do

novo elemento.

Figura 13 – Tela do aplicativo NSD Editor

37

2.8.2 Structorizer

Este aplicativo é um editor para diagramas N-S, criado na linguagem pascal com o

código fonte aberto. Possui compilações para os sistemas operacionais Linux, Windows e

Mac OS. Foi iniciado pelo autor no ano de 2006, devido seu descontentamento com os

editores de diagrama N-S existentes (STRUCTORIZER, 2007).

Permite os elementos de instrução, decisão, laços de repetição, comando de seleção,

chamada de sub-rotina e instrução de salto. Não dá suporte a geração de código. Os diagramas

criados nesta ferramenta são gravados em arquivos no formato XML. A Figura 14 mostra a

tela principal do aplicativo. Nela é possível selecionar um elemento já existente no diagrama e

incluir um novo elemento acima ou abaixo do elemento selecionado.

Figura 14 – Tela do aplicativo Structorizer

38

2.8.3 Jupe

Jupe (JUPE 2007a) é um editor de diagramas de classe escrito em Java na forma de um

plugin para o ambiente Eclipse. É resultado do trabalho de seis alunos da Ecole Centrale Paris

(ECF) sob a supervisão da professora Dominique Sauquet, sendo um projeto de código fonte

aberto. A proposta do Jupe é ser um editor de diagramas da UML para o ambiente Eclipse.

Atualmente ele dá suporte ao diagrama de classe. Diagramas editados por ele são salvos no

formato XML. Permite a geração de código automática para a linguagem Java e engenharia

reversa, permitindo montar o diagrama de classes a partir de programas escritos na linguagem

Java. Possui algumas limitações como (JUPE 2007b):

a) sincronização: o Jupe pode ser configurado para que as alterações realizadas no

diagrama sejam transferidas automaticamente para os arquivos gerados, entretanto,

nem todas as alterações são propagadas para o código fonte e vice-versa, gerando

algumas inconsistências;

b) múltiplos projetos: trabalhar em mais de um projeto pode causar problemas;

c) trabalho em equipe: não podem ser utilizadas ferramentas para alterações

concorrentes;

d) visuais: elementos do diagrama podem se sobrepor.

A Figura 15 apresenta a tela principal do plugin. Nela é apresentada a janela com o

diagrama em edição, onde é possível através da paleta de componentes selecionar um novo

elemento e adicionar ao diagrama. Também é possível verificar as interfaces, classes,

atributos e métodos criados de maneira gráfica.

39

Figura 15 – Tela principal do plugin Jupe

2.8.4 Topcased

O Topcased (TOPCASED, 2007) é um projeto de código fonte aberto com o objetivo

de disponibilizar para a comunidade de código aberto um conjunto de ferramentas de

engenharia de software. Uma destas ferramentas é o Topcased UML2. Esta ferramenta, escrita

na linguagem Java na forma de um plugin para o ambiente Eclipse, permite a criação dos

seguintes tipos de diagrama: classe, caso de uso, seqüência, máquina de estados, atividades,

componentes e implantação. A edição desses diagramas é realizada de maneira integrada ao

ambiente Eclipse. Ela permite a geração de código a partir do diagrama de classes.

Estão envolvidas neste projeto nove empresas francesas e onze instituições de ensino,

entre elas o Departamento de Automação e Sistemas (DAS) do centro tecnológico da

Universidade Federal de Santa Catarina (PROJETO TOPCASED, 2007).

Na Figura 16 é possível verificar a tela para edição de diagramas de classes do plugin.

40

Figura 16 – Editor de diagrama de classe do plugin TOPCASED

41

3 DESENVOLVIMENTO DO PLUGIN

Este capítulo descreve a especificação da ferramenta desenvolvida neste trabalho,

doravante denominada de Drawcode, um plugin para o ambiente de desenvolvimento Eclipse

que possibilita gerar código na linguagem Java a partir de diagramas de classe e diagramas N-

S, utilizando para isso o motor de templates Velocity. Na primeira seção estão descritos os

requisitos funcionais e não funcionais que o plugin deve atender. Na segunda seção é

apresentada a especificação do mesmo, demonstrando como o problema foi representado. A

terceira detalha as técnicas e ferramentas utilizadas e a operacionalidade do plugin. Na quarta

são apresentados os resultados e discussões sobre o trabalho, comparando-o com os seus

correlatos.

3.1 REQUISITOS PRINCIPAIS DO PROBLEMA A SER TRABALHADO

Nesta seção são apresentadas as funcionalidades necessárias pesquisadas para o

funcionamento do plugin elaborado neste trabalho. O resultado é demonstrado na Figura 17 e

Figura 18 na forma de requisitos funcionais e não-funcionais.

Figura 17 - Requisitos funcionais do plugin

42

Figura 18 - Requisitos não funcionais do plugin

3.2 ESPECIFICAÇÃO

Os tópicos seguintes descrevem a especificação do plugin Drawcode. As suas

funcionalidades são apresentadas através de casos de uso. Também são descritas as principais

classes modeladas.

3.2.1 Diagrama de casos de uso

O diagrama de casos de uso do Drawcode é mostrado na Figura 19 e descreve as

funcionalidades que ele fornece ao seu usuário. Um detalhamento dos casos de uso é

apresentado no Quadro 3 e no Quadro 4.

Figura 19 - Diagrama de casos de uso do plugin

43

UC01 – Editar diagrama de classe Descrição: Relacionado aos requisitos funcionais RF01 e RF03 Pré-condições:

1) Executar o ambiente de desenvolvimento Eclipse 2) Diretório usado pelo ambiente para armazenar as informações do usuário deve estar

funcional 3) Drawcode plugin deve estar devidamente instalado no ambiente

Cenário principal: Incluir um novo diagrama de classes 1) Selecionar o projeto ou pacote a ser incluído o novo diagrama 2) Clicar com o botão direito do mouse e comandar a criação de um novo arquivo com a

extensão “.drcd” 3) O arquivo é incluído com o nome definido pelo usuário

Cenário alternativo: Abrir um diagrama de classes existente 1) Usuário executa um duplo clique sobre o diagrama a ser editado 2) Ambiente apresenta na janela principal o diagrama previamente salvo 3) Ambiente apresenta uma paleta com os componentes característicos do diagrama de classes

Cenário alternativo: Incluir um novo elemento ao diagrama 1) Usuário seleciona um dos elementos existentes na paleta de componentes 2) Usuário clica sobre um elemento previamente existente no diagrama 3) Novo elemento é inserido

Cenário alternativo: Excluir um elemento existente no diagrama 1) Usuário seleciona qual o elemento do diagrama deve ser excluído 2) Pressionar o tecla <Delete> 3) Elemento é excluído

Cenário alternativo: Editar um elemento existente no diagrama 1) Usuário seleciona o elemento a ser editado 2) Usuário clica novamente sobre o elemento 3) Plugin apresenta um campo sobre o elemento com o conteúdo antigo do elemento 4) Usuário define o novo valor do elemento e ao final tecla <Enter> 5) Novo conteúdo do elemento é atualizado no diagrama

Cenário alternativo: Salvar um diagrama de classes em edição 1) Usuário comanda através do menu do ambiente que as alterações sejam salvas 2) Situação atual do diagrama é salva no arquivo

Cenário alternativo: Excluir um diagrama de classes 1) Selecionar o diagrama de classes a ser excluído 2) Clicar com o botão direito do mouse e comandar a exclusão 3) Arquivo é excluído

Cenário alternativo: Fechar diagrama em edição 1) No título da tela do ambiente onde o diagrama está sendo editado, clicar no ícone em forma

de “x” 2) O diagrama em edição é fechado

Cenário de exceção: Fechar o diagrama em edição com alterações ainda não salvas 1) Usuário é questionado se as alterações pendentes no diagrama devem ser salvas 2) Se a resposta do usuário for positiva as alterações são salvas 3) Diagrama em edição é fechado

Cenário alternativo: Atribuir um diagrama N-S existente a um método da classe 1) Usuário executa um duplo-clique sobre o método desejado 2) Ambiente apresenta uma tela permitindo escolher um arquivo com a extensão “.nsd” 3) Ao confirmar, o caminho completo para este arquivo é armazenado no método

Cenário alternativo: Gerar código para o diagrama de classe 1) Na tela do ambiente onde o diagrama está sendo editado usuário clica com o botão direito

do mouse 2) Usuário seleciona a opção: “Generate from class diagram” 3) Ambiente apresenta tela solicitando o arquivo a ser gerado 4) As classes são geradas no arquivo selecionado

44

Quadro 3 – Detalhes do caso de uso: editar diagrama de classe

UC02 – Editar diagrama N-S Descrição: Relacionado aos requisitos funcionais RF02 e RF03 Pré-condições:

1) Executar o ambiente de desenvolvimento Eclipse 2) Diretório usado pelo ambiente para armazenar as informações do usuário deve estar

funcional 3) Drawcode plugin deve estar devidamente instalado no ambiente

Cenário principal: Incluir um novo diagrama N-S 1) Selecionar o projeto ou pacote a ser incluído o novo diagrama 2) Clicar com o botão direito do mouse e comandar a criação de um novo arquivo com a

extensão “.nsd” 3) O arquivo é incluído com o nome definido pelo usuário

Cenário alternativo: Abrir um diagrama N-S existente 1) Usuário executa um duplo clique sobre o diagrama a ser editado 2) Ambiente apresenta na janela principal o diagrama previamente salvo 3) Ambiente apresenta uma paleta com os componentes característicos do diagrama N-S

Cenário alternativo: Incluir um novo elemento ao diagrama 1) Usuário seleciona um dos elementos existentes na paleta de componentes 2) Usuário clica sobre um elemento previamente existente no diagrama 3) Novo elemento é inserido

Cenário alternativo: Excluir um elemento existente no diagrama 1) Usuário seleciona qual o elemento do diagrama deve ser excluído 2) Pressionar a tecla <Delete> 3) Elemento é excluído

Cenário alternativo: Editar um elemento existente no diagrama 1) Usuário seleciona o elemento a ser editado 2) Usuário clica novamente sobre o elemento 3) Plugin apresenta um campo sobre o elemento com o conteúdo antigo do elemento 4) Usuário define o novo valor do elemento e ao final tecla <Enter> 5) Novo conteúdo do elemento é atualizado no diagrama

Cenário alternativo: Salvar um diagrama N-S em edição 1) Usuário comanda através do menu do ambiente que as alterações sejam salvas 2) Situação atual do diagrama é salva no arquivo

Cenário alternativo: Excluir um diagrama N-S 1) Selecionar o diagrama N-S a ser excluído 2) Clicar com o botão direito do mouse e comandar a exclusão 3) Arquivo é excluído

Cenário alternativo: Fechar diagrama em edição 1) No título da tela do ambiente onde o diagrama está sendo editado, clicar no ícone em forma

de “x” 2) O diagrama em edição é fechado

Cenário de exceção: Fechar o diagrama em edição com alterações ainda não salvas 1) Usuário é questionado se as alterações pendentes no diagrama devem ser salvas 2) Se a resposta do usuário for positiva as alterações são salvas 3) Diagrama em edição é fechado

Cenário alternativo: Gerar código para o diagrama de classe 1) Na tela do ambiente onde o diagrama está sendo editado usuário clica com o botão direito

do mouse 2) Usuário seleciona a opção: “Generate from N-S diagram” 3) Ambiente apresenta tela solicitando o nome do arquivo 4) Código é gerado no arquivo selecionado pelo usuário

Quadro 4 – Detalhes do caso de uso: editar diagrama N-S

45

3.2.2 Diagrama de classes do Drawcode

Nas subseções seguintes são detalhados os diagramas de classes do Drawcode, sendo

eles: a classe principal DrawcodePlugin que representa o plugin e que possibilita a integração

com o Eclipse, diagrama de classes do editor de diagrama de classes, diagrama de classes

relacionadas ao editor de diagramas N-S e diagrama de classes da geração de código dos

editores.

3.2.2.1 Diagrama da principal classe do plugin

A Figura 20 apresenta a principal classe do plugin Drawcode, no formato de um

diagrama de classe, sendo a classe DrawCodePlugin. Essa é a classe que representa o

plugin, controlando o seu ciclo de vida, sendo responsável por tratar a inicialização e

finalização do plugin e controlar quais arquivos o usuário mantêm aberto e qual deles é o

ativo.

Figura 20 - Classe principal do Drawcode

46

3.2.2.2 Diagrama de classe do editor de diagrama de classes

A Figura 21 apresenta na forma de um diagrama de classes a representação do editor

de diagramas de classe.

Figura 21 - Diagrama de classe do editor de diagramas de classe

Este conjunto de classes mapeia para o modelo os elementos existentes num diagrama

47

de classes como por exemplo as classes, seus atributos e métodos, sendo elas:

a) ClassDiagramHandler: é a classe responsável por fazer a persistência do modelo

de dados no formato XML, ler arquivos neste formato e transformar no modelo de

dados novamente, adicionar e remover elementos do modelo, assim como retornar

uma lista de elementos filhos de determinado elemento. Estas operações estão

definidas em classes chamadas de visitadores. O conceito de visitadores é

apresentado a partir da página 56, na subseção 3.3.1.1;

b) ClassDiagramElement: esta classe é a representação do diagrama de classes, ou

seja uma lista de elementos possíveis em um diagrama de classes. Esta classe não

implementa nenhuma funcionalidade. Ao ser solicitada, faz com que o visitador

recebido por parâmetro visite ela mesma e seus filhos;

c) ClassElement: é a representação no modelo para uma classe em um diagrama de

classes. Ela armazena o nome de determinada classe e têm duas listas, sendo elas

uma lista de atributos e uma lista de métodos. Ao receber a solicitação accept faz

com que o visitador recebido por parâmetro, visite a si mesma e suas listas de

atributos e métodos;

d) MethodElement: é a representação no modelo para um método de determinada

classe. Ela armazena a assinatura do método e, caso tenha sido informado, o

caminho para um determinado arquivo. Ao receber um visitador, faz com que tal o

visite;

e) AttributeElement: é a representação de um atributo de uma classe;

f) CDNodeAdder: é a classe responsável por adicionar elementos ao modelo. Recebe

solicitações contendo o elemento a ser inserido e em qual lista de elementos ele

deve ser inserido. Assim, percorre o modelo até encontrar a lista e adiciona o

elemento;

g) CDNodeRemover: esta classe é responsável por retirar elementos do modelo.

Recebe qual elemento deve ser retirado e percorre o modelo à sua procura. Ao

encontrá-lo, o remove do modelo;

h) ICDElementVisitable: esta interface representa os elementos que podem fazer

parte do modelo proposto para representar o diagrama de classes;

i) ICDElementsVisitor: esta interface representa as classes que implementam

alguma funcionalidade sobre o modelo. Classes que pretendem visitar o modelo

independente da funcionalidade desejada devem implementar esta interface;

48

j) MethodsList: esta classe representa a lista de métodos da classe existente no

diagrama;

k) AttributesList: esta classe representa a lista de atributos da classe existente no

diagrama;

l) CDElementList: esta classe representa uma lista com qualquer tipo de elemento

existente no modelo. Para incluir determinado elemento nesta lista, o mesmo deve

implementar a interface ICDElementVisitable.

3.2.2.3 Diagrama de classe do editor de diagrama N-S

A Figura 22 apresenta na forma de um diagrama de classes, as classes que representam

o modelo do editor de diagramas N-S.

49

Figura 22 - Diagrama de classes do editor de diagramas N-S

50

Este conjunto de classes é o mapeamento das estruturas existentes nos diagramas N-S

para elementos do modelo, sendo:

a) NSDiagramCommand: esta classe é a representação do diagrama N-S, ou seja uma

lista de elementos possíveis em um diagrama N-S. Esta classe mantém uma lista de

comandos do diagrama. Basicamente, ao ser solicitada, faz com que o visitador

informado passe nela mesma e nos seus elementos filhos;

b) BaseElementsTokenizer: esta é uma classe base que é estendida por cada um dos

elementos presentes no modelo proposto para o diagrama N-S. Sua função é,

através de um analisador léxico, receber uma string e retornar uma lista de tokens

reconhecidos;

c) CommandList: é a representação no modelo de uma lista de comandos. Ela tem as

funcionalidades de adicionar e remover elementos e retornar uma lista com os

elementos contidos nela;

d) IfCommand: esta classe representa os comandos de decisão. Armazena uma

condição e duas listas de comandos, sendo uma a lista de comandos verdadeiros,

que devem ser executados caso a expressão da decisão seja verdadeira e a outra

lista caso a expressão seja falsa;

e) IfCommands: esta classe representa a lista de comandos verdadeiros de um

elemento de decisão;

f) ElseCommands: esta classe representa a lista de comandos falsos de um elemento

de decisão;

g) WhileCommand: é a classe que representa um comando de repetição. Armazena a

condição da repetição e a lista de comandos a ser repetido enquanto a expressão

seja verdadeira;

h) DoWhileCommand: representa um comando de repetição com a condição de

repetição sendo verificada no final do laço de repetição. Armazena a lista de

comandos a serem repetidos e a expressão de condição para a repetição;

i) ForCommand: representa um comando de repetição com número de repetições

definido. Armazena a lista de comandos a serem repetidos e a definição da

quantidade de repetições a ser executada;

j) CaseCommand: representa o comando de seleção. Armazena qual é o elemento a ser

comparado, e uma lista de opções possíveis;

51

k) CaseOptionList: esta classe representa a lista de opções possíveis para um

determinado comando de seleção. Tem as funcionalidades de adicionar e remover

opções na lista de opções possíveis;

l) CaseOption: esta classe representa uma das opções do comando de seleção. Ele

armazena o valor que o representa junto ao comando de seleção e sua lista de

comandos a serem executados;

m) NullCommand: esta classe representa um comando vazio, que é criado na lista de

comandos quando vazia e retirado ao incluir o primeiro elemento;

n) InstructionCommand: esta classe representa um comando de atribuição,

declaração de variável ou chamada de sub rotina.

Na Figura 23 são apresentadas algumas classes que fazem parte do editor de diagramas

N-S. As operações das classes foram omitidas para melhor visualização do diagrama. As

operações omitidas estão listadas no apêndice D.

52

Figura 23 - Diagrama de classe da manutenção do modelo e representação gráfica

Este conjunto de classes é responsável pela manutenção do modelo de dados e

produção da sua representação gráfica. São elas:

a) NSDiagramEditor: é a classe principal do editor de diagramas N-S,

responsável pelas inicializações necessárias para que o ambiente possa tratar a

edição deste tipo de diagrama;

b) LayoutCalculatorVisitor: esta classe é responsável por calcular o

posicionamento dos componentes visuais de cada um dos elementos presentes no

diagrama N-S;

c) LayoutAdjustCalculatorVisitor: esta classe ajuda no cálculo do

posicionamento dos componentes visuais;

53

d) NSDiagramHandler: é a classe responsável por fazer a persistência do modelo de

dados do diagrama N-S no formato XML, ler arquivos neste formato e transformar

no modelo de dados novamente, adicionar e remover elementos do modelo

(utilizando os devidos visitadores) e retornar lista de elementos filhos de

determinado elemento, também utilizando um visitador criado com este propósito;

e) ICommandVisitable: esta interface representa os elementos que podem fazer parte

do modelo proposto para representar o diagrama N-S;

f) ICommandVisitor: esta interface representa as classes que implementam alguma

funcionalidade sobre o modelo. Classes que pretendem visitar o modelo

independente da funcionalidade desejada devem implementar esta interface;

g) CommandAdder: esta classe é responsável por incluir elementos do modelo,

recebendo qual elemento deve ser incluído e qual o seu comando anterior. Com

esta informação ele percorre o modelo e insere o elemento após aquele informado

como anterior;

h) CommandRemover: esta classe é responsável por remover elementos do modelo;

i) NodeChildrenDiscover: esta classe é responsável por percorrer o modelo

procurando por um determinado comando e retornar uma lista com os comandos

internos do mesmo;

j) NSPartFactory: esta classe é responsável por receber solicitações do framework

gráfico e criar instâncias de classes controladoras para cada elemento do modelo;

k) NSDiagramEditParts: esta classe controla a relação entre um elemento do modelo

e sua representação gráfica. Cada elemento do modelo está relacionado a uma

instância desta classe;

l) NSXYLayoutEditPolicy: esta classe controla as requisições do framework gráfico,

fazendo o devido tratamento e criando instâncias de comandos a serem executados

posteriormente pelo framework gráfico;

m) NodeChildrenDiscover: esta classe é responsável por montar uma lista com os

elementos existentes dentro de algum elemento do modelo;

n) NSNodeCreateCommand: esta classe é a representação de um comando a ser

executado pelo framework gráfico. Ele é criado pela classe de controle de

requisições;

o) CaseFigure: esta classe trata a representação visual de um elemento de seleção;

54

p) DecisionFigure: esta classe trata a representação visual de um elemento de

decisão;

q) DoWhileFigure: esta classe cuida da representação visual do elemento de

repetição com a condição no final da lista de comandos;

r) ForFigure: esta classe trata a representação visual do elemento de repetição com

número de repetições definido;

s) GenericFigure: esta classe trata da representação visual de componentes

genéricos;

t) InstructionFigure: esta classe trata da representação visual de comandos

simples;

u) NodeFigure: classe base para todas as classes de representação visual. Tem a

funcionalidade de armazenar a referência para o editor ao qual este elemento está

associado. A partir desta referência do editor, requisitar do mapa de

posicionamento de componentes qual a posição e tamanho do componente visual;

v) NullFigure: classe pra representar visualmente o elemento NullCommand;

w) WhileFigure: esta classe cuida da representação visual dos elementos de repetição

do tipo WhileCommand.

3.2.2.4 Diagrama de classes do gerador de código

A Figura 24 apresenta na forma de um diagrama de classes das estruturas responsáveis

pela geração de código, as quais são:

a) CDCodeGenerationVisitor: esta classe é responsável pela geração de código no

modelo do diagrama de classes. Faz a inicialização do Velocity e começa o

processo de visitação dos elementos do modelo;

b) CDGenerationConstants: é uma classe apenas com constantes indicando qual o

template a ser utilizado por cada um dos elementos do modelo;

c) CDNSGenerationProvider: no momento da geração de código para o diagrama de

classe, esta classe é responsável por gerar o código referente ao diagrama N-S nos

elementos do tipo método, quando este possuir um diagrama N-S associado;

55

d) NSCodeGenerationVisitor: esta classe é responsável pela geração de código no

modelo do diagrama N-S. Ela faz a inicialização do Velocity e inicia o processo de

visitação dos elementos do modelo;

e) NSGenerationConstants: é uma classe apenas com constantes indicando qual o

template a ser utilizado por cada um dos elementos do modelo N-S;

f) NSTokenProcessorVisitor: esta classe é responsável por tratar os tokens

reconhecidos em cada um dos elementos do diagrama N-S.

Figura 24 – Diagrama de classe da geração de código

3.3 IMPLEMENTAÇÃO

A seguir são mostradas as técnicas e ferramentas utilizadas no desenvolvimento do

plugin e a utilização do mesmo.

56

3.3.1 Técnicas e ferramentas utilizadas

O Drawcode foi desenvolvido na linguagem Java, utilizando o ambiente de

desenvolvimento Eclipse. Para a geração do analisador léxico optou-se por utilizar o GALS,

uma ferramenta livre que provê esta funcionalidade.

Como motor de template é utilizado o Velocity, uma ferramenta de código aberto

escrita na linguagem Java.

Para fazer a persistência dos modelos foi utilizada a biblioteca XStream pelo seu alto

nível de abstração para converter objetos Java no formato XML e do formato XML para

objetos Java.

3.3.1.1 Entendendo o modelo criado

No projeto foi utilizado o padrão de projeto Visitor. Isso fez com que as classes criadas

para representar o modelo ficassem extremamente simples, contendo apenas os atributos

necessários para cada elemento, apresentando apenas as funcionalidades básicas para permitir

a visitação.

Um exemplo, é a classe IfCommand. Ela foi criada para representar um comando de

decisão da estrutura do diagrama N-S. Conta apenas com um atributo do tipo String para

armazenar a sua expressão lógica de condição, uma lista com os comandos se a expressão for

verdadeira, chamada de ifCommands e outra lista de comandos caso a expressão seja falsa,

chamada de elseCommands. O código completo dela pode ser visto no Quadro 5.

57

package org.henkels.drawcode.editors.nsdiagram; import java.util.List; public class IfCommand extends BaseElementsTokenizer implements ICommandVisitable { //expressão de condição para o comando if public String condition; //lista de comandos “verdadeiros” public IfCommands ifCommands = new IfCommands(); //lista de commandos “falsos” public ElseCommands elseCommands = new ElseCommands(); //construtor padrão public IfCommand() { super(); //inicialização da condição da decisão com texto genérico condition = "if condition"; } @Override public String toString() { //sobrescreve o método toString de Object pra retornar a condição return condition; } public void setValue(String newValue) { //setar o valor da condição da decisão this.condition = newValue; } @Override public boolean accept(ICommandVisitor visitor, Object ctx) { //faz com que o visitador passado visite este elemento if (!visitor.Visit(this, ctx)) { //visitador retornou que o processo de visitação deve ser parado pois o objetivo já foi atingido return false; } //se visitador retornou que processo de visitação deve continuar, manda visitar os elementos filhos verdadeiros e falsos, ifCommands e elseCommands respectivamente return ifCommands.accept(visitor, ctx) && elseCommands.accept(visitor, ctx); } @Override public void vlaccept(ICommandVisitor visitor, Object ctx) { //criado pra ser utilizado pelo velocity //mesma função do accept, apenas ignorando o retorno accept(visitor, ctx); } @Override public List<String> getTokenList() { //chama classe base (BaseElementsTokenizer) pra montar lista de tokens existentes na condição return super.getElementTokenList(condition); } }

Quadro 5 – Código completo da classe IfCommand

Para as operações necessárias foram criadas classes separadas, cada uma delas

incluindo uma nova funcionalidade ao modelo, como por exemplo, a classe CommandAdder,

58

cuja finalidade é incluir novos elementos no modelo. Esta classe é mais detalhada na próxima

subseção. Assim criaram-se dois papéis: as classes “visitáveis” que são os elementos do

modelo, sem funcionalidades específicas e as classes “visitadoras” que representam as

funcionalidades existentes sobre o modelo.

Foram definidas então duas interfaces para estes dois papéis. A interface

ICommandVisitable para as classes visitáveis, sendo que todos os elementos que fazem parte

do modelo têm que implementar esta interface para garantir que podem ser visitadas por

algum visitador que necessite visitar os elementos do modelo. Já a interface

ICommandVisitor foi criada para ser implementada pelas classes ditas “visitadoras”. O

conteúdo de ambas pode ser visto nos Quadro 6 e Quadro 7.

package org.henkels.drawcode.editors.nsdiagram; import java.util.List; public interface ICommandVisitable { //recebe um visitador e um contexto //como retorno indica se o visitador deve continuar visitando o modelo boolean accept(ICommandVisitor visitor, Object ctx); //usado pelo velocity, pois não pode ter retorno //internamente vai chamar accept e desconsiderar o retorno void vlaccept(ICommandVisitor visitor, Object ctx); void setValue(String newValue); //retornar uma lista de strings com os tokens presentes no comando List<String> getTokenList(); }

Quadro 6 – Conteúdo da interface ICommandVisitable

package org.henkels.drawcode.editors.nsdiagram; public interface ICommandVisitor { //visitadores necessitam saber visitar todos os elementos do modelo public boolean Visit(NSDiagramCommand command, Object ctx); public boolean Visit(NullCommand command, Object ctx); public boolean Visit(WhileCommand command, Object ctx); public boolean Visit(DoWhileCommand command, Object ctx); public boolean Visit(ForCommand command, Object ctx); public boolean Visit(InstructionCommand command, Object ctx); public boolean Visit(CaseCommand command, Object ctx); public boolean Visit(CaseOption command, Object ctx); public boolean Visit(IfCommand command, Object ctx); public boolean Visit(IfCommands command, Object ctx); public boolean Visit(ElseCommands command, Object ctx); }

Quadro 7 – Conteúdo da interface ICommandVisitor

59

3.3.1.2 Manutenção dos modelos de dados

Nesta subseção é apresentada a estratégia criada para a manutenção do modelo de

dados. O plugin conta com dois modelos. Um modelo que representa o diagrama de classes e

outro o diagrama N-S. Em seguida é apresentada a estratégia utilizada no diagrama N-S,

sendo que para o diagrama de classes foi utilizada a mesma estratégia, tendo como diferença

apenas os elementos existentes no modelo.

A classe NSDiagramHandler é responsável por controlar as alterações no modelo de

dados, assim a entidade que necessita fazer alterações, precisa fazer requisições a esta classe

para que o modelo seja alterado. Como o modelo é representado graficamente, as

necessidades de alteração do modelo são produzidas de maneira visual. A Figura 25 apresenta

na forma de um diagrama de seqüência de que maneira são geradas as necessidades de

alteração do modelo.

60

Figura 25 – Diagrama de seqüência da inclusão de um elemento no diagrama N-S

A Figura 25 ajuda a demonstrar como são criadas as necessidades de alteração no

modelo de dados. No momento que é solicitado ao editor (NSDiagramEditor), além de

informar qual o novo elemento que está sendo inserido, é passado também como parâmetro o

elemento do modelo que o usuário clicou. Esta informação é importante, pois indica o ponto

que o novo elemento deve ser inserido. Desta maneira a classe criada como visitador de

inserção tem as informações necessárias para iniciar o processo de inclusão do novo elemento

61

no modelo.

Como apresentado anteriormente, quem implementa esta funcionalidade é a classe

CommandAdder. Esta classe acrescenta a funcionalidade de inserir elementos no modelo, e

para fazer isto, ela espera receber como parâmetro além do novo elemento, um elemento que

já exista no modelo. Esta informação é necessária por que esta classe vai procurar por este

elemento no modelo e incluir o novo elemento imediatamente após o já existente.

Esta classe por se caracterizar como sendo um visitador, ela implementa a interface

ICommandVisitor, que em outras palavras indica que a mesma conhece as particularidades de

cada um dos elementos do modelo, e assim sabe como incluir um novo elemento em cada um

deles.

No momento que a classe NSDiagramEditor é inicializada, ela cria internamente uma

instância da classe NSDiagramHandler, que vai controlar suas necessidades junto ao modelo.

Já a classe NSDiagramHandler por sua vez quando é inicializada, cria internamente instâncias

das classe CommandAdder e CommandRemover, que serão usadas respectivamente pra inserir e

pra remover itens. No Quadro 8 são apresentadas algumas partes da classe

NSDiagramHandler. Esta seqüência de ativação é mostrada na Figura 26.

Figura 26 – Seqüência de inicialização da classe NSDiagramEditor

62

package org.henkels.drawcode.editors.nsdiagram; .... public class NSDiagramHandler { //visitador de inserção private CommandAdder commandAdder = new CommandAdder(); //visitador de remoção private CommandRemover commandRemover = new CommandRemover(); //elemento inicial do modelo (lista de comandos inicial) public NSDiagramCommand root = new NSDiagramCommand(); //edit part principal public NSDiagramEditParts rooteditpart = null; //construtor padrao public NSDiagramHandler() { super(); ICommandVisitable nullcmd = new NullCommand(); insertCommand(nullcmd, root.getRootCommand()); } //inserir elemento public void insertCommand(ICommandVisitable node, ICommandVisitable previousBrother) { root.accept(commandAdder, new CommandAdder.AddContext(previousBrother, node)); } //remover elemento public void RemoveCommand(ICommandVisitable killedNode) { root.accept(commandRemover, new CommandRemover.RemoveContext(killedNode)); } //retornar lista de elementos filhos public List<ICommandVisitable> getChildrens(ICommandVisitable node) { List<ICommandVisitable> ret = new ArrayList<ICommandVisitable>(); new NodeChildrenDiscover().fillList(ret, node); return ret; } ..... }

Quadro 8 – Parte da classe NSDiagramHandler

No momento que a função insertCommand é chamada uma instância da classe

AddContext é criada. Seu objetivo é encapsular o elemento a ser inserido e o elemento já

existente no modelo, chamado de “irmão anterior”. Depois de criada a instância desta classe, é

iniciado o processo de visitação chamando o método accept no elemento inicial do modelo,

neste caso o atributo root, instância de NSDiagramCommand.

A Figura 27 apresenta um diagrama de atividades cujo objetivo é ajudar a demonstrar

como ocorre o processo de inserção de novos elementos. Enquanto o elemento irmão não tiver

sido encontrado e o novo elemento não tiver sido adicionado imediatamente ao seu lado, o

63

processo de visitação continua enquanto existirem elementos a serem visitados.

Figura 27 – Diagrama de atividades do processo de inserção de elementos no modelo

3.3.1.3 Representação gráfica do diagrama N-S

Esta subseção apresenta como é montada a representação visual do modelo. Uma das

partes mais importantes do Drawcode é sua interface gráfica. Isto por que a literatura

apresenta que um dos principais problemas dos diagramas N-S é sua representação visual. Ao

incluir, excluir, ou até mesmo alterar os elementos existentes, a sua representação precisa ser

redesenhada para que comporte os elementos internos de cada um dos elementos presentes no

diagrama.

Assim, o plugin deve conter mecanismos que possibilitem essa manutenção de maneira

totalmente automática, eliminando este problema dos diagramas N-S. Diante disto foi criado

um mecanismo que trata sua representação visual.

Para desenvolver tal mecanismo deve ser estudado cada um dos elementos existentes

no diagrama N-S, verificando as características de cada um deles. Externamente todos os

elementos são um retângulo, com particulares para cada um dos elementos na sua parte

interna. As particularidades encontradas são apresentadas a seguir.

Instrução é o elemento que representa uma atribuição ou a chamada de uma sub-rotina.

Suas dimensões (altura e largura) são definidas apenas pelo texto que o usuário definir. A

Figura 28 apresenta um exemplo.

64

Figura 28 – Exemplo de representação gráfica de uma instrução simples

Comando de decisão é o elemento que representa as estruturas de decisão criadas pelo

usuário. Ela apresenta o texto da sua condição e duas listas de comandos, sendo a lista de

comandos verdadeiros e a lista de comandos falsos. Seu tamanho depende do tamanho de seu

texto de condição e do tamanho de sua lista de comandos verdadeiros e falsos

respectivamente. Sua lista de comandos verdadeiros é posicionada abaixo da condição do lado

esquerdo. A lista de comandos falsos é posicionada ao lado da lista de comandos verdadeiros.

Todos os comandos que existirem dentro da sua lista de comandos verdadeiros, independente

de comando, serão posicionados verticalmente a partir do início da lista um abaixo do outro.

Os comandos da lista de comandos falsos também serão posicionados desta maneira. A Figura

29 apresenta um exemplo de um comando de decisão.

Figura 29 – Exemplo de representação gráfica de uma instrução de decisão

Comando de repetição “for” é o elemento que representa os comandos do tipo

repetição com um número de iterações definido. Apresenta um texto indicando sua condição e

uma lista de comandos. Seu tamanho é definido pelo texto da condição e o tamanho da lista

de comandos. Os comandos presentes na sua lista de comandos serão posicionados

horizontalmente, um abaixo do outro. A Figura 30 apresenta um exemplo de um comando de

repetição do tipo “for”.

Figura 30 – Exemplo de representação gráfica de uma instrução “for”

Os comandos de repetição dos tipos “while” e “repeat-until” têm representação

65

parecida com a do comando de repetição “for”. Também apresentam uma condição e uma

lista de comandos que é posicionada verticalmente, com comandos um abaixo do outro. Um

exemplo de representação de comando de repetição “while” pode ser visto na Figura 31.

Figura 31 – Exemplo de representação gráfica de uma instrução “while”

Um exemplo de representação de comando de repetição “repeat-until” pode ser visto

na Figura 32.

Figura 32 – Exemplo de representação gráfica de uma instrução “repeat-until”

Comando de seleção é o elemento que representa as estruturas de seleção criadas pelo

usuário. Ela apresenta o texto da sua condição de seleção e uma ou várias opções, cada uma

contendo uma lista de comandos. Seu tamanho depende do tamanho de seu texto de condição

de seleção, do tamanho das suas listas de comandos de cada uma de suas opções. As opções

são posicionadas abaixo da condição de seleção, horizontalmente uma ao lado da outra,

iniciando do lado esquerdo. Todos os comandos que existirem dentro da lista de comandos de

cada opção, independente do comando, são posicionados verticalmente a partir do início de

sua respectiva lista, um abaixo do outro. Um exemplo de representação de um comando de

seleção é apresentado na Figura 33.

Figura 33 – Exemplo de representação gráfica de uma instrução de seleção

O diagrama é a lista principal de comandos existentes. É formado por uma lista de

comandos posicionados verticalmente um abaixo do outro. Seu tamanho é definido pelo

tamanho dos elementos existente na sua lista de comandos. Um exemplo de representação de

66

um diagrama é apresentado na Figura 34.

Figura 34 – Exemplo de representação gráfica de um diagrama N-S e sua lista de comandos

Verificadas as particularidades gráficas de cada um dos elementos, conclui-se que o

diagrama é formado basicamente por listas de comandos. Algumas posicionadas de maneira

vertical com comandos um abaixo do outro e listas de comandos horizontais com comandos

um ao lado do outro. Além disso, independente da orientação horizontal ou vertical, a

dimensão delas é definida pelo tamanho de todos os elementos existentes nestas listas

internas.

As informações de tamanho dos elementos dependem de cada um dos elementos

presentes nestas listas de comandos, assim não é necessário armazenar informações de

tamanho no modelo que armazena o diagrama. Isso por que estas informações mudam

constantemente, sendo recalculadas a cada interação do usuário que resulte em alterações no

modelo.

Ao abrir um diagrama, ou depois de cada interação do usuário, a representação gráfica

é atualizada. Isso acontece da seguinte maneira: a classe NSDiagramHandler tem uma

referência para o primeiro elemento visual criado pela GEF. Todos os demais elementos

visuais criados são considerados pela GEF como filhos deste elemento. Depois de qualquer

alteração no modelo é mandada uma mensagem para o primeiro elemento visual para que o

mesmo apague todos os seus elementos filhos. Isso apaga a representação desatualizada. A

GEF percebe que houve alguma alteração visual e solicita novamente os filhos do elemento

principal e seus filhos respectivamente, até que não existam mais filhos. No momento que

cada novo elemento é desenhado, este solicita à classe NSDiagramEditor qual deve ser a sua

67

posição na tela. Esta classe mantém um mapa com a posição de cada elemento do modelo.

Sempre que a posição de um elemento for solicitada e a mesma não se encontrar no modelo, o

mapa é apagado e é feita uma solicitação ao visitador que calcula a posição novamente de

todos os elementos do modelo. O diagrama de seqüência apresentado na Figura 35 representa

todo este processo.

Figura 35 – Diagrama de seqüência do processo de atualização gráfica do modelo

Sempre que a posição de um elemento é necessária, a classe NSDiagramEditor é

solicitada através do método getNodeRect. Se a posição deste elemento é encontrada no

mapa de posições, este é retornado, se não o mapa é totalmente limpo. Então é instanciado

LayoutCalculatorVisitor e iniciada a visitação no elemento inicial do modelo. O código

deste método é apresentado no Quadro 9.

68

public Rectangle getNodeRect(ICommandVisitable node) { //se o mapa de posiçoes estiver vazio if (rectmap == null) { //instancia visitor e inicia visitacao no elemento principal rectmap = new LayoutCalculatorVisitor().getLayout(nsDiagram.root); } //pega posicao do elemento no mapa Rectangle ret = rectmap.get(node); if (ret == null) { // se nao encontrou o elemento no mapa de posicoes recalcula tudo rectmap = new LayoutCalculatorVisitor().getLayout(nsDiagram.root); //pega posicao do elemento no mapa ret = rectmap.get(node); } //retorna posicao do elemento return ret; }

Quadro 9 – Método responsável por retornar a posição do elemento

Para calcular a posição de cada um dos elementos foi criada uma classe

LayoutCalculatorVisitor do tipo visitador que tem como objetivo visitar o modelo inteiro,

atualizando um mapa com as posições de cada elemento. Basicamente o que este visitador faz

é, para cada elemento, calcular a posição e tamanho deste elemento e gravar no mapa de

posições.

Para calcular a posição e tamanho ele precisa saber o tamanho de seus elementos

internos, que por sua vez precisam ter definido o tamanho de seus elementos internos, até o

momento que a lista tenha apenas comandos simples, onde o tamanho não depende de

elementos internos, mas apenas do tamanho do texto definido para este comando. No

momento que é definido o tamanho de determinado elemento, o que precisava de seu tamanho

já o tem. Assim é feito recursivamente até o momento que todos os elementos já têm tamanho

e posição definidos. A Figura 36 apresenta um diagrama de atividades representando este

processo.

69

Figura 36 – Diagrama de atividades do processo de cálculo dos elementos visuais

3.3.1.4 Geração de código

Esta subseção apresenta a estratégia utilizada para gerar código. Como apresentado

anteriormente o Drawcode está divido em dois modelos, sendo um representando o diagrama

de classes e outro o diagrama N-S. Desta maneira a geração de código também foi criada

separada. A classe CDCodeGenerationVisitor é um visitador responsável por gerar código

para o diagrama de classes e a classe NSCodeGenerationVisitor outro visitador responsável

por gerar código para o diagrama N-S.

O processo de geração de código é formado por três artefatos de software, sendo eles:

o motor de templates, a classe responsável por instanciar e inicializar o motor e o modelo de

dados do diagrama com os elementos que o usuário inseriu.

O diagrama de seqüência da Figura 37 apresenta o processo de geração de código.

70

Figura 37 – Seqüência para a geração de código do diagrama N-S

A geração de código para o diagrama de classes tem a mesma seqüência que o

diagrama N-S, porém, no momento que é encontrado no modelo um elemento do tipo método

e seu atributo methodElement é diferente de vazio, é criada uma instância da classe

CDNSGenerationProvider. Isto indica que o método tem um diagrama N-S associado, então

esta classe vai ser responsável por gerar o código deste diagrama, instanciando o visitador que

gera código N-S. A Figura 38 apresenta um diagrama de seqüência da geração de código para

o diagrama de classe.

71

Figura 38 – Seqüência de geração de código para o diagrama de classe

Como apresentado na Figura 37 e na Figura 38, para gerar o código, a classe

responsável instancia o Velocity, carrega o template para aquele elemento, seta os valores do

contexto e comanda que o Velocity faça o processamento do template. Cada elemento do

modelo do diagrama de classe e N-S tem seu próprio arquivo de template. Estes arquivos é

que determinam qual o código a ser gerado para cada um dos elementos.

O Quadro 10 apresenta um exemplo de template para o elemento de decisão criado

para gerar código na linguagem Java. Os identificadores precedidos pelo caractere “$” são

variáveis de contexto para o Velocity. Através destas variáveis que cada um dos elementos do

modelo de dados do diagrama é inserido no contexto do Velocity. No momento do

processamento deste arquivo e contexto, estas variáveis serão substituídas e tratadas.

##template para geração de código java do elemento de decisão if ($command.vlaccept($tokentranslator,$ctx)) { $ifchild.vlaccept($this,$ctx) } else { $elsechild.vlaccept($this,$ctx) }

Quadro 10 – Template escrito na VTL para elemento de decisão gerando código Java

72

Na Figura 39 é apresentado o mesmo template do Quadro 10 com algumas anotações

para ajudar no entendimento.

Figura 39 – Exemplo de template VTL de decisão com anotações

Antes de requisitar o processamento do template, o visitador coloca no contexto do

Velocity cada uma das variáveis definidas no arquivo de template. No exemplo da Figura 39

são: $command, $tokenTranslator, $ctx, $ifchild, $elsechild. No momento que o

Velocity processar o template, serão chamados os métodos destas variáveis, nesta ordem:

a) $command.vlaccept($tokentranslator, $ctx): processa o conteúdo da

expressão definida pelo usuário;

b) $ifchild.vlaccept($this,$ctx): processa a lista de comandos verdadeiros da

decisão, gerando código para todos os elementos desta lista;

c) $elsechild.vlaccept($this,$ctx): processa a lista de comandos falsos da

decisão, gerando código para todos os elementos desta lista.

O resultado do processamento do template do elemento de decisão pelo Velocity é

apresentado no Quadro 11.

if ( <resultado do processamento do item a>) { <resultado do processamento do item b> } else { <resultado do processamento do item c> }

Quadro 11 - Esquema representando o resultado do processamento de um elemento de decisão

Quando é solicitado que o visitador visite um elemento do diagrama N-S, dependendo

do tipo de elemento, dois métodos podem ser chamados para tratar a visitação:

processChilds ou processSingleCommand. A implementação de ambos pode ser vista no

Quadro 12 e no Quadro 13.

73

private boolean processChilds(ICommandVisitable command, List<ICommandVisitable> list, Object ctx, String templateFile) { //buffer é utilizado pelo velocity pra gerar a saida BufferedWriter buffer = (BufferedWriter) ctx; //novo contexto do velocity VelocityContext vlctx = new VelocityContext(); //responsavel por fazer a analise lexica no conteudo do comando e gerar a saida processando a tabela de mapeamento NSTokenProcessorVisitor tokenVisitor = new NSTokenProcessorVisitor(); //colocar tradutor de tokens no contexto do velocity vlctx.put("tokentranslator", tokenVisitor); //elemento a ser processado vlctx.put("command", command); // ifCommand eh diferente pois sempre vai ter if e else sides. if (command instanceof IfCommand) { vlctx.put("ifchild", list.get(0)); vlctx.put("elsechild", list.get(1)); } else { //demais elementos do N-S vlctx.put("childs", list); } //colocar no contexto a instancia do visitador pro velocity utilizar nos filhos vlctx.put("this", this); //colocar no contexto do velocity o contexto do visitador vlctx.put("ctx", ctx); try { //iniciar arquivo de template (cada elemento possui o seu) Template template = Velocity.getTemplate(templateFile); //mandar Velocity processar template template.merge(vlctx, buffer); //parar visitacao neste nivel pois elemento já foi "processado" return false; } catch (Exception e) { e.printStackTrace(); return false; } }

Quadro 12 – Implementação do método processChilds

74

private boolean processSingleCommand(ICommandVisitable command, Object ctx) { //processar o comando simples, este não tem "filhos" BufferedWriter buffer = (BufferedWriter) ctx; //novo contexto VelocityContext vlctx = new VelocityContext(); //processador de tradução NSTokenProcessorVisitor tokenVisitor = new NSTokenProcessorVisitor(); //colocar no contexto do velocity vlctx.put("tokentranslator", tokenVisitor); vlctx.put("command", command); vlctx.put("ctx", ctx); try { //iniciar arquivo de template para o elemento de instrucao //(não tem filhos) Template template = Velocity.getTemplate(NSGenerationConstants.SINGLECOMMANDVM); //processar template template.merge(vlctx, buffer); //retornar return false; } catch (Exception e) { e.printStackTrace(); return false; } }

Quadro 13 – Implementação do método processSingleCommand

O resultado do processo de geração de código pode ser afetado por três elementos:

a) texto inserido pelo usuário: é o texto que o usuário do plugin inseriu nos elementos

dos diagramas de classe e N-S. Pode ser o texto da condição de um comando de

decisão, o texto de um comando simples ou ainda o texto de um elemento do tipo

método no diagrama de classes;

b) templates para os elementos dos diagramas: são os arquivos de template criados

para representar cada um dos elementos dos diagramas de classe e N-S. Um

exemplo deste tipo de template é apresentado na Figura 39. Os templates criados

para os elementos dos diagramas de classe e N-S são apresentados nos apêndices A

e B;

c) templates com as tabelas de tradução: são os arquivos de template criados para

representar uma tabela de tradução. Os templates criados para as tabelas de

tradução são apresentados no apêndice C.

A tabela de tradução dá maior flexibilidade à utilização do plugin, pois permite ao

usuário definir uma tabela de palavras a serem substituídas. Se o gerador de código encontrar

75

uma determinada palavra em um elemento do diagrama, ela é substituída por outra palavra no

código gerado. Esta tabela de tradução é determinada através de um arquivo de template onde

apresenta a palavra a ser pesquisada e a palavra resultante. Um exemplo deste tipo de

template para mapear uma tabela de tradução pode ser visto no Quadro 14.

## Table mapping for conditions to JAVA #foreach($token in $tokens)# ##se encontrar ‘<>’ subtitui por ‘!=’ if($token.toUpperCase() == "<>")!= ##se encontrar ‘=’ subtitui por ‘==’ {elseif}($token.toUpperCase() == "=")== ##se encontrar ‘E’ subtitui por ‘&&’ {elseif}($token.toUpperCase() == "E")&& ##se encontrar ‘OU’ subtitui por ‘||’ {elseif}($token.toUpperCase() == "OU")|| ##palavra não encontrada, o resultado é a própria palavra {else}$token end #end

Quadro 14 – Template criado com a tabela de tradução para a condição dos elementos

Para possibilitar este mapeamento, a entrada definida pelo usuário passa por um

analisador léxico, que transforma uma String em uma lista de tokens. Por exemplo, se o

usuário inseriu no diagrama um elemento de decisão e na condição deste elemento ele inseriu

a seguinte String “a = b”, no momento que o Velocity processar esse elemento, esta String

vai passar pelo analisador léxico que vai retornar uma lista de tokens, neste caso “a”, “=” e

“b”. Esta lista é coloca no contexto do Velocity juntamente com o arquivo de template

apresentado no Quadro 14. Assim, a condição definida no elemento pelo usuário como “a =

b”, vai ser gerada na saída como “a == b”.

Existem ferramentas que são capazes de gerar um analisador léxico a partir de uma

definição regular. Uma destas ferramentas é o Gerador de Analisadores Léxicos e Sintáticos,

ou simplesmente GALS (SOURCEFORGE, 2007). Assim, foi criada uma definição regular

na ferramenta e a definição de tokens. A partir delas foi gerado código na linguagem Java que

correspondem às classes: AnalysisError, Constants, LexicalError, Lexico,

ScannerConstants, Token. Estas classes são utilizadas pela classe

BaseElementsTokenizer, para fazer a transformação de uma String em uma lista de tokens.

No Quadro 14 podem ser vistas as definições regulares criadas e no Quadro 15 a definição

dos tokens.

76

letra: [a-zA-Z] dígito: [0-9] caractere: [^\r\n'\\] caracteres: [^!\*] expoente: (E | e) (\+ | \-)? {dígito}+ decimal: "." {dígito}+ {expoente} | {expoente} | "." {dígito}+

Quadro 15 – Definições regulares criadas na ferramenta GALS

//ignorar :[\s\r\n\t] identificador: {letra} ( _ ({letra} | {dígito}) | {dígito} | {letra})* _? cte_inteira: {dígito}+ cte_real: {dígito}+ {decimal} cte_literal: \34 {caractere}* ( \\ \r\n (\s | \t)* \\ {caractere}*)* \34 //símbolos especiais ";" ":" "," "[" "]" "=" "." "(" ")" "+" "-" "*" "/" "<>" "<" "<=" ">" ">=" "%"

Quadro 16 – Definições de tokens criados na ferramenta GALS

3.3.2 Operacionalidade da implementação

O trabalho desenvolvido é um plugin para o ambiente Eclipse, então o primeiro passo

para sua utilização é entrar no ambiente de desenvolvimento. No momento que o usuário

inicia o ambiente, o mesmo solicita qual a pasta de trabalho a ser utilizada. A Figura 40

apresenta a tela que o ambiente apresenta solicitando a pasta de trabalho ou simplesmente

workspace.

77

Figura 40 – Iniciando o ambiente Eclipse: definir pasta de trabalho

Depois de iniciado o ambiente, é possível verificar se o plugin Drawcode está

instalado. Para isto, no menu principal deve-se clicar em Help>About Eclipse SDK. Será

aberta uma tela com informações sobre a versão do ambiente. Ao clicar no botão Plugin-

Details é apresentada uma tela contendo informações sobre todos os plugins instalados no

ambiente. A Figura 41 apresenta esta tela, destacando o plugin Drawcode.

Figura 41 – Informações sobre os plugins instalados no ambiente

A tela principal do ambiente apresenta as informações sobre a pasta de trabalho

escolhida, sendo todos os elementos do projeto armazenados nesta pasta. Na Figura 42 é

apresentada à tela principal do ambiente. Neste exemplo, o usuário criou um projeto chamado

projeto_drawcode_01 na pasta de trabalho. Dentro deste projeto o usuário criou um

diagrama de classes chamado diagrama_classe.drcd e dois diagramas N-S, nomeados

como metodo1.nsd e metodo2.nsd.

78

Figura 42 – Tela principal do ambiente Eclipse

Para editar o diagrama de classes, basta executar um duplo clique sobre o diagrama a

ser editado. Ao editá-lo, o ambiente abre uma nova janela para editar o diagrama e

disponibiliza uma paleta com os componentes possíveis para o diagrama de classes.

A Figura 43 apresenta um diagrama de classes em edição, onde foi definida a classe

Aluno com os atributos nota1, nota2, nota3 e o método getSituacao. Para incluir uma

classe, o usuário deve clicar na paleta sobre o elemento Class e clicar em alguma parte do

diagrama. Uma nova classe vai ser criada. Para incluir um novo atributo, deve-se clicar sobre

o botão Attribute na paleta e clicar dentro da área de Attributes da classe. Para incluir um

novo método, clicar sobre o botão Method e clicar dentro da área de Methods da classe.

79

Figura 43 – Edição do diagrama de classe: incluindo uma classe com atributos e métodos

Para editar o diagrama N-S, basta executar um duplo clique sobre o diagrama a ser

editado. Ao editá-lo o ambiente abre uma nova janela para editar o diagrama e disponibiliza

uma paleta com os componentes possíveis para o diagrama N-S.

A Figura 44 apresenta um diagrama N-S em edição, onde foi desenvolvido um

algoritmo que soma três notas e faz a divisão por três chegando à média. Se a média

encontrada for maior ou igual a seis, o algoritmo retorna a String “aprovado”. Caso contrário

vai retornar a String “reprovado”. Para incluir uma instrução, o usuário deve clicar na paleta

sobre o elemento Instruction e clicar em algum elemento no diagrama. Uma nova instrução

é criada abaixo do elemento selecionado. Para incluir mais uma instrução, basta repetir este

processo. Para incluir um elemento de decisão, deve-se clicar sobre o botão Decision na

paleta e clicar num dos comandos já existentes no diagrama. A instrução será criada abaixo do

elemento clicado.

80

Figura 44 – Edição do diagrama N-S: definindo o algoritmo

Para fazer a associação entre o método existente na classe e o algoritmo definido no

diagrama N-S, é preciso editar o diagrama de classes e dar um duplo clique sobre o método. A

Figura 45 apresenta um exemplo deste processo de associação. O ambiente então vai

apresentar uma tela solicitando um arquivo com a extensão “nsd”. Depois de selecionar o

arquivo e confirmar, a associação estará realizada.

81

Figura 45 – Associar um algoritmo representado por diagrama N-S para o método da classe

Depois de criada a classe e definido o algoritmo para atender o propósito do método, é

possível então gerar o código para o diagrama de classes. Este vai contemplar o corpo da

classe e o corpo dos métodos que tiverem um diagrama N-S associado. Para gerar o código

então é necessário no editor do diagrama de classes, clicar com o botão direito e selecionar a

opção Generate from Class Diagram. O ambiente então vai solicitar que seja definido um

arquivo. Neste arquivo serão geradas as classes definidas no diagrama.

O Quadro 17 apresenta o resultado da geração de código do diagrama de classes,

usando o DrawCode. Ele apresenta a classe Aluno, os atributos nota1, nota2, nota3 e o

método getSituacao(), para o qual também foi gerado o código na linguagem Java para o

algoritmo definido no diagrama N-S, que soma as três notas do aluno, calcula a média e

retorna a String “aprovado” se a média for maior ou igual a seis e “reprovado” se a média for

menor que seis.

O ambiente Eclipse possui um mecanismo para identação automática do código. Este

recurso foi utilizado no código gerado para melhorar sua legibilidade. Nenhum tipo de

alteração no conteúdo do código foi realizado.

82

//código gerado automaticamente pelo drawcode public class Aluno { int nota1 = 0; int nota2 = 0; int nota3 = 0; public String getSituacao() { // Corpo de metodo gerado automaticamento pelo drawcode int soma = nota1; soma = soma + nota2; soma = soma + nota3; int media = soma / 3; if (media >= 6) { return ("aprovado"); } else { return ("reprovado"); } } }

Quadro 17 – Resultado da geração de código a partir do diagrama de classe

3.4 RESULTADOS E DISCUSSÃO

Os resultados obtidos com o desenvolvimento deste projeto estão relacionados ao

tempo de desenvolvimento do software, complexidade para seu desenvolvimento e abstração

de linguagem de programação utilizada para criação. Também o aumento da abrangência de

código gerado por um gerador de código, afinal o corpo do método da classe também é

gerado.

Durante a revisão bibliográfica sobre os termos relacionados ao trabalho, foram

pesquisadas ferramentas para edição de diagramas de classe assim como para edição de

diagramas N-S. As ferramentas pesquisadas apresentam os diagramas N-S e de classe em

contextos diferentes. No Quadro 18 é apresentado um comparativo entre o Drawcode e os

trabalhos correlatos pesquisados.

83

Jupe

Top

case

d

NS

DE

dito

r

Str

ucto

rize

r

Dra

wco

de

Permite associar algum tipo de diagrama (para o corpo do método) com o diagrama de classe X

Diagrama classe X X X

Permite a edição de outros diagramas da UML X

Diagrama N-S X X X

Gera algum tipo de código X X X X

Permite incluir nova linguagem para geração de código X Quadro 18 – Comparativo entre Drawcode e seus correlatos

O principal diferencial do Drawcode entre seus correlatos é a de possibilitar o que

Souza (2000, p. 42) afirma ser possível.

“A Resolução Orientada a Objetos pode fazer uso da metodologia Resolução Estruturada para especificação dos métodos da classe, visto que aquela não apresenta técnica específica para elaboração dos algoritmos que os formam” (SOUZA 2000, p. 42).

Além de trazer essa possibilidade ao ambiente de desenvolvimento de software, outro

diferencial é utilizar um motor de template para a geração de código. Isso permite ao usuário

definir qual a linguagem que o código deve ser gerado, dando flexibilidade na sua utilização.

Os editores de diagramas de classe apenas geram o código para o corpo da classe, seus

atributos e operações mais simples como ler e escrever os valores dos atributos. Já os editores

de diagramas N-S por sua vez fazem a representação do algoritmo e geram o código para o

algoritmo, porém sem estarem contextualizados dentro de uma classe de objetos. O plugin

relaciona estas formas de representação do problema, cada uma contribuindo da melhor

maneira possível para a representação e resolução do problema.

O Drawcode apresenta algumas limitações. Uma delas é no editor de diagrama de

classes. No diagrama de classes serão editados apenas o nome da classe, os atributos e

métodos, não sendo tratados as demais representações deste tipo de diagrama como

associações, agregação, herança, entre outros.

Outra limitação é que o editor do diagrama N-S não possibilita a mudança de posição

de um elemento. Depois que um elemento é colocado no diagrama, não é possível alterar sua

posição. Alterar a ordem de dois comandos, por exemplo, exige que seja excluído e criado

novamente um dos dois comandos.

Outra limitação é quanto à edição do diagrama N-S. Não há nada que ajude o usuário a

consultar quais os atributos existentes na classe, ou ainda quais são os parâmetros recebidos

pelo método. Isso dificulta a criação do algoritmo, exigindo que o usuário conheça todos os

84

atributos ou parâmetros presentes no contexto do método. Os símbolos de paralelismo e bloco

de comandos não foram implementados.

Outra limitação que pode ser citada também é que o Drawcode não faz a validação das

expressões criadas pelo usuário nos elementos do diagrama de classes ou N-S. Se o usuário

criar um comando contendo uma expressão lógica com problema, o mesmo vai ser gerado da

mesma maneira, resultando em erro no momento da compilação do código gerado. Isso

decorre da não existência de formalismos na definição da linguagem interna dos comandos de

um Diagrama N-S.

85

4 CONCLUSÕES

O objetivo deste trabalho era criar uma ferramenta gráfica integrada ao ambiente de

desenvolvimento Eclipse que permitisse criar diagramas de classe e N-S. Depois de criados

estes diagramas permitir ao usuário associar um diagrama N-S para os métodos de uma classe

e a partir desta associação gerar o código completo para uma classe, contemplando o corpo da

classe, atributos, métodos e corpos dos métodos naqueles que apresentam um diagrama N-S

associado. Outro objetivo ainda era que fosse gerado código para a linguagem Java, com a

utilização de um motor de templates que permitiria ao usuário gerar código para outras

linguagens, bastando apenas alterar os templates criados.

Todos os objetivos foram alcançados, pois o Drawcode provê todas estas

funcionalidades. Embora não tivesse sido constatada a necessidade de uma tabela de tradução

nos objetivos iniciais, durante o desenvolvimento do projeto, optou-se por dar esta

possibilidade ao usuário, para aumentar a capacidade de utilização do mesmo. Para permitir

esta tabela de tradução, foi utilizada a ferramenta GALS para gerar um analisador léxico que

trata as entradas do usuário nos elementos do diagrama e gera uma lista de tokens,

possibilitando esta tradução.

Durante o desenvolvimento a escolha do padrão de projeto Visitor mostrou-se uma

escolha acertada, diminuindo a complexidade das operações necessárias sobre o modelo e

dando flexibilidade ao projeto, principalmente nas operações de montar a representação visual

do modelo e gerar código. Como as operações realizadas sobre o modelo são escritas em

classes separadas, novas operações podem ser adicionadas sem necessidade de alterações no

modelo. Se fosse necessária uma nova representação dos diagramas em outro framework

gráfico ou a utilização de outro motor de template, isto seria possível sem alterações no

modelo, sendo necessário apenas escrever um novo visitador que adicionaria esta

funcionalidade.

A utilização do Velocity como motor de templates cumpriu todas as necessidades do

projeto, apresentando simplicidade na linguagem usada para escrever os templates e

facilidade de acoplamento com a linguagem Java utilizada pelo Drawcode.

O ambiente Eclipse mostrou-se uma ferramenta muito adequada para o projeto. Sua

estrutura de funcionamento através de plugins o torna altamente extensível, dando

flexibilidade para que desenvolvedores que não fazem parte do projeto incluam novas

funcionalidades ao ambiente, como é o caso do Drawcode. Documentação completa e

86

exemplos facilitaram a criação do projeto. A criação deste plugin ainda oferece a

oportunidade de utilizá-lo em conjunto com outros plugins que contemplam outras fases do

desenvolvimento de software, como a fase de testes, por exemplo.

Como contribuições deste trabalho, destaca-se que o Drawcode vai possibilitar aos

desenvolvedores desenhar soluções Orientadas a Objeto e criar um algoritmo para representar

o que determinado método de uma classe deve fazer para atender os objetivos da mesma,

preenchendo uma lacuna existente nos diagramas da UML, que não apresenta nenhum de seus

diagramas com estas características.

Também, os professores que lecionam para as primeiras fases dos cursos de

computação podem utilizar o Drawcode para incentivar seus alunos a desenharem soluções

Orientadas a Objeto, porém dando a oportunidade de criar algoritmos utilizando a formalidade

do diagrama N-S para os métodos das classes.

Em ambos os casos citados, a geração de código vai permitir que os usuários do

Drawcode preocupem-se apenas com a definição da solução, abstraindo a linguagem de

programação a ser utilizada.

4.1 EXTENSÕES

Algumas sugestões de extensão para este trabalho são:

a) possibilitar na edição do diagrama N-S alterar a posição dos elementos do

diagrama;

b) incluir o recurso de complementação automática de código. Este recurso seria uma

combinação especial de teclas que ao pressioná-las apresente os comandos e ou

atributos existentes no contexto daquele elemento, no diagrama de classe e N-S;

c) possibilitar a geração de código de cada classe em arquivos separados;

d) definir e implementar uma linguagem e uma sintaxe a ser obedecida durante a

utilização do plugin, possibilitando validações sintáticas e semânticas sobre o

algoritmo criado, ou sobre a definição da classe;

e) implementar os demais elementos existentes no diagrama de classes, tais como,

associação, herança, multiplicidade, navegabilidade, entre outros;

f) possibilitar engenharia reversa, permitindo ler código fonte de programas já

existente e montar o diagrama de classes e o seus respectivos diagramas N-S;

87

g) criar arquivos de template que possibilitem gerar código em outras linguagens de

programação.

88

REFERÊNCIAS BIBLIOGRÁFICAS

AHO, Alfred V.; SETHI, Ravi; ULLMAN, Jeffrey D. Compiladores, princípios, técnicas e ferramentas. Tradução Daniel de Ariosto Pinto. Rio de Janeiro: LTC, 1995.

APACHE SOFTWARE FOUNDATION. Velocity overview. [S.l.], 2007a. Disponível em: <http://velocity.apache.org/engine/devel/overview.html>. Acesso em: 15 nov. 2007.

_________________________________. VTL reference. [S.l.], 2007b. Disponível em: <http://velocity.apache.org/engine/devel/vtl-reference-guide.html>. Acesso em: 15 nov. 2007.

BARROS, Leliane Nunes de et al. Desenvolvendo plugins. [S.l.], 2003. Disponível em: <http://www.ime.usp.br/~articuno/eclipse/desenvolvendo_plugins.html>. Acesso em: 08 abr. 2007.

CARBONI, Irenice de Fátima. Lógica de programação. São Paulo: Pioneira Thomson Learning, 2003.

ECLIPSE FOUNDATION. What is Eclipse ? [S.l.], 2007a. Disponível em: <http://www.eclipse.org/>. Acesso em: 16 abr. 2007.

_____________________. Eclipse plugin central. [S.l.], 2007b. Disponível em: <http://www.eclipseplugincentral.com/>. Acesso em: 16 abr. 2007.

_____________________. About the eclipse foundation. [S.l.], 2007c. Disponível em: <http://www.eclipse.org/org/>. Acesso em: 08 nov. 2007.

_____________________. Help - Eclipse SDK. [S.l.], 2007d. Disponível em: <http://help.eclipse.org/help33/index.jsp>. Acesso em: 12 nov. 2007.

FOWLER, Martin. UML essencial: um breve guia para a linguagem-padrão de modelagem de objetos. 3. ed. Tradução João Tortello. Porto Alegre: Bookman, 2005.

HERRINGTON, Jack. Code generation in action. Greenwich: Manning, 2003.

JUPE. Jupe is a UML plugin for Eclipse. [S.l.], 2007a. Disponível em: <http://jupe.binaervarianz.de/>. Acesso em: 17 nov. 2007.

____. Documentation. [S.l.], 2007b. Disponível em: <http://jupe.binaervarianz.de/wiki/Documentation>. Acesso em: 17 nov. 2007.

KALT, Marcel. NSD-Editor. [S.l.], 1996. Disponível em: <http://diuf.unifr.ch/softeng/student-projects/completed/kalt/NSD.html>. Acesso em: 15 nov. 2007.

89

MARTIN, James; MCCLURE, Carma. Técnicas estruturadas e case. Tradução Lúcia Faria Silva. São Paulo: Makron, 1991.

MARTIN, James; ODELL, James J. Análise e projeto orientados a objetos. Tradução José Carlos Barbosa dos Santos. São Paulo: Makron Books, 1996.

NASSI, Isaac; SHNEIDERMAN, Ben. Flowchart techniques for structured programming. ACM SIGPLAN Notices, New York, v. 8, n. 8, p. 12-26, ago. 1973.

ORIENTAÇÃO A OBJETO. In: WIKIPÉDIA, a enciclopédia livre. [S.l.]: Wikimedia Foundation, 2007. Disponível em: <http://pt.wikipedia.org/wiki/Orientação_a_objeto>. Acesso em: 10 set. 2007.

PARADIGMA DE PROGRAMAÇÃO. In: WIKIPÉDIA, a enciclopédia livre. [S.l.]: Wikimedia Foundation, 2007. Disponível em: <http://pt.wikipedia.org/wiki/Paradigma_de_programação>. Acesso em: 11 set. 2007.

PILONE, Dan; PITMAN, Neil. UML 2 rápido e prático: guia de referência. Tradução Armando Figueiredo. Rio de Janeiro: Alta Books, 2006.

PLUGIN. In: WIKIPÉDIA, a enciclopédia livre. [S.l.]: Wikimedia Foundation, 2007. Disponível em: <http://pt.wikipedia.org/wiki/Plugin>. Acesso em: 16 abr. 2007.

PRICE, Ana Maria de Alencar; TOSCANI, Simão Sirineo. Implementação de linguagens de programação: compiladores. 2. ed. Porto Alegre: Sagra Luzzato, 2001.

PROJETO TOPCASED. Projeto TOPCASED. [S.l.], 2007. Disponível em: <http://www.das.ufsc.br/das/projetos/projeto_index.php?lang=pt&pg=pe&projeto=13>. Acesso em: 17 nov. 2007.

ROCHA, Lucas. APE: plataforma para o desenvolvimento de aplicações web com PHP. [Salvador], 2005. Disponível em: <http://twiki.im.ufba.br/bin/view/Aside/ProjetoConclusaoDeCursoAPEMonografia#4_2_Motores_de_templates>. Acesso em: 16 abr. 2007.

SOURCEFORGE. GALS: gerador de analisadores léxicos e sintáticos. [S.l.], 2007. Disponível em: <http://gals.sourceforge.net/>. Acesso em: 17 nov. 2007.

SOUZA, Eliane Moreira Sá de. Um modelo para processo ensino-aprendizagem de procedimentos lógicos em diversos domínios. 2000. 202 f. Tese (Doutorado em Engenharia de Produção) – Pós-Graduação em Engenharia de Produção, Universidade Federal de Santa Catarina, Florianópolis. Disponível em: <http://teses.eps.ufsc.br/defesa/pdf/2417.pdf >. Acesso em: 10 abr. 2007.

SOUZA, Marco Antonio Furlan de et al. Algoritmos e lógica de programação. São Paulo: Pioneira Thomson, 2005.

90

STRUCTORIZER. Structorizer: about the project. [S.l.], 2007. Disponível em: <http://structorizer.fisch.lu/>. Acesso em: 17 nov. 2007.

TEMPLATE PROCESSOR. In: WIKIPÉDIA, a enciclopédia livre. [S.l.]: Wikimedia Foundation, 2007. Disponível em: <http://en.wikipedia.org/wiki/Template_processor>. Acesso em: 15 nov. 2007.

TONSIG, Sergio Luiz. Engenharia de software: análise e projeto de sistemas. São Paulo: Futura, 2003.

TOPCASED. UML Tools. [S.l.], 2007. Disponível em: <http://topcased-mm.gforge.enseeiht.fr/website/modeling/uml/index.html>. Acesso em: 17 nov. 2007.

91

APÊNDICE A – Templates criados na linguagem VTL para o diagrama N-S

Este apêndice apresenta os templates criados para a geração de código dos elementos

do diagrama N-S na linguagem Java. Foram criados 9 templates escritos na linguagem VTL,

representando cada um dos elementos do diagrama N-S (Quadro 19, 20, 21, 22, 23, 24, 25, 26

e 27).

## main list of commands to JAVA $command.toString() //Corpo de metodo gerado automaticamento pelo drawcode #foreach($child in $childs) $child.vlaccept($this,$ctx) #end

Quadro 19 - Template para a lista principal do diagrama N-S

## single command to JAVA $command.vlaccept($tokentranslator,$ctx);

Quadro 20 - Template para os comandos simples, atribuições e chamadas de sub-rotinas

## case to JAVA switch ($command.toString()) { #foreach($child in $childs) $child.vlaccept($this,$ctx) #end }

Quadro 21 - Template para o comando de seleção

## case option to JAVA #if ($command.toString().toUpperCase() != "DEFAULT")case $command.toString():#{else}default:#end #foreach($child in $childs) $child.vlaccept($this,$ctx) #end break;

Quadro 22 - Template para as opções do comando de seleção

## do-while to JAVA do { #foreach($child in $childs) $child.vlaccept($this,$ctx) #end } while ($command.vlaccept($tokentranslator,$ctx));

Quadro 23 - Template para o comando de repetição com condição no final do laço de repetição

## for to JAVA for ($command.vlaccept($tokentranslator,$ctx)) { #foreach($child in $childs) $child.vlaccept($this,$ctx) #end }

Quadro 24 - Template para o comando de repetição com número de repetições definido

92

## while to JAVA while ($command.vlaccept($tokentranslator,$ctx)) { #foreach($child in $childs) $child.vlaccept($this,$ctx) #end }

Quadro 25 - Template para o comando de repetição com condição no inicio do laço de repetição

## if to JAVA if ($command.vlaccept($tokentranslator,$ctx)) { $ifchild.vlaccept($this,$ctx) } else { $elsechild.vlaccept($this,$ctx) }

Quadro 26 - Template para o comando de decisão

## if and else sides of commands to JAVA #foreach($child in $childs) $child.vlaccept($this,$ctx) #end

Quadro 27 - Template para a lista de comandos verdadeiros e falsos do comando de decisão

93

APÊNDICE B – Templates criados na linguagem VTL para o diagrama de classes

Este apêndice apresenta os templates criados para representar o diagrama de classes.

Para a geração de código do diagrama de classe foram criados 5 templates escritos na

linguagem VTL que representam cada um dos elementos do diagrama de classe para geração

de código na linguagem Java (Quadro 28, 29, 30, 31, 32 e 33).

## main list of nodes class diagram to JAVA //código gerado automaticamente pelo drawcode #foreach($child in $childs) $child.vlaccept($this,$ctx) #end

Quadro 28 - Template para o lista de classes do diagrama de classes

## class declaration from classdiagram to JAVA public class $node.toString() { #foreach($child in $childs) $child.vlaccept($this,$ctx) #end }

Quadro 29 - Template criado para o elemento classe

## list of attributes from class diagram to JAVA #foreach($child in $childs) $child.vlaccept($this,$ctx) #end

Quadro 30 - Template criado para a lista de atributos da classe

## attribute from class diagram to JAVA $node.toString();

Quadro 31 - Template criado para o elemento atributo

## method from class diagram to JAVA public $node.toString() { $nsGeneration.genNS($node,$buffer) }

Quadro 32 - Template criado para o elemento método

## list of methods from class diagram to JAVA #foreach($child in $childs) $child.vlaccept($this,$ctx) #end

Quadro 33 - Template criado para lista de métodos da classe

94

APÊNDICE C – Relação dos templates da tabela de tradução

No Quadro 34 e Quadro 35 são apresentados os templates criados para representar as

tabelas de tradução.

## Table mapping for instruction to JAVA ## cada uma das opcoes do "if" tem um comentario no final da linha '##' ## por uma organizacao visual, se nao estiver presente o velocity entende ## como uma nova linha #foreach($token in $tokens) #if($token.toUpperCase() == "LEIA")IMPLEMENTAR O LER ## #{elseif}($token.toUpperCase() == "ESCREVA")System.out.println## #{elseif}($token.toUpperCase() == "INT")int ## #{elseif}($token.toUpperCase() == "REAL")Double ## #{elseif}($token.toUpperCase() == "LOGICO")Boolean ## #{elseif}($token.toUpperCase() == "LÓGICO")Boolean ## #{elseif}($token.toUpperCase() == "CHAR")char ## #{elseif}($token.toUpperCase() == "STRING")String ## #{elseif}($token.toUpperCase() == "RETORNA")return ## #{elseif}($token.toUpperCase() == "E")&& ## #{elseif}($token.toUpperCase() == "OU")|| ## #{elseif}($token.toUpperCase() == "<>")!= ## #{else}$token ## #end #end

Quadro 34 - Template contendo a tabela de mapeamento para os comandos do tipo instrução

## Table mapping for conditions to JAVA ## cada uma das opcoes do "if" tem um comentario no final da linha '##' ## por uma organizacao visual, se nao estiver presente o velocity entende ## como uma nova linha #foreach($token in $tokens) #if($token.toUpperCase() == "<>")!=# {elseif}($token.toUpperCase() == "=")==# {elseif}($token.toUpperCase() == "E")&&# {elseif}($token.toUpperCase() == "OU")||# {else}$token #end #end

Quadro 35 - Template com a tabela de mapeamento para as condições dos elementos do diagrama N-S

95

APÊNDICE D – Relação de métodos das classes apresentadas na Figura 23

No Quadro 36 é apresentado todos os métodos definidos para as classes representadas

na Figura 23.

96

Classe: CaseFigure

Método Tipo Visibilidade Parâmetros CaseFigure Public NSDiagramEditor [in] editor;

CaseCommand [in] node; paintFigure void Protected Graphics [in] g;

Classe: CommandAdder

Método Tipo Visibilidade Parâmetros Visit boolean Public NSDiagramCommand [in] command; Object

[in] ctx; Visit boolean Public NullCommand [in] command; Object [in] ctx; Visit boolean Public WhileCommand [in] command; Object [in]

ctx; Visit boolean Public DoWhileCommand [in] command; Object [in]

ctx; Visit boolean Public ForCommand [in] command; Object [in] ctx; Visit boolean Public InstructionCommand [in] command; Object

[in] ctx; Visit boolean Public CaseCommand [in] command; Object [in] ctx; Visit boolean Public CaseOption [in] command; Object [in] ctx; Visit boolean Public IfCommand [in] command; Object [in] ctx; Visit boolean Public IfCommands [in] command; Object [in] ctx; Visit boolean Public ElseCommands [in] command; Object [in] ctx;

Classe: CommandRemover

Método Tipo Visibilidade Parâmetros Visit boolean Public NSDiagramCommand [in] command; Object

[in] ctx; Visit boolean Public NullCommand [in] command; Object [in] ctx; Visit boolean Public WhileCommand [in] command; Object [in]

ctx; Visit boolean Public DoWhileCommand [in] command; Object [in]

ctx; Visit boolean Public ForCommand [in] command; Object [in] ctx; Visit boolean Public InstructionCommand [in] command; Object

[in] ctx; Visit boolean Public CaseCommand [in] command; Object [in] ctx; Visit boolean Public CaseOption [in] command; Object [in] ctx; Visit boolean Public IfCommand [in] command; Object [in] ctx; Visit boolean Public IfCommands [in] command; Object [in] ctx; Visit boolean Public ElseCommands [in] command; Object [in] ctx;

Classe: DecisionFigure

Método Tipo Visibilidade Parâmetros DecisionFigure Public NSDiagramEditor [in] editor; IfCommand [in]

node; paintFigure void Protected Graphics [in] g;

97

Classe: DoWhileFigure

Método Tipo Visibilidade Parâmetros DoWhileFigure Public NSDiagramEditor [in] editor;

DoWhileCommand [in] node; Classe: ForFigure

Método Tipo Visibilidade Parâmetros ForFigure Public NSDiagramEditor [in] editor; ForCommand

[in] node; Classe: InstructionFigure

Método Tipo Visibilidade Parâmetros InstructionFigure Public NSDiagramEditor [in] editor;

InstructionCommand [in] node; Classe: LayoutAdjustCalculatorVisitor

Método Tipo Visibilidade Parâmetros adjustLayout void Public ICommandVisitable [in] node;

HashMap<ICommandVisitable, Rectangle> [in] map;

processHorizontalLayout boolean Private ICommandVisitable [in] command; List<ICommandVisitable> [in] list; Object [in] ctx; Rectangle [in] offset;

processSingleCommand boolean Private ICommandVisitable [in] command; Object [in] ctx;

processVerticalLayout boolean Private ICommandVisitable [in] command; List<ICommandVisitable> [in] list; Object [in] ctx; Rectangle [in] offset;

Visit boolean Public NSDiagramCommand [in] command; Object [in] ctx;

Visit boolean Public NullCommand [in] command; Object [in] ctx;

Visit boolean Public WhileCommand [in] command; Object [in] ctx;

Visit boolean Public DoWhileCommand [in] command; Object [in] ctx;

Visit boolean Public ForCommand [in] command; Object [in] ctx;

Visit boolean Public InstructionCommand [in] command; Object [in] ctx;

Visit boolean Public CaseCommand [in] command; Object [in] ctx;

Visit boolean Public CaseOption [in] command; Object [in] ctx;

Visit boolean Public IfCommand [in] command; Object [in] ctx;

Visit boolean Public IfCommands [in] command; Object [in] ctx;

Visit boolean Public ElseCommands [in] command; Object [in] ctx;

98

Classe: LayoutCalculatorVisitor

Método Tipo Visibilidade Parâmetros getLayout HashMap<ICo

mmandVisitable, Rectangle>

Public ICommandVisitable [in] node;

processHorizontalLayout boolean Private ICommandVisitable [in] command; List<ICommandVisitable> [in] list; Object [in] ctx; Rectangle [in] offSets;

processSingleCommand boolean Private ICommandVisitable [in] command; Object [in] ctx;

processVerticalLayout boolean Private ICommandVisitable [in] command; List<ICommandVisitable> [in] list; Object [in] ctx; Rectangle [in] offSets;

Visit boolean Public NSDiagramCommand [in] command; Object [in] ctx;

Visit boolean Public NullCommand [in] command; Object [in] ctx;

Visit boolean Public WhileCommand [in] command; Object [in] ctx;

Visit boolean Public DoWhileCommand [in] command; Object [in] ctx;

Visit boolean Public ForCommand [in] command; Object [in] ctx;

Visit boolean Public InstructionCommand [in] command; Object [in] ctx;

Visit boolean Public CaseCommand [in] command; Object [in] ctx;

Visit boolean Public CaseOption [in] command; Object [in] ctx;

Visit boolean Public IfCommand [in] command; Object [in] ctx;

Visit boolean Public IfCommands [in] command; Object [in] ctx;

Visit boolean Public ElseCommands [in] command; Object [in] ctx;

Classe: NSDiagramEditParts

Método Tipo Visibilidade Parâmetros activate void Public addRootEditPartChild void Public NSDiagramEditParts [in] child; createEditPolicies void Protected createFigure IFigure Protected deactivate void Public getCastedModel ICommandVisitable Private getModelChildren List<ICommandVisitable> Public NSDiagramEditParts Public NSDiagramEditor [in] editor;

ICommandVisitable [in] node; performDirectEdit void Protected performRequest void Public Request [in] request; propertyChange void Public PropertyChangeEvent [in] evt;

99

refreshChildren void Public removeChildrens void Public

Classe: NSDiagramEditor

Método Tipo Visibilidade Parâmetros commandStackChanged void Public EventObject [in] event; configureGraphicalViewer void Protected createPaletteViewerProvider PaletteViewerProv

ider Protected

createTransferDropTargetListener

org.eclipse.jface.util.TransferDropTargetListener

Private

doSave void Public IProgressMonitor [in] monitor; getChildrens List<ICommandVi

sitable> Public ICommandVisitable [in] node;

getNodeRect Rectangle Public ICommandVisitable [in] node; getNSDHandler NSDiagramHandl

er Public

getPalettePreferences FlyoutPreferences Protected getPaletteRoot PaletteRoot Protected initializeGraphicalViewer void Protected NSDiagramEditor Public RefreshVisual void Public setInput void Public IEditorInput [in] input;

Classe: NSDiagramHandler

Método Tipo Visibilidade Parâmetros getChildrens List<ICommandVisitable> Public ICommandVisitable [in] node; getRootModelNode ICommandVisitable Public insertCommand void Public ICommandVisitable [in] node;

ICommandVisitable [in] previousBrother;

MoveCommand boolean Public ICommandVisitable [in] Source; ICommandVisitable [in] previousBrother;

NSDiagramHandler Public ReadDiagram void Public String [in] file; RemoveCommand void Public ICommandVisitable [in]

killedNode; SaveDiagram void Public String [in] file; toModel void Public String [in] xml; toXML String Public

Classe: NSNodeCreateCommand

Método Tipo Visibilidade Parâmetros canExecute boolean Public execute void Public NSNodeCreateCommand Public NSDiagramEditor [in] editor;

ICommandVisitable [in] newNode; ICommandVisitable [in] previousBrother;

100

redo void Public undo void Public

Classe: NSPartFactory

Método Tipo Visibilidade Parâmetros createEditPart EditPart Public EditPart [in] context; Object [in] node; NSPartFactory Public NSDiagramEditor [in] editor;

Classe: NSXYLayoutEditPolicy

Método Tipo Visibilidade Parâmetros createAddCommand Command Protected EditPart [in] child;

Object [in] constraint; createAddCommand Command Protected EditPart [in] child;

Rectangle [in] constraint; ChangeBoundsRequest [in] request;

createChangeConstraintCommand Command Protected ChangeBoundsRequest [in] req; EditPart [in] nodePart; Object [in] constraint;

createChangeConstraintCommand Command Protected EditPart [in] child; Object [in] constraint;

getAddCommand Command Protected Request [in] generic; getCreateCommand Command Protected CreateRequest [in] request; getDeleteDependantCommand Command Protected Request [in] request; getMoveChildrenCommand Command Protected Request [in] request; NSXYLayoutEditPolicy Public NSXYLayoutEditPolicy Public NSDiagramEditor [in] editor;

XYLayout [in] layout; Classe: NodeChildrenDiscover

Método Tipo Visibilidade Parâmetros fillList void Public List<ICommandVisitable> [in] list;

ICommandVisitable [in] node; Visit boolean Public NSDiagramCommand [in] command; Object [in] ctx; Visit boolean Public NullCommand [in] command; Object [in] ctx; Visit boolean Public WhileCommand [in] command; Object [in] ctx; Visit boolean Public DoWhileCommand [in] command; Object [in] ctx; Visit boolean Public ForCommand [in] command; Object [in] ctx; Visit boolean Public InstructionCommand [in] command; Object [in] ctx; Visit boolean Public CaseCommand [in] command; Object [in] ctx; Visit boolean Public CaseOption [in] command; Object [in] ctx; Visit boolean Public IfCommand [in] command; Object [in] ctx; Visit boolean Public IfCommands [in] command; Object [in] ctx; Visit boolean Public ElseCommands [in] command; Object [in] ctx;

Classe: NodeFigure

Método Tipo Visibilidade Parâmetros NodeFigure Public NSDiagramEditor [in] editor;

ICommandVisitable [in] node;

101

Classe: NullFigure

Método Tipo Visibilidade Parâmetros NullFigure Public NSDiagramEditor [in] editor; NullCommand

[in] node; Classe: WhileFigure

Método Tipo Visibilidade Parâmetros WhileFigure Public NSDiagramEditor [in] editor; WhileCommand [in]

node; Interface: ICommandVisitable

Método Tipo Visibilidade Parâmetros accept boolean Public ICommandVisitor [in] visitor; Object [in] ctx; getTokenList List<String> Public setValue void Public String [in] newValue; vlaccept void Public ICommandVisitor [in] visitor; Object [in] ctx;

Interface: ICommandVisitor

Método Tipo Visibilidade Parâmetros Visit boolean Public NSDiagramCommand [in] command; Object [in] ctx; Visit boolean Public NullCommand [in] command; Object [in] ctx; Visit boolean Public WhileCommand [in] command; Object [in] ctx; Visit boolean Public DoWhileCommand [in] command; Object [in] ctx; Visit boolean Public ForCommand [in] command; Object [in] ctx; Visit boolean Public InstructionCommand [in] command; Object [in] ctx; Visit boolean Public CaseCommand [in] command; Object [in] ctx; Visit boolean Public CaseOption [in] command; Object [in] ctx; Visit boolean Public IfCommand [in] command; Object [in] ctx; Visit boolean Public IfCommands [in] command; Object [in] ctx; Visit boolean Public ElseCommands [in] command; Object [in] ctx;

Quadro 36 – Operações das classes apresentadas na Figura 23