DOMINGUES, W.B. Linguagem EspecÃfica de - LTS-i

Transcrição

DOMINGUES, W.B. Linguagem EspecÃfica de - LTS-i
Instituto de Pesquisas Tecnológicas do Estado de São Paulo
Wladimir Braguini Domingues
Linguagem Específica de Domínio para
Governo Eletrônico em Mídia Cruzada
São Paulo
2009
Wladimir Braguini Domingues
Linguagem Específica de Domínio para
Governo Eletrônico em Mídia Cruzada
Dissertação de Mestrado apresentada ao
Instituto de Pesquisas Tecnológicas do
Estado de São Paulo - IPT, como parte
dos requisitos para a obtenção do título de
Mestre em Engenharia de Computação
Data da aprovação: __ / __ / ____
Prof. Dra. Lucia Vilela Leite Filgueiras
IPT – Instituto de Pesquisas Tecnológicas
do Estado de São Paulo
Membros da Banca Examinadora:
Prof. Dra. Lucia Vilela Leite Filgueiras (Orientadora)
IPT — Instituto de Pesquisas Tecnológicas
Prof. Dr. Jose Eduardo Zindel Deboni
IPT — Instituto de Pesquisas Tecnológicas
Prof. Dr. João José Neto
EPUSP — Escola Politécnica da Universidade de São Paulo
Wladimir Braguini Domingues
Linguagem Específica de Domínio para
Governo Eletrônico em Mídia Cruzada
Dissertação de Mestrado apresentada ao
Instituto de Pesquisas Tecnológicas do
Estado de São Paulo - IPT, como parte
dos requisitos para a obtenção do título de
Mestre em Engenharia de Computação
Área de Concentração: Engenharia de Software
Orientadora: Prof. Dra. Lucia Vilela Leite Filgueiras
Dez/2009
Dedicatória
Dedico este trabalho aos meus avós, Zilda e Hermogenes Braguini (in memorian), por
sempre acreditarem em mim e no valor da educação.
Agradecimentos
À minha orientadora Lucia, não só pela valiosa orientação, mas também pela amizade
e compreensão.
À minha esposa Luciana, pelo carinho, dedicação e, sobretudo, amor.
À minha família, pela apoio constante e incondicional.
Um agradecimento especial a todos do IPT por tornarem este trabalho possível.
Ao Grupo de Interação Humano-Computador do PCS-LTS da Poli/USP, pelo convívio
alegre, pelos momentos de descontração e pela troca de conhecimento.
E a todos que, de alguma forma, contribuíram para essa minha vitória.
Muito Obrigado!
RESUMO
Avanços tecnológicos criam novos meios de comunicação e ampliam os modos de
interação homem-computador proporcionando uma experiência de uso positiva. Um
sistema de mídia cruzada se caracteriza pelo uso de múltiplos meios de comunicação
suportando um tema central ou conteúdo principal. Um tema central que pode ser
aplicado sobre múltiplas mídias é o de serviços de governo. Este trabalho objetiva
projetar uma linguagem específica de domínio que consiga expressar aspectos de
serviços de governo em mídia cruzada. Com essa linguagem é possível modelar
novos sistemas x-gov em um nível mais alto de abstração.
Palavras-chave: DSL, Serviços de Governo, x-gov, Mídia Cruzada.
iii
ABSTRACT
Domain Specific Language for e-Government on Cross-Media
Technological advances creates new media that expands the modes of humancomputer interaction providing a positive experience of use. A cross-media system
is characterized by the use of multiple media, supporting a central theme or content.
A central theme that can be applied over multiple media is the theme of government
services. This work aims to design a domain specific language that can express
aspects of government services in cross-media. This language allows modeling new
x-gov systems in a higher level of abstraction.
Key Words: DSL, government services, x-gov, cross-media.
iv
Sumário
Resumo
iii
Abstract
iv
Lista de Ilustrações
viii
Lista de Tabelas
ix
Lista de Códigos
x
Lista de Abreviaturas e Siglas
xi
1 Introdução
1.1 Motivação . . . . . . . . . . . . . . . .
1.2 Objetivo . . . . . . . . . . . . . . . . .
1.3 Resultados Esperados e Contribuições
1.4 Método de Trabalho . . . . . . . . . . .
1.5 Organização do Trabalho . . . . . . . .
.
.
.
.
.
1
2
4
5
5
6
.
.
.
.
.
.
.
.
.
.
.
8
8
9
12
12
13
13
14
16
16
18
18
3 Mídia Cruzada e Governo Eletrônico
3.1 Mídia Cruzada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
20
20
2 Linguagem Específica de Domínio
2.1 Introdução . . . . . . . . . . . . . .
2.2 Definição . . . . . . . . . . . . . . .
2.3 Classificação . . . . . . . . . . . .
2.3.1 DSL Externa . . . . . . . . . . . .
2.3.2 DSL Interna . . . . . . . . . . . .
2.4 Método de Desenvolvimento . . . .
2.4.1 Decisão . . . . . . . . . . . . . .
2.4.2 Análise . . . . . . . . . . . . . . .
2.4.3 Projeto . . . . . . . . . . . . . . .
2.4.4 Implementação . . . . . . . . . .
2.5 Considerações . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
v
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3.1.1 Definição de Mídia . . . . . . . . . . . . . . . .
3.1.2 Mídia Cruzada . . . . . . . . . . . . . . . . . . .
3.2 Governo Eletrônico em Mídia Cruzada . . . . . .
3.2.1 e-gov, m-gov, t-gov, x-gov . . . . . . . . . . . .
3.2.2 Serviços de Governo . . . . . . . . . . . . . . .
3.2.3 Padrões de Tarefas para Serviços de Governo .
.
.
.
.
.
.
20
21
24
24
25
27
.
.
.
.
.
.
.
.
.
29
29
31
31
33
35
37
37
37
39
.
.
.
.
.
.
41
41
42
46
52
59
70
6 Conclusões
6.1 Análise dos Resultados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.2 Reflexões . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6.3 Trabalhos Futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
72
73
75
77
REFERÊNCIAS
78
A Exemplos de DSLs
A.1 jMock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.2 API Fluente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
83
83
84
B Framework X-Gov
B.1 Diagrama de Classes do FrameworkLibrary . . . . . . . . . . . . . . . . . .
86
86
C Implementação da CroMeL
90
4 Framework X-Gov
4.1 Conceito . . . . . . . . . . . . . .
4.2 Arquitetura . . . . . . . . . . . . .
4.2.1 Modelo de Domínio . . . . . . .
4.2.2 Componentes . . . . . . . . . .
4.3 Partes Integrantes do Framework
4.3.1 Gerenciador de Componentes .
4.3.2 Gerenciador de Transições . . .
4.3.3 Linguagem de Configuração . .
4.4 Conclusão . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
5 A Linguagem CroMeL
5.1 Introdução a CroMeL . . . . . . . .
5.1.1 Elementos da linguagem CroMeL
5.1.2 Implementação . . . . . . . . . .
5.2 Gramática . . . . . . . . . . . . . .
5.3 Semântica . . . . . . . . . . . . . .
5.4 Discussão dos Resultados . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
vi
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
C.1
C.2
C.3
C.4
C.5
C.6
C.7
C.8
Regras Léxicas e Sintáticas da CroMeL . . . . . . . .
Regras Semânticas da CroMeL . . . . . . . . . . . .
Diagramas de Sintaxe . . . . . . . . . . . . . . . . .
Autômato Finito Determinístico . . . . . . . . . . . .
ANTLRWorks . . . . . . . . . . . . . . . . . . . . . .
CroMeL XML . . . . . . . . . . . . . . . . . . . . . .
CromelService para Interpretador na versão C# . . .
ComponentFactory para Interpretador na versão C# .
vii
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
90
92
99
101
102
102
104
110
Lista de Ilustrações
Figura 3.1 Big Brother Brasil 9 . . . . . . . . . . . . . . . . . . . . . . . . . .
Figura 3.2 Cadeia de Conteúdo Digital [Fonte: Boumans2004] . . . . . . . .
23
27
Figura 4.1
Figura 4.2
Figura 4.3
Figura 4.4
Figura 4.5
Figura 4.6
Figura 4.7
Figura 4.8
Composição de um X-Gov . . . . . . . . . . . . . . . . .
Arquitetura X-Gov . . . . . . . . . . . . . . . . . . . . .
ComponentModel . . . . . . . . . . . . . . . . . . . . . .
Componente GetTrackIdComponent . . . . . . . . . . .
Padrões de Tarefas . . . . . . . . . . . . . . . . . . . . .
Modelo X-Gov . . . . . . . . . . . . . . . . . . . . . . . .
Ferramenta gráfica para descrição de um serviço . . . .
Configuração através do X-Builder e através da CroMeL
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
30
31
32
34
35
36
38
39
Figura 5.1
Figura 5.2
Figura 5.3
Figura 5.4
Figura 5.5
Figura 5.6
Contexto da linguagem CroMeL . . . . . . . . . . . .
Mapeamento de contexto na linguagem CroMeL . .
Etapas de implementação do interpretador CroMeL
Implantação de um script CroMeL . . . . . . . . . .
Interpretação de um script CroMeL . . . . . . . . . .
Grafo de dependência entre as regras sintáticas . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
42
44
46
51
52
58
Figura B.1
Figura B.2
Figura B.3
Figura B.4
Exemplo de classes de componentes . . . . . . . . . .
Componentes FindEntityInfo para TV, Mobile e Web . .
Componente GetPreServiceInfo para TV, Mobile e Web
Classes de Transição . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
87
88
89
89
Figura C.1
Figura C.2
Figura C.3
Figura C.4
Figura C.5
Figura C.6
Figura C.7
Figura C.8
Figura C.9
Diagrama de sintaxe da raiz da gramática . . . . . . . . . . . . .
Diagrama da sintaxe de declaração de um serviço . . . . . . . .
Diagrama da sintaxe dos elementos que pertencem a um serviço
Diagrama da sintaxe de uma atividade . . . . . . . . . . . . . . .
Diagrama da sintaxe de declaração de parametros . . . . . . . .
Diagrama de sintaxe de transições . . . . . . . . . . . . . . . . .
Diagrama de sintaxe de navegação . . . . . . . . . . . . . . . . .
DFA reconhecedor dos Tokens da linguagem CroMeL . . . . . .
Ferramenta ANTLRWorks no desenvolvimento da CroMeL . . . .
99
99
99
100
100
100
100
101
102
viii
.
.
.
.
.
.
Lista de Tabelas
Tabela 2.1
Tabela 2.2
Tabela 2.3
Tabela 2.4
Tabela 2.5
Tabela 2.6
Tabela 2.7
Padrões de Decisão . . . . . . . . . . . . . . . . . . . . . . .
Exemplos para os Padrões de Decisão . . . . . . . . . . . .
Padrões de Análise . . . . . . . . . . . . . . . . . . . . . . .
Padrões de Projeto . . . . . . . . . . . . . . . . . . . . . . . .
Exemplos de linguagens para os Padrões de Projeto . . . . .
Sistemas e Ferramentas de Desenvolvimento de Linguagem
Padrões de Implementação para DSLs executáveis . . . . .
ix
.
.
.
.
.
.
.
.
.
.
.
.
.
.
15
15
16
17
17
18
18
Lista de Códigos
5.1
5.2
5.3
5.4
5.5
5.6
5.7
5.8
5.9
5.10
5.11
5.12
5.13
5.14
5.15
5.16
5.17
C.1
C.2
C.3
C.4
C.5
Cenario de matricula escolar . . . . . . . . . . . . . . . . . . . .
Raiz da linguagem . . . . . . . . . . . . . . . . . . . . . . . . . .
Sentenças de entrada para um serviço e declaração de variáveis
Gramática para descrição das ativadades de um serviço . . . . .
Sentenças de entrada para uma atividade . . . . . . . . . . . . .
Gramática para declaração de transições e navegações . . . . .
Sentenças de entrada para transição e navegação . . . . . . . .
Regras léxicas . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Script CroMeL de entrada . . . . . . . . . . . . . . . . . . . . . .
Semântica de declaração de variável . . . . . . . . . . . . . . . .
Semântica de uma atividade . . . . . . . . . . . . . . . . . . . .
Semântica de navegação . . . . . . . . . . . . . . . . . . . . . .
Semântica de uma transição . . . . . . . . . . . . . . . . . . . .
Semântica dos parâmetros de componentes e transições . . . .
Semântica de expressões . . . . . . . . . . . . . . . . . . . . . .
Semântica de um Serviço . . . . . . . . . . . . . . . . . . . . . .
Codigo de Saida . . . . . . . . . . . . . . . . . . . . . . . . . . .
Gramatica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Semantica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Cromel Service . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Component Factory . . . . . . . . . . . . . . . . . . . . . . . . .
x
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 50
. 54
. 54
. 55
. 55
. 56
. 57
. 57
. 60
. 62
. 63
. 64
. 64
. 65
. 66
. 67
. 68
. 90
. 92
. 102
. 104
. 110
Lista de Abreviaturas e Siglas
G2C
x-gov
GPL
DSL
CroMeL
EDSL
IETF
W3C
Mime
HTTP
ANTLR
YAML
XAML
XUL
VB
Government to Citizen.
Serviço de governo sobre mídia cruzada — cross-media
government.
Arcabouço de software para apoiar a criação de
serviços x-gov — Framework X-Gov.
General Purpose Language.
Domain-Specific Language.
Cross-Media Language.
Embedded Domain Specific Language.
Internet Engineering Task Force.
World Wide Web Consortium.
Multipurpose Internet Mail Extensions.
Hypertext Transfer Protocol.
ANother Tool for Language Recognition.
YAML Ain’t Markup Language.
eXtensible Application Markup Language.
XML User Interface Language.
Visual Basic.
JSF
EJB
IHC
CTA
LP
API
EBNF
AST
IDE
IPT
CMID
ORM
AJAX
TDD
MOP
Java Server Faces.
Enterprise Java Beans.
Interação Homem-Computador.
call-to-action.
Linguagem de Programação.
Application Programming Interface.
Extended Backus–Naur Form.
Abstract Syntax Tree.
Integrated Development Environmnet.
Instituto de Pesquisas Tecnológicas.
Cross-Media Interaction Design.
Object Relational Mapping.
Asynchronous JavaScript and XML.
Test Driven Development.
Meta-Object Protocol.
FXG
xi
Seção
1
Introdução
A cada nova invenção concebida no transcorrer da história, o homem viu-se
obrigado a descobrir meios de interagir com elas e, na maioria das vezes, a necessidade levou-o além, tornando-o capaz de ressignificar a função para a qual o objeto
fora originalmente pensado. Sharp et al. (2007) explica:
Avanços nas interfaces gráficas, reconhecimento de fala e escrita, junto
com a chegada da Internet, telefones celulares, redes sem fios, tecnologias de sensores e um conjunto de outras tecnologias disponíveis com
telas grandes e pequenas, mudaram como se dá a interação homemcomputador. . . Por exemplo, maneiras inovadoras de controlar e interagir
com informações digitais foram desenvolvidas, o que inclui reconhecimento
de gestos, interfaces sensíveis, e até a interação estimulada pela emoção.
Pesquisadores e desenvolvedores começaram a combinar o mundo físico
com o digital, resultando em novas interfaces. . . Com isso o projeto de
novas interfaces vai além do usuário individual, suportando interações sociais de pequena e grande escala para pessoas em trânsito, em casa, ou
no trabalho.
No mundo atual, onde as informações são produzidas em todo lugar e cada
vez mais acessíveis por meios diversos, deve-se aproveitar essas características para
criar recursos melhores com o objetivo de facilitar novos tipos de interação.
1
1.1
Motivação
Cross media can be defined as the collaborative support of multiple media
to delivering a single story or theme, in which the storyline directs the receiver from one medium to the next, according to each medium’s strength to
the dialogue. (Filgueiras et al., 2008)
Um projeto de mídia cruzada pode ser visto como: “Uso de conteúdo sobre vários
dispositivos suportando um tema central.” Neste caso, o tema central será um serviço
de governo.
Conforme defendido por Boumans (2004), o essencial ao conceito de mídia
cruzada (cross-media) é que exista mais de uma mídia ou dispositivo de distribuição
para suportar o tema central ou conteúdo principal de um projeto com suas próprias
forças. Assim, a informação é distribuída em múltiplas mídias ampliando as formas de
acesso ao conteúdo, para o qual muda o paradigma de um usuário interagindo com
um computador desktop, e possibilita o acesso a informações e serviços também pela
TV, telefone fixo ou celular, além da mídia impressa e do próprio computador desktop.
A mídia cruzada é uma particularização importante do conceito de multimodalidade,
no sentido de que há uma integração forte entre os meios (Filgueiras, 2007).
O governo necessita se comunicar de maneira eficiente e oferecer serviços aos
cidadãos para cumprir na totalidade o seu papel. Sendo assim, poderia aproveitarse das várias mídias disponíveis para ampliar as formas de comunicação. Segundo
Filgueiras (2007), a mídia cruzada pode ser uma maneira promissora para ampliar a
interatividade G2C.
No entanto, existe uma grande dificuldade para desenvolver um sistema com
apoio às características apresentadas devido à diversidade de tecnologias utilizadas
(relacionadas a programação, interface, capacidade de rede e multimídia), sendo que
cada programa necessita de um ambiente de execução apropriado. Esse ambiente
de execução, ou plataforma, é utilizado para construir e executar as aplicações que
fazem parte do sistema e pode-se observar facilmente que uma aplicação para um
dispositivo celular com apoio a apenas uma mídia poderia ser desenvolvida em diversas plataformas, como JavaME (Micro Edition), BREW, Symbian e .NET Mobile.
Um sistema em mídia cruzada envolve, normalmente, mais de uma aplicação
construída sobre diferentes tecnologias/plataformas. Deve ser projetado não apenas
para incluir as diversas aplicações, mas também coordená-las, transferir estado e estruturar suas ações a serem executadas em conjunto para correto funcionamento do
sistema. Portanto, visto dessa forma, um sistema em mídia cruzada torna-se complexo e distribuído.
Nesse contexto surge a necessidade de um framework que apóie a implementação de sistemas em mídia cruzada.
2
Com o intuito de suprir essa necessidade iniciou-se, em 2007, o projeto X-Gov
(Filgueiras, 2007), patrocinado pela Fapesp e Microsoft Research, com o objetivo de
estudar a mídia cruzada como uma abordagem promissora para ampliar a interatividade entre o governo e o cidadão.
Em sua completude, o projejo X-Gov envolve uma série de sub-projetos, entre
os quais se encontra esta proposta, que, quando reunidos, resultam em um arcabouço de software (framework ) que facilita o desenvolvimento de serviços de governo
utilizando diversos meios de comunicação. O propósito do Framework X-Gov é permitir um desenvolvimento rápido de aplicações, e para conseguir isso, conta com um
conjunto de componentes de software, ferramentas de modelagem e uma aplicação
central que roda em um servidor web.
No texto da proposta do projeto submetida a Fapesp foram colocadas sob enfoque as tendências mundiais referentes à governo eletrônico, e estas demonstraram
que, apesar dos aspectos positivos de comunicação e acessibilidade, o governo eletrônico seria suplantado pelo X-Gov, devido ao fato deste atingir o cidadão não somente
pelo computador desktop, mas também pela televisão, telefone fixo ou celular, jornais,
revistas, enfim, por múltiplas mídias. Essas cenário atual diferencia-se do projeto XGov por apresentar limitadas possibilidades de interação, uma vez que a experiência
do usuário restringe-se a um computador desktop, provavelmente em um centro de
inclusão digital.
Considerando que estas interações ocorrem sobre diferentes plataformas e associado a elas estão diversas tecnologias, deve-se trabalhar em um nível de abstração
adequado, para construir sistemas que são constituídos de componentes distribuídos
em vários dispositivos, sendo este nível de abstração, por sua vez, o tema desta dissertação; assim faz-se necessário um nível de abstração adequado para ser utilizado
como ferramenta de modelagem no projeto X-Gov.
Buscar uma linguagem capaz de descrever os vários componentes contidos
nos dispositivos de uma plataforma de mídia cruzada apresentou-se como uma oportunidade para explorar as diferenças entre uma enfoque genérico e um específico
aplicado às disciplinas de engenharia de software. Assim, notou-se que um enfoque genérico fornece soluções para muitos problemas, mas poderá não ser o mais
adequado quando se trata de um problema particular, enquanto que, um enfoque específico fornece uma solução melhor para um pequeno grupo de problemas, porém
sua utilização é limitada a essa classe de problemas, o que torna difícil sua aplicação
em situações diferentes. Dentro dessa dicotomia em computação, encontra-se linguagens específicas de domínio (DSLs) versus linguagens de propósito geral (GPLs) (van
Deursen et al., 2000).
Segundo Brooks (1975) programadores criam instruções (statements), ou linhas de código, a uma taxa constante, portanto linguagens de mais alto nível são
3
mais produtivas. O uso de DSLs pode aumentar o nível de abstração aplicado na
programação, podendo declarar, ou especificar o que deverá acontecer e deixar para
camadas inferiores, de interpretação, tratar de executar as instruções, uma característica típica de linguagens declarativas ou de configuração.
A seguir são apresentadas algumas DSLs muito utilizadas, junto com seus respectivos domínios Jones (1996) apud Mernik et al. (2005):
• BNF (Backus–Naur Form): Especificação formal de sintaxe de linguagens;
• Excel: Manipulação de dados em planilhas;
• HTML: Páginas web com hypertexto;
• LATEX: Processador e formatador de textos;
• Make: Ferramenta para construção de software;
• MATLAB: Computação técnica matemática;
• SQL (Structured Query Language): Consulta a bancos de dados;
• VHDL (VHSIC hardware description language): Linguagem para descrição de
hardware.
Linguagens específicas de domínio são importantes para o desenvolvimento
de software porque representam uma maneira de codificar a solução de um problema
de forma mais natural, com maior fidelidade e manutenabilidade do que as linguagens
de propósito geral.
1.2
Objetivo
Essa pesquisa é motivada pela dificuldade em se criar sistemas constituídos de
diversas tecnologias, característica intrínseca da mídia cruzada, e como as questões
de comunicação do governo com o cidadão é um forte fator motivador para aplicar a
mídia cruzada, faz-se necessário considerar uma forma de programação que facilite a
criação de sistemas dessa natureza.
Dessa maneira, o principal objetivo desta pesquisa é elaborar uma linguagem
específica de domínio que por meio de notações adequadas consiga expressar os
conceitos de serviços de governo em mídia cruzada. Mais especificamente, a linguagem permite descrever quais são as etapas de um serviço, as mídias utilizadas e as
transições entre mídias, além de servir para configurar os componentes utilizados dentro de um processo de governo possibilitando assim disponibilizar aplicações sobre o
Framework X-Gov.
4
1.3
Resultados Esperados e Contribuições
Esse trabalho tem como resultado prático, atendendo aos requisitos do mestrado profissional, criar uma linguagem de programação que permitirá ao gestor público descrever os serviços de governo auxiliando na criação de um sistema em ambiente de mídia cruzada. Mais especificamente, a linguagem permite descrever quais
são as etapas de um serviço, as mídias utilizadas e as transições entre mídias, além de
servir para configurar os componentes utilizados dentro de um processo de governo.
Com auxílio dessa ferramenta, o gestor conseguirá implementar, validar e modificar os
serviços com mais agilidade, já que para isso utiliza uma linguagem criada sob medida
para esse problema.
Foi feito um ensaio da linguagem aplicado na descrição de um cenário de serviço de governo, que pode ser utilizado para analisar o aspecto de como uma linguagem específica de domínio (DSL) pode contribuir para facilitar o desenvolvimento de
um novo sistema X-Gov. Esse ensaio, também serve de exemplo de script para quem
quiser utilizar futuramente esta linguagem.
O resultado deste trabalho contribui para o levantamento do vocabulário e a
definição de um modelo de domínio em sistemas de mídia cruzada, aplicado em governo eletrônico. O domínio e a linguagem poderão ser extrapolados para outra áreas
de aplicações como jogos eletrônicos, publicidade, entretenimento, etc.
Entre as contribuições acadêmicas destacam-se o levantamento de referências
que podem ser utilizadas para o desenvolvimento de linguagens específicas de domínio. Além disto, todo o código fonte está disponível para o uso no desenvolvimento de
novas aplicações e para trabalhos futuros. Como contribuições adicionais, destacamse a revisão de metodologias, ferramentas e técnicas para construção de uma DSL.
Este trabalho é parte integrante do projeto X-Gov e tornou-se a ferramenta de
modelagem do framework.
1.4
Método de Trabalho
O desenvolvimento desta pesquisa segue as etapas listadas para atingir seu
objetivo proposto:
Na etapa de revisão bibliográfica, obteve-se o estado da arte sobre linguagens específicas de domínio, com intuito de se determinar os conceitos, trabalhos
relacionados e método de desenvolvimento.
Em seguida, foi analisada a área de mídia cruzada, seu significado e aplicação,
com destaque em serviços de governo. Posteriormente foram levantados os requisitos
do Framework X-Gov.
As referências teóricas o estudo da implementação de uma prova de conceito
5
são a base para proposta de uma nova linguagem que serve para modelar serviços de
governo sobre mídia cruzada. Na definição da sintaxe desta linguagem são analisados
os componentes do Framework X-Gov e as transições de mídias em três serviços de
governo simulados.
Após as considerações acima, têm início as fases clássicas de um projeto de
software: análise, projeto, implementação e deployment.
Na fase de análise é descrito o modelo de domínio e são identificados os componentes do Framework X-Gov associados aos padrões de tarefa. Assim pode-se
agrupar o conhecimento em notações e operações úteis para a linguagem.
Na fase de projeto é criado um rascunho da DSL por meio do mapeamento
dos conceitos de domínio com a implementação dos elementos do Framework X-Gov.
Observe que variabilidades indicam precisamente que informação é necessária
para especificar uma instância do sistema. Essa informação deve ser especificada
diretamente em um programa da DSL ou derivada dele. Terminologia e conceitos são
utilizados para guiar o desenvolvimento das construções da DSL correspondente às
variabilidades. O que é comum é utilizado para definir o modelo de execução (por um
conjunto de operações comuns) e primitivas da linguagem.
Na fase de implementação as seguintes atividades foram executadas:
1. Construção da gramática da linguagem no nível léxico e sintático;
2. Construção de ações semânticas embutidas no reconhecedor gerado;
3. Construção de um conjunto de classes para servir como interface da linguagem
como o framework.
Após a fase de implementação, foi necessário criar um mecanismo de deployment para a linguagem ser instalada no Framework X-Gov.
Para efeito de avaliação da aplicabilidade da DSL, foi desenvolvida uma prova
de conceito para um serviço de agendamento médico que será utilizado como exemplo
posteriormente.
1.5
Organização do Trabalho
Este trabalho estrutura-se da seguinte forma:
A Sessão 1 é esta introdução.
A Sessão 2 intitulada Linguagem Específica de Domínio apresenta revisão da
literatura do estado da arte sobre DSL, sua definição, os tipos, exemplos e metodologia
de desenvolvimento.
A Sessão 3 intitulada Mídia Cruzada e Governo Eletrônico apresenta uma
breve descrição sobre os conceitos de mídia cruzada e serviço de governo eletrônico.
6
A Sessão 4 intitulada Framework X-Gov apresenta as partes que constituem o
Framework X-Gov relevantes aos objetivos desse trabalho.
A Sessão 5 intitulada A Linguagem CroMeL introduz a linguagem CroMeL e
apresenta seu projeto e implementação.
A Sessão 6 intitulada Conclusões concentra os resultados obtidos e possíveis
direções para trabalhos futuros.
7
Seção
2
Linguagem Específica de Domínio
“Se sua única ferramenta é um martelo, você tende a ver todo problema como um
prego.” (Abraham Maslow)
Este capítulo apresenta diversos trabalhos relacionados à linguagens específicas de domínio com objetivo de definir seu conceito, a classificação dos diferentes
tipos existentes, e alguns exemplos para ilustrar as vantagens, técnicas de programação e alternativas sobre métodos de desenvolvimento. Ainda serão analisados alguns
projetos e padrões que podem ser aplicados na solução proposta no capítulo 5.
Não existe um consenso entre os autores quanto a sigla DSL, várias definições
foram criadas para a mesma como referenciadas em Mernik et al. (2005): linguagem
orientada a aplicação (Sammet, 1969), linguagem de propósito especial (Wexelblat,
1981), linguagem especializada (Bergin & Gibson, 1996), linguagem específica de
uma tarefa (Nardi, 1993), linguagem específica de uma aplicação (Martin, 1985) e
linguagens pequenas (Bentley, 1986).
2.1
Introdução
Qual é a abstração ideal para uma aplicação particular? Segundo Hudak (1996)
é uma linguagem de programação projetada para essa aplicação: deve capturar precisamente a semântica do domínio do problema (nem mais, nem menos).
A Engenharia de Software e as linguagens atuais de programação propõem
diversos mecanismos de abstração: componentes, módulos, classes, objetos, tipos
8
de dados abstratos, interfaces, funções de ordem superior, lambdas, monadas, continuações, etc. Uma determinada linguagem de programação suporta melhor muitos
desses mecanismos do que outras.
Guy Steele Jr. 1 explica em Steele (1998):
. . . um bom programador, nestes tempos, não apenas escreve programas.
. . . um bom programador projeta uma linguagem, não do zero, mas sim a
contrói a partir de uma linguagem base.
Considera-se que especialistas de um domínio possuem um vocabulário próprio que expressa conceitos dentro de um contexto particular, permitindo que façam
afirmações sem explicar detalhes sobre o que estão falando, o que torna sua comunicação eficiente dentro do grupo no qual se insere. Pode-se ver que essa forma de
comunicação acontece por meio de uma linguagem específica de domínio. Por exemplo, um americano pode pedir um café no Starbucks da seguinte forma: “one non
fat, no whip, no foam, ventti half coffe latte” (um café com leite desnatado, tamanho
grande, sem expresso, sem espuma e sem chantilly 2 ) e já que fala dentro de um
contexto será corretamente interpretado.
No artigo van Deursen et al. (2000) é destacado que ao longo do tempo as
seguintes soluções foram adotadas para o desenvolvimento de aplicações:
1. Bibliotecas de subrotinas: contém subrotinas que executam tarefas relacionadas
em um domínio bem definido como equações diferenciais, gráficos, GUI, bancos
de dados — método clássico para reutilizar conhecimento de domínio.
2. Frameworks orientados a objetos e de componentes: Conjunto de classes que
definem uma interface de programação (API) usada diretamente enquanto controla execução usando métodos fornecidos por um código específico da aplicação.
3. DSLs: linguagens pequenas, normalmente declarativas que oferecem expressividade em um domínio de problema particular. Em muitos casos o programa é
traduzido para chamadas de uma biblioteca comum e a DSL pode ser vista como
uma maneira de esconder os detalhes dessa biblioteca.
2.2
Definição
Linguagem Específica de Domínio, ou DSL (Domain-Specific Language), como
muitos outros termos em computação, tem uma definição um pouco confusa e ampla,
1
Participou de comitês para especificação de linguagens como ECMAScript, C, Fortran, Scheme,
*LISP, Java e mais recentemente Fortress
2
Se achar que a tradução não está coerente consulte http://www.quicksilverweb.net/sbucks/
sbcharts.htm
9
mas existe um entendimento razoável do que elas são pela observação de exemplos
que aparecem de diferentes maneiras em diversas comunidades.
A definição adotada para DSL é: uma linguagem de programação que oferece, através de notações e abstrações apropriadas, poder de expressão enfática e restrita a um domínio de problema particular.
Uma comunidade particular em que as DSLs são notadas é a comunidade
UNIX, que tem como tradição chamá-las de linguagens pequenas ou mini-linguagens.
Como exemplo, existem os arquivos de configuração utilizados em sistemas UNIX
(e.g. Makefile), que podem ser vistos como uma DSL para descrever o processo de
construção (compilação, bibliotecas, diretórios, etc.) de um sistema.
Um bom exemplo é expressão regular, usada para reconhecimento de padrões de textos disponível em praticamente qualquer plataforma de desenvolvimento
(e.g. Java, C#, Ruby).
Outra comunidade que se destaca por utilizar essa técnica desde o inicio é a
comunidade LISP, que há muito tempo tem o hábito de criar DSLs utilizando a própria
sintaxe da linguagem. Por ter uma característica metacircular (Abelson & Sussman,
1996), na qual os dados e o programa usuário estão no mesmo espaço de memória,
então o interpretador age como uma ponte entre os objetos de dados que são manipulados pela linguagem de programação e a própria linguagem de programação. A
forma na qual as pessoas desenvolvem sistemas em LISP se inicia com a concepção
de uma linguagem personalizada para descrever o sistema obtendo um novo “dialeto”
de LISP, e a partir dele, descreve-se a solução do problema por meio dessa extensão
funcional (i.e. Emacs Lisp, Auto Lisp).
Essa idéia de construir uma linguagem embutida em outra também é bastante
utilizada pela comunidade Ruby que utiliza de recursos de metaprogramação da linguagem (apresentado inicialmente por Kiczales & Rivieres (1991)) para alcançar o
mesmo objetivo.
De certa forma, bibliotecas de aplicações (APIs) são competidoras de DSLs
(Mernik et al., 2005). Na maioria das vezes a linguagem utilizada para solucionar um
problema é construída na forma de bibliotecas. Utiliza classes, atributos e métodos
na sua implementação (no caso de linguagens orientadas a objetos) ou composição
de funções (em linguagens funcionais). Desta forma, a linguagem da GPL é obrigatoriamente usada (i.e. notação de “ponto” em Java para acessar os membros de
uma classe/objeto). Isto pode não ser muito adequado a um especialista de domínio,
porque ele precisará conhecer as várias construções que pertencem a GPL, e que
não são necessariamente úteis ao entendimento do programa (i.e. declaração de uma
variável de controle para construir uma iteração em um loop).
Freeman & Pryce (2006) apresentam um estudo de caso no qual uma linguagem explícita é embutida em um framework por meio de uma API fluente (tradução
10
livre do termo fluent interfaces3 ). Apesar de construída em uma linguagem com sintaxe grande e rígida (nesse caso a linguagem Java) os autores preocupam-se com
a legibilidade do código e seu resultado, e assim torna a programação sobre essa
API mais natural e contextualizada. O framework JMock usa interfaces encadeadas
para definir uma sintaxe concisa e auto-explicativa que facilita a leitura do código e
seu uso por parte de um programador, se o leitor desejar, pode ver um exemplo no
apêndice A.1. Esse framework permite criar objetos mock, que são muito utilizados
em desenvolvimento orientado a testes.
A experiência demonstrou que a partir do momento em que a API se tornou
uma DSL, o desenvolvimento ficou mais simples e direto por dois motivos destacados
por Freeman & Pryce (2006): Primeiro, com uma clara separação da sintaxe e interpretação em camadas. Segundo, livrou do estilo de programação comum em Java
quando apropriado, criando novas convenções, onde o estilo chamada em cadeia
(call chain) faz da leitura do código mais uma especificação declarativa do que o uso
de uma API imperativa (pode-se ver um exemplo de API fluente no apêndice A.2).
Contrasta com uma GPL no sentido em que seus recursos sintáticos e semânticos são limitados para implementar apenas algumas funcionalidades específicas necessárias dentro de um domínio de problema e não precisa ser Turing-completa 4 .
Seu valor está no fato dela representar muito melhor o vocabulário desse domínio o que torna mais fácil sua programação e entendimento por um especialista no
domínio.
Uma GPL (e.g. C, C#, VB, Java, Ruby, Python, LISP), por sua vez, implementa
uma linguagem equivalente ao modelo de máquina de Turing, e permite desenvolver
soluções para qualquer domínios.
A interface de programação de uma aplicação (API) constitui um vocabulário
específico de domínio, com nomes de classes, métodos e funções disponíveis para
criação de um programa em uma GPL. Contudo uma DSL oferece especificidade de
domínio de uma maneira melhor como é destacado por Mernik et al. (2005):
• Notação específica de domínio estabelecida ou apropriada vão além dos operadores disponíveis na GPL. Não devem ser subestimados já que estão associados
a maior produtividade;
• Construções e abstrações específicas de domínio nem sempre podem ser mapeadas para funções e/ou objetos de uma biblioteca;
• Uso de uma DSL oferece possibilidade de análise, verificação, otimização, paralelização e transformação; no caso de uma GPL, devido à padronização do
3
Termo criado por Martin Fowler sobre um estilo de programação que objetiva criar um código de
fácil leitura, veja mais em: http://martinfowler.com/bliki/FluentInterface.html
4
http://en.wikipedia.org/wiki/Turing_completeness
11
código-fonte torna-se muito complexo ou não é bem definido;
• Ao contrário de uma GPL, uma DSL não precisa ser executável — apesar de que
não existe acordo sobre isso na literatura segundo Wile (2001) e van Deursen
et al. (2000).
Outro aspecto importante no que tange às DSLs é que também são consideradas como uma forma de reuso de artefatos de software (Biggerstaff, 1998). Os
artefatos nesse caso são: a gramática, o código fonte e as abstrações modeladas. A
partir desse modelo, também é possível gerar aplicações completas segundo Krueger
(1992) apud Mernik et al. (2005).
Freeman & Pryce (2006) descrevem uma DSL para o domínio de teste de software que começou sua história na forma de uma biblioteca de classes (API) que implementava as funções do framework e depois evoluiu para uma linguagem embutida,
a qual é explicada na seção 2.3.2. É essa evolução postulada como nível mais maduro
desse framework o que facilita seu uso e disseminação.
2.3
Classificação
A maior parte das DSLs encontradas atualmente é textual, mas também existem na forma gráfica. As DSLs gráficas necessitam de uma ferramenta e símbolos
para representar sua notação, como também um gerador de artefatos (e.g. código,
dados, arquivos de configuração) e são chamadas de linguagens de modelagem específica de domínio.
Uma importante forma de classificar os tipos de DSLs encontrados pode ser
feita de acordo com sua forma de construção, que as divide entre DSLs externas e
internas.
2.3.1
DSL Externa
Uma DSL externa é uma linguagem que pode ser compilada, interpretada ou
executada, e tem uma sintaxe própria ou usa alguma representação pré-definida como
YAML Ain’t Markup Language (YAML) ou Extensible Markup Language XML — como
por exemplo Extensible Application Markup Language (XAML) e XML User Interface
Language (XUL) — entre outras, mas precisa de um parser para processá-las, um gerador de código objeto, ligação de bibliotecas, etc. Trata-se de uma linguagem construída muitas vezes da mesma forma que linguagens tradicionais completas. Tem-se
total liberdade para criar sua estrutura sintática e semântica. Existem ferramentas tais
como analisadores léxicos e sintáticos (e.g. lex, yacc) e geradores de parser (e.g.
ANTLR Parr (2007)) que são utilizados na construção, compilação e interpretação da
linguagem.
12
São exemplos de DSLs externas: arquivos de configuração de ferramentas
para compilação em Java (ANT5 ), em .NET (NANT6 ), em C/C++ (Make7 ) e em Ruby
(Rake8 ). Todos estes utilizam uma linguagem personalizada que descreve as dependências entre as partes do sistema no processo de compilação e ligação. Outros
exemplos citados por Fowler (2008) incluem: CSS, expressões regulares, SQL, HQL,
linguagem gráfica de pontos graphviz, FIT, arquivo de configuração que utilizam notação XML como do Struts, Spring, Java Server Faces (JSF) e Enterprise Java Beans
(EJB) 2.x. Como exemplo histórico, a NASA utiliza de DSL desde a década de 60 para
computação vetorial no projeto Apollo 9 .
2.3.2
DSL Interna
Também chamada embutida (embedded language), é uma linguagem expressa
dentro de uma GPL. Essa modalidade requer uma linguagem “hospedeira” e sua sintaxe é valida dentro da linguagem de propósito geral que a contém. A partir dessa
extensão da linguagem base podem-se personalizar os símbolos e mecanismos de
controle de uma maneira especial de acordo com a necessidade do domínio ao desenvolver essa nova linguagem.
Quando uma DSL não vai além do nível de uma biblioteca da aplicação (isto é
não tem um compilador que a transforma em código de máquina) é chamada também
de DSEL (Domain Specific Embedded Language) segundo Hudak (1996). Usa-se o
termo DSL Interna no lugar de DSL Embutida para não confundir com linguagens de
scripting (e.g. JavaScript) utilizada na construção de aplicações, embora o segundo
termo tenha sido mais utilizado historicamente pela academia, atualmente a mesma
técnica tem sido chamada pelos praticantes de linguagem específica de domínio
interna (Fowler, 2008).
São exemplos de DSLs internas: parte do framework Ruby on Rails (e.g. ActiveRecords para mapeamento objeto-relacional), dialeto LISP para programação do
editor Emacs, expectativas com JMock em Java, etc.
2.4
Método de Desenvolvimento
Não é fácil de determinar quando e como construir DSLs, vantagens como
aumento de produtividade, facilidade de manutenção, rápido processo de aprendizado,
além de ser uma maneira de reutilizar artefatos de software, não são obtidas sem
5
http://ant.apache.org/
http://nant.sourceforge.net/
7
http://www.gnu.org/software/make/
8
http://rake.rubyforge.org/
9
http://www.ibiblio.org/apollo/assembly_language_manual.html
6
13
grandes esforços.
Contudo deve-se considerar ainda os seguintes itens:
• Existe dificuldade no desenvolvimento da DSL pois se requer especialistas na
linguagem e no domínio;
• Diversas técnicas de desenvolvimento são encontradas, portanto requer consideração cuidadosa dos fatores envolvidos;
• Dependendo do tamanho da comunidade de usuários, demanda alto custo na
criação de material de treinamento, suporte, padronização e manutenção.
Seu desenvolvimento também pode vir posteriormente na forma de reengenharia de
software ou evolução do software (Bennett & Rajlich, 2000).
Na literatura encontram-se importantes contribuições como o trabalho de van
Deursen et al. (2000) que é uma bibliografia anotada e serve de referência histórica
sobre o assunto.
O trabalho de Mernik et al. (2005) trata-se de um survey que objetiva responder
as perguntas: quando e como construir DSLs. Trata-se de um dos poucos trabalhos
que oferecem um guia ou método para criação de DSLs, apresentando uma revisão
sistemática dos vários fatores envolvidos, por meio da identificação de padrões em
cada uma das fases de desenvolvimento: decisão, análise, projeto e implementação.
Grande parte da metodologia descrita nas seções 2.4.1, 2.4.2 e 2.4.3 foi extraída deste trabalho Mernik et al. (2005), sendo que algumas técnicas de implementação consideradas na seção 2.4.4 podem ser encontradas em Fowler (2008), Fernandez (2007), Kilmer (2008), Ford (2008), Subramaniam (2008) e Parr (2007).
A seguir serão apresentadas as fases no desenvolvimento de uma DSL e os
padrões destacados no que tange a este trabalho em particular. Na prática, o desenvolvimento de uma DSL não é um processo seqüencial, no qual o processo decisório
pode ser influenciado por uma análise preliminar, e o projeto é muitas vezes influenciado por restrições ou diretivas de implementação.
2.4.1
Decisão
Para determinar quando o desenvolvimento de uma DSL deve ser aplicado,
usa-se os padrões de decisão conforme destacados na Tabela 2.1, extraído de Mernik et al. (2005), pode-se observar que esses padrões ajudam no processo decisório
sobre a devida aplicação de uma DSL.
14
Tabela 2.1: Padrões de Decisão
O padrão Interaction, por exemplo, objetiva tornar a interação programável.
Esse padrão é definido da seguinte forma: Interações baseadas em menu ou texto
freqüentemente devem ser suportadas por uma DSL apropriada para especificar entradas complicadas ou repetitivas de dados. A linguagem de macro do Excel suporta
sua manipulação interativa o que a torna programável.
Seguem alguns exemplos de linguagens criadas nas quais observou-se a utilização do padrão Interaction: CHEM, FPIC, Fran, Mawl, Service Combinators. Outras
linguagens associadas a outros padrões, bem como suas referências, podem ser vistas na Tabela 2.2, encontrado em Mernik et al. (2005). Um exemplo de DSL que não é
apresentado na tabela, mas foi possível notar que segue o mesmo padrão de decisão
é a WebDSL. A WebDSL é utilizada para implementação de aplicações web dinâmicas
(Groenewegen et al., 2008).
Também é fácil evidenciar o padrão GUI construction, já que normalmente a
construção de interface gráfica é feita por meio de DSLs (e.g. XUL, XAML, JavaFX).
Tabela 2.2: Exemplos para os Padrões de Decisão
15
2.4.2
Análise
Para a fase de Análise: o domínio do problema é identificado e o conhecimento
sobre esse domínio é adquirido. Para isso várias fontes de informações sobre o domínio (implícitas e explícitas) são necessárias, como documentos técnicos, conhecimento fornecido por um especialista de domínio, código pré-existente e questionários
com clientes e usuários.
O resultado da análise de domínio consiste basicamente de terminologia e semântica da linguagem, existe uma forte relação entre a “Análise de Domínio” e “Engenharia de Informação” para capturar conhecimento, representar conhecimento e
desenvolvimento de ontologias (Denny (2003) apud Mernik et al. (2005)) que também
pode ser útil nessa fase de análise.
Padrões de análise são destacados na Tabela 2.3, extraído de Mernik et al.
(2005), sendo que muitas vezes essa análise de domínio é feita de maneira informal.
Tabela 2.3: Padrões de Análise
A partir da análise pode-se construir um modelo de domínio. Esse modelo é
constituído da seguinte forma:
• definição do domínio e especificação do escopo;
• terminologia do domínio (vocabulário, ontologia);
• descrição dos conceitos do domínio;
• modelo de requisitos que descreve o que é constante e variável no domínio,
conceitos e suas interdependências.
Note que o modelo de execução de uma DSL é muito mais rico do que para
uma GPL, pois, com base em uma única análise de domínio muitas DSLs diferentes
podem ser desenvolvidas sendo que todas compartilham características importantes
encontradas nos requisitos.
2.4.3
Projeto
Abordagens para projetar uma DSL podem ser caracterizadas por duas dimensões ortogonais: (1) a relação da DSL com linguagens existentes, e (2) a natureza
16
formal da descrição do projeto. Pode-se observar os padrões de projeto na Tabela 2.4
e exemplos de linguagens que seguem esses padrões na Tabela 2.5 — ambas extraídas de Mernik et al. (2005).
Tabela 2.4: Padrões de Projeto
Tabela 2.5: Exemplos de linguagens para os Padrões de Projeto
Uma das formas mais utilizadas para se projetar uma nova linguagem é fazer
uma extensão funcional ou sintática em uma linguagem já existente, com o benefício
de ter usuários já familiarizados com a sintaxe da linguagem original. Dessa maneira
adicionam-se novos recursos de acordo com os conceitos do domínio, e aproveitam-se
recursos que já existem na linguagem base. O desafio é integrar recursos específicos
do domínio com o resto da linguagem de uma maneira que não haja conflitos.
Como exemplo, tem as comunidades de LISP e Ruby que utilizam com freqüência o padrão de exploração de uma linguagem por meio de extensão, onde uma linguagem pré-existente é estendida para acomodar DSLs.
Em um projeto informal, a especificação é normalmente feita por meio de uma
linguagem natural, e provavelmente inclui um conjunto de programas para ilustrar o
uso da DSL. Já o desenvolvimento de uma descrição formal possibilita a aplicação
de ferramentas de desenvolvimento de linguagens que são capazes de gerar uma
implementação automática de parsers e analisadores sintáticos.
17
A indústria também tem investido na criação de ferramentas desse tipo, como
por exemplo, o Eclipse Modeling Project (EclipseFoundation, 2009), Xtext (OpenArchitectureWare, 2009), Netbeans Generic Languages Framework (Netbeans, 2009),
Microsoft OSLO (Microsoft, 2009), e outras. A Tabela 2.6 apresenta outras ferramentas observadas no survey de Mernik et al. (2005).
Tabela 2.6: Sistemas e Ferramentas de Desenvolvimento de Linguagem
2.4.4
Implementação
Quando uma DSL executável é projetada é preciso escolher sob qual ótica ela
é implementada: na forma de um interpretador, um compilador/gerador de aplicações,
um pré-processador, uma linguagem embutida ou híbrida que trata-se da combinação
de mais de uma forma. Pode-se observar padrões de implementação na Tabela 2.7,
encontrado em Mernik et al. (2005), que auxiliam no processo de escolha.
Tabela 2.7: Padrões de Implementação para DSLs executáveis
2.5
Considerações
Em virtude das dificuldades que surgem ao se criar uma nova linguagem, como
definir seus símbolos e sua sintaxe, normalmente opta-se pelo uso de mecanismos
18
encontrados nas linguagens padrões, porém estes podem não suportar devidamente
as abstrações exigidas pela aplicação e consequentemente perderem expressividade,
com a intercalação sem critério da sintaxe da própria linguagem de programação com
as abstrações do modelo de domínio.
Portanto, a opção pelas DSLs justifica-se pelo fato destas permitirem que soluções sejam expressas no idioma e nível de abstração do problema de domínio, e
desta forma possibilitam à especialistas de domínio (não programadores) poderem
entender, validar, modificar e até mesmo criar programas por meio dessas linguagens
específicas.
19
Seção
3
Mídia Cruzada e Governo Eletrônico
“As sociedades sempre foram moldadas mais pela natureza dos meios do que pelo
conteúdo da comunicação.” (Marshall McLuhan)
Este capítulo introduz o domínio de aplicação no qual este trabalho está inserido, primeiramente apresenta o conceito de mídia e mídia cruzada, seguido pela sua
aplicação em governo eletrônico. Os termos mídia cruzada, cross-media, crossmedia
e transmedia serão utilizados de forma intercambiada para se referir a mesma coisa
de acordo com os autores e contextos apresentados — diferentes autores utilizam
esses termos em conformidade apenas com sua área de aplicação.
3.1
Mídia Cruzada
Para se entender mídia cruzada é necessário analisar o conceito de mídia empregado em comunicação e posteriormente como esse conceito é expandido para
múltiplas mídias.
3.1.1
Definição de Mídia
Para esse trabalho entende-se como mídia os meios pelos quais as mensagens chegam até o público. A própria palavra mídia deriva do latim media, que quer
dizer meio. Na mídia tradicional o público era mero receptor da mensagem, sem a
possibilidade de interagir com esta pelo meio na qual ela foi produzida, porem isso
mudou, atualmente existem muitos meios para a difusão de mensagens que permitem
20
a interação do receptor, por exemplo web, e-mail, twitter, sms, mms, portal de voz,
entre outros.
Segundo Cunha (2006):
“É esta mesma recepção que, em momento de expansão tecnológica mais
propício, assume o papel da narração antes delegado a outros centros
emissores e busca construir um conteúdo cada vez mais individualizado.
Para tanto, a recepção se apropria das linguagens que estão na base de
qualquer narração midiática e passa a produzir para si e para os públicos
que se auto-organizam na rede.”
Ainda, no que se refere ao conceito de mídia, Lima (2001) consegue articular
uma definição mais precisa do que mídia significa hoje e esclarece um pouco mais a
íntima conexão entre comunicação e mídia. Segundo ele, mídia pode ser entendida
como o conjunto de instituições que utilizam tecnologias específicas para realizar a
comunicação humana. Vale dizer que a mídia implica a existência de um intermediário tecnológico para que a comunicação se realize. A comunicação passa, portanto,
a ser uma comunicação mediatizada. Dessa forma, aparece um tipo específico de
comunicação que constitui um dos importantes símbolos da modernidade.
Em outras palavras, se assim como afirmou Lima é imprescindível a existencia
de um intermediário tecnológico para que a comunicação se realize, quando fala-se
em mídia cruzada esta mesma comunicação só se tornará possível a partir da interação de múltiplos dispositivos que necessitam de alguma rede para distribuição dessas
mídias como por exemplo a Internet.
A Internet é um dos intermediários tecnológicos que torna possível as pessoas
se comunicarem sobre diversas mídias. Padrões mantidos pelo Internet Engineering
Task Force (IETF) foram criados para definir os tipos de mídias suportadas na rede
— o tipo de mídia da internet foi derivado do Multipurpose Internet Mail Extensions
(Mime), criado para que diversos tipos de conteúdos fossem incluídos em e-mail, e
expandiu para outros protocolos (e.g. Hypertext Transfer Protocol, Real-time Transport Protocol, Session Initiation Protocol). Por meio do Mime Type, o tipo de mídia
transportado é definido a partir de um tipo e subtipo, como por exemplo: text/html
(para transporte de hypertexto), image/gif (para transporte de imagem no formato gif),
application/pdf (para transporte de um documento no formato pdf), entre outros. Podese consultar tipos de mídias suportados para imagem, audio, vídeo e aplicações na
RFC2046 (Freed & Borenstein, 1996).
3.1.2
Mídia Cruzada
O termo mídia cruzada (cross-media) é recente e tem significados diferentes de
acordo com a disciplina em que é aplicado. Contudo, segundo Boumans (2004), existe
21
um significado comum que se traduz como o uso de múltiplos meios para propagar
uma mesma mensagem com o objetivo de tornar o conteúdo mais acessível. Quando
se fala em Web, o termo é associado com o uso eficiente de mais de uma plataforma
técnica, que torna o conteúdo disponível para um grande número de pessoas sobre
diferentes dispositivos, em marketing significa usar múltiplos canais de distribuição,
e assim por diante, o conceito de cross-media vai adquirindo novas características
a medida que é explorado por áreas distintas como e-learning, turismo, propaganda,
etc.
De acordo com Boumans (2004) podem-se observar diversos sinônimos ao
termo cross-media, criados ao longo dos anos e por diferentes disciplinas, como multimídia, multiplas mídias, mídia interativa e integrada, multiplataforma, mídia convergente e híbrida. Embora o termo seja recente, o seu conceito de utilização já era
empregado na década de 70 quando o conteúdo de enciclopédias eram distribuídos
também em fita cassete, e posteriormente em CD-ROM quando o termo multimídia
passou a ser utilizado. Até meados da década de 90, a idéia de cross-media (embora
não com este nome) esteve ligado com o slogan “Create Once, Publish Everywhere”
usado por Paul Zazzera, CEO da Time Inc. em 1996 (hoje, pertence ao grupo Time
Warner e é uma das maiores companhias de conteúdo do mundo distribuídos em revistas, na web, em rádio e na televisão).
Quando o termo começou a ser usado no final dos anos 90 (principalmente
devido a popularização da Internet), significava obter mais informações sobre um programa na Web. Somente em 1999, com o lançamento do programa de televisão
Big Brother, criado pela produtora Endemol na Holanda, e seu respectivo sucesso,
o termo cross-media bem como seu uso em áreas diversas, no caso entretenimento,
popularizou-se. O programa de TV tornou-se um significativo exemplo de um bem
sucedido uso de mídia cruzada, uma vez que sua imensa repercussão deveu-se ao
fato que em sua veiculação foram usadas além da TV analógica, a TV interativa, telefone, celular e Internet, sendo ainda apoiado pela mídia impressa (jornal e revista)
para produzir diálogos únicos sobre múltiplas mídias. Ainda, entre os exemplos de utilização de múltiplas mídias (com diálogos diferenciados em cada mídia) na industria
de entretenimento, pode-se citar a trilogia Matrix que teve além dos filmes uma versão
em quadrinhos e jogos e a série Lost da ABC que tem sites na web em que o usuário
pode continuar a explorar o universo criado pela série.
O conceito de mídia cruzada utilizado neste trabalho é semelhante aquele empregado pelo programa Big Brother (em que até o momento já ocorreram nove edições
no brasil 3.1), onde são utilizados diversos meios para produzir diálogos únicos sobre
múltiplas mídias. Em outras palavras, para este trabalho, mídia cruzada (cross-media)
é uma forma de comunicação na qual o receptor é convidado a utilizar diferentes mídias para acessar um conteúdo que pode levá-lo para outras mídias.
22
Figura 3.1: Big Brother Brasil 9
A mídia cruzada possui cinco características que a distinguem, listadas por
Boumans (2004): (1) a mídia cruzada envolve mais de uma mídia; (2) a mídia cruzada
objetiva uma produção integrada; (3) o conteúdo entregue em múltiplas mídias; (4)
mais de uma mídia é necessária para apoiar uma única mensagem/narrativa/meta;
(5) a mensagem/narrativa/meta é distribuída em múltiplas plataformas e a interação
apoiada pode acontecer nestas diferentes plataformas.
No cenário atual existe uma mistura de aplicações, plataformas, dispositivos,
que possibilitam o acesso de conteúdo sobre um meio, são exemplos as redes sociais e organizacionais que suportam muitas atividades humanas como jogos, compras,
comunicação, até serviços públicos. Por meio destes exemplos, percebe-se o quão
fundamental a Internet tornou-se, mesmo para ações corriqueiras de nosso cotidiano,
e que como disse Bolter & Grusin (2000) apud Wiberg et al. (2007) a Internet segue
um rumo de alto grau de convergência entre diferentes tipos de mídia e conteúdo.
Um fenômeno similar a este de acordo com Wiberg et al. (2007) está sendo estudado
pelas áreas de IHC e novas mídias. Esse fenômeno visto como uma mensagem contada em mais de uma mídia também é chamado de cross-media (conceito observado
principalmente pelas áreas de comunicação e novas mídias).
Quando uma história, ou diálogo de interação, é contada sobre mais de uma
mídia e o receptor é convidado para mudar de uma mídia para outra, pode-se dizer
que ocorre um diálogo cross-media e segundo Dena (2007), esse convite é chamado
“call-to-action” (CTA). O “call-to-action” é um termo criado pela área de marketing que
objetiva levar a pessoa a tomar uma ação diante de uma propaganda. Neste trabalho,
o mesmo conceito pode ser aplicado a outros domínios como serviços de governo.
Dena propõe um processo constituído por três fases que resultarão neste con23
vite à ação (CTA): (1) Preparar e motivar o ator a agir; (2) Fornecer o meio e as instruções de como e quando agir e (3) Reconhecer e recompensar a ação. O sucesso
de um projeto de interação sobre mídia cruzada é evidente quando a pessoa migra
de uma plataforma para outra e quando esse movimento tem um impacto positivo na
experiência do próprio usuário. Essa experiência é muito diferente daquela com apenas uma mídia (forma tradicional e dominante) porque a pessoa tem que tomar uma
ação muitas vezes de forma ativa, embora também possa ocorrer transições automáticas (passivas) . Existem mecanismos que podem facilitar uma transição como por
exemplo o QR-CODE1 que permite um telefone celular capturar uma imagem em uma
mídia impressa (jornal, revista) e levar o usuário para uma página na web que continua
a narrativa, por exemplo apresentando um mapa (Dena, 2007).
Ainda hoje no Brasil, o principal meio pelo qual as pessoas buscam se informar
é a televisão, sendo seu número em domicílios muito mais representativo do que o
de computadores, estejam estes conectados ou não a internet, seguidos apenas pelo
número de telefones usados principalmente para serviços de voz 2 . Assim, tendo em
vista este contexto sócio-cultural, este conceito de comunicação (cross-media) tornase mais atrativo aos olhos do cidadão, uma vez que o conteúdo chega até ele pela TV,
telefone fixo, celular, além da mídia impressa e do computador. Este é um fator chave
para explicar a necessidade do governo em comunicar-se com o cidadão por diversas
mídias ampliando sua presença em todos os extratos sociais. No futuro, usuários
estarão tão acostumados a cross-media que não irão notar sua presença, mas irão
perceber sua falta Boumans (2004).
3.2
Governo Eletrônico em Mídia Cruzada
Com base nos conceitos anteriormente expostos de mídia e mídia cruzada,
nesse ponto faz-se necessário mostrar como podem ser aplicados em governo eletrônico. A seguir são apresentadas as formas de comunicação utilizadas pelo governo,
o que são esses serviços e como eles podem ser mapeados para o desenvolvimento
de uma solução tecnológica.
3.2.1
e-gov, m-gov, t-gov, x-gov
Atualmente o governo se relaciona com os cidadãos tanto fisica quanto virtualmente. Cada vez mais conta-se com o auxílio de dispositivos computacionais que
1
QR-CODE é um tipo de código de barras de duas dimensões contendo um conjunto limitado de
dados que pode ser por exemplo um endereço na internet ou uma imagem
2
O CGI.BR faz uma pesquisa anual sobre o uso das Tecnologias da Informação e da Comunicação
no Brasil que pode ser vista em http://cetic.br/usuarios/index.htm
24
permitem a interação do governo com o cidadão, e a mídia cruzada é uma forma de
ampliar ambas as formas de relacionamento.
Os acrônimos e-gov, m-gov, t-gov apresentam meios pelos quais o governo
interage com o cidadão, e-gov sendo pelo meio eletrônico (usualmente pela web3 ), mgov é normalmente quando o usuário interage por meio de um telefone celular, e t-gov
é a interação do cidadão com o governo pela tv (em um futuro próximo com a tv digital
essa interação também será bidirecional). O termo x-gov, mais recente, determina o
uso das diversas mídias (daí o “x” que refere-se a cross em inglês) para interação do
governo com o cidadão.
Para Filgueiras (2007) x-gov é definido como sendo a entrega de serviços de
governo em mídia cruzada, na qual a comunicação G2C é apoiada por diversos meios
alternativos, cada qual direcionando o cidadão ao próximo passo no processo de interação e ao meio mais adequado a este passo . . . x-gov difere das demais aplicações
de mídia cruzada porque no x-gov a narrativa principal deve ser apoiada por mídias alternativas. Nas demais aplicações, há uma mídia principal (em geral, a TV) que apóia
o tema central.
Apesar dos esforços do governo e das entidades civis o acesso a internet ainda
é restrito a um pequeno número de pessoas (comparando esse número com toda
população do país), assim, o governo eletrônico brasileiro não pode se apoiar apenas
nesse meio, mas deve explorar outros meios de comunicação. Alguns benefícios do
método x-gov, segundo o relatório de Filgueiras (2007) são:
• aumentar o número de alternativas pelas quais o cidadão alcança o governo,
bem como a possibilidade de obter esse acesso a qualquer momento, de qualquer lugar;
• mover a interação eletrônica para além do ponto em que ela se interrompe hoje:
transações eletrônicas são substituídas por interações presenciais;
• favorecimento de uma diversidade de usuário, pessoas com algum tipo de deficiência podem se comunicar com o governo pelo canal mais adequado a elas;
• a vida moderna exige a linguagem de mídia cruzada: envia-se um e-mail ao
mesmo tempo em que se conversa ao telefone e acompanha o noticiário na TV.
3.2.2
Serviços de Governo
Como dito anteriormente, conceito de cross-media tornou-se popular em diferentes contextos como no meio artístico, de jogos, filmes, rádio e TV. Com a tecnologia
3
pode-se ver um exemplo de diversos serviços oferecidos pelo governo do estado de São Paulo em
http://www.cidadao.sp.gov.br/
25
digital e uma gama cada vez maior de dispositivos, o conteúdo pode ser acessado,
transmitido e armazenado facilmente em diversas plataformas. Apesar do aspecto de
entretenimento, este conceito é facilmente extrapolado para outras aplicações, como
neste trabalho para serviços de governo.
O dicionário Oxford (2a edição) define serviço como “(1) a ação de ajudar ou fazer trabalho para alguém; (2) um sistema que fornece uma necessidade pública como
transporte, comunicação, ou utilidades como elétrica e de saneamento”. É necessário
estreitar essa definição para serviços públicos que são executados por uma unidade/departamento/organização do governo para atender seus cidadãos. Usando este
conceito entende-se como serviço de governo: serviços executados por uma unidade/departamento/organização do governo com objetivo de fornecer um bem público.
Para ser melhor compreendido, um determinado serviço de governo deve ser
decomposto em um conjunto de atividades que serão executadas por um ator, podendo ser este uma unidade/departamento/organização/representante do governo ou
um cidadão (pessoa física ou jurídica) que precise desempenhar essas atividades.
Normalmente o ator deverá executar vários passos para atingir seu objetivo,
e existem vários recursos como informação, dinheiro, dcumentos entre outros que
devem ser trocados durante o processo. Dentro de cada passo existe um diálogo entre
o ator e a ação que precisa ser executada, um conceito popularmente conhecido como
round ou rodada de acordo com Filgueiras (2007).
Ainda, é importante ressaltar a escolha de mídias ideais para um serviço, partindo, por um lado, das características de apresentação, geração ou recebimento de
cada mídia e, por outro, das necessidade de recursos (informação, transação financeira, documento) de cada etapa do serviço.
A produção de conteúdo sobre as diferentes mídias deve ser complementar
para que a pessoa possa (1) em alguns casos, escolher qual quer usar; (2) usar a
mídia mais adequada para uma certa situação como por exemplo, ter disponível apenas o telefone celular quando estiver em trânsito; e (3) usá-las simultaneamente para
apoiar uma narrativa/atividade/meta. Dessa forma surgem tres conceitos que podem
ser benéficos para serviços de governo (Miyamaru et al., 2008a), abaixo descritos:
1. Corroboração
2. Concomitância
3. Completude
Corroboração prega que as mídias carreguem o mesmo conteúdo, o que reforça a
mensagem para o receptor. O conceito de Concomitância determina que uma mídia
esteja conectada com outra mídia (normalmente sobre outro dispositivo) e essa conexão permite criar um sincronismo entre as mídias. O conceito de Completude é
26
Figura 3.2: Cadeia de Conteúdo Digital [Fonte: Boumans2004]
aplicado quando uma determinada informação não é adequada para ser entregue em
uma mídia, então o dialogo prossegue em outra.
3.2.3
Padrões de Tarefas para Serviços de Governo
Em virtude das questões apresentadas em 3.1.2 e em 3.2.2, compreendeuse que um projeto de interação integrado de múltiplas mídias/plataformas/dispositivos
deve contemplar toda a cadeia de produção de conteúdo digital (apresentado na figura 3.2) desde a criação até o consumo desse conteúdo (Boumans, 2004, p 6).
O propósito de um projeto de interação em mídia cruzada, ou Cross-Media Interaction Design (CMID), é mostrar o conteúdo que deve estar disponível em cada
mídia, levando em consideração as características do conteúdo e da mídia, do dispositivo, e do meio de distribuição. CMID é uma particularização da multimodalidade, já
que contempla um projeto de movimento sobre diferentes modalidades de interação.
Um projeto de interação sobre mídia cruzada preocupa-se com aspectos que possibilitem transitar sobre as diferentes modalidades, no qual o ator, dessa transição, é o
usuário que segue dicas migratórias criadas pelo projetista como caminhos de uma
narrativa. Ainda no projeto deve ser definido como implementar uma narrativa (do
inglês storytelling), e quais metáforas são mais adequadas para a interação com o
usuário.
Assim, segundo Miyamaru et al. (2008b), padrões de tarefas são boas soluções
para projeto de interação com serviços de governo e são convenientes para aplicações
disponíveis em múltiplos dispositivos, uma vez que padrões de tarefa capturam a dimensão humana da interação, sendo capazes de expressar intenções humanas que
devem ser atendidas pela interface de usuário.
27
A etapa inicial deste trabalho foi desenvolver, junto com outros pesquisadores,
18 padrões de tarefa para expressar o uso de serviços de governo em ambiente de
mídia cruzada. Para isso foram analisados 30 serviços públicos dos quais 27 estavam
disponíveis pela internet, 6 foram serviços que requerem a presença do cidadão em
alguma etapa e 2 foram serviços disponíveis para celulares. 4
Os 18 padrões de tarefa para governo eletrônico em mídia cruzada foram divididos em 4 categorias da seguinte forma:
• Informação: (1) Obter informações a respeito de um serviço; (2) Enviar informações para o governo; (3) Enviar informações pessoais; (4) Encontrar informações
públicas; (5) Encontrar informações sobre alguma entidade e (6) Encontrar informação privada.
• Documento: (7) Obter documento com assinatura digital; (8) Criar uma fatura;
(9) Verificar validade de um documento; (10) Imprimir documento e (11) Salvar
como arquivo.
• Transação: (12) Autenticação; (13) Obter identificador do processo; (14) Pagar
taxa/imposto e (15) Agendamento.
• Relacionamento: (16) Falar com ombudsman; (17) Receber uma mensagem e
(18) Acompanhar um processo.
4
A lista completa dos padrões de tarefa e outros detalhes pode ser obtida no site http://lts-i.
pcs.usp.br/index.php/projetos/xgov/63.
28
Seção
4
Framework X-Gov
“Para visão exigem-se três coisas, o objeto, o orgão e o meio.” (Raymond Williams)
O desenvolvimento do arcabouço tecnológico chamado de Framework X-Gov
tem o objetivo de projetar e desenvolver uma arquitetura reutilizável de componentes
computacionais para a criação de serviços de governo em mídia cruzada. Fez parte
deste trabalho elaborar a arquitetura do Framework que é descrito nessa seção, assim
como uma forma alternativa de programar aplicações geradas a partir dele por meio de
uma linguagem específica de domínio. A seguir é apresentada a arquitetura definida,
seu conceito e propósito, assim como um detalhamento de suas partes integrantes.
Essa arquitetura oferece uma visão de alto nível do projeto que pode ser aplicado a
outros domínios com requisitos semelhantes como: utilização de componentes para
criar aplicações em ambiente de mídia cruzada.
O termo x-gov ou X-Gov representa um serviço de governo sobre mídia cruzada arbitrário, enquanto Framework X-Gov (FXG) será usado para se referenciar ao
arcabouço de software criado para apoiar o desenvolvimento desse tipo de sistema.
4.1
Conceito
Governo eletrônico em mídia cruzada, ou simplesmente X-Gov, trata-se de um
sistema complexo que busca integrar diversas plataformas computacionais, dispositivos e mídias para permitir a interação do cidadão com o governo por esses múltiplos
meios. Visto desta forma, é um sistema complexo, distribuído, no qual um arcabouço
29
tecnológico se faz necessário para permitir que sejam construídas aplicações desse
tipo.
O conceito de framework pode ser entendido como uma arquitetura (design)
reutilizável em seu todo ou como parte de um sistema, que é representado por um
conjunto de classes e a forma pela qual suas instâncias interagem. Outra definição
comum para framework é compará-lo ao esqueleto de uma aplicação que pode ser
personalizado por um desenvolvedor. Enquanto a primeira definição descreve a estrutura de um framework, a segunda descreve seu propósito (Johnson, 1997).
O propósito do Framework X-Gov é permitir que gestores públicos1 definam
um ou mais serviços de governo em um ambiente de mídia cruzada. O processo para
definir um serviço de governo (de maneira macroscópica) significa planejar quais as
atividades de um serviço, o padrão de tarefa e as mídias a serem utilizadas em cada
atividade, além das transições que ocorrem entre as mídias — a composição desse
processo pode ser analisado na figura 4.1 onde um portal de governo eletrônico é
representado por um conjunto de serviços, que por sua vez possui um conjunto de
atividades e associado a cada atividade uma ou mais mídias.
Figura 4.1: Composição de um X-Gov
1
generalização de um funcionário público que pode ser a equipe técnica de uma unidade/departamento/organização do governo
30
4.2
Arquitetura
O diagrama de deployment de alto-nível apresentado na figura 4.2 apresenta
as partes do FXG, como elas são distribuídas nos seus respectivos nós de hardware
e os protocolos de comunicação. A decisão por utilizar Web Services na comunicação dos componentes com o servidor X-Gov oferece um baixo acoplamento entre
os componentes distribuídos nos diferentes dispositivos e o servidor. Essa decisão
também é apoiada pela proposta de que um serviço ou cliente de Web Service podem ser construídos em diferentes plataformas de desenvolvimento, o que garante a
interoperabilidade necessária a esta arquitetura.
Figura 4.2: Arquitetura X-Gov
4.2.1
Modelo de Domínio
O modelo de domínio apresentado na figura 4.3 detalha os principais objetos
criados para descrevem a estrutura de classe dos componentes do Framework XGov 2 . Outros diagramas com classes criadas até o momento podem ser vistos no
apêndice 4. Os padrões de tarefa foram obtidos pela equipe do projeto X-Gov em
2
Por convenção determinada no projeto, os módulos, as classes, as propriedades, e operações,
foram nomeados em inglês e são trazidos aqui dessa forma por tratar-se de um projeto de cunho
internacional.
31
um trabalho (do qual o autor deste trabalho participou) em que 32 sites de governo
eletrônico foram analisados para se obterem as tarefas humanas recorrentes. Estas
tarefas foram modeladas usando-se o conceito de design patterns3 .
Figura 4.3: ComponentModel
No modelo, observe que existe uma classe que representa todos os componentes chamada ‘Component’ especializada para cada tipo de padrão de tarefa identificado como ‘FindEntityInfoComponent’, ‘AuthenticationComponent’ e ‘PayFeeTaxComponent’. Por sua vez os padrões de tarefa são implementados para cada uma das
mídias alvo do projeto (tv, web e mobile). Existe uma classe que representa todas as
transições ‘Transition’ e outra que representa navegações ‘ComponentConnection’.
Essas classes servem para embutir dados e comportamentos necessários para
implementação de cada componente em cada mídia. Todas compartilham uma estrutura básica de propriedades (identificação do componente, seu nome, seu tipo) para
o correto funcionamento das partes integrantes do FXG. Cada especialização dessa
classe corresponde a um padrão de tarefa identificado na análise de serviços de governo realizada anteriormente (3.2.3).
Por exemplo, o componente que implementa o padrão de tarefa ‘Obtain preservice information’ é definido pela classe ‘GetPreServiceInfoComponent’ depositada
3
verificar no endereço http://lts-i.pcs.usp.br/ onde está o trabalho de task patterns.
32
na camada de domínio da aplicação, e cada versão específica para uma mídia corresponde a uma especialização dessa classe. Assim, as classes relacionadas com a
implementação de um componente herdam operações e atributos determinados pelo
padrão de tarefa.
Foi feita uma análise de vários padrões de tarefa para encontrar todos elementos necessários à sua implementação, onde esses elementos foram capturados na
forma de classes, atributos e métodos. Este processo é semelhante ao processo de
“sedimentação” (Fach, 2001) no qual os elementos analisados são colocados em camadas, e os elementos de camadas superiores utilizam os elementos das camadas
inferiores.
No desenvolvimento do Framework foram criados componentes para atender
cada um dos padrões de tarefa estudados. O conjunto dessas classes correspondem
a um módulo chamado FrameworkLibrary. Para atender a um novo padrão de tarefa,
é necessário apenas adicionar ao FrameworkLibrary novas classes que a partir desse
momento, podem ser utilizadas em um serviço de governo — o conjunto de classes
do FrameworkLibrary corresponde aos objetos de domínio da aplicação. Cada nova
mídia incluída também necessita de especializações das classes correspondentes aos
padrões de tarefa em que essa mídia pode ser aplicada.
4.2.2
Componentes
A idéia de reuso de software sempre esteve associada à componentes os quais
podem ser facilmente conectados para montagem de um sistema. Inclusive, assim,
surgiram ambientes de programação orientados a componentes (e.g. Visual Basic,
Delphi). A mesma idéia é aplicada ao Framework X-Gov, onde um determinado tipo
de componente foi criado para atender um padrão de tarefa, e especializado para
cada uma das mídias suportadas: tv, mobile e web. A biblioteca de componentes tem
o importante papel de fornecer soluções padronizadas para o projeto de um serviço
de governo elaborado pelo gestor público.
Do ponto de vista técnico, por ser construído com linguagens orientadas a objeto, o Framework X-Gov é uma coleção de classes dos quais originam seus objetos que trabalham em cooperação, formando assim uma biblioteca de componentes.
Cada componente foi originado a partir de um padrão de tarefa, por exemplo, o padrão ‘Get track id’, que corresponde à tarefa de obter um número de processo para ser
futuramente acompanhado, originou um componente representado pela classe ‘GetTrackIdComponent’. Como cada mídia tem necessidades específicas, essa classe foi
especializada gerando outras 3 classes: ‘WebGetTrackIdComponent’, ‘TVGetTrackIdComponent’ e ‘MobGetTrackIdComponent’ — veja na figura 4.4.
33
Figura 4.4: Componente GetTrackIdComponent
Os componentes de interface são as peças que representam as soluções para
as tarefas de interação do cidadão em cada mídia. O componente oferece os elementos de interface com o usuário como uma página web, uma mensagem SMS, um
e-mail, ou um programa interativo da TVDi, etc. O objetivo de passar um componente
pelo processo de sedimentação é torná-lo menor e mais flexível, uma vez que um
componente novo realiza uma tarefa macro, com pouca flexibilidade. A tendência é
que a tarefa realizada por um componente seja dividida em tarefas menores e com
maiores opções de configurações, permitindo uma composição de componentes mais
flexível.
Os padrões de tarefa apresentados, e resumidos pela figura 4.5, estão conectados aos componentes de interface de usuário. Dessa forma, faz parte do Framework
X-Gov uma biblioteca de componentes composta pelos 18 padrões de tarefa com suporte para 3 mídias, totalizando 54 tipos diferentes de componentes.
34
Figura 4.5: Padrões de Tarefas
No entanto, é impossível criar uma biblioteca com extensão suficiente para cobrir todas as necessidades atuais e futuras. A arquitetura do FXG permite a extensão
desses componentes para aplicação em outros serviços que necessitem de novos
componentes ou versões modificadas dos mesmos.
Conforme exposto, deve existir a possibilidade de se criar e adicionar novos
componentes. As novas classes criadas devem seguir a mesma estrutura definida
pelas outras classes, ou reutilizar classes que existam em camadas inferiores. O
mecanismo para criar novos componentes, considerando que os componentes podem
ser feitos em diferentes plataformas de desenvolvimento como Java, .NET, Symbian,
Android, etc., é seguir uma interface de programação pré-definida com métodos de
retorno utilizados na integração com o FXG.
O desenvolvimento dos componentes do framework X-Gov seguiu um modelo
iterativo com entregas determinadas por três provas de conceito. Cada prova de conceito adicionou novas características à arquitetura, o que levou a uma nova etapa de
sedimentação. Note que o conjunto de padrões de tarefa permitem criar serviços de
governo além daqueles implementados nas provas de conceito.
4.3
Partes Integrantes do Framework
Quando um novo serviço de governo ou a atualização de um existente é proposta por gestores públicos, eles deverão projetar como desejam que o cidadão interaja com o serviço. É necessário, portanto, um processo de modelagem que forneça
35
o ferramental para que esse serviço seja produzido, concentrando-se o projetista na
escolha das tarefas a serem realizadas pelo cidadão utilizando múltiplas mídias de
forma integrada.
Podem-se ver os elementos gerais que compõem o FXG na figura 4.6 notandose a existencia de:
• uma ferramenta capaz de modelar um serviço e suas mídias utilizada pelo gestor
para descrever um serviço;
• uma linguagem que descrever o que foi modelado e serve como dados de configuração para o FXG;
• um repositório de componentes que contém implementações na forma de classes para cada tipo de componente;
• um repositório de transições que contém a implementação na forma de classes
e acionam outras aplicações externas (e.g. um servidor de e-mail) para cada tipo
de transição;
• um gerenciador de componentes capaz de processar os dados de configuração,
instanciar componentes e transições para criar uma aplicação X-Gov.
Figura 4.6: Modelo X-Gov
36
4.3.1
Gerenciador de Componentes
O Gerenciador de Componentes (Component Manager ) é uma peça central
do Framework X-Gov responsável por instanciar os componentes utilizados por um
serviço de governo. Ele mantém uma lista de componentes em memória para que as
diversas aplicações que fazem parte de um serviço possam acessar, e disponibiliza
os dados destes componentes por meio de Web Services.
4.3.2
Gerenciador de Transições
Essa parte do Framework X-Gov reúne uma série de mecanismos e funcionalidades para a navegação cross-media. Objetiva integrar componentes utilizados em
múltiplos meios de comunicação. Oferece serviços para controle de navegação do
usuário, controlar dados compartilhados entre várias mídias, semelhante a idéia de
sessão web, chamada de X-Session, e possui ainda adaptadores para comunicação
com servidores de e-mail, gateways de SMS, portais de voz e envio de mensagens
instantâneas (e.g. MSN).
4.3.3
Linguagem de Configuração
O FXG necessita de uma linguagem de modelagem para descrever um serviço
que sirva para alimentar o gerenciador de componentes na hora de configurar uma
nova aplicação X-Gov. A Cross-Media Language (CroMeL) é uma linguagem específica de domínio definida neste trabalho, usada para modelar um serviço de governo
sobre mídia cruzada, ou simplesmente, para modelar um serviço X-Gov. Ela é capaz
de descrever quais as atividades que fazem parte de um serviço, quais as mídias utilizadas em cada atividade (determinando assim os componentes), além de especificar
as transições que ocorrem entre elas.
Um serviço X-Gov pode ser especificado por meio de uma ferramenta gráfica
chamada de X-Builder (veja figura 4.7) que gera um código XML com as informações
necessárias para criar uma aplicação pelo FXG. Uma desvantagem dessa alternativa
atualmente, é a falta de meios para inserir código embutido, mas que poderia ser
implementada com uso de elementos XML tipo CDATA e a inclusão de outros editores
no X-Builder. Outra ponto a se considerar é a necessidade do gestor utilizar essa
ferramenta na hora de criar um novo serviço, seria difícil criar esse código XML sem o
auxílio da ferramenta.
37
Figura 4.7: Ferramenta gráfica para descrição de um serviço
A CroMeL visa facilitar a foram de descrever a conexão entre as mídias, os
componentes e seus parâmetros, assim como os demais elementos de um modelo
X-Gov no que diz respeito a criação de uma aplicação como o FXG. Na sua versão
em XML, dos dados de configuração são gerados pela ferramenta supracitada, e o
gerenciador de componentes interpreta esses dados para gerar uma aplicação X-Gov.
Na versão da CroMeL, os dados de configuração são inseridos em um tipo de script
e o gerenciador de componentes torna-se o interpretador desse script. A figura 4.8
destaca as partes afetadas dos elementos que compõem o FXG.
38
Figura 4.8: Configuração através do X-Builder e através da CroMeL
4.4
Conclusão
O Framework X-Gov é apoiado pelo reuso de seus componente (o que contempla seus dados, interfaces e controles), e por isso garante a consistência do modelo de
interação por todos os componentes em diversas instâncias de aplicações com o FXG.
Do ponto de vista de IHC, devido ao reuso dos componentes, caso seja necessário
realizar alterações de interface ou do modelo de interação após uma análise de usabilidade, com a simples alteração de um componente todos os serviços construídos
que o utilizam serão atualizados.
De acordo com Fach (2001), o processo de sedimentação funciona bem
quando aplicado para a uma industria tradicional como o setor bancário, onde o domínio é conhecido e apresenta-se estável por muitos anos. Contudo, em novos campos
de negócio onde o domínio da aplicação está sendo explorado ou elaborado, como é
este caso, existe uma dificuldade maior para aplicar este processo na definição do seu
modelo de domínio.
O processo para modelar, e consequentemente, criar um novo serviço de governo com o FXG depende primeiramente da competência de um usuário conhecer os
padrões de tarefa suportados pelo FXG, bem como conhecer os serviços de transição
e as mídias disponíveis na hora de se modelar um serviço X-Gov. A partir daí, ele
pode criar uma descrição do serviço por meio da linguagem de configuração do FXG
(CroMeL) e quando a descrição é carregada pelo FXG automaticamente uma nova
aplicação X-Gov é disponibilizada. É da competência dos programadores do governo
ampliar os componentes, transições e mídias conforme novas necessidades de um
serviço, podendo para isso reutilizar os elementos disponíveis inicialmente nos repo-
39
sitórios do FXG. Eles também devem criar integrações com os sistemas legados para
que sejam utilizados por uma aplicação X-Gov.
40
Seção
5
A Linguagem CroMeL
“Aquele que não conhece outras línguas não conhece a sua própria.” (GOETHE)
Esse capítulo introduz a linguagem CroMeL, detalha sua sintaxe e semântica
com todos os elementos necessários para modelar serviços de governo no Framework
X-Gov. A sintaxe é definida por meio da notação Extended Backus–Naur Form (EBNF)
e para implementação foi utilizada uma ferramenta chamada ANother Tool for Language Recognition (ANTLR)1 .
5.1
Introdução a CroMeL
CroMeL significa Cross-Media Language, e seu nome já indica uma linguagem
aplicada ao domínio de mídia cruzada. Por uma feliz coincidência CroMeL também é
um termopar do tipo K ou E 2 , e a título de curiosidade, um termopar é a junção de
dois metais utilizado para medição de temperatura. Neste caso também trata-se de
uma linguagem criada com objetivo de unificar componentes presentes em diferentes
mídias, particularizado para serviços de governo.
CroMeL é uma linguagem específica de domínio, declarativa, que permite especificar um serviço de governo em mídia cruzada. Para entender melhor o conceito
da linguagem, veja a figura 5.1 que apresenta seu contexto. Nessa figura pode-se
observar que a CroMeL é uma linguagem utilizada no mapeamento de conceitos do
domínio X-Gov com o Framework X-Gov, que corresponde aos conceitos de serviço,
1
2
http://www.antlr.org/
http://pt.wikipedia.org/wiki/Termopar
41
atividades, padrões de tarefa, transições e navegações com as classes que implementam esses conceitos.
Figura 5.1: Contexto da linguagem CroMeL
Os conceitos de domínio podem ser observados da seguinte forma:
• Dentro do contexto de um serviço, pode existir diversas atividades, transições e
navegações;
• Uma atividade depende da determinação explícita de um padrão de tarefa, e é
composta por uma ou mais declarações de mídias;
• A mídia junto com o padrão de tarefa define qual implementação de componente
deve ser utilizado;
• As navegações permitem definir uma migração na mesma mídia;
• As transições permitem definir uma maneira de migrar de uma mídia para outra.
O conceito de mídia cruzada é visível na linguagem quando observa-se que a
partir da declaração de uma mídia, dentro de uma atividade, pode-se declarar uma
transição que leva para outra mídia da mesma ou de outra atividade.
5.1.1
Elementos da linguagem CroMeL
O mapeamento dos elementos de domínio feitos pela CroMeL podem ser observados na figura 5.2. A seguir é feito um detalhamento desses elementos que fizeram parte dos requisitos para construção da gramática da linguagem.
42
Um serviço de governo é a instância de um sistema com objetivo de suprir uma
necessidade pública (veja na sessão 3.2.2 mais informações sobre essa definição). Na
CroMeL, um serviço é definido por um nome e um contexto formado por um conjunto
de atividades, transições e navegações.
Uma atividade é uma tarefa executada por um cidadão em um serviço de governo, e é definida por um nome e por um padrão de tarefa (veja na sessão 3.2.3 os
padrões de tarefa disponíveis). Dentro do contexto de uma atividade, contém a declaração de uma mídia, e de acordo com o padrão de tarefa selecionado e a mídia,
um tipo de componente é definido. Para cada tipo de componente, deve-se passar
parâmetros utilizados na sua configuração. Por exemplo, se for declarada para a atividade ObterSenhaParaAtendimento o padrão de tarefa GetTrackId, e a mídia mobile,
o tipo de componente definido será MobGetTrackIdComponent que contém uma série
de propriedades chamadas de parâmetros desse componente.
Uma transição é uma maneira de migrar de uma mídia para outra, e depende
da definição do seu tipo — o tipo da transição, assim como o tipo do componente,
determina quais os parâmetros devem ser passados, para consultar as transições disponíveis, veja a figura B.4 no apêndice B.1) — e qual é a mídia de origem e destino
que deverá ocorrer uma transição. Para declarar tanto a mídia de origem quanto a
mídia de destino deve-se usar o nome da atividade e o tipo de mídia declarado na
atividade. Por exemplo, pode-se declarar uma transição da atividade/mídia ObterSenhaParaAtendimento.mobile para a atividade/mídia PreencherCadastro.web por uma
transição do tipo PushTransitionData.
Uma navegação, é mais simples que uma transição, e permite declarar um caminho de uma atividade para outra dentro da mesma mídia. Necessita apenas de um
identificador dessa navegação chamado de label e qual a atividade/mídia de origem e
destino. Veja que uma navegação não tem tipo e nem parâmetros de configuração e
suas informações são obtidas pelos componentes de uma mídia para indicar que ele
pode levar o usuário para um outro componente da mesma mídia.
43
Figura 5.2: Mapeamento de contexto na linguagem CroMeL
Além dos elementos de domínio, outros elementos foram incorporados na CroMeL para incrementar a linguagem:
• Uma forma de declarar variáveis utilizadas internamente na hora de atribuir va44
lores aos parâmetros dos componentes e das transições;
• Uma forma de fazer referência a uma atividade/mídia por meio do nome da atividade e o tipo da mídia na hora de declarar uma navegação ou transição;
• Incluir código embutido para ser executado na inicialização de cada atividade;
• Comentários que não são processados pelo interpretador.
Para a declaração de variáveis utilizadas internamente foi usada a forma mais
comum encontrada em linguagens de programação: um identificador para a variável,
o símbolo de atribuição (=) e seu valor (não sendo necessário definir o tipo). Podese recuperar o valor de uma variável, na hora de atribuir o valor de um parâmetro,
adicionando-se $ antes de seu identificador.
Para declarar a referência de uma atividade/mídia na determinação da origem e
destino de uma navegação ou transição, foi utilizado o mesmo símbolo de passagem
de parâmetro por referência da linguagem C (&), dessa forma, a referência de uma
atividade/mídia deve ser escrita como &NomeAtividade.mídia.
A inclusão de código embutido permite ampliar o uso de um script CroMeL na
declaração das atividades, podendo conter códigos que são executados na inicialização do serviço3 . A inspiração na forma utilizada para incluir regras de negócio como
código embutido veio da conceito de literate programming (Knuth, 1984) que permite
que cada trecho de código seja associado com uma pequena descrição de seu significado.
Comentários em múltiplas linhas foram influenciados pela notação clássica de
C e outras linguagens (\* ... *\) e comentário em linha foi inspirado pela sintaxe de
Ruby onde o símbolo # indica para o interpretador ignorar qualquer coisa até o final
da linha.
Em resumo, na definição da linguagem CroMeL foram utilizados elementos
para indicar o tipo de mídia (web, mobile, tv), o tipo de transição (nome da classe de
transição), o nome e o tipo da atividade (definido pelo padrão de tarefa), o tipo do componente (definido pelo padrão de tarefa + mídia) e uma forma de passar parâmetros
de configuração para os componentes e para as transições. Além dos elementos de
domínio foram acrescentados símbolos que permitem declarar variáveis, comentários
e referência aos componentes. Além disso, com intuito de ampliar sua capacidade, foi
criado uma maneira de embutir código de uma linguagem GPL.
3
O código embutido poderia ser executado em outras etapas do ciclo de vida do serviço além da
inicialização, como por exemplo, na hora em que uma atividade é iniciada por um usuário, no momento
que uma transição ocorre, ou quando uma atividade é finalizada, no entanto, essa lógica ainda não foi
especificada no FXG, e portanto, não foi incluído suporte a outros estados na linguagem CroMeL até o
momento.
45
5.1.2
Implementação
Desenvolver uma linguagem de programação depende da implementação de
um programa capaz de analisar e processar dados de entrada, e dessa forma, significa construir uma aplicação que executa determinadas ações de acordo com as
sentenças definidas para essa nova linguagem. Desenvolver uma linguagem de programação pode ser bastante complicado, portanto essa tarefa deve ser decomposta
em etapas que incluem a criação de um reconhecedor capaz de realizar a análise
léxica e sintática e a criação de um interpretador capaz de executar ações de acordo
com a semântica definida. Um reconhecedor, conhecido também como dispositivo
cognitivo, é um sistema formal capaz de aceitar todas as sentenças que pertençam a
uma determinada linguagem (Neto et al., 2009).
Um reconhecedor é capaz criar uma representação intermediária das informações encontradas nos dados de entrada, enquanto o interpretador utiliza as informações coletadas para executar ações e produzir dados de saída. A figura 5.3 representa
as partes que compõem a implementação da CroMeL.
Figura 5.3: Etapas de implementação do interpretador CroMeL
O objetivo principal em criar uma linguagem específica de domínio é aumentar
a produtividade de um Engenheiro de Software por meio da definição de notações
melhores em um determinado domínio, e assim, aumentando o nível de abstração
do problema (como conseqüência também facilita a leitura do código escrito nessa
linguagem).
Diversos frameworks como Ruby on Rails 4 , JBOSS Seam 5 , ROMA 6 , utilizam técnicas consideradas por muitos como aplicação de DSLs para realizar ma4
http://rubyonrails.org/
http://seamframework.org/
6
http://www.romaframework.org/
5
46
peamento objeto-relacional, especificar templates de páginas e declarar componentes de interação, e por meio dessas técnicas, conseguem elevar o nível do desenvolvimento para camadas mais altas de abstração, simplificando o criação de sistemas com esses frameworks (Se interessar, veja um vídeo em que um sistema
de blog é construído em apenas 15 minutos, incluindo a definição do schema do
banco de dados e interface web com recursos AJAX em apenas 15 minutos http:
//media.rubyonrails.org/video/rails_blog_2.mov.).
Para o Framework X-Gov atingir todo seu potencial existe a necessidade de
facilitar a modelagem de um serviço de governo em mídia cruzada. Para simplificar
o desenvolvimento de um sistema com o Framework X-Gov foram consideradas diferentes alternativas na implementação de sua DSL:
• Representação da linguagem em notação XML;
• Uma DSL Interna feita em Ruby;
• Uma DSL Externa.
A vantagem em se criar uma representação da linguagem em notação XML
foi não ser necessário construir o reconhecedor — existem inúmeros reconhecedores
de XML disponíveis nas mais diversas linguagens de programação — no entanto, a
notação em XML não atende o objetivo principal para o qual se define uma DSL que
é aumentar a produtividade através de um nível de abstração mais alto. E apesar do
uso da notação em XML ser adequado para comunicação entre programas, ele não
se apresentou adequado para servir para comunicação com outros seres humanos
encarregados de escrever e ler esse código.
Essa foi a primeira alternativa implementada completamente e serviu para definir muitos dos elementos necessários para a construção do interpretador que envolve
a execução de ações a partir das informações coletadas do XML, essa versão foi
chamada de CromelXML. Como modelar um serviço em CromelXML não é muito adequado para ser escrita por pessoas, foi criado uma ferramenta gráfica7 que gera o
código em XML a partir de um diagrama em que são declarados os elementos apresentados na sessão 5.1.1.
Embora alguns autores também considerem arquivos de configuração em XML
uma DSL Externa, se diferencia de uma verdadeira DSL Externa pois sua notação
ainda fica restrita as regras de criação de um XML bem formado, sendo que em uma
DSL Externa autêntica pode-se definir a notação que quiser, ou seja, aquela que for
mais adequada para um domínio.
A implementação da CroMeL como uma DSL Interna em Ruby pareceu promissora no inicio pelas seguintes razões:
7
trabalho de iniciação científica associado ao projeto X-Gov, desenvolvido pelos alunos Daniel Interliche de Oliveira, com bolsa da FUSP e André Martini Diniz.
47
• Ruby é extensível por natureza, e tem uma sintaxe flexível na qual é possível definir sobrecarga de operadores, parêntesis são opcionais, classes abertas como
Number e String que permitem incluir novas funções aos objetos principais da
linguagem;
• Ruby oferece recursos de meta-programação (e.g. method missing, alias
method) ou MOP (meta-object protocol) que de acordo com Kiczales & Rivieres (1991), trata-se de uma interface orientada a objeto para especificação de
extensão de linguagem e transformação e ainda conta com alguns recursos de
linguagens funcionais como closures e lambdas;
• Existe implementação de Ruby em C8 , e nas plataformas Java (JRuby9 ) e .NET
(IronRuby10 ).
Não foram consideradas outras linguagens inicialmente por não atenderem aos três
requisitos apresentados acima — Python atendia bem o segundo e terceiro, enquanto
Groovy atendia bem o primeiro e o segundo.
Essa estratégia de criar uma DSL embutida (ou interna) possui como vantagem: (a) Menor esforço de desenvolvimento já que a implementação atual pode ser
utilizada; (b) Normalmente produz uma linguagem mais poderosa do que os outros
métodos, já que muitos recursos da LP hospedeira estão disponíveis ou pré-existem;
(c) a infra-estrutura da linguagem hospedeira pode ser reutilizada (ambiente de desenvolvimento, editores, debuggers, profilers, etc.) e (d) caso o usuário conheça a
linguagem hospedeira, a compreensão da nova DSL torna-se para este mais fácil.
Embora essa alternativa pareceu promissora no início, foi descartada pois não
era possível atender o objetivo principal em ter uma notação totalmente adequada ao
domínio sendo obrigatório que o usuário da CroMeL soubesse primeiramente programar em Ruby para utilizar essa versão — não é a realidade de muitos funcionários
públicos conhecer mais de uma linguagem de programação, ainda mais uma linguagem que não é muito popular11 . Pode-se dizer que a alternativa de criar uma DSL
Interna é uma forma mais simples de implementar uma DSL (comparando com uma
DSL Externa) pois aproveita o reconhecedor e o analisador da linguagem hospedeira,
e embora facilite sua construção (pode ser por isso que observa-se tantas DSLs internas atualmente), pode não ser uma alternativa adequada a determinados tipos de
aplicações como foi neste caso. Um ponto que pesou fortemente para essa que essa
alternativa fosse descartada, foi a falta de capacidade de retornar informações de erro
8
http://www.ruby-lang.org/en/
http://jruby.codehaus.org/
10
http://www.ironruby.net/
11
a popularidade de uma linguagem de programação pode ser analisada no índice TIOBE http:
//www.tiobe.com/index.php/content/paperinfo/tpci/index.html.
9
48
relativos a sintaxe do script, e não a sintaxe do Ruby, o que por si só apresenta um
grande desafio para o uso de DSLs internas.
A escolha em criar uma DSL Externa veio do amadurecimento obtido sobre
esses conceitos, e o desejo de criar notações mais adequadas para a linguagem conseguindo assim aproximar-se do objetivo principal de definir um nível mais alto de
abstração e permitir que especialistas de domínio entendam seu código, e inclusive,
auxiliem os programadores na modelagem de um serviço de governo eletrônico com
o Framework X-Gov.
Para sua implementação existiam diversas ferramentas disponíveis, desde geradores de parsers como os clássicos lex, yacc, bison, até ferramentas chamadas de
language workBenches que tratam-se de verdadeiras IDEs para construção de linguagens como o Meta Programming System (http://www.jetbrains.com/mps/) da
JetBrains ou o xText (http://www.eclipse.org/Xtext/) doado para fundação eclipse.
A escolha da ferramenta não foi sistemática por não ser foco deste trabalho, e apesar
das diversas opções, foi escolhida a ferramenta chamada ANTLR que atendeu a uma
simples premissa: gerar o código do parser em Java e C#. Essa é uma ferramenta que
pode ser utilizada para construção de reconhecedores, interpretadores, compiladores
e tradutores a partir de ações contidas na descrição da gramática. Seguem algumas
outras vantagens encontradas:
• Gera código que pode ser modificado posteriormente, e é facilmente integrado
em outras aplicações;
• Gera um reconhecedor descendente-recursivo utilizando uma extensão do LL(k)
chamada de LL(*) capaz de utilizar lookahead arbitrário;
• Integrado com um engine de template chamado StringTemplate projetado para
gerar código estruturado;
• Possui um ambiente de desenvolvimento de gramática chamado ANTLRWorks;
• Open-source liberado sob a licença BSD;
• Suporta diversas linguagens destino como: Java, C#, Python, Ruby, Objective-C,
C/C++
O desenvolvimento da CroMeL pode ser visto sob a ótica de um método interativo/incremental, já que seus elementos foram determinados a partir da construção
de provas de conceito que tornaram possível refinar a linguagem para atender aos
cenários planejados.
Um primeiro cenário trata de uma simulação de matricula escolar com múltiplos
dispositivos e mídias e pode ser visto pelo vídeo disponível em http://lts-i.pcs.
usp.br/index.php/projetos/xgov/61. A seguir é descrito o cenário:
49
1
2
3
4
5
6
7
8
O usuário inicia sua interaç~
a o do caso de uso pela TV digital que contém
informaç~
o es sobre o serviço de matrı́cula . Após obter algumas
informaç~
o es básicas sobre o serviço , ele seleciona onde quer continuar
o diálogo : no celular ou na internet .
A impossibilidade de continuar a interaç~
a o sobre uma determinada mı́dia
ilustra a situaç~
a o na qual aquela mı́dia pode n~
a o ser adequada para a
atividade em quest~
a o , e indica um \ emph { call - to - action } sobre qual
mı́dia o usuário pode continuar a interaç~
ao .
O usuário seleciona continuar pelo celular , e para facilitar a transiç~
ao
, aparece uma imagem QR Code \ footnote { Para saber mais sobre QR Code
ver \ url { http :// en . wikipedia . org / wiki / QR_Code }} que um aplicativo
instalado no celular é capaz de capturar e interpretar .
No celular , o QR Code é decodificado em uma URL , e pergunta se o usuário
quer navegar na Web . Ao acessar a página do serviço de matrı́cula pelo
celular s~
a o apresentadas opç~
o es na página inicial . O usuário
seleciona a opç~
a o buscar escolas pelo nome , entra com parte do nome e
executa a busca . Após o sistema apresentar os resultados , o usuário
seleciona uma das escolas encontradas e o sistema retorna com
informaç~
o es da escola e opç~
o es para continuar o diálogo na TV . Pode - se
ver a foto da escola na TV ou ver o mapa da escola na TV , que pelo
fato de ter uma tela grande , é uma mı́dia mais adequada para apresentar
esse conteúdo .
O usuário pode entrar também no celular com seu endereço de e - mail para
receber o formulário de matrı́cula . Em seguida , já no \ emph { desktop } ,
ao selecionar um link no e - mail recebido , o usuário é levado ao portal
web para preencher seu cadastro . Nesse momento ocorreu uma transiç~
ao
de dispositivos do celular para o \ emph { desktop } , e no \ emph { desktop }
ocorreu uma transiç~
a o de mı́dias do e - mail para a web --- preencher um
formulário na web pelo \ emph { desktop } é muito mais adequado do que por
exemplo na web pelo celular .
Ao terminar o cadastro , o sistema conhece o número do celular do usuário
, e envia um SMS notificando que a matricula foi recebida e informa um
número para acompanhamento do processo .
Listagem 5.1: Cenario de matricula escolar
A partir deste cenário a maior parte dos elementos da CroMeL foram definidos
como a necessidade de se declarar atividades, e no seu contexto, as mídias. Também ficou fácil notar a necessidade de existir alguma construção na linguagem para
declarar uma transição.
A partir de outro cenário para construção de um agendamento médico, foi
possível perceber a necessidade de declarar uma navegação entre componentes na
mesma mídia.
50
O script CroMeL é um arquivo texto que pode ser criado com qualquer editor
de texto simples. Depois desse código ter sido escrito, ele é implantado no servidor
que contém o interpretador da linguagem — fase conhecida como deployment. A
implantação é feita a partir de qualquer desktop com auxílio de um browser web.
Para isso, o desenvolvedor acessa uma página do servidor e selecionar a opção de
implantar um novo serviço em CroMeL.
A figura 5.4 ilustra o processo de implantação representado por um diagrama
de atividade. Após o script ser carregado, ocorre a validação sintática e semântica. Se
não ocorrerem erros de validação, ele é interpretado, o que disponibiliza um serviço
para ser acessado pelos cidadãos. A validação sintática visa verificar se os símbolos
encontrados no script pertencem à gramática da linguagem. E a validação semântica verifica se os componentes utilizados de fato existem, se as mídias utilizadas
nas transições foram declaradas no serviço e se os parâmetros apontados para cada
componente estão corretos e em acordo com seu tipo. Caso ocorram erros, eles serão apresentados ao usuário na interface web de deployment e a implantação será
cancelada, permitindo ao deployer ou desenvolvedor corrigir erros do script.
Figura 5.4: Implantação de um script CroMeL
O final da implantação do script consiste no seu armazenamento no servidor
e posterior interpretação. A figura 5.5 ilustra o interpretador criado para CroMeL e
as classes utilizadas pelo interpretador para realizar as funções necessárias durante
a interpretação de um script no Framework X-Gov. A interpretação do script aciona
51
a classe CromelService que implica em criar uma série de objetos para alimentar a
estrutura de dados interna necessária, preparar as transições (e.g. gerador de QRCode, envio de e-mail, envio de sms). Cada componente tem uma estrutura de dados
específica, mas compartilham o modelo de transição descrito no script e as regras de
negócio executadas na inicialização de cada atividade.
Figura 5.5: Interpretação de um script CroMeL
5.2
Gramática
A sintaxe da linguagem foi criada em inglês de acordo com as convenções
adotadas pelo projeto, no entanto seria fácil criar uma versão traduzida para português
o que poderia facilitar seu aprendizado por programadores brasileiros.
Uma gramática é uma DSL que foi projetada especificamente para descrever
outras linguagens, também chamada de metalinguagem. Ela é formada por um conjunto de regras que descrevem as frases de um linguagem, e o ANTLR é capaz de
converter essas regras em um programa reconhecedor. Os requisitos para construção da gramática da linguagem CroMeL determinam que ela deve suportar as seguintes construções (ilustradas pelos seus respectivos diagramas de sintaxe) — caso
queira, o leitor poderá consultar os diagramas de sintaxe para verificar a maioria dessas regras no apêndice C.3 (alguns diagramas de sintaxe foram omitidos por serem
extremamente simples).
52
1. Declaração de um ou mais serviços (Figura C.1);
2. Declaração de variáveis (Figura C.1);
3. Descrição das atividades que pertencem a um serviço (Figura C.4);
4. Descrição das mídias aplicadas à uma atividade e seus parâmetros (Figura C.4);
5. Declaração de transições entre mídias que pertencem a um serviço (Figura C.6);
6. Declaração de parâmetros para navegação dos componentes web que pertencem a um serviço (Figura C.7).
Segundo Neto et al. (2009), existem muitas notações (metalinguagens) utilizadas na definição gramatical das linguagens formais. Entre elas, as Expressões Regulares, o Backus-Naur Form (BNF), a Notação de Wirth e os Diagramas de Sintaxe são
bastante populares.
Os próximos parágrafos explicam em detalhes cada uma das regras léxicas
e sintáticas da linguagem CroMeL utilizando a Notação de Backus-Naur extendida
(EBNF) e alguns exemplos. Para ver a gramática completa ainda sem ações semânticas consulte o apêndice C.1 (as regras já com ações semânticas serão apresentadas
na seção 5.3).
Regras léxicas começam com uma letra maiúscula (para CroMeL essas regras
foram escritas todas em maiúsculo o que facilita sua identificação), e as regras sintáticas começam em minúsculo. Ambos os tipos de regras foram definidos no mesmo
arquivo. A linguagem começa pela declaração do nome de sua gramática e esse nome
faz parte do nome da classe do código gerado (primeira linha da listagem 5.2).
A primeira regra sintática contém a raiz da linguagem que permite declarar zero
ou mais variáveis e um ou mais serviços — o leitor pode ver que, na linha 2 da listagem 5.2, existe uma declaração da regra prog que contém zero ou muitas variáveis
(var *) e um ou muitos serviços (service+). As variáveis podem ser utilizadas para armazenar um valor de tipos diferentes e esse valor pode ser recuperado posteriormente
durante a interpretação do script.
No que service é uma palavras-chave obrigatória e por isso aparece entre aspas simples na regra gramatical service na linha 4 da listagem 5.2. Cada serviço, por
sua vez, possui um nome opcional (service_name?) (atualmente o nome do serviço
não é utilizado para nada, porém no futuro poderá servir para identificar diferentes
serviços criados em um mesmo script CroMeL), e declaração de suas partes que correspondem a uma ou mais atividades (task+), zero ou mais transições (transition*), e
navegação entre componentes web (web_navigation*) — sendo a primeira obrigatória
e as outras duas opcionais pois pode existir um serviço com apenas uma atividade e
sem nenhuma transição.
53
1
2
3
4
5
6
7
8
9
grammar
prog
var
service
decl
assign
CroMeL ;
: var * service + ;
: assign ;
: ’ service ’ service_name ? ’{ ’ decl ’} ’ ;
: task +
transition *
web_navigation *
;
: ID ’= ’ expr
Listagem 5.2: Raiz da linguagem
Quando uma variável for encontrada é executada a regra de atribuição (assign),
que o leitor pode ver na linha 3 da listagem 5.2, e de acordo com essa regra, recebe o
token ID (do analisador léxico) e seu respectivo valor, que inicia a execução de outra
regra (expr ) que é apresentada posteriormente. O valor de uma variável pode conter
uma seqüência de caracteres colocados entre aspas simples ou duplas, um número
inteiro ou um valor booleano. A entrada presente na listagem 5.3 é reconhecida pelas
regras da listagem 5.2.
1
2
3
4
5
6
7
var1 = ’ texto ’
var2 =123
var3 = true
var4 = ’ Detalhes do seu CPF ’
service ’ Consulta CPF ’ { ... }
service ’ Matricula Escolar ’ { ... }
Listagem 5.3: Sentenças de entrada para um serviço e declaração de variáveis
Na declaração de uma atividade (task ) — primeira linha da listagem 5.4 — é
obrigatório a definição do seu nome (usado posteriormente para identificar um componente em uma transição/navegação), e o padrão de tarefa dessa atividade colocado
após a palavra-chave ‘of’ (usado posteriormente para definir a classe do componente
que será instanciada de acordo a mídia). O conteúdo de uma atividade é colocado
dentro de ‘{’ e ‘}’ e contém a declaração do tipo de mídia e seus parâmetros.
Os parâmetros de cada mídia (params) contêm instruções para atribuição de
valores aos parâmetros do componente. A entrada presente na listagem 5.5 é reconhecida pelas listadas em 5.4. Observe que para a atribuição dos valores nos parâmetros de uma mídia pode-se usar as variáveis declaradas anteriormente, desde
que colocadas com o símbolo $ na frente, por exemplo, o leitor pode ver na linha 3
das sentenças de entrada de uma atividade o uso da variável $var4 que deve ter sido
declarada anteriormente.
54
1
2
3
4
5
6
7
8
9
10
11
12
task
: ’ task ’ task_name ’of ’ pattern_name ’{ ’ media + ’} ’ ;
media
: MEDIA params ;
params : ’( ’ assign ( ’ , ’ assign ) * ’) ’;
assign : ID ’= ’ expr
task_name
: ID ;
pattern_name : ID ;
expr
: STRING
| INT
| BOOLEAN
| QID // substituir ID por valor em memoria
| REF // substituir ID por numero gerado pela Task . media
;
Listagem 5.4: Gramática para descrição das ativadades de um serviço
A regra dos parâmetros (params) chama de maneira recursiva a regra de atribuição (assign), e pode ser usado quando tiver apenas um parâmetro, ou para muitos
parâmetros separados por vírgula, sendo que todos eles devem estar entre parênteses — veja o exemplo nas linhas 2,3 e 4 da listagem 5.5 dos parâmetros passados
para a mídia web, ou nas linhas 6,7 e 8 da mesma listagem os parâmetros passados
para a mídia mobile.
1
2
3
4
5
6
7
8
9
10
task ConsultaCpf of GetPreServiceInfo {
web ( componentName = ’ Informacoes sobre como consultar seu CPF ’ ,
description = $var4 ,
urlCalled = ’ webCpfInfo ’
)
mobile ( componentName = $var4 ,
uriCalled = ’ mobCpfInfo ’ ,
welcomeMessage = ’ Bem vindo a consulta de CPF ’
)
}
Listagem 5.5: Sentenças de entrada para uma atividade
A regra de atribuição (assign) de um valor utiliza um identificador (ID) de uma
variável e uma expressão (expr ). A regra de expressão determina o tipo de dado por
inferência de acordo com o token enviado pelo reconhecedor léxico. Os tipos podem
ser:
• STRING que corresponde a um valor entre aspas simples ou duplas;
• INT que corresponde a um valor numérico inteiro;
• BOOLEAN que corresponde a um dos literais ‘true’ ou ‘false’;
55
• QID que corresponde ao valor de uma variável declarada anteriormente e começa com ‘$’ seguido pelo nome da variável;
• REF que corresponde a referência de um componente, deve começar por ‘&’
seguido pelo componente identificado pelo nome ‘tarefa.mídia’ em que ele foi
declarado.
Os outros elementos que fazem parte de um serviço (além das atividades) são:
transições (transition) e navegações (navigation) que ocorrem entre mídias e componentes (Listagem 5.6). Estes elementos são opcionais, embora seja difícil imaginar
um serviço em mídia cruzada sem nenhuma transição entre mídias, podem existir
serviços simples que não necessitam de transições neste caso o Framework X-Gov
poderia ser usado com intuito de aproveitar os seus componentes.
Uma transição começa pela palavra reservada ‘transition’, seguida de qual tipo
de transição será utilizado (o tipo determina a classe a ser utilizada pelo FXG). Uma
transição deve levar a ação de um componente para outro, o que fica explícito na regra
de navegação (navigation). Para determinar uma navegação, utiliza-se a referência de
um componente declarado em alguma atividade precedido pelo caractere ‘&’ — veja
um exemplo de entrada reconhecida por esse gramática na listagem 5.7, onde deve
observar a linha 1 que contém a declaração de uma trasição do tipo BarCode que
deve ser realizada entre o componente web declarado na atividade ConsultaCpf e o
componente mobile declarado na mesma atividade.
1
2
3
4
5
6
7
transition
web_navigation
navigation
begin
end
transition_type
label
:
:
:
:
:
:
:
’ transition ’ transition_type navigation params ;
’ navigation ’ label navigation ;
’[ ’ begin ’->’ end ’] ’ ;
REF ;
REF ;
ID ;
STRING ;
Listagem 5.6: Gramática para declaração de transições e navegações
Além da declaração da navegação entre os componentes, uma transição geralmente necessitará de parâmetros, utilizados pela sua implementação, pois aciona
outros recursos como envio de um e-mail ou geração de uma imagem — a regra para
atribuição de parâmetros é a mesma apresentada anteriormente na listagem 5.4.
A regra de navegação (web_navigation) é mais simples do que uma transição,
ela contém um label usado na apresentação de um link e declaração de navegação
entre os componentes — da mesma maneira que ocorre em uma transição, os componentes são identificados pela atividade, e pela mídia, como pode ser observado
na listagem 5.7 na linha 9 onde foi declarada uma navegação do componente web
56
da atividade InfoSobreMatricula para o componente web da atividade SelecaoEscola.
Atualmente o recurso de navegação tem sido utilizado apenas pelos componentes
web, mas a CroMeL não tem nenhuma limitação na sua construção de ser utilizada
para declarar navegação entre componentes de mídias diferentes.
1
2
3
4
5
6
7
8
9
transition BarCode [ & ConsultaCpf . web -> & ConsultaCpf . mobile ]
( BaseUrl = ’ http :// www . receita . fazenda . gov . br / WS / consultaCpf ’ ,
ErrorCorrection = ’M ’ ,
ImageSize =5 ,
LabelMessage = ’ Use esse QRCode para acessar o proximo passo do
servico . ’ ,
TransitionId =7 ,
TransitionName = ’ QRCODE teste web -& gt ; mob ’)
navigation ’ Veja os dados de sua matricula ’ [ & InfoSobreMatricula .
web -> & SelecaoEscola . web ]
Listagem 5.7: Sentenças de entrada para transição e navegação
As regras léxicas são mais simples que as sintáticas e servem para determinar
os token utilizados pelas regras sintáticas. Esses tokens são formados pela cadeia de
caracteres lidos e selecionados de acordo com as seguintes regras apresentadas na
listagem 5.8.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
MEDIA
: ( ’ mobile ’ | ’web ’ | ’tv ’) ;
BOOLEAN
: ( ’ true ’| ’ false ’) ;
INT
: ’0 ’.. ’9 ’+ ;
ID
: ( ’a ’.. ’ z ’| ’A ’.. ’ Z ’| ’_ ’) ( ’a ’.. ’ z ’| ’A ’.. ’ Z ’| ’0 ’.. ’9 ’| ’ _
’) * ;
// referencia de uma variavel ( usada para recuperar seu valor )
QID
: ’$ ’ ID ;
// uma referencia do tipo Task . media ( usado para identificar
componentes )
REF
: ’\& ’ ID ( ’. ’ MEDIA ) ;
STRING
: ’" ’ .* ’" ’ | ’\ ’ ’ ~( ’\\ ’| ’\ ’ ’| ’\* ’) * ’\ ’ ’ ;
// espacos em branco
WS
: ( ’ ’| ’\t ’| ’\ r ’| ’\ n ’) { $channel = HIDDEN ;} ;
// comentarios
CMT
: ’# ’ ~( ’\ n ’| ’\ r ’) * ’\r ’? ’\n ’ { $channel = HIDDEN ;};
COMMENT
: ’/* ’ .* ’*/ ’ { $channel = HIDDEN ;} ;
Listagem 5.8: Regras léxicas
MEDIA identifica o tipo de mídia podendo ser apenas um dos literais ‘mobile’,
‘web’ ou ‘tv’. Os tipos de dados reconhecidos são STRING, BOOLEAN e INT, e são di57
ferentes da referência de uma variável QID que começa com ‘$’ e da referência de um
componente REF que começa com ‘&’. Espaços em branco (que incluem tabs e salto
de linhas), assim como comentários, não são enviados para o analisador sintático,
pois é escolhido um canal de comunicação diferente (HIDDEN) 12 .
O estudo da dependência entre as regras — que pode ser viso na figura 5.6 —
pode ajudar a otimizar a construção do reconhecedor, permitindo identificar situações
de reuso, e dessa forma criar um reconhecedor equivalente mais eficiente.
Figura 5.6: Grafo de dependência entre as regras sintáticas
O autômato finito deterministico (DFA) gerado para reconhecer todos os tokens definidos tem 72 estados, e se o leitor desejar, pode consultar seu diagrama
no apêndice C.8. O resultado da geração de um reconhecedor a partir da gramática
apresentada permite responder apenas SIM ou NÃO se as sentenças de entrada são
válidas. Porém para construir algo útil, como um interpretador, a gramática precisa ser
ampliada com ações semânticas.
12
O ANTLR permite que cada token seja emitido por canais diferentes de comunicação entre o analisador léxico e sintático, assim como freqüências de rádio, o parser pode ‘sintonizar’ em um canal e
ignorar os tokens emitidos pelos outros
58
5.3
Semântica
Ações semânticas são blocos de código escritos na linguagem de programação
do programa reconhecedor gerado e inseridas em diversos lugares dentro da gramática (como poderá ser observado pelos exemplos a seguir). O ANTLR realiza substituições de símbolos relativos aos atributos declarados, parâmetros e retorno das regras
sintáticas, mas não interpreta nenhuma instrução inserida nesses blocos de código
que pertence a linguagem destino do programa reconhecedor gerado.
Para interpretar o código da CroMeL uma série de ações semânticas foram
colocadas em sua gramática para extrair as informações necessárias na execução de
um script. Essas ações devem ser capazes de atender os seguintes requisitos para
integração da CroMeL com o Framework X-Gov :
• Para cada componente (definido pelo par atividade/mídia) deve ser atribuído um
identificador numérico único que pode ser utilizado em transições e navegações
entre os componentes;
• Cada par padrão/midia é determinado o tipo de componente a ser instanciado (o
nome da classe que implementa o componente é encontrado em um arquivo de
configuração externo, o que permite adicionar novos tipos de componentes sem
alteração na linguagem);
• A declaração de um tipo de transição determina a classe a ser instanciada (esse
tipo corresponde a uma classe que também fica em um arquivo de configuração
externo);
• Os parâmetros dos componentes e das transições devem corresponder as propriedades de suas classes conforme foram declarados, para serem atribuídos
aos objetos criados por meio de reflexão;
• As variáveis podem ser utilizadas para atribuir valores para qualquer parâmetro
facilitando reutilizar esses valores em parâmetros repetidos, assim como isolar
parâmetros que mudam com freqüência;
• O nome do componente definido por um par atividade/mídia precedido pelo sinal
de ‘&’ pode ser utilizado para fazer referência ao identificador numérico criado.
Declarações tanto de transição quanto navegação necessitam desse identificador numérico e o programador pode usar o seu nome.
• Identifica e extrair código embutido em uma atividade para executar quando uma
atividade for inicializada.
59
Para ilustrar todas as regras semânticas adicionadas, acompanhe pela listagem 5.9 um exemplo de script de entrada que alimenta o interpretador da CroMeL
com um serviço de agendamento médico. Se quiser, o leitor pode comparar essa
entrada com uma versão em XML utiliza inicialmente no apêndice C.6, e poderá observar algumas vantagens no uso da CroMeL em comparação com a representação
em XML como por exemplo: o uso de variáveis para atribuição de valores aos parâmetros, a declaração de componentes por meio de seu identificador (atividade/mídia)
na hora de realizar uma transição ou navegação, e a inclusão de código executado na
inicialização de uma atividade.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
G W S F i n d P r i v a t e I n f o r m a t i o n = ’ http ://143.107.102.15/ govside /
G W S F i n d P r i v a t e I n f o r m a t i o n / GWSFindPrivateInfo . asmx ’
service ’ Exams Schedule ’ {
task Ba s i c I nf o A b ou t S c h ed u l e of GetPreServiceInfo {
web ( componentName = ’ Basic information ’ ,
description = ’ For more information use the menu ’ ,
urlCalled = ’ webExamInfo ’
)
mobile ( componentName = ’ informations ’ ,
uriCalled = ’ mobExamInfo ’ ,
welcomeMessage = ’ Welcome to the X - Media Service ’
)
tv ( componentName = ’ My Exams List ’ ,
uriCalled = ’ tvExamInfo ’ ,
first = true
)
<< Test if database is online > >=
unless databale_online ? update_site ’ come back later . ’
@
<< Pre - notify health center > >=
var now = Time . now
schedule_new_exam ( now )
@
}
task ExamsList of FindPrivateInfo {
web ( componentName = ’ My Exams List ’ ,
au th ent ica ti onC om pId =& Authentication . web ,
uriCalled = ’ webExamList ’ ,
dataUrl = $GWSFindPrivateInformation ,
g e t F u l l E n t i t i e s L i s t W e b M e t h o d = ’ GWSGetPermittedExams ’ ,
60
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
g e t E n t i t y I n f o r m a t i o n W e b M e t h o d = ’ GWSGetExamInformation ’ ,
scheduleCompId =& Schedule . web
)
mobile ( componentName = ’ My Exams List ’ ,
au th ent ic ati onC om pId =& Authentication . mobile ,
uriCalled = ’ mobExamList ’ ,
instructionText = ’ Select an exam : ’ ,
listName = ’ Exams Requested ’ ,
dataUrl = $GWSFindPrivateInformation ,
g e t F u l l E n t i t i e s L i s t W e b M e t h o d = ’ GWSGetPermittedExams ’ ,
g e t E n t i t y I n f o r m a t i o n W e b M e t h o d = ’ GWSGetExamInformation ’
)
tv ( componentName = ’ My Exams List ’ ,
entityType = ’ Exam ’ ,
compAuthId =& Authentication . tv ,
compAuthId =& B as i c I n fo A b o u tS c h e d ul e . tv ,
uriCalled = ’ tvExamList ’ ,
dataUrl = $GWSFindPrivateInformation ,
g e t F u l l E n t i t i e s L i s t W e b M e t h o d = ’ GWSGetPermittedExams ’ ,
g e t E n t i t y I n f o r m a t i o n W e b M e t h o d = ’ GWSGetExamInformation ’
)
}
transition BarCode [ & B a si c I n f oA b o u tS c h e d ul e . tv -> & ExamsList . mobile ]
( BaseUrl = ’ http ://143.107.102.15/ poc3xgov / Mobile_Comp / mobile /
mobFindPrivExam ’ ,
ErrorCorrection = ’M ’ ,
ImageSize =5 ,
LabelMessage = ’ Use this QRCode to access next service step . ’ ,
TransitionId =7 ,
TransitionName = ’ QRCODE teste web -& gt ; mob ’
)
59
60
61
62
63
64
65
66
67
68
navigation ’ See your exam list ’ [ & B a s i cI n f o Ab o u t S ch e d u l e . web -> &
ExamsList . web ]
}
Listagem 5.9: Script CroMeL de entrada
Toda ação semântica embutida na gramática fica entre { }. Por exemplo, para
guardar o valor de uma variável quando executada a regra ‘var’ é recuperado os valores de ‘ID’ e ‘expr’ obtidos pela chamada da regra ‘assign’ por meio de uma instrução
de retorno dos valores ‘n’ e ‘v’. A chamada de uma regra é bem semelhante a chamada de uma função em uma linguagem de programação e permite passar e retornar
parâmetros. Pode-se observar pela regra ‘assign’ na listagem 5.14 que ela é capaz
61
de retornar dois valores simultaneamente para a regra ‘var’ que armazena o nome e o
valor da variável na memória que é um HashTable no escopo global. Esta ação será
utilizada para satisfazer o requisito de substituir os valores de variáveis na declaração
de parâmetros, veja a declaração de uma variável no código de entrada 5.9 na linha 1.
1
2
3
4
5
6
7
8
9
10
11
var
: assign
{
System . out . println (" Declaracao de variavel : "+ $assign . n
+"="+ $assign . v ) ;
memory . put ( $assign .n , $assign . v ) ;
};
assign returns [ String n , Object v ]
: ID ’= ’ expr
{
$n = $ID . text ;
$v = $expr . value ;
};
Listagem 5.10: Semântica de declaração de variável
A semântica de uma atividade (task ) apresentada na listagem 5.11 é um pouco
mais complexa pois envolve a passagem de parâmetros, apelidos para regras e uso de
variáveis com escopo dinâmico. Em resumo ela cria os objetos correspondentes aos
componentes declarados na atividade, determinar qual o tipo de cada componente e
coleta seus parâmetros. Depois guarda a representação do componente criado em
uma lista de componentes de escopo global, e por fim, executa um ou mais códigos
embutidos na hora de inicializar a atividade.
Para realizar isso, observe primeiramente a regra ‘media’: Ela recebe como parâmetro o nome da atividade (taskName) em que foi declarada, e o padrão de projeto
associado a essa atividade (patternName), — linha 12 da listagem 5.11 — obtém um
identificador para o componente por meio de uma variável contadora que pertence
ao escopo de um serviço (assim nenhum componente do mesmo serviço receberá o
mesmo identificador) e guarda o identificador em uma tabela de símbolos global para
ser usado posteriormente quando fizer referência a este componente pelo par: nome
da atividade e mídia (linha 17). Em seguida, o tipo do componente é determinado
de acordo com o padrão de tarefa e o tipo de mídia (linha 20), obtém sua lista de
parâmetros (linha 23) e por fim é criado um objeto que contém os dados do componente e serve para representar o componente reconhecido armazenando na lista de
componentes criado na etapa final do interpretador (linha 28).
Ao final da regra ‘task’ é executado o código embutido de inicialização de uma
atividade que pode ser visto nas linhas 7-8. Esse código escrito em Ruby13 é passado
13
Outras linguagens como JavaScript ou Python poderiam ser suportadas desde que incluído algum
62
para o IronRuby da versão em .NET ou JRuby da versão em Java dentro do FXG.
Para que o código seja processado pelo interpretador na versão em C#, é chamada a
função RunCromelScript da classe CromelService listado no apêndice C.7 — o leitor
pode ver como um código Ruby é executado pelo Dynamic Language Runtime do
.NET nas linhas 23-33.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
task
: ’ task ’ task_name { System . out . println (" Declaracao da atividade
:"+ $task_name . text ) ; }
’of ’ pattern_name ’{ ’ media [ $task_name . text , $pattern_name .
text ]+
( lc = literate_code
{
// Executa as regras definidas em um servico
System . out . println (" Executa codigo embutido : "+
$lc . comment ) ;
System . out . println ( $lc . code ) ;
}
) * ’} ’ ;
media [ String taskName , String patternName ]
: m = MEDIA params
{
int componentId = $service :: componentId ++;
String media = $m . text ;
String componentName = $taskName +"."+ media ;
componentIds . put ( componentName , componentId ) ;
String componentType = $patternName +"."+ media ;
System . out . println (" Novo componente do tipo "+
componentType +" [ id ="+ componentId +"]") ;
System . out . println (" parametros ="+ $params . p ) ;
ComponentDTO dto = new ComponentDTO () ;
dto . type = componentType ;
dto . parameters = $params . p ;
components . add ( dto ) ;
};
Listagem 5.11: Semântica de uma atividade
A semântica de navegação (listagem 5.12) é bem mais simples e se resume
a armazenar o label (linha 6), e obter o identificador dos componentes de navegação
parâmetro na CroMeL para indicar em qual linguagem o código embutido foi escrito.
63
referenciados na entrada (linhas 7 e 8). Finalmente guarda um objeto que representa
a navegação na lista global de objetos de navegação (linha 9). Para obter o ID do componente de navegação referenciado, as regras ‘begin’ e ‘end’ executam uma função
embutida no interpretador (linhas 19 e 22)14 .
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
web_navigation
: ’ navigation ’ label
navigation
{
NavigationDTO dto = new NavigationDTO () ;
dto . label = $label . text ;
dto . begin = $navigation . b ;
dto . end = $navigation . e ;
navigations . add ( dto ) ;
};
navigation returns [ int b , int e ]
: ’[ ’ begin ’->’ end ’] ’
{
$b = $begin . id ;
$e = $end . id ;
System . out . println (" Navegacao do componente ["+ $begin . id
+"] -> ["+ $end . id +"]") ;
};
begin returns [ Integer id ]
: REF { $id = getComponentId ( $REF . text ) ; };
end returns [ Integer id ]
: REF { $id = getComponentId ( $REF . text ) ; };
Listagem 5.12: Semântica de navegação
Uma transição tem ações bem parecidas com uma navegação ao que diz respeito da navegação entre componentes (linhas 11 e 12 da listagem 5.13), acrescentando sua lista de parâmetros obtidos pela chamada da regra ‘params’, armazenados
em um objeto na linha 10 e depois guardado na lista global de transições na linha 13.
1
2
3
4
5
transition
: ’ transition ’ transition_type
navigation
params
{
14
O código completo que contém essa função embutida pode ser visto no apêndice C.2 declarado na
linha 48.
64
6
7
8
9
10
11
12
13
14
System . out . println (" Nova transicao do tipo "+
$transition_type . text ) ;
System . out . println (" parametros ="+ $params . p ) ;
TransitionDTO dto = new TransitionDTO () ;
dto . type = $transition_type . text ;
dto . parameters = $params . p ;
dto . begin = $navigation . b ;
dto . end = $navigation . e ;
transitions . add ( dto ) ;
};
Listagem 5.13: Semântica de uma transição
A regra ‘params’ apresentada na listagem 5.14 tem alguns elementos novos:
tem uma rotina de inicialização para criar um objeto do tipo HashMap (linha 3) que
implementa uma estrutura de dados do tipo nome-valor para guardar os parâmetros
obtidos na entrada. Como um componente ou transição pode conter um ou mais
parâmetros, ela tem uma função para guardar o parâmetro do primeiro caso (linha 5)
e um loop para guardar os outros parâmetros quando fornecidos (linha 6) — como
existe mais de uma chamada a mesma regra ‘assign’, cada para cada chamada foi
atribuído um label ‘a1’ e ‘a2’ para que possam ser utilizados de maneira independente
nas suas respectivas regras semânticas. Por fim, esse Map é retornado para que
quem chamou essa regra possa recuperar seus parâmetros. Esses parâmetros são
utilizados na inicialização dos componentes e das transições como visto anteriormente
no código semântico das listagens 5.13 e 5.11 — se o leitor quiser, pode ver exemplo
dos parâmetros passados aos componentes nas linhas 6-8, 10-12, 14-16, 29-35, 3744, 46-53 e exemplo dos parâmetros passados a uma transição nas linhas 58-63 do
script de entrada 5.9
1
2
3
4
5
6
7
params returns [ Map p ]
@init {
p = new HashMap () ;
}
: ’( ’ a1 = assign { p . put ( $a1 .n , $a1 . v ) ; }
( ’ , ’ a2 = assign { p . put ( $a2 .n , $a2 . v ) ; } ) *
’) ’;
Listagem 5.14: Semântica dos parâmetros de componentes e transições
Toda atribuição de um valor apresentado pela regra ‘assign’ (listagem 5.14)
chama a regra ‘expr’ (listagem 5.15) que é capaz de determinar o tipo de dado por
inferência (de acordo com o TOKEN emitido) e fazer a conversão necessária. Quando
o valor identificado começar com $ (TOKEN QID) o valor da variável armazenada é recuperado na memória. Quando o valor identificado começar com & (TOKEN REF) que
65
corresponde a referência de um componente, seu identificador é buscado na tabela
de símbolos global. Observe que o tipo REF é utilizado também nas regras de navegação é para não ter que repetir o código da ação de consultar a tabela de símbolos,
foi declarado um método membro do parser.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
expr returns [ Object
: STRING {
| INT
{
| BOOLEAN {
value ]
$value = $STRING . text ; }
$value = Integer . parseInt ( $INT . text ) ; }
$value = Boolean . parseBoolean ( $BOOLEAN . text ) ; }
| QID // substituir ID por valor em memoria
{
// busca valor na memoria ( eliminando o $ que nao foi
colocado na tabela )
Object v = memory . get ( $QID . text . substring (1) ) ;
// se encontrado seta o valor de retorno , caso contrario
imprime erro
if ( v != null ) {
$value = v ;
System . out . println (" resolucao da variavel "+ $QID
. text +"="+ v ) ;
}
else System . err . println (" undefined variable "+ $QID . text )
;
}
| REF // substituir ID por numero gerado pela Task . media
{
$value = getComponentId ( $REF . text ) ;
}
;
Listagem 5.15: Semântica de expressões
Para finalizar a apresentação das ações semânticas implementadas, veja o código da regra ‘service’ na listagem 5.16. Elas são responsáveis por acionar as funções
do interpretador que criam os objetos dos componentes (linha 9), os objetos de transição (linha 15) e navegação (linha 22) guardados nas listas globais. Note que todas
essas ações são executadas após todos os elementos de um serviço declarado em
um script terem sido reconhecidos. O leitor deve se lembrar que código semântico
pode ser inserido em diversos lugares dentro da gramática, esse código é transplantado para o reconhecedor gerado pelo ANTLR. Para executar um código ao final da
execução de uma regra ele é inserido na instrução ‘@after’ (linha 6).
66
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
service
scope {
// contador usado para atribuir um ID para cada
componente em um servico
int componentId ;
}
@after {
System . out . println (" Execucao apos processamento da
entrada !") ;
// Cria os componentes da CroMeL e seta seus parametros
por reflexao
for ( ComponentDTO component : components ) {
System . out . println (" Criando componente "+
component . type ) ;
System . out . println (" Setando "+ component .
parameters . size () +" parametros ") ;
}
// Cria os objetos de transicao e seta seus parametros
por reflexao
for ( TransitionDTO transition : transitions ) {
System . out . println (" Criando transicao "+
transition . type ) ;
System . out . println (" Setando "+ transition .
parameters . size () +" parametros ") ;
System . out . println (" Transicao entre componente
"+ transition . begin +" e "+ transition . end ) ;
}
// Cria os objetos de navegacao
for ( NavigationDTO navigation : navigations ) {
System . out . println (" Criando navegacao "+
navigation . label ) ;
System . out . println (" Navegacao entre "+ navigation
. begin +" e "+ navigation . end ) ;
}
}
: { $service :: componentId =1; } // inicializacao do contador
’ service ’ service_name ? ’{ ’ decl ’} ’ ;
Listagem 5.16: Semântica de um Serviço
A maior parte do código semântico da CroMeL foi apresentado, algumas partes
foram omitidas por tratarem de instruções para resolução do nome de classes, da definição de classes internas, inicialização das listas globais de componentes, transições
67
e navegação. Se o leitor quiser, pode consultar o código da gramática completa no
apêndice C.2.
Quando este código é alimento com a entrada apresentada na listagem 5.9,
obtem-se a saída apresentada na listagem 5.17 que serve para acompanhar a execução do interpretador quando alimentado com o script CroMeL de entrada supracitado.
Essa versão apresentada trata-se de uma versão para depuração da implementação
da CroMeL e contém uma série de instruções de log (println) que foram colocadas
para permitir o acompanhamento da execução de um script em cada uma de suas
regras, e dessa forma, pode-se observar que todos os elementos necessários para
executar o script estão presentes.
Para que os componentes, transições e navegações sejam processados pelo
interpretador na sua versão em C#, são chamadas respectivamente as funções CreateComponents (linha 86), CreateTransitions (linha 125) e CreateNavigations (linha
36) da classe CromelService listado no apêndice C.7. Essa classe serve como um
camada de serviço usado pelo código do interpretador para processamento das instruções reconhecidas no script. Ela por sua vez utiliza outras classes auxiliares como
o ComponentFactory listado no apêndice C.8 para processar o script e acionar funções do FXG. A classe ServiceComponent serve como uma interface simplificada para
grande quantidade de código executado pelo FXG, ela implementa o padrão de projeto Façade (Gamma et al., 1995). Para construção das classes que transmitem os
dados entre a camada do interpretador e o ServiceComponent foi aplicado o padrão
de projeto Data Transfer Object (Alur et al., 2001). E para a criação dos componentes, transições e navegações foi aplicado o padrão de projeto Factory (Gamma et al.,
1995).
1
2
3
4
5
6
7
8
9
10
11
- declaraç~
a o da variável : G W S F i n d P r i v a t e I n f o r m a t i o n = ’ http
://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n / GWSFindPrivateInfo
. asmx ’
Declaraç~
a o da atividade : B as i c I n fo A b o ut S c h e du l e
Novo componente do tipo GetPreServiceInfo . web [ id =1]
parametros ={ componentName = ’ Basic information ’ , description = ’ For
more information use the menu ’ , urlCalled = ’ webExamInfo ’}
Novo componente do tipo GetPreServiceInfo . mobile [ id =2]
parametros ={ componentName = ’ informations ’ , uriCalled = ’ mobExamInfo
’ , welcomeMessage = ’ Welcome to the X - Media Service ’}
Novo componente do tipo GetPreServiceInfo . tv [ id =3]
parametros ={ componentName = ’ My Exams List ’ , uriCalled = ’ tvExamInfo
’ , first = true }
Executa código embutido : Pre - notify health center
var now = Time . now
schedule_new_exam ( now )
68
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
Executa código embutido : Test if database is online
unless databale_online ? update_site ’ come back later . ’
Declaraç~
a o da atividade : ExamsList
Erro : refer^
e ncia indefinida & Authentication . web
- resoluç~
a o da variável $ G W S F i n d P r i v a t e I n f o r m a t i o n = ’ http
://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n / GWSFindPrivateInfo
. asmx ’
Erro : refer^
e ncia indefinida & Schedule . web
Novo componente do tipo FindPrivateInfo . web [ id =4]
parametros ={ g e t F u l l E n t i t i e s L i s t W e b M e t h o d = ’ GWSGetPermittedExams ’ ,
componentName = ’ My Exams List ’ , uriCalled = ’ webExamList ’ ,
au th ent ic ati onC om pId = null , scheduleCompId = null ,
g e t E n t i t y I n f o r m a t i o n W e b M e t h o d = ’ GWSGetExamInformation ’ , dataUrl
= ’ http ://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n /
GWSFindPrivateInfo . asmx ’}
Erro : refer^
e ncia indefinida & Authentication . mobile
- resoluç~
a o da variável $ G W S F i n d P r i v a t e I n f o r m a t i o n = ’ http
://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n / GWSFindPrivateInfo
. asmx ’
Novo componente do tipo FindPrivateInfo . mobile [ id =5]
parametros ={ g e t F u l l E n t i t i e s L i s t W e b M e t h o d = ’ GWSGetPermittedExams ’ ,
componentName = ’ My Exams List ’ , uriCalled = ’ mobExamList ’ ,
au th ent ic ati onC om pId = null , instructionText = ’ Select an exam : ’ ,
g e t E n t i t y I n f o r m a t i o n W e b M e t h o d = ’ GWSGetExamInformation ’ , dataUrl
= ’ http ://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n /
GWSFindPrivateInfo . asmx ’ , listName = ’ Exams Requested ’}
Erro : refer^
e ncia indefinida & Authentication . tv
- resoluç~
a o da refer^
e ncia id = 3
- resoluç~
a o da variável $ G W S F i n d P r i v a t e I n f o r m a t i o n = ’ http
://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n / GWSFindPrivateInfo
. asmx ’
Novo componente do tipo FindPrivateInfo . tv [ id =6]
parametros ={ g e t F u l l E n t i t i e s L i s t W e b M e t h o d = ’ GWSGetPermittedExams ’ ,
componentName = ’ My Exams List ’ , uriCalled = ’ tvExamList ’ ,
compAuthId =3 , g e t E n t i t y I n f o r m a t i o n W e b M e t h o d = ’
GWSGetExamInformation ’ , entityType = ’ Exam ’ , dataUrl = ’ http
://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n /
GWSFindPrivateInfo . asmx ’}
- resoluç~
a o da refer^
e ncia id = 3
- resoluç~
a o da refer^
e ncia id = 5
Navegaç~
a o do componente [3] -> [5]
Nova transiç~
a o do tipo BarCode
parametros ={ BaseUrl = ’ http ://143.107.102.15/ poc3xgov / Mobile_Comp /
mobile / mobFindPrivExam ’ , ImageSize =5 , TransitionName = ’ QRCODE
teste web -& gt ; mob ’ , ErrorCorrection = ’M ’ , LabelMessage = ’ Use
this QRCode to access next service step . ’ , TransitionId =7}
- resoluç~
a o da refer^
e ncia id = 1
69
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
- resoluç~
a o da refer^
e ncia id = 4
Navegaç~
a o do componente [1] -> [4]
Execuç~
a o após processamento da entrada !
Criando componente GetPreServiceInfo . web
armazenamento de 3 parametros
Criando componente GetPreServiceInfo . mobile
armazenamento de 3 parametros
Criando componente GetPreServiceInfo . tv
armazenamento de 3 parametros
Criando componente FindPrivateInfo . web
armazenamento de 7 parametros
Criando componente FindPrivateInfo . mobile
armazenamento de 8 parametros
Criando componente FindPrivateInfo . tv
armazenamento de 7 parametros
Criando transiç~
a o BarCode
armazenamento de 6 parametros
transiç~
a o entre os componentes 3 e 5
Criando navegaç~
a o ’ See your exam list ’
navegaç~
a o entre os componentes 1 e 4
Listagem 5.17: Codigo de Saida
5.4
Discussão dos Resultados
Essa seção apresentou as técnicas utilizadas para criar o interpretador da CroMeL utilizado no Framework X-Gov. Toda sua sintática e semântica foi definida nas
sessões 5.2 e 5.3, e foi mostrado como uma entrada é processada internamente pelo
interpretador.
Por meio da CroMeL provou-se que é possível declarar um serviço, suas atividades, transições e navegações, além de outras construções mais específicas para
mapear os conceitos do domínio de governo em mídia cruzada na implementação do
Framework X-Gov. Da maneira que a linguagem foi construída, ela permite incluir novos tipos componentes e tipos de transições, o que a torna extensível para o contínuo
aperfeiçoamento do FXG.
Uma limitação observada se refere a possibilidade de declarar apenas um tipo
de componente de cada mídia dentro de uma atividade. Como não foram criados
cenários que necessitassem de mais de um tipo de componente da mesma mídia
na mesma atividade, essa limitação não foi percebida inicialmente, porém ela pode
ser contornada com a declaração de outra atividade com o mesmo padrão de tarefa
onde um novo componente do mesmo tipo e para mesma mídia daquele declarado
anteriormente pode ser definido.
70
Ficou claro pelas propostas de implementação as vantagens de construir uma
DSL Externa, e embora a alternativa adotada seja mais trabalhosa pois necessita criar
um reconhecedor e um interpretador, e as outras alternativas (notação em XML ou
DSL Interna) já fornecem uma ou as duas etapas prontas, se mostrou a mais versátil
para definição das notações e da semântica desejada.
71
Seção
6
Conclusões
“O verdadeiro prazer está em descobrir ao invés de saber.” (Isaac Asimov)
Esta sessão apresenta uma discussão dos resultados obtidos tanto no desenvolvimento da linguagem quanto na sua aplicação, ainda, resume as principais contribuições desta pesquisa e propõe recomendações para trabalhos futuros.
Diante das necessidades de configuração do Framework X-Gov e dos resultados obtidos na implementação da CroMeL constatou-se que, para muitos problemas
específicos, linguagens mais próximas de linguagens naturais oferecem um alto grau
de expressividade. Infelizmente linguagens naturais são ambíguas e difíceis de serem
reconhecidas e interpretadas por um computador, mas com um pouco de trabalho é
possível definir um subconjunto dessa linguagem, sem ambiguidade, e ainda assim
expressiva o bastante para se aplicar a um domínio de problema.
Abstração é um conceito chave no progresso da engenharia de software. Encapsulando detalhes de operações de baixo nível em abstrações de alto nível, desenvolvedores são mais produtivos e utilizam de um vocabulário determinado por uma
linguagem para comunicar-se com especialistas de domínio nos mesmos termos. Depois de trabalhar por um certo tempo com as abstrações do nível ‘n’, padrões emergem, e permitem identificar novas abstrações no nível ‘n+1’. Assim o conceito continuará a ser desenvolvido. O principal objetivo de uma DSL é aumentar a produtividade
de Engenheiros de Software abstraindo código boilerplate e de níveis mais baixos de
abstração.
Os mecanismos usados nas linguagens de programação tradicionais para definir abstrações, como métodos, atributos e classes, não serão suficientes para criar
72
novas camadas de abstração no futuro. Mesmo bibliotecas e frameworks sendo boas
formas de implementar funcionalidades, as linguagens que o desenvolvedor precisa
utilizar para acessar essas funcionalidades são muitas vezes inadequadas. Atualmente, diversos enfoques tem sido dados a questão de buscar novos mecanismos de
abstração para o desenvolvimento de software, incluindo arquitetura dirigida a modelo
(model-driven-architecture) Ivkovic & Kontogiannis (2004), engenharia dirigida a modelo (model-driven-engineering) Schmidt (2006), modelagem específica de domínio
(domain-specific modeling) Kelly & Tolvanen (2008), fabricas de software (softwarefactories) Greenfield & Short (2003) e software intencional (intentional software) Laird
& Barrett (2009).
Existem dois caminhos para se projetar uma DSL: um caminho descendente
que observa as palavras do domínio de problema e foca em uma boa linguagem para
capturar os requisitos funcionais de forma não ambígua sem se preocupar como a linguagem será interpretada; e o caminho ascendente, que observa padrões de código,
repetições, e busca maneiras de descrever as variações encontradas para que possam ser substituídas por abstrações, as quais são interpretadas nessa nova linguagem
mais concisa.
O caminho seguido para a definição da CroMeL foi intermediário (tanto descendente quanto ascendente), no qual alguns elementos necessários na linguagem foram
obtidos dos requisitos do Framework X-Gov, o que inclui a definição de serviços de
governo, atividades e transições entre mídias, e outros elementos foram determinados
pelo próprio código implementado no Gerenciador de Componentes e no arquivo de
configuração em XML utilizado por ele.
6.1
Análise dos Resultados
O desenvolvimento da CroMeL apresentou resultados específicos para cada
uma de suas fases:
• Na fase de análise foi possível identificar que cada padrão de tarefa possui um
tipo de componente específico para cada uma das mídias utilizadas no projeto
(web, tv e mobile), em outras palavras, um componente está relacionado a um
padrão de tarefa e a uma mídia, identificados por uma classe especializada que
contém atributos e comportamentos específicos para as necessidades de cada
mídia. Desta forma, foi possível determinar que um dos elementos da linguagem
deve identificar o tipo do componente, e para isso necessita reconhecer qual o
padrão de tarefa e a mídia associada, para ser possível determinar qual objeto
deve ser criado — os padrões utilizados nessa fase foram ‘Informal’ e ‘Extract
from code’ apresentados na tabela 2.3 da sessão 2.4.2.
73
• Na fase de projeto, observou-se que a CroMeL necessitaria permitir adicionar
novos componentes e realizaria uma busca pelo nome de suas classes. Para
suprir essa necessidade foi desenvolvido um dicionário externo à linguagem,
que indica para cada tipo de componente a classe que o implementa (determinado pelo padrão de tarefa x mídia). Constatou-se que a linguagem também
deveria permitir a definição de parâmetros para os componentes enquanto eles
estavam sendo desenvolvidos e alterados, portanto sua gramática foi construída
para ser flexível nesse ponto tanto em relação ao número de parâmetros quanto
aos seus nomes e valores. Também foi decidido acrescentar recursos semânticos para facilitar sua utilização por um programador na hora de fazer referência
aos componentes declarados. Assim, outros elementos da linguagem surgiram
para referenciar componentes durante a declaração de uma transição ou navegação — dentre as opções de padrões encontrados nessa fase de acordo com
a tabela 2.4 da sessão 2.4.3 foi aplicado o padrão ‘Formal’.
• Durante a implementação ocorreram as maiores mudanças. A primeira versão
implementada foi na forma de uma DSL Interna em Ruby. Embora o Ruby, assim como outras linguagens como Groovy, Scala, Boo, ofereçam ótimos recursos
para definir extensões funcionais como classes abertas, captura de mensagens
para métodos que não existem e outros “truques” de meta-programação, o que
faz delas boas candidata para a construção de uma DSL interna, essa alternativa trouxe algumas desvantagens: Não existe separação entre a sintaxe da
DSL e da GPL; Dificuldade em mapear erros relativos a DSL; Dificuldade em
balancear especificidade do domínio dentro dos limites de construção sintática
da GPL; O usuário (programador) deve conhecer a linguagem hospedeira e as
novas construções da DSL para usar esta solução — assim inicialmente foi aplicado o padrão ‘Embedding’ encontrado na tabela 2.7 para construção de uma
linguagem embutida na linguagem Ruby.
• A nova implementação como um DSL Externa permitiu um controle total de sua
sintaxe. Para o desenvolvimento dessa solução foi especificada a gramática formalmente em EBNF e utilizada a ferramenta ANTLR para geração do reconhecedor e do interpretador da CroMeL (apresentados na sessão ??). Nesse caso, o
usuário da CroMeL (programador) utiliza uma nova notação para declarar os elementos de configuração de um serviço (i.e. atividades, transições e navegações)
utilizado pelo Framework X-Gov. Uma das principais vantagem dessa ferramenta
em comparação com outras (e.g. lex/yacc, bison, tree-top) é que ela é capaz de
gerar o código do reconhecedor em diversas linguagens de programação, sendo
Java e C# importantes para essa solução. Dessa forma foi criado o interpretador
da CroMeL que substitui o Gerenciador de Componentes desenvolvido anterior74
mente que trabalhava com XML1 . O interpretador conta com classes auxiliares
para implementar as ações determinadas na fase de análise e projeto — Na implementação final apresentada, foi utilizado o padrão ‘Interpreter ’ encontrado na
tabela 2.7 da sessão 2.4.4.
• Após a fase de implementação, foi necessário criar um mecanismo de deployment para um arquivo CroMeL ser instalada no servidor do Framework X-Gov.
6.2
Reflexões
Estudos demonstram que a maioria dos projetos de software falha, seja porque
não cumprem o orçamento, ou não cumprem o cronograma, ou as funcionalidades não
atendem às necessidades dos usuários ou porque todos estes fatores estão presentes
em conjunto. Alguns deles ocorrem devido a problemas de comunicação nas diversas
fases de projeto conhecidas pela engenharia de software 2 .
Em inúmeros casos, devido a perda de informações, simplificações, generalizações na fase de análise a diferenças entre o resultado obtido e o esperado é muito
longa. Essa distância do resultado é um fator de risco para qualquer projeto de software no qual regras de negócio devem ser definidas pelos especialistas e praticantes
e os programadores precisam compreender e implementar essas regras — usar uma
linguagem mais próxima do domínio do problema pode ser uma forma de minimizar
problemas dessa natureza.
O desenvolvimento de uma DSL é difícil pois requer conhecimento de domínio e na linguagem de desenvolvimento, mas poucas pessoas têm os dois (Mernik
et al., 2005). Embora já seja possível criar ambientes de mídia cruzada, essa não
é uma tarefa fácil, recorre-se na maioria das vezes à soluções ad-hoc que utilizam
apenas uma tecnologia/plataforma específica. Seria ideal a utilização combinada de
diversas tecnologias e dispositivos para emergir sistemas dessa natureza. Esse foi o
objetivo da construção do Framework X-Gov e consequentemente de sua linguagem
de modelagem, a CroMeL.
A construção de linguagens pequenas (declarativas) com alto poder de expressão dentro de um domínio de problema não é uma prática nova da Engenharia de
Software, mas encontra-se em um momento de renaissance e não se trata de uma
arte perdida, aplicável apenas para construção de compiladores, ou protocolos de comunicação, como pode ser ser observado nesta pesquisa, portanto deve(ria) tornar-se
mais popular no desenvolvimento das mais diversas soluções.
1
XML não é uma interface de programação adequada para o ser humano, veja http://www.ibm.
com/developerworks/xml/library/x-sbxml.html
2
Veja figura popular que ilustra esses problemas na Engenharia de Software http://www.
openplans.org/projects/opencore/iteration-tracker/software_engineering_explained.gif
75
Criar uma DSL Interna foi a idéia inicial deste trabalho, no entanto, durante
a implementação, notou-se não se tratar da criação de uma “nova” linguagem, mas
apenas uma lapidação de uma linguagem pré-existente para incluir algumas expressões idiomáticas específicas do domínio. Essa pseudo-linguagem ainda estaria presa
a todas construções sintáticas da linguagem hospedeira, como por exemplo, o uso
da notação de ponto (.) para acesso de métodos e atributos. Ainda, a validade de
sua implementação seria questionável, pois era aplicável apenas a uma única linguagem hospedeira. No entanto, uma vantagem dessa forma de implementação é que
não precisa especificar a gramática formalmente — o que deve facilitar a entrada de
muitos programadores a este universo.
A decisão em usar o ANTLR foi acertada, pois além de contar com um arsenal de recursos como livros, sites, e exemplos, também disponibiliza uma excelente
ferramenta de desenvolvimento chamada ANTLRWorks que pode ser verificada no
apêndice C.9 e plug-ins para trabalhar com sua gramática no Netbeans, Eclispe e Visual Studio. O uso dessa ferramenta tornou mais simples o trabalho de construção da
CroMeL como pode ser observado pelas seguintes métrica: 198 linhas de código na
CroMeL.g gerou 1214 linhas de código do analisador léxico e 1600 linhas de código
do analisador sintático, totalizando 2814 linhas de código geradas automaticamente.
Isso corresponde a cerca de 7% do trabalho de programar o mesmo reconhecedor
manualmente.
As ações semânticas foram inseridas diretamente nas regras do parser tornando a gramática complexa, o que dificulta sua manutenção. Poderia ser criada uma
representação intermediária na forma de uma Abstract Syntax Tree (AST), por meio
de regras de tradução da gramática, e incluir uma nova fase no processo que recebe
a AST criada e executa as ações semânticas da mesma forma sobre uma estrutura
de dados mais conveniente. Uma sugestão de melhoria para implementação é refatorar a gramática para utilizar essa representação intermediária, facilitaria a inclusão de
novas ações semânticas.
Com algumas soluções “engenhosas” para construir uma DSL Externa pode-se
despender menos tempo do que a princípio aparentava, por meio da construção de
uma sintaxe simplificada, padrões de projeto, e o uso de uma linguagem hospedeira
com recursos de reflexão. A mesma técnica poderia ser aplicada a outras partes do
Framework X-Gov, como por exemplo, na integração de um componente com as APIs
do governo ou com o gerenciador de transições. No entanto a principal dificuldade no
desenvolvimento da CroMeL foi em criar uma linguagem para servir a um framework
que não estava pronto e não havia uma versão estável ou especificada.
76
6.3
Trabalhos Futuros
Esta pesquisa é o início de um trabalho que pretende criar uma linguagem
declarativa para especificar serviços de governo em mídia cruzada, pautado pela importante questão de inserir cross-media na interação do governo com os cidadãos, e a
potencialidade para sua continuidade, existe uma série de possíveis trabalhos futuros
a serem desenvolvidos:
1. Validação dos estudos sobre métodos de desenvolvimento de linguagem específica de domínio;
2. Estudo sobre um processo de desenvolvimento interativo e incremental para
construção de DSLs;
3. Estudo de novas alternativas para construção de linguagens e os limites de cada
técnica, a determinação desses limites ainda é um desafio para os Engenheiros
de Software;
4. Estudo destinado a solucionar o problema da análise de um domínio com base
na Engenharia de Informação;
5. Estudo de alternativas sintáticas para construção da linguagem CroMeL.
6. Tradução das palabras reservadas da sintaxe da CroMeL para o idioma português, o que pode ser um atrativo para desenvolvedores brasileiros;
7. Desenvolvimento de plug-ins para o Eclipse, Netbeans e/ou Visual Studio para
oferecer suporte a linguagem CroMeL com realce de sintaxe, recurso de autocompletar, refactoring, entre outros;
8. Melhorar o suporte a informações sobre erros do reconhecedor para facilitar a
utilização da linguagem;
9. Criação de um editor que permita modificar uma configuração já instalada no
servidor (semelhante aqueles disponíveis pelas ferramentas do tipo wiki).
77
REFERÊNCIAS
Abelson, H. e Sussman, G. J. (1996). Structure and Interpretation of Computer Programs. MIT Press, Cambridge, MA, USA.
Alur, D., Malks, D., e Crupi, J. (2001). Core J2EE Patterns: Best Practices and Design
Strategies. Prentice Hall PTR, Upper Saddle River, NJ, USA.
Bennett, K. H. e Rajlich, V. T. (2000). Software maintenance and evolution: a roadmap.
In ICSE ’00: Proceedings of the Conference on The Future of Software Engineering,
pp. 73–87, New York, NY, USA. ACM.
Bentley, J. (1986). Programming pearls: little languages. Commun. ACM, 29(8):711–
721.
Bergin, Jr., T. J. e Gibson, Jr., R. G., editors (1996).
languages—II. ACM, New York, NY, USA.
History of programming
Biggerstaff, T. J. (1998). A perspective of generative reuse. Ann. Softw. Eng., 5:169–
226.
Bolter, J. D. e Grusin, R. (2000). Remediation: Understanding New Media. The MIT
Press, 1st edition.
Boumans, J. (2004).
Cross media: E-content report 8.
<http://www.acten.net>. Acesso em: 10 abr. 2008.
Disponível em
Brooks, Jr., F. P. (1975). The mythical man-month. In Proceedings of the international
conference on Reliable software 193, p., New York, NY, USA. ACM.
Cunha, M. R. (2006). Possibilidades tecnológicas apontam para mudanças em conceitos da comunicação. Razón y Palabra, v. 53, p. 1.
78
Dena, C. (2007). Patterns in Cross-Media interaction design: It’s much more than
a URL. In Proceedings of 1st International Conference on Crossmedia Interaction
Design, pp. 4–10, Hemavan, Sweden.
Denny, M. (2003).
Ontology building:
A
http://www.xml.com/lpt/a/2002/11/06/ontologies.html.
survey
of
editing
tools.
EclipseFoundation (2009). Eclipse modeling project. http://www.eclipse.org/modeling/.
Fach, P. W. (2001). Design reuse through frameworks and patterns. IEEE Softw.,
18(5):71–76.
Fernandez,
O.
(2007).
Agile
dsl
development
http://www.infoq.com/presentations/agile-dsl-development-in-ruby.
in
ruby.
Filgueiras, L. (2007). X-gov: mídia cruzada em serviços de governo. Plano de Trabalho LTS2007.PR.029.00, PCS: Departamento de Engenharia de Computação e
Sistemas digitais – Escola Politécnica da USP.
Filgueiras, L. V. L., Correa, D. O., Neto, J. S. O., e Facis, R. P. (2008). X-gov planning:
How to apply cross media to government services. In ICDS, pp. 140–145. IEEE
Computer Society.
Ford, N. (2008). Advanced dsls in ruby. http://rubyconf2008.confreaks.com/advanceddsls-in-ruby.html.
Fowler, M. (2008). Domain specific languages. http://martinfowler.com/dslwip/.
Freed, N. e Borenstein, N. (1996). RFC2046: Multipurpose Internet Mail Extensions
(MIME) Part Two: Media Types. RFC Editor United States.
Freeman, S. e Pryce, N. (2006). Evolving an embedded domain-specific language
in java. In OOPSLA ’06: Companion to the 21st ACM SIGPLAN symposium on
Object-oriented programming systems, languages, and applications, pp. 855–865,
New York, NY, USA. ACM.
Gamma, E., Helm, R., Johnson, R., e Vlissides, J. (1995). Design patterns: elements
of reusable object-oriented software. Addison-Wesley Professional.
Greenfield, J. e Short, K. (2003). Software factories: assembling applications with
patterns, models, frameworks and tools. In OOPSLA ’03: Companion of the 18th
annual ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications, pp. 16–27, New York, NY, USA. ACM.
Groenewegen, D. M., Hemel, Z., Kats, L. C., e Visser, E. (2008). Webdsl: a domain79
specific language for dynamic web applications. In OOPSLA Companion ’08: Companion to the 23rd ACM SIGPLAN conference on Object-oriented programming systems languages and applications, pp. 779–780, New York, NY, USA. ACM.
Hudak, P. (1996). Building domain-specific embedded languages. ACM Comput. Surv.
196, p.
Ivkovic, I. e Kontogiannis, K. (2004). Model synchronization as a problem of maximizing model dependencies. In OOPSLA ’04: Companion to the 19th annual ACM
SIGPLAN conference on Object-oriented programming systems, languages, and applications, pp. 222–223, New York, NY, USA. ACM.
Johnson, R. E. (1997). How frameworks compare to other object-oriented reuse techniques. frameworks = (components + patterns. In in ’Communications of the ACM,
pp. 39–42.
Jones, C. (1996).
Spr programming languages
http://www.theadvisors.com/langcomparison.htm.
table
release
8.2.
Kelly, S. e Tolvanen, J.-P. (2008). Domain-Specific Modeling: Enabling Full Code Generation. Wiley-IEEE Computer Society Pr.
Kiczales, G. e Rivieres, J. D. (1991). The Art of the Metaobject Protocol. MIT Press,
Cambridge, MA, USA.
Kilmer, R. (2008).
Ruby and the art of domain
http://www.infoq.com/presentations/kilmer-ruby-dsls.
specific
languages.
Knuth, D. E. (1984). Literate programming. 27(2):97–111.
Krueger, C. W. (1992). Software reuse. ACM Comput. Surv., 24(2):131–183.
Laird, P. e Barrett, S. (2009). Towards context sensitive domain specific languages. In
CAMS ’09: Proceedings of the 1st International Workshop on Context-Aware Middleware and Services, pp. 31–36, New York, NY, USA. ACM.
Lima, V. A. (2001). Mídia: Teoria e Política. Number 8586469602. Fundação Perseu
Abramo.
Martin, J. (1985). Fourth-generation languages. Volume I: principles. Prentice-Hall,
Inc., Upper Saddle River, NJ, USA.
Mernik, M., Heering, J., e Sloane, A. M. (2005). When and how to develop domainspecific languages. ACM Comput. Surv., 37(4):316–344.
80
Microsoft (2009). code name for microsoft’s next generation application development
platform. http://msdn.microsoft.com/en-us/oslo/default.aspx.
Miyamaru, F., Leite, L., Bertuzzi, A., e Filgueiras, L. (2008a). Mídia cruzada em serviços de governo: conceito e aplicaç ao. In IHC ’08: Proceedings of the VIII Brazilian
Symposium on Human Factors in Computing Systems, pp. 330–331, Porto Alegre,
Brazil, Brazil. Sociedade Brasileira de Computaç ao.
Miyamaru, F., Leite, L., Bertuzzi, A., e Filgueiras, L. (2008b). Task patterns for egovernment services. In IHC ’08: Proceedings of the VIII Brazilian Symposium on
Human Factors in Computing Systems, pp. 276–279, Porto Alegre, Brazil, Brazil.
Sociedade Brasileira de Computaç ao.
Nardi, B. A. (1993). A small matter of programming: perspectives on end user computing. MIT Press, Cambridge, MA, USA.
Netbeans (2009). Generic languages framework. http://languages.netbeans.org/.
Neto, J. J., Ramos, M. V. M., e Ítalo Santiago Veja (2009). Linguagens Formais: Teoria,
Modelagem e Implementação. bookman, 1 edition.
OpenArchitectureWare (2009). Xtext. http://wiki.eclipse.org/Xtext.
Parr, T. (2007). The Complete Antlr Reference Guide. Pragmatic Bookshelf.
Sammet, J. E. (1969). Programming Languages: History and Fundamentals. PrenticeHall, Inc., Upper Saddle River, NJ, USA.
Schmidt, D. C. (2006). Guest editor’s introduction: Model-driven engineering. Computer, 39(2):25–31.
Sharp, H., Rogers, Y., e Preece, J. (2007). Interaction Design: Beyond HumanComputer Interaction. John Wiley & Sons Ltd, 2 edition.
Steele, Jr., G. L. (1998). Growing a language. In OOPSLA ’98 Addendum: Addendum to the 1998 proceedings of the conference on Object-oriented programming,
systems, languages, and applications (Addendum), New York, NY, USA. ACM.
Subramaniam, V. (2008). Programming Groovy: Dynamic Productivity for the Java
Developer. Pragmatic Bookshelf.
van Deursen, A., Klint, P., e Visser, J. (2000). Domain-specific languages: an annotated
bibliography. SIGPLAN Not., 35(6):26–36.
Wexelblat, R. L. (1981). History of Programming Languages. Academic Press, Inc.,
81
Orlando, FL.
Wiberg, C., Bodén, J., e Jegers, K. (2007). Cross-Media interaction design. In HCI and
New Media Arts: Methodology andEvaluation, San Jose, CA, USA.
Wile, D. S. (2001). Supporting the dsl spectrum. J. Comput. Inform.
82
Apêndice
A
Exemplos de DSLs
A.1
jMock
Exemplo sem pontuação e parênteses da sintaxe java:
1
2
mainframe expects once method ‘‘buy’’
with eq QUANTITY will return value TICKET
De volta com a notação da linguagem Java:
1
2
3
4
5
6
7
8
9
10
11
Mock mainframe = mock(Mainframe.class);
Mock auditing = mock(Auditing.class);
Agent agent = new Agent( QUANTITY, (Mainframe)mainframe.proxy(), (Auditing)auditing.proxy() );
public void testBuysWhenPriceEqualsThreshold() {
mainframe.expects(once())
.method(‘‘buy’’).with(eq(QUANTITY))
.will(returnValue(TICKET));
,auditing.expects(once())
.method(‘‘bought’’).with(same(TICKET));
,agent.onPriceChange(THRESHOLD);
}
12
13
14
15
16
17
18
public void testDoesNotBuyIfMainframeUnavailable() {
mainframe.stubs().method(‘‘buy’’)
.will(throwException(new NotAvailableException());
auditing.expects(never()).method(‘‘bought’’);
agent.onPriceChange(THRESHOLD);
}
83
A.2
API Fluente
Implementação de uma API usada de forma imperativa:
1
2
3
4
Processor p = new Processor(2, Processor.Type.i386);
Disk d1 = new Disk(150, Disk.UNKNOWN_SIZE, null);
Disk d2 = new Disk(75, 7200, Disk.Interface.SATA);
return new Computer(p, d1, d2);
Usando encadeamento de métodos:
1
2
3
4
5
6
7
8
9
10
11
computer()
.processor()
.cores(2)
.i386()
.disk()
.size(150)
.disk()
.size(75)
.speed(7200)
.sata()
.end();
Sequenciamento de funções:
1
2
3
4
5
6
7
8
9
10
computer();
processor();
cores(2);
processorType(i386);
disk();
diskSize(150);
disk();
diskSize(75);
diskSpeed(7200);
diskInterface(SATA);
Funções aninhadas:
1
2
3
4
5
6
7
8
9
computer(
processor(
cores(2),
Processor.Type.i386
),
disk(
size(150)
),
disk(
84
size(75),
speed(7200),
Disk.Interface.SATA
10
11
12
13
14
)
);
85
Apêndice
B
Framework X-Gov
B.1
Diagrama de Classes do FrameworkLibrary
86
87
Figura B.1: Exemplo de classes de componentes
Figura B.2: Componentes FindEntityInfo para TV, Mobile e Web
88
Figura B.3: Componente GetPreServiceInfo para TV, Mobile e Web
Figura B.4: Classes de Transição
89
Apêndice
C
Implementação da CroMeL
C.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Regras Léxicas e Sintáticas da CroMeL
grammar CroMeL ;
/************************************************
* PARSER RULES
*
************************************************/
prog
: var * service + ;
service : ’ service ’ service_name ? ’{ ’ decl ’} ’ ;
decl
: task +
transition *
web_navigation *
;
task
: ’ task ’ task_name ’of ’ pattern_name ’{ ’ media + ’} ’ ;
media
: MEDIA params ;
transition : ’ transition ’ transition_type navigation params ;
web_navigation : ’ navigation ’ label navigation ;
navigation : ’[ ’ begin ’->’ end ’] ’ ;
90
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
params
: ’( ’ assign ’) ’ ;
assign
: ID ’= ’ expr ( ’ , ’ ID ’= ’ expr ) * ;
var
: assign ;
begin
: REF ;
end
: REF ;
expr
:
|
|
|
|
;
STRING
INT
BOOLEAN
QID // substituir ID por valor em memória
REF // substituir ID por número gerado pela Task . media
// parametro opcional n~
a o utilizado
service_name
: STRING ;
// pode restringir aos nomes de padr~
o es de tarefas conhecidos
pattern_name
: ID ;
// pode restringir aos tipos de transiç~
o es conhecidos
transition_type : ID ;
// label da navegacao
label
: STRING ;
// nome do servico serve como chave para navegaç~
a o / transiç~
ao
task_name
: ID ;
/************************************************
* LEXER RULES
*
************************************************/
MEDIA
: ( ’ mobile ’ | ’web ’ | ’tv ’) ;
BOOLEAN : ( ’ true ’| ’ false ’) ;
INT
: ’0 ’.. ’9 ’+ ;
ID
: ( ’a ’.. ’ z ’| ’A ’.. ’ Z ’| ’_ ’) ( ’a ’.. ’ z ’| ’A ’.. ’ Z ’| ’0 ’.. ’9 ’| ’ _ ’) * ;
// uma referencia de uma variável ( usada para recuperar seu valor )
91
70
71
72
73
74
75
76
77
78
79
80
81
82
QID
: ’$ ’ ID ;
// uma referencia do tipo Task . media ( usado para identificar componentes
)
REF
: ’\& ’ ID ( ’. ’ MEDIA ) ;
STRING
: ’" ’ .* ’" ’ | ’\ ’ ’ ~( ’\\ ’| ’\ ’ ’| ’\* ’) * ’\ ’ ’ ;
// espaços em branco
WS
: ( ’ ’| ’\t ’| ’\ r ’| ’\ n ’) { $channel = HIDDEN ;} ;
// comentários
CMT
: ’# ’ ~( ’\ n ’| ’\ r ’) * ’\r ’? ’\n ’ { $channel = HIDDEN ;};
COMMENT :
’/* ’ .* ’*/ ’ { $channel = HIDDEN ;} ;
Listagem C.1: Gramatica
C.2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Regras Semânticas da CroMeL
grammar CroMeL ;
@header {
import java . util . Map ;
import java . util . HashMap ;
import java . util . List ;
import java . util . ArrayList ;
import java . util . regex . Matcher ;
import java . util . regex . Pattern ;
}
@members {
// Classe que armazena os dados de um componente
class ComponentDTO {
public String type ;
public Map parameters ;
}
class TransitionDTO {
public String type ;
public Map parameters ;
public Integer begin , end ;
}
class NavigationDTO {
public String label ;
public Integer begin , end ;
}
class CodeDTO {
92
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public CodeDTO ( String comment , String code ) {
this . comment = comment ;
this . code = code ;
}
public String comment ;
public String code ;
}
// lista de componentes , transicoes e navegacoes declaradas
List < ComponentDTO > components = new ArrayList < ComponentDTO >() ;
List < TransitionDTO > transitions = new ArrayList < TransitionDTO >() ;
List < NavigationDTO > navigations = new ArrayList < NavigationDTO >() ;
// memória para as variáveis locais
Map memory = new HashMap () ;
// lista com todos identificadores de componentes
Map componentIds = new HashMap () ;
// metodo para buscar o id de um componente ( usado na definicao de
parametros e navegacao )
public Integer getComponentId ( String componentName ) {
// busca valor na memória ( eliminando o & que nao foi colocado
na tabela )
Object v = componentIds . get ( componentName . substring (1) ) ;
// se encontrado seta o valor de retorno , caso contrário imprime
erro
if ( v != null ) {
System . out . println (" - resoluç~
a o da refer^
e ncia id = "+ v ) ;
return new Integer ( v . toString () ) ;
}
else {
System . err . println (" Erro : refer^
e ncia indefinida "+
componentName ) ;
return null ;
}
}
}
/************************************************
* PARSER RULES
*
************************************************/
prog
: var * service + ;
// declaraç~
a o de variáveis para usar como valor nas propriedades
93
71
72
73
74
75
76
77
78
79
80
81
82
83
var
: assign
{
System . out . println (" - declaraç~
a o da variável : "+ $assign .
n +"="+ $assign . v ) ;
memory . put ( $assign .n , $assign . v ) ;
};
service
scope {
// contador usado para atribuir um ID para cada
componente em um serviço
int componentId ;
}
@after {
System . out . println (" Execuç~
a o após processamento da
entrada !") ;
84
85
// Cria os componentes da CroMeL e seta seus parametros
por reflexao
for ( ComponentDTO component : components ) {
System . out . println (" Criando componente "+
component . type ) ;
System . out . println ("\ tarmazenamento de "+
component . parameters . size () +" parametros ") ;
}
86
87
88
89
90
91
// Cria os objetos de transicao e seta seus parametros
por reflexao
for ( TransitionDTO transition : transitions ) {
System . out . println (" Criando transiç~
a o "+
transition . type ) ;
System . out . println ("\ tarmazenamento de "+
transition . parameters . size () +" parametros ") ;
System . out . println ("\ ttransiç~
a o entre os
componentes "+ transition . begin +" e "+
transition . end ) ;
}
92
93
94
95
96
97
98
99
100
// Cria os objetos de navegacao
for ( NavigationDTO navigation : navigations ) {
System . out . println (" Criando navegaç~
a o "+
navigation . label ) ;
System . out . println ("\ tnavegaç~
a o entre os
componentes "+ navigation . begin +" e "+
navigation . end ) ;
}
101
102
103
}
94
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
: { $service :: componentId =1; } // inicializacao do contador
’ service ’ service_name ? ’{ ’ decl ’} ’ ;
decl
: task +
transition *
web_navigation *
;
// criar objetos para cada midia e setar os parametros ( chamada da API
de reflexao )
task
: ’ task ’ task_name { System . out . println (" Declaraç~
a o da atividade
:"+ $task_name . text ) ; }
’of ’ pattern_name ’{ ’ media [ $task_name . text , $pattern_name .
text ]+
( lc = literate_code
{
// Executa as regras definidas em um serviço
System . out . println (" Executa código embutido : "+
$lc . comment ) ;
System . out . println ("\ t "+ $lc . code ) ;
}
) * ’} ’ ;
// retornar o componente com os parametros para a task
media [ String taskName , String patternName ]
: m = MEDIA params
{
// atribui um id ( setar na propriedade da superclasse ) e
guarda para referencia
int componentId = $service :: componentId ++;
String media = $m . text ;
String componentName = $taskName +"."+ media ;
componentIds . put ( componentName , componentId ) ;
// define o tipo do componente
String componentType = $patternName +"."+ media ;
System . out . println (" Novo componente do tipo "+
componentType +" [ id ="+ componentId +"]") ;
// parametros do componente
System . out . println ("\ tparametros ="+ $params . p ) ;
// guarda o componente na lista
// TODO : incluir ID na lista de par^
a metros
ComponentDTO dto = new ComponentDTO () ;
dto . type = componentType ;
95
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
dto . parameters = $params . p ;
components . add ( dto ) ;
};
// criar objeto de transicao e setar os parametros
transition
: ’ transition ’ transition_type
navigation
params
{
System . out . println (" Nova transiç~
a o do tipo "+
$transition_type . text ) ;
System . out . println ("\ tparametros ="+ $params . p ) ;
TransitionDTO dto = new TransitionDTO () ;
dto . type = $transition_type . text ;
dto . parameters = $params . p ;
dto . begin = $navigation . b ;
dto . end = $navigation . e ;
transitions . add ( dto ) ;
};
// criar objeto de navegacao web e seta o label
web_navigation
: ’ navigation ’ label
navigation
{
NavigationDTO dto = new NavigationDTO () ;
dto . label = $label . text ;
dto . begin = $navigation . b ;
dto . end = $navigation . e ;
navigations . add ( dto ) ;
};
// recupera o ID do begin e do end
navigation returns [ int b , int e ]
: ’[ ’ begin ’->’ end ’] ’
{
$b = $begin . id ;
$e = $end . id ;
System . out . println (" Navegaç~
a o do componente ["+ $begin . id
+"] -> ["+ $end . id +"]") ;
};
// guardar os parametros em um HashMap ( nome , valor ) passado pela regra
params returns [ Map p ]
@init {
p = new HashMap () ;
96
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
}
: ’( ’ a1 = assign { p . put ( $a1 .n , $a1 . v ) ; }
( ’ , ’ a2 = assign { p . put ( $a2 .n , $a2 . v ) ; } ) *
’) ’;
// retorna um par nome - valor
assign returns [ String n , Object v ]
: ID ’= ’ expr
{
$n = $ID . text ;
$v = $expr . value ;
};
begin returns [ Integer id ]
: REF { $id = getComponentId ( $REF . text ) ; };
end returns [ Integer id ]
: REF { $id = getComponentId ( $REF . text ) ; };
// regra que determina o tipo de dado por infer^
e ncia
expr returns [ Object value ]
: STRING { $value = $STRING . text ; }
| INT
{ $value = Integer . parseInt ( $INT . text ) ; }
| BOOLEAN { $value = Boolean . parseBoolean ( $BOOLEAN . text ) ; }
| QID // substituir ID por valor em memória
{
// busca valor na memória ( eliminando o $ que nao foi
colocado na tabela )
Object v = memory . get ( $QID . text . substring (1) ) ;
// se encontrado seta o valor de retorno , caso contrário
imprime erro
if ( v != null ) {
$value = v ;
System . out . println (" - resoluç~
a o da variável "+
$QID . text +"="+ v ) ;
}
else System . err . println (" Erro : variável indefinida "+
$QID . text ) ;
}
| REF // substituir ID por numero gerado pela Task . media
{
$value = getComponentId ( $REF . text ) ;
}
97
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
;
// parametro opcional nao utilizado
service_name
: STRING ;
// pode restringir aos nomes de padr~
o es de tarefas conhecidos
pattern_name
: ID ;
// pode restringir aos tipos de transicoes conhecidos
transition_type : ID ;
// label da navegacao
label
: STRING ;
// nome do servico serve como chave para navegacao / transicao
task_name
: ID ;
literate_code returns [ String comment , String code ]
: CODE
{
String pattern = " < <(\\ w +) > >=(.*) @ ";
Pattern p = Pattern . compile ( pattern , Pattern .
MULTILINE ) ;
Matcher m = p . matcher ( $CODE . text ) ;
if ( m . find () ) {
$comment = m . group (1) ;
$code = m . group (2) ;
System . out . println ( $comment ) ;
System . out . println ( $code ) ;
} else {
System . out . println (" Erro : código
inválido ") ;
}
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
};
/************************************************
* LEXER RULES
*
************************************************/
CODE
: ’<<’ .* ’@ ’;
MEDIA
: ( ’ mobile ’ | ’web ’ | ’tv ’) ;
BOOLEAN : ( ’ true ’| ’ false ’) ;
98
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
INT
: ’0 ’.. ’9 ’+ ;
ID
: ( ’a ’.. ’ z ’| ’A ’.. ’ Z ’| ’_ ’) ( ’a ’.. ’ z ’| ’A ’.. ’ Z ’| ’0 ’.. ’9 ’| ’ _ ’) * ;
// uma referencia de uma variavel ( usada para recuperar seu valor )
QID
: ’$ ’ ID ;
// uma referencia do tipo Task . media ( usado para identificar componentes
)
REF
: ’\& ’ ID ( ’. ’ MEDIA ) ;
STRING
: ’" ’ .* ’" ’ | ’\ ’ ’ ~( ’\\ ’| ’\ ’ ’| ’\* ’) * ’\ ’ ’ ;
// NEWLINE
: ’\r ’? ’\n ’ ;
// espaço em branco
WS
: ( ’ ’| ’\t ’| ’\ r ’| ’\ n ’) { $channel = HIDDEN ;} ;
// comentários
CMT
: ’# ’ ~( ’\ n ’| ’\ r ’) * ’\r ’? ’\n ’ { $channel = HIDDEN ;};
COMMENT :
’/* ’ .* ’*/ ’ { $channel = HIDDEN ;} ;
Listagem C.2: Semantica
C.3
Diagramas de Sintaxe
Figura C.1: Diagrama de sintaxe da raiz da gramática
Figura C.2: Diagrama da sintaxe de declaração de um serviço
Figura C.3: Diagrama da sintaxe dos elementos que pertencem a um serviço
99
Figura C.4: Diagrama da sintaxe de uma atividade
Figura C.5: Diagrama da sintaxe de declaração de parametros
Figura C.6: Diagrama de sintaxe de transições
Figura C.7: Diagrama de sintaxe de navegação
100
C.4
Autômato Finito Determinístico
Figura C.8: DFA reconhecedor dos Tokens da linguagem CroMeL
101
C.5
ANTLRWorks
Figura C.9: Ferramenta ANTLRWorks no desenvolvimento da CroMeL
C.6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CroMeL XML
<? xml version ="1.0" encoding =" utf -8"? >
< service >
<! - - Initial information -->
< task taskId ="1" pattern =" GetPreServiceInfo " >
< name > Basic Information about exams schedule . </ name >
< executedBy > Citizen </ executedBy >
<web >
< componentId >11 </ componentId >
< componentName > Basic Information </ componentName >
< description > For more information about the medical examination
service use the menu on the side </ description >
< uriCalled > webExameInfo </ uriCalled >
</ web >
< mobile >
< componentId >12 </ componentId >
< componentName > Informations </ componentName >
< uriCalled > mobExamInfo </ uriCalled >
< welcomeMessage > Welcome to the X - Media Service </ welcomeMessage >
</ mobile >
102
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<tv >
< componentId >13 </ componentId >
< componentName > Basic Information about exams schedule . </
componentName >
< uriCalled > tvExamInfo </ uriCalled >
< first > true </ first >
</ tv >
</ task >
<! - - User ’ s Exam List -->
< task taskId ="2" pattern =" FindPrivateInfo " >
< name > Exams List </ name >
< executedBy > Citizen </ executedBy >
<web >
< componentId >21 </ componentId >
< componentName > My Exams List </ componentName >
< authenticationCompId >71 </ authenticationCompId >
< uriCalled > webExamList </ uriCalled >
< dataUrl > http ://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n /
GWSFindPrivateInfo . asmx </ dataUrl >
< getFullEntitiesListWebMethod > GWSGetPermittedExams </
getFullEntitiesListWebMethod >
< getEntityInformationWebMethod > GWSGetExamInformation </
getEntityInformationWebMethod >
< scheduleCompId >31 </ scheduleCompId >
</ web >
< mobile type =" SearchByOptionList " >
< componentId >22 </ componentId >
< componentName > My Exams List </ componentName >
< authenticationCompId >72 </ authenticationCompId >
< uriCalled > mobExamList </ uriCalled >
< instructionText > Select an exam : </ instructionText >
< listName > Exams Requested </ listName >
< dataUrl > http ://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n /
GWSFindPrivateInfo . asmx </ dataUrl >
< getFullEntitiesListWebMethod > GWSGetPermittedExams </
getFullEntitiesListWebMethod >
< getEntityInformationWebMethod > GWSGetExamInformation </
getEntityInformationWebMethod >
</ mobile >
<tv >
< componentId >23 </ componentId >
< componentName > My Exams List </ componentName >
< entityType > Exam </ entityType >
< compAuthId >73 </ compAuthId >
< uriCalled > tvExamList </ uriCalled >
< dataUrl > http ://143.107.102.15/ govside / G W S F i n d P r i v a t e I n f o r m a t i o n /
GWSFindPrivateInfo . asmx </ dataUrl >
103
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
< getFullEntitiesListWebMethod > GWSGetPermittedExams </
getFullEntitiesListWebMethod >
< getEntityInformationWebMethod > GWSGetExamInformation </
getEntityInformationWebMethod >
</ tv >
</ task >
< transition class =" BarCode " >
< BarCodeType > QRCode </ BarCodeType >
< OriginComponentId >13 </ OriginComponentId >
< DestinationComponentId >22 </ DestinationComponentId >
< BaseUrl > http ://143.107.102.15/ poc3xgov / Mobile_Comp / mobile /
mobFindPrivExam </ BaseUrl >
< ErrorCorrection >M </ ErrorCorrection >
< ImageSize >5 </ ImageSize >
< LabelMessage > Use this QRCode to access next service step . </
LabelMessage >
< TransitionId >7 </ TransitionId >
< TransitionName > QRCODE teste web -& gt ; mob </ TransitionName >
</ transition >
< navigation >
< originComponent >11 </ originComponent >
< endComponent >21 </ endComponent >
< label > See your exam list </ label >
</ navigation >
< navigation >
< originComponent >21 </ originComponent >
< endComponent >31 </ endComponent >
< label > Schedule an exam </ label >
</ navigation >
</ service >
Listagem C.3: XML
C.7
1
2
3
4
5
6
7
8
9
10
11
using
using
using
using
using
using
using
using
using
using
using
CromelService para Interpretador na versão C#
System ;
System . Collections . Generic ;
System . Linq ;
System . Text ;
System . Xml . Linq ;
System . IO ;
log4net ;
FrameworkLibrary ;
System . Xml ;
System . Net ;
System . Configuration ;
104
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using
using
using
using
XTransitionLibrary ;
Newtonsoft . Json ;
System . Reflection ;
System . Web . Hosting ;
namespace X WSCompon entMana ger
{
public class CromelService
{
private static readonly ILog log = LogManager . GetLogger ( typeof (
CromelService ) ) ;
public static void RunCromelScript ( string scriptComment , string
scriptCode )
{
var runtime = IronRuby . Ruby . CreateRuntime () ;
var engine = runtime . GetEngine (" rb ") ;
// Run embedded code in CroMeL script
var result = engine . Execute ( cromelScript ) ;
log . Info ( String . Format (" Running {0} with result : {1}." ,
scriptComment , result ) ) ;
return result . ToString () ;
}
public static void CreateNavigations ( List < NavigationDTO >
navigations ) {
log . Info ( String . Format ("{0} navigations found ." , navigations
. Count () ) ) ;
// component list to add in the configuration manager
List < ComponentConnection > list = new List <
ComponentConnection >() ;
// this constructor because mappings of the classes and
properties are known for C omponen tConnec tion
ComponentFactory cf = new ComponentFactory () ;
foreach ( NavigationDTO nav in navigations ) {
Comp onentCo nnection cc = ( Compone ntConne ction ) cf .
createObject (" FrameworkLibrary " , " Compone ntConne ction
") ;
cf . setProperty ( cc , " originComponent " , nav . Begin ) ;
cf . setProperty ( cc , " endComponent " , nav . End ) ;
cf . setProperty ( cc , " label " , nav . Label ) ;
105
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
}
int i = 0;
foreach ( Compone ntConne ction cc in list )
{
// Verify if connected components exist
if ( Global . ComponentList . Exists ( c = > c . ComponentId == cc
. OriginComponentId ) )
{
if ( Global . ComponentList . Exists ( c = > c . ComponentId
== cc . Com pon en tCo nn ect ed Id ) )
{
if ( Global . ComponentList . Single ( c = > c .
ComponentId == cc . OriginComponentId ) . Medium
== Global . ComponentList . Single ( c = > c .
ComponentId == cc . C omp one nt Con ne cte dId ) .
Medium )
{
// Insert connection to component .
Global . ComponentList . Single ( c = > c .
ComponentId == cc . OriginComponentId ) .
I n s e r t C o m p o n e n t C o n n e c t i o n ( cc ) ;
i ++;
}
else
{
log . Error (" Components " + cc .
OriginComponentId . ToString () + " and " +
cc . C omp on ent Co nne ct edI d . ToString () + " are
not from the same medium !") ;
}
}
else
{
log . Error (" There is no component with id : " + cc
. Co mp one nt Con nec te dId . ToString () + " to end a
connection .") ;
}
}
else
{
log . Error (" There is no component with id : " + cc .
OriginComponentId . ToString () + " to start a
connection .") ;
}
}
log . Info ( i . ToString () + " connections created .") ;
106
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
}
public static void CreateComponents ( List < ComponentDTO >
components ) {
log . Info ( String . Format ("{0} components found ." , components .
Count () ) ) ;
// component list to add in the configuration manager
List < Component > componentsCreated = new List < Component >() ;
Dictionary < String , String > mappingClasses =
loadMappingClasses (" classNames . mapping ") ;
Dictionary < String , String > mappingProperties =
l oa dM a pp i ng Pr o pe rt i es (" propertyNames . mapping ") ;
// mapping null because the names of the classes are known
ComponentFactory cf = new ComponentFactory ( mappingClasses ,
mappingProperties ) ;
foreach ( ComponentDTO component in components ) {
String type = component . Type ;
Hashtable params = component . parameters ;
// create a new component and add to the list
Component component = ( Component ) cf . createComponent ( type
);
if ( component != null ) {
componentsCreated . Add ( component ) ;
foreach ( DictionaryEntry de in parameters )
{
cf . setProperty ( component , de . Key () , de . Value () ) ;
}
} else {
log . Warn (" Component not found , please verify the
component mapping .") ;
}
log . Info ( String . Format ("{0} components created ." ,
componentsCreated . Count () ) ) ;
// Atualiza o Global Component List ( TODO : poderia
utilizar o AddRange ( componentsCreated ) mas necessita
testar primeiro )
foreach ( var comp in componentsCreated )
{
Global . ComponentList . Add ( comp ) ;
107
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
}
}
}
public static void CreateTransitions ( List < TransitionDTO >
transitions ) {
log . Info ( String . Format ("{0} transitions found ." , transitions
. Count () ) ) ;
TransitionFactory tf = new TransitionFactory () ;
tf . L oa d T r a ns i t i on A s s e mb l y () ;
foreach ( TransitionDTO transitionElement in transitions )
{
String transitionClass = transitionElement . Type ;
Hashtable parameters = transitionElement . parameters ;
log . Info (" New transition element found : " +
transitionClass ) ;
Object transitionObject = null ;
try
{
transitionObject = tf . Cr e a t e Tr a n s it i o n O bj e c t (
transitionClass ) ;
}
catch ( Exception )
{
log . Error (" Could not instantiate class : " +
transitionClass + ".") ;
log . Info (" Skipping this transition element ..") ;
continue ;
}
log . Debug (" Configuring transition parameters : " +
transitionClass ) ;
foreach ( DictionaryEntry de in parameters )
{
try {
cf . setProperty ( transitionObject , de . Key () , de .
Value () ) ;
} catch ( Exception e ) {
log . Error ( e ) ;
log . Info (" Skipping this transition property ..") ;
continue ;
}
108
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
}
Int32 originTaskId = 0;
Int32 destinationTaskId = 0;
Int32 transitionId = 0;
try {
originTaskId = transitionElment . Begin ;
destinationTaskId = transitionElement . End ;
if ( tf . TransitionExists ( originTaskId ,
destinationTaskId , transitionClass ) ) {
try {
tf . S e t T r a n s i t i o n O b j e c t P r o p e r t y (
transitionObject , " TransitionId " , tf .
GetTransitionId ( originTaskId ,
destinationTaskId , transitionClass ) .
ToString () ) ;
tf . E di t E x i st i n g Tr a n s i ti o n ( transitionObject ,
transitionClass ) ;
transitionId = tf . GetTransitionId (
originTaskId , destinationTaskId ,
transitionClass ) ;
log . Info (" Existent transition id was caught
.") ;
} catch ( Exception e ) {
log . Error (" Error while editing existent
transition ." , e ) ;
log . Error (" Skipping this transition element
..") ;
continue ;
}
} else {
try {
transitionId = tf .
CreateNewTransitionThroughWebService (
transitionObject , transitionClass ,
originTaskId , destinationTaskId ) ;
log . Info (" New transition id was received .") ;
} catch ( Exception e ) {
log . Error (" Error while creating new
transition : " + transitionClass , e ) ;
log . Error (" Skipping this transition element
..") ;
continue ;
}
}
} catch ( Exception e ) {
109
191
log . Error (" Could not verify if the transition
already exists ." , e ) ;
log . Error (" Skipping this transition element ..") ;
continue ;
192
193
194
195
196
197
}
// Edit object with new transition id
try {
tf . S e t T r a n s i t i o n O b j e c t P r o p e r t y ( transitionObject , "
TransitionId " , transitionId . ToString () ) ;
log . Debug (" TransitionId property was sucessfully
setted . (" + transitionId . ToString () + ") .") ;
} catch ( Exception e ) {
log . Error (" Could not set value : " + transitionId + "
to TransitionId property ." , e ) ;
log . Error (" Skipping this transition element ..") ;
continue ;
}
// Sending object to memory
try {
tf . Sa ve C om po n en t In Me m or y ( transitionClass ,
transitionId , originTaskId ) ;
log . Debug (" Transition successfully added to
component .") ;
} catch ( Exception e ) {
log . Error (" Error when adding transition to component
." , e ) ;
continue ;
}
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
}
}
....
}
Listagem C.4: Cromel Service
C.8
ComponentFactory para Interpretador na versão
C#
1
2
3
4
5
6
7
using
using
using
using
using
using
using
System ;
System . Collections . Generic ;
System . Linq ;
System . Text ;
System . Reflection ;
FrameworkLibrary ;
log4net ;
110
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System . Web . Hosting ;
namespace X WSCompon entMana ger
{
/// < summary >
/// This class uses reflection to instantiate dynamically the
components from FrameworkLibrary
/// </ summary >
class ComponentFactory
{
private static readonly ILog log = LogManager . GetLogger ( typeof (
ComponentFactory ) ) ;
private Assembly assembly ;
private Dictionary < String , String > mappingClasses ;
private Dictionary < String , String > mappingProperties ;
/// < summary >
/// Used to create a ComponentFactory for FrameworkLibrary
assembly without a dictionary to bind the properties
/// </ summary >
public ComponentFactory () : this (" FrameworkLibrary . dll ") {}
/// < summary >
/// Create a ComponentFactory for FrameworkLibrary with a
dictionary used to bind the properties to names
/// </ summary >
/// < param name =" mappingClasses " > Dictionary to lookup the name
of the classes </ param >
/// < param name =" mappingProperties " > Dictionary to lookup the
name of the properties </ param >
public ComponentFactory ( Dictionary < String , String >
mappingClasses , Dictionary < String , String > mappingProperties )
: this (" FrameworkLibrary . dll ")
{
this . mappingProperties = mappingProperties ;
this . mappingClasses = mappingClasses ;
}
/// < summary >
/// Used to create a ComponentFactory for an assembly without a
dictionary to bind the properties
/// </ summary >
/// < param name =" assembly " > The name of the assembly ( e . g .
FrameworkLibrary . dll ) </ param >
public ComponentFactory ( String assembly )
{
try
111
45
46
{
String assemblyWithPath = HostingEnvironment .
A p p l i c a t i o n P h y s i c a l P a t h + @ " bin \"+ assembly ;
log . Debug (" FrameworkLibrary path : " + assemblyWithPath ) ;
this . assembly = Assembly . LoadFrom ( assemblyWithPath ) ;
// this . assembly = AppDomain . CurrentDomain . Load ( assembly )
;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
}
catch ( Exception e )
{
log . Error (" Could not load assembly ( dll or exe ) , verify
path : " + assembly , e ) ;
}
}
/// < summary >
/// Creates a new object from a namespace of the assembly
/// </ summary >
/// < param name =" namespaceName " > Name of the namespace or
namespace . subnamespace </ param >
/// < param name =" className " > Name of the class that belongs to
the namespace </ param >
/// < returns > </ returns >
public Object createObject ( String namespaceName , String
className )
{
// Create component by parametrized constructor
// MyClass myObj = ( MyClass ) myAssembly . CreateInstance ("
R e fl e c t i on T e s t As s e m bl y . MyClass " ,
//
false , BindingFlags . Default , null ,
//
new object [] { 5 } , null , null ) ;
Object newObject = null ;
// Lookup in the dictionary for class names
if (( mappingClasses != null ) && mappingClasses . ContainsKey (
className ) )
{
className = mappingClasses [ className ];
}
try
{
newObject = ( Object ) assembly . CreateInstance (
namespaceName + "." + className ) ;
if ( newObject == null ) throw new
C o m p o n e n t F a c t o r y E x c e p t i o n (" Creating class "+ className )
;
112
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
}
catch ( Exception e )
{
log . Warn (" Can ’ t instantiate the component : " + className
, e);
}
return newObject ;
}
/// < summary >
/// Creates a new object from FrameworkLibrary namespace
/// </ summary >
/// < param name =" objectName " > Name of the class </ param >
/// < returns > New Object instance </ returns >
public Object createObject ( String objectName )
{
return this . createObject (" FrameworkLibrary " , objectName ) ;
}
/// < summary >
/// Creates a new component from FrameworkLibrary namespace
/// </ summary >
/// < param name =" componentName " > Name of the class </ param >
/// < returns > New Component instance </ returns >
public Component createComponent ( String componentName )
{
return ( Component ) this . createObject (" FrameworkLibrary " ,
componentName ) ;
}
/// < summary >
/// Set the property of a object . If you have a ComponentFactory
created with a dictionary
/// it will try to avoid the Mi s s i n gM e t h od E x c e pt i o n using the
key of the dictionary for lookup
/// </ summary >
/// < param name =" target " > The object that will be set a property
value </ param >
/// < param name =" property " > The name of the property </ param >
/// < param name =" value " > The value of the property ( any datatype
as Object ) </ param >
public void setProperty ( Object target , String property , Object
value )
{
try
{
113
121
122
// Lookup in the dictionary for property names
if (( mappingProperties != null ) && mappingProperties .
ContainsKey ( property ) )
{
property = mappingProperties [ property ];
}
123
124
125
126
127
128
// transfor 1 st char in upcase ( convention in C #)
property = StringExtension . ToUpperFirstLetter (( String )
property ) ;
129
130
131
132
Type componentType = target . GetType () ;
// if int datatype is passed as string will have a
M e th o d M i ss i n g E xc e p t io n because it should be converted
int iValue = 0;
bool bValue = false ;
if ( value is String && Int32 . TryParse ( value . ToString () ,
out iValue ) )
{
// int value
componentType . InvokeMember ( property , BindingFlags .
SetProperty , null , target , new object [] { iValue
}) ;
}
else
{
// if bool datatype is passed as string , will have a
M e th o d M i ss i n g E xc e p t io n because it should be
converted
if ( value is String && Boolean . TryParse ( value .
ToString () , out bValue ) )
{
// bool value
componentType . InvokeMember ( property ,
BindingFlags . SetProperty , null , target , new
object [] { bValue }) ;
}
else
{
// string or object value
componentType . InvokeMember ( property ,
BindingFlags . SetProperty , null , target , new
object [] { value }) ;
}
}
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
}
114
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
catch ( Exception e )
{
log . Warn ( String . Format (" Can ’ t setProperty : {0} = {1}
({2}) " , property , value , value . GetType () ) , e ) ;
}
}
/// < summary >
/// Call a method on the target object with parameters
/// </ summary >
/// < param name =" target " > The object to call the method </ param >
/// < param name =" methodName " > The name of the method </ param >
/// < param name =" parameters " > list of parameters </ param >
public void callMethod ( Object target , String methodName , Object
parameters )
{
try
{
// Lookup in the dictionary for property names
if (( mappingProperties != null ) && mappingProperties .
ContainsKey ( methodName ) )
{
methodName = mappingProperties [ methodName ];
}
175
176
177
178
179
180
// transfor 1 st char in upcase ( convention in C #)
methodName = StringExtension . ToUpperFirstLetter (( String )
methodName ) ;
181
182
183
184
185
Type componentType = target . GetType () ;
// call the method
componentType . InvokeMember ( methodName , BindingFlags .
InvokeMethod , null , target , new object [] { parameters }
);
186
187
188
189
190
191
192
193
194
}
catch ( Exception e )
{
log . Warn ( String . Format (" Can ’ t call the method {0} with
parameter {1}" , methodName , parameters ) , e ) ;
}
}
/// < summary >
115
195
/// Ainda nao foi usado para nada , mas serve para inspecionar um
assembly .
/// </ summary >
/// < param name =" assembly " > nome completo do assembly </ param >
public static void printTypes ( String assembly ) {
if ( assembly == null )
{
assembly = " FrameworkLibrary . dll ";
}
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
// Load an assembly from file
Assembly myAssembly = Assembly . LoadFrom ( assembly ) ;
// Get the types contained in the assembly and print their
names
Type [] types = myAssembly . GetTypes () ;
foreach ( Type type in types )
{
log . Debug ( type . FullName ) ;
}
}
}
/// < summary >
/// Utiity class for string manipulation
/// </ summary >
public static class StringExtension
{
// string extension method ToUpperFirstLetter
public static string ToUpperFirstLetter ( this string source )
{
if ( string . IsNullOrEmpty ( source ) )
return string . Empty ;
// convert to char array of the string
char [] letters = source . ToCharArray () ;
// upper case the first char
letters [0] = char . ToUpper ( letters [0]) ;
// return the array made of the new char array
return new string ( letters ) ;
}
}
/// < summary >
/// Used to show that something is wrong in the factory
/// </ summary >
class C o m p o n e n t F a c t o r y E x c e p t i o n : Exception
{
public C o m p o n e n t F a c t o r y E x c e p t i o n ( String msg ) : base ( msg ) { }
116
240
241
}
}
Listagem C.5: Component Factory
117
Este documento foi preparado com o formatador de textos LATEX .