Você está na página 1de 52

DSL Encoder: Uma ferramenta web para desenvolvimento

de linguagens específicas de domínio
Bruno F. Leão Maia1, Vinicius Cardoso Garcia1,2, Leandro M. Nascimento1,3
1

2

3

Centro de Estudos Avançados do Recife (C.E.S.A.R.)
Recife – Pernambuco – Brasil

Centro de Informática (CIn) – Universidade Federal de Pernambuco - UFPE
Recife – Pernambuco – Brasil

Departamento de Estatística e Informática (DEINFO) - Universidade Federal Rural de
Pernambuco - UFRPE
Recife – Pernambuco – Brasil
brunoleaomaia@gmail.com, [lmn2,vcg]@cin.ufpe.br

Resumo. Adotar uma abordagem DSL aumenta o nível de abstração para o
nível do problema do domínio, melhorando a produtividade e habilitando o
reuso. O desenvolvimento e implementação de DSLs requer a utilização de
ferramentas especializadas. Este artigo apresenta um IDE baseado na web,
para o desenvolvimento de linguagens específicas de domínio e apresenta um
estudo de caso da utilização desta ferramenta com foco no reuso e geração de
código.
Abstract. Adopting a DSL approach raises the level of abstraction to the level
of problem domain, improving productivity and enabling reuse. The
development and implementation of DSLs requires the use of specialized tools.
This paper presents a web based IDE for developing domain-specific
languages and presents a case study of the use of this tool with a focus on
reuse and code generation.
Palavras-chave: web programável, DSL, ferramenta, reuso, geração de
código.

1. Introdução
Um dos objetivos da Engenharia de Software é aumentar a produtividade, seja pela
adoção de uma arquitetura que possibilite o reuso, seja pela utilização de técnicas que
permitam um especificação mais abstrata, sem detalhes de implementação, e que
possibilitem a geração de código consistente, de qualidade e que permita responder as
necessidades de mudança com facilidade [1][2]. O uso de linguagens específicas de
domínio, ou do inglês “domain-specific language” (DSL), tem possibilitado aumentar a
abstração [3], criando soluções voltadas para resolver problemas específicos do
domínio. Os geradores de aplicação, por exemplo, são uma categoria de suma
importância para o reuso de software, e muitos deles utilizam DSLs como idioma de
entrada [4].

1

No entanto, o desenvolvimento de linguagens específicas de domínio requer o uso de
ferramentas especializadas, que geralmente possuem versões específicas para cada
sistema operacional, que muitas vezes dependem de outro software ou máquina virtual e
que precisam ser instaladas para que possam ser executadas, dificultando o uso em
ambientes de rede controlados, em que o usuário não possui autonomia para instalar
programas.
O advento da “web 2.0” [5] revolucionou a forma como o software é distribuído. Hoje
grandes aplicações utilizam a “web como plataforma”. Novas técnicas de programação
e a evolução dos navegadores e do poder computacional dos dispositivos possibilitaram
que as aplicações baseadas na web tivessem um comportamento semelhante ao das
aplicações desktop [6]. Hoje, as aplicações baseadas na web estão passando por uma
nova fase e a web agora é vista como uma plataforma programável [7]. Esta nova
abordagem tornou possível utilizar recursos de outras aplicações ao redor do mundo e
tornou as aplicações baseadas na web ainda mais poderosas [8].
Este artigo apresenta uma ferramenta para o desenvolvimento de DSL, extensível, com
foco na geração de código e no reuso de software, que utiliza a web como plataforma e
que pode ser integrada a outros serviços da web, como uma alternativa de fácil acesso, e
que necessita apenas do navegador para ser executada. A Seção 2.1 apresenta os
conceitos de DSL, as motivações para o seu uso, suas fases de desenvolvimento e a
necessidade da utilização de ferramentas especializadas. A Seção 2.2 apresenta os
princípios da “web 2.0” e apresenta uma nova fase que está surgindo, a “web
programável”. A Seção 3 apresenta a proposta de construção da ferramenta, suas
premissas e como estas foram atendidas e a Seção 4 mostra como utilizar a ferramenta.
A Seção 5 apresenta um estudo de caso da utilização da ferramenta e os ganhos de
produtividade obtidos. Na Seção 6 são apresentadas as conclusões e os trabalhos futuros
relacionados.

2. Background
2.1. Domain-Specific Languages
Ao longo da história de desenvolvimento de software, os engenheiros de software
procuraram melhorar a produtividade aumentando a abstração [9]. Linguagem
específica de domínio é uma “linguagem pequena, usualmente declarativa, que oferece
poder expressivo focado em um domínio de um problema particular” [3]. Uma DSL
pode aumentar o nível de abstração muito além das linguagens de programação atuais,
criando soluções específicas baseadas no domínio do problema.
Linguagem específica de domínio não é um conceito novo e foi observado pela primeira
vez no final da década de 50 com a linguagem automatically programmed tools (APT),
que era uma DSL para programação de ferramentas controladas numericamente [10].
Atualmente, linguagens como SQL (utilizada em bancos de dados), HTML (utilizada
em páginas da web) e LaTeX (utilizada na produção de textos matemáticos e
científicos) são exemplos de DSL amplamente utilizadas.
Por outro lado, as linguagens de programação de propósito geral, do inglês generalpurpose programming languages (GPLs), combinadas com bibliotecas de aplicação,
podem ter um comportamento parecido com uma DSL, no entanto, ganhos notáveis e
substanciais em expressividade e facilidades de uso são obtidos quando uma DSL é
2

desenvolvida. O desenvolvimento de uma linguagem específica melhora a
produtividade por oferecer notações e construtores mais adequados e específicos para o
domínio do problema, tornando a construção e escrita mais leve e direta. Além da
produtividade, as DSLs são importantes por possibilitar o reuso. Os geradores de
aplicação são uma categoria de suma importância em reuso por utilizar DSL como
idioma de entrada, reutilizando a semântica do domínio [4].
No entanto, decidir por desenvolver uma nova DSL é uma atividade complexa e deve
levar em consideração alguns fatores como reduzir custos futuros com desenvolvimento
de software e habilitar o desenvolvimento por usuários sem experiência em
programação mas com conhecimento sobre o domínio, ou o inverso, usuários com
experiência em programação e pouco conhecimento sobre o domínio [4].
Riscos e oportunidades devem ser avaliados antes de se decidir pela adoção do
desenvolvimento de uma nova DSL. Apesar dos custos de desenvolvimento,
manutenção e de aprendizado do usuário, adotar uma abordagem DSL propicia uma
série de benefícios, uma vez que programas DSL são concisos e em sua maioria autodocumentados, escritos no idioma e no nível de abstração do domínio do problema. O
uso de DSLs aumenta a produtividade, a confiabilidade, a manutenabilidade, a
portabilidade e o reuso já que os programas de DSL podem ser validados e modificados
e até criados pelos próprios especialistas do domínio, com ou sem experiência em
programação [3].
De acordo com Mernik et al. [4] alguns padrões dão sustentabilidade às motivações para
o desenvolvimento de DSL como notação (transformando visual para textual ou
adicionando notações amigáveis a APIs existentes), automação de tarefas, linhas de
produto, representação de estrutura de dados, intercâmbio de estrutura de dados,
interação de sistemas front-end, construção de interfaces gráficas do usuário e AVOPT
(Análise, Verificação, Otimização, Paralelização e Transformação do domínio
específico). Uma vez decidido por uma nova DSL, o processo de desenvolvimento
geralmente envolve as etapas de análise, projeto e implementação.
Na etapa de análise, o domínio do problema é identificado, o conhecimento relevante do
domínio é coletado e agrupado e o resultado é um conjunto de noções semânticas e
operações deste domínio. Na maioria das vezes, a análise do domínio é feita
informalmente, sobretudo, metodologias formais de análise de domínio podem ser
utilizadas e o resultado dessa análise formal são: um modelo de domínio (domainmodel), que é formado por uma definição do escopo do domínio; uma terminologia do
domínio (vocabulário, ontologia), descrições dos conceitos do domínio; e modelos de
características (feature-models), que descreve os pontos comuns e variações do domínio
e suas interdependências [4].
Deursen et al. [3] destaca as seguintes metodologias de engenharia de domínio como as
“mais conhecidas”:


ODM – Organization Domain Modeling
FODA – Feature-Oriented Domain Analysis
DSSA – Domain-Specific Software Architectures

Mernik et al. [4] identifica duas dimensões ortogonais nas abordagens de projetos de
DSL: Uma onde há uma relação com linguagens já existentes e outra onde uma nova
linguagem é criada sem nenhuma relação com outra existente. Basear uma DSL em uma
3

linguagem existente pode acelerar o processo de desenvolvimento e torná-lo mais fácil e
três padrões são identificados por ele: o primeiro é pegar carona nas características do
domínio específico em uma linguagem existente (piggyback), o segundo é estender uma
linguagem existente para atender as características do domínio (extension) e o terceiro é
especializar uma linguagem existente para atender um problema específico dentro do
domínio (specialization). No entanto a criação de novas linguagens sem relação com
outra existente é um processo mais complexo, difícil de caracterizar, podendo ser
descrito de maneira informal, onde a especificação é geralmente baseada em alguma
linguagem natural, ou formal, no qual a especificação utiliza um dos métodos de
definições semânticas disponíveis.
Fowler [12] afirma que não há uma forma ideal para projetar uma DSL, que o “objetivo
geral de uma DSL, como com em qualquer escrita, é a clareza para o leitor”, e que a
linguagem deverá ser de fácil utilização tanto para programadores quanto para
especialistas do domínio.
Após a etapa de projeto de uma DSL (executável), é necessário definir uma abordagem
de implementação. Mernik et al. [4] e Deursen [3] destacam a abordagem de
interpretação ou compilação como clássica para a implementação de novos idiomas,
sendo amplamente utilizada na prática. Embora a construção de um compilador ou
interpretador traga algumas vantagens, como total adaptação as notações da DSL, o
custo da construção é elevado, e geralmente são utilizadas ferramentas especialmente
projetadas para este propósito.
Caso a abordagem do projeto da DSL seja baseada em outra linguagem (piggyback,
extension ou specialization) a abordagem de implementação da linguagem base poderá
ser reutilizada das seguintes formas:

Incorporação: onde uma DSL é implementada ao estender uma GPL existente e
os “mecanismos existentes, tais como definições de funções ou operadores com
sintaxe definida pelo usuário são utilizados para construir uma biblioteca de
operações do domínio específico”[3].

Processamento e Macro-processamento:
onde “novas construções são
traduzidas para declarações na linguagem base por um pré-processamento”[3].

Compilador ou Interpretador Extensível: semelhante a abordagem anterior
porém “a fase de processamento é agora integrada no compilador” [3] e traz
como vantagem a possibilidade de uma melhor otimização e checagem de tipos.

Mernik et al. [4] afirma que o “desenvolvimento de DSL é difícil, exigindo tanto
conhecimento do domínio quanto experiência no desenvolvimento de linguagens” e que
este processo pode ser facilitado com a adoção de ferramentas de desenvolvimento de
DSL. As ferramentas podem variar de um simples verificador de consistência e
interpretador até um ambiente integrado de desenvolvimento, do inglês integrated
development environment (IDE), formado por um editor de texto syntax-directed
(dirigido pela sintaxe), um prettyprinter (exibindo o texto em diferentes cores baseado
na sintaxe), um verificador de inconsistência (incremental), ferramentas de análise, um
interpretador ou compilador/gerador de aplicações e um depurador.
Geralmente, a entrada para estas ferramentas são metalinguagens com informações
sobre os vários aspectos da DSL entre eles “sintaxe, prettyprinting, verificação de
4

consistência, análise, execução, tradução, transformação e depuração”[4]. É comum a
sintaxe de uma DSL ser descrita com algo semelhante a BNF[11], no entanto, Fowler
[12] faz menção a linguagens de estruturação de dados como XML[13], JSON[14] e
YAML[15] como forma de descrever DSL, e que muitas vezes arquivos de
configuração ou que especificam interfaces gráficas do usuários no formato XML são
efetivamente DSLs.
Kelly e Tolvanen [9] e Fowler [16] destacam algumas ferramentas para o
desenvolvimento de DSL. Uma listagem com a principal dependência, gratuidade e
sistemas operacionais suportados por estas ferramentas pode ser observado na Tabela 1.
Tabela 1. Ferramentas para Desenvolvimento de DSL
Gratuita

Sistemas Operacionais
Suportados

MetaEdit+ (MetaCase)

Não

Windows, Linux e
Mac OS X

GME (Vanderbilt
University)

Sim

Windows

Ferramenta

Dependências

DSL Tools (Microsoft)

Visual Studio 2005
Professional Edition

Não

Windows

MPS (JetBrains)

Java Virtual Machine (JVM)

Sim

Windows, Linux e
Mac OS X

Eclipse Modeling
Project (Eclipse)

Java Virtual Machine (JVM)

Sim

Windows, Linux e
Mac OS X

Xtext

Eclipse Modeling Project
(Eclipse)

Sim

Windows, Linux e
Mac OS X

Existem poucas ferramentas de desenvolvimento de DSL, quando comparamos ao
número de ferramentas de desenvolvimento de linguagens de programação de propósito
geral. Geralmente, essas ferramentas são distribuídas em versões específicas para cada
sistema operacional, possuem dependências e necessitam ser instaladas para que possam
ser executadas, o que dificulta a sua utilização em ambientes de rede controlados, onde
os usuários não tem autonomia para instalar programas.
Muitas são as motivações para o desenvolvimento de linguagens específicas de
domínio, no entanto, decidir por uma abordagem DSL envolve custos e riscos que
podem sem minimizados pela adoção de ferramentas especializadas nas fases de
desenvolvimento e implementação de uma nova DSL. Sobretudo, essa ferramentas são
escassas, precisam ser instaladas e muitas vezes possuem dependências. Para resolver
este problema este artigo apresenta na Seção 3 uma ferramenta alternativa, gratuita,
multiplataforma para o desenvolvimento e implementação de DSL.
2.2. Web Programável
O’Reilly [5] define que “Web 2.0 é a mudança para uma internet como plataforma”, e
que “a regra mais importante é desenvolver aplicativos que aproveitem os efeitos de
rede para se tornarem melhores quanto mais são usados pelas pessoas, aproveitando a
inteligência coletiva” e acredita que os serviços tornam-se melhor a medida que mais
pessoas o utilizam e que a colaboração dos usuários, definido por ele como “rede de
5

contribuições”, é o fator chave para a melhoria contínua destes serviços e a forma de
garantir sua continuidade.
Ao assumir uma postura colaborativa, os usuários assumiram o papel de codesenvolvedores dos serviços que utilizam, o que fez com que o
“ditado do código aberto ‘libere cedo e libere frequentemente’ de fato se
transformasse numa posição ainda mais radical, ‘o beta perpétuo’, onde
produtos são desenvolvidos em aberto, com novas funcionalidades sendo
transmitidas em base mensal, semanal ou mesmo diário”[5].
Nas aplicações web, novas funcionalidades são disponibilizadas aos usuários
constantemente e o monitoramento das atividades do usuário é fundamental para decidir
se um novo recurso na aplicação deverá ser explorado ou deixado de lado, tornando seu
ciclo de desenvolvimento diferente da era PC ou cliente-servidor [5].
A experiência do usuário também melhorou, inicialmente com as aplicações multimídia
e interfaces do usuário mais bem elaboradas em Flash, onde a Macromedia cunhou o
termo “Rich Internet Applications”, e posteriormente com o lançamento do Gmail pelo
Google, um aplicativo baseado na web, com interface rica do usuário e com
interatividade semelhante a um software desktop. O conjunto de tecnologias utilizada
pelo Google foi batizado de AJAX e que se tornou um componente chave para as
aplicações web 2.0. Jesse James Garret citado por O’Reilly [5] define Ajax como:
“Ajax não é uma tecnologia. É o conjunto de várias tecnologias, cada uma
florescendo em seu próprio direito, juntando-se em maneiras novas e
poderosas. Ajax incorpora:
-­‐

Apresentação baseada em padrões usando XHTML e CSS,

-­‐

Exibição dinâmica e interação com o Document Object Model,

-­‐

Intercâmbio de dados usando XML e XSLT,

-­‐

Recuperação de dados assíncrona usando XMLHttpRequest,

-­‐

e JavaScript mantendo tudo isso junto.”

Hoje as aplicações e serviços web deixaram de ser exclusividade dos computadores
pessoais estão nos smartphones, tablets e internet das coisas. As aplicações agora
atendem ao princípio defendido por O’Reilly [5] para “software acima do nível de um
único dispositivo”. Agora, o teclado e o mouse não são mais os principais dispositivos
de entrada. Telas sensíveis ao toque e sensores enriqueceram ainda mais a experiência
do usuário adicionando recursos como geolocalização, reconhecimento de voz,
reconhecimento de imagem, detecção facial, sensores de proximidade e movimento.
Meira et al. [7] acredita que uma nova fase está surgindo, onde a web é vista como uma
plataforma de programação, onde a inovação reside no poder de desenvolver para web,
na própria web, ou seja, usar a web como plataforma de desenvolvimento e execução.
Um subconjunto de tecnologias da web 2.0 que estiveram em profunda transformação
nos últimos anos permitiu que os usuários passassem de consumidores, a criadores de
poderosas aplicações web utilizando recursos de terceiros, aplicações estas
denominadas mashups [8]. De acordo com Maximilien et al. [17], mashups são a
principal manifestação da web programável, e combinam visualizações, dados e lógica
6

de sites ou aplicações existentes para criar novas aplicações com foco em situações e
problemas efêmeros.
Os maiores provedores de serviço da internet como Google, Amazon e eBay tem
provido application programming interfaces (APIs) como serviços da web (do inglês
web services) para que usuários e desenvolvedores possam criar novas aplicações a
baixo custo ou gratuitamente [8]. O número de empresas provendo APIs para uso
público vem crescendo exponencialmente. Segundo DuVander [18] o diretório de APIs
Programmable Web registrou o marco de 8000 APIs em novembro de 2012,
principalmente impulsionado pela adoção de APIs abertas por grandes empresas.
Outro acelerador do crescimento do número de APIs foi a evolução dos smartphones e
dispositivos conectados a internet. “Existe uma grande chance que qualquer aplicativo
no seu telefone faça alguma coisa interessante usando uma API”[19].
O Rich Site Summary (RSS), tecnologia que permitiu que o usuário se inscrevesse para
receber o conteúdo que quer ler, apresentou novas formas de consumir informações e
serviços da web [5]. A popularização do RSS fez com que serviços web antes somente
disponibilizados através do formalismo do Simple Object Access Protocol (SOAP), que
transporta XML através do protocolo HTTP, passassem a ser oferecidos de formas
alternativas, mais leves e diretas, como os serviços REST (Representational State
Transfer) também conhecidos com RESTful services [20]. Uma outra mudança que
veio com a adoção de serviços REST foi a adoção de um formato leve de intercâmbio
de dados chamado JSON como alternativa ao formato XML, utilizado nos serviços
SOAP e XML-RPC.
DuVander [21] aponta que como atualmente existem mais serviços REST que SOAP,
XML-RPC ou outros protocolos, o formato JSON vem crescendo e ganhando espaço
em utilização frente ao formato XML (Figura 1). Segundo DuVander [21] o formato
JSON é o formato preferido pelos desenvolvedores atualmente e com isso está se
tornando também a escolha dos provedores de API. O formato JSON pode ser
facilmente analisado pela maioria das linguagens de programação, principalmente em
JavaScript por ser nativo e quando a API oferece suporte a JSONP (JSON with padding,
técnica de programação JavaScript que permite solicitar dados em um domínio
diferente), esta pode ser consumida diretamente do navegador. O formato JSON, sem
abrir e fechar tags, é mais leve sendo apreciado por desenvolvedores e provedores de
serviços [21].
Porcentagem+de+novas+APIs++
com+suporte+somente+a+JSON+

Porcentagem de APIs
com suporte a XML
95%$

25%#

90%$

20%#

85%$

15%#
10%#

80%$

5%#

75%$

0%#

70%$
2006#

2007#

2008#

2009#

2010#

2011#

2009$

2010$

2011$

Fonte: Programmable Web[21]

Figura 1. Estatísticas sobre Utilização de JSON e XML em APIs

7

Muita coisa mudou desde que o eBay lançou sua primeira API no ano 2000. A
utilização de APIs se tornou a principal forma de conectar dados e funcionalidades entre
aplicações. Hoje as APIs são o centro da estratégia do Google (que conta com mais de
90 APIs) e aceleradores de crescimento de serviços com Twitter e Facebook [22].
“Pense na web de 1995. Havia uma abundância de empresas sem sites.
Muito rapidamente, todas essas empresas perceberam que precisavam para
ter um site para competir. Vimos a mesma coisa com as mídias sociais e
este é o caminho que as APIs estão seguindo. Uma série de grandes
empresas acrescentado APIs em 2011, incluindo as três principais
empresas norte-americanas de cartão de crédito”[22].
O universo das APIs ainda é muito novo, muita coisa ainda está em evolução e não
existem padrões definidos. “O caos de um universo de APIs em expansão vai levar
algum para procurar por ordem. E um pouco de ordem é provavelmente necessária”
[22]. As APIs SOAP são mais ordenadas, auto documentas e fáceis de serem
desenvolvidas, uma vez que existem ferramentas de apoio. No entanto, a leveza e a
simplicidade do REST tem facilitado a implementação de APIs por provedores de
serviços e o consumo por parte dos desenvolvedores, levando o número de APIs REST
crescer e cada vez mais e se sobrepor percentualmente em relação as APIs SOAP
(Figura 2).
Protocolos usados por Web APIs
SOAP
23%
OUTROS
2%
JavaScript
5%
XML-RPC
2%

REST
68%

Fonte: Programmable Web [23]

Figura 2. Protocolos usados por APIs

A utilização de APIs é uma tendência, que se popularizou pelo uso em redes sociais,
posteriormente com o crescimento do mercado de aplicações móveis, e agora com a
adoção de APIs abertas pelas Enterprises. A utilização de APIs não é mais um
diferencial técnico, é uma necessidade. Recentemente, um novo modelo de negócio
emergiu, “backend-as-service” [24], provendo a desenvolvedores recursos como
armazenamento na nuvem, gerenciamento de usuários, operações de CRUD,
notificações push, integração com redes sociais, entre outros.
Independente da tecnologia, protocolo ou formato de intercâmbio utilizado (Figura 3), o
mais importante do que API que está exposta são os dados que ela acessa. A facilidade
de uso, uma boa documentação de seus recursos e utilização, funcionalidades
exclusivas, a qualidade e confiabilidade dos dados gerenciados, são os verdadeiros
diferenciais, que se transformam em vantagem competitiva [25].

8

Que tecnologia você usou em 2012?
REST
JSONP
OAuth 2
SOAP
RSS/Atom feeds
WebSockets
CORS
WS-*
Webhooks
OAuth 1.0a
PubSubHubbub

35,40%
34,60%
29,20%
13,10%
12,30%
11,50%
10,00%
8,50%
6,90%
2,30%

85,40%

Fonte: Programmable Web [25]

Figura 3. Tecnologias e Protocolos usados em APIs

A evolução do poder computacional dos dispositivos conectados a internet e a evolução
dos navegadores e dos padrões que estes utilizam, possibilitaram que aplicações mais
robustas, antes exclusividade de ambientes desktop, fossem disponibilizadas na web. A
evolução das tecnologias de integração das aplicações e o surgimento das APIs
possibilitou a criação de novas aplicações, integradas a vários serviços da web, que
trazem mais recursos e poder colaborativo aos usuários que as aplicações da era PC. O
formato JSON de intercâmbio de dados vem se popularizando entre os desenvolvedores
cada vez mais e hoje é o formato base para intercâmbio em APIs que utilizam os
princípios REST. A Seção 3 apresenta uma ferramenta que se baseia nos princípios da
Web 2.0, que disponibiliza recursos para que seus usuários a estendam através da
utilização de APIs de terceiros e que utiliza JSON como meta linguagem de entrada
para o desenvolvimento de DSLs.

3. Proposta de Construção da Ferramenta
Este artigo tem por objetivo apresentar uma ferramenta para o desenvolvimento de
linguagens específicas de domínio [3], utilizando a web como plataforma [5]. A
ferramenta, DSL Encoder (DSLE), é um ambiente de desenvolvimento integrado [4], de
código aberto, de fácil utilização, que pode ser conectada a outros serviços da web
através de APIs [8], e que oferece recursos para sua melhoria contínua por meio da
“inteligência colaborativa” [5].
A ferramenta DSLE possui um gerenciador de projetos e arquivos interno, um editor de
texto integrado com syntax highlighter, e um console que apresenta informações ao
usuário, as saídas impressas do processamento dos programas DSL e em caso de
apresenta a posição do código fonte original onde o erro foi encontrado.
Em seu núcleo existe um framework DSL [26], escrito em JavaScript, que permite a
criação de DSLs descritivas e programas baseados nessas DSLs, utilizando o formato
leve de intercâmbio de dados JavaScript Object Notation (JSON) [14]. A ferramenta
também permite a criação de templates para processamento dos programas DSL e/ou
geração de código [9].
DSLE se propõe a ser um ambiente extensível, onde os usuários podem criar seus
próprios plug-ins, utilizando a linguagem JavaScript, na própria ferramenta. Estes plugins tanto podem adicionar novas funcionalidades a ferramenta como conectá-la a outros
serviços da web através do consumo de APIs de terceiros.
9

Os plug-ins, templates, DSLs e programas DSL podem ser escritos, validados e
processados na própria ferramenta, no entanto, os usuários podem instalar recursos
desenvolvidos por terceiros através da “Extensions Marketplace”, um diretório de
extensões integrado a ferramenta.
A seção 3.1 aborda as premissas para construção da ferramenta e apresenta as
abordagens tomadas para que estas fossem atendidas.
3.1. Premissas para a Construção da Ferramenta
3.1.1. Código Aberto
Um dos objetivos da ferramenta é que ela seja melhorada constantemente, seja pela
adição de novos recursos através de plug-ins, seja pela própria evolução em seu código
fonte. Como citado por Raymond [27] “dados olhos suficientes, todos os erros são
triviais”, dessa forma, para que ferramenta seja evoluída pela colaboração de vários
desenvolvedores e/ou usuários, a opção de licenciamento da ferramenta e de seu código
fonte foi o código aberto, e a licença escolhida foi a New BSD [28] por ser uma licença
mais permissiva quanto a utilização do código fonte comercialmente.
O’Reilly [29] cita que “dar aos usuários de um produto acesso ao seu código fonte e
direitos para criar trabalhos derivados, permite se auto-ajudarem, e encoraja a
evolução natural do produto, bem como o projeto inicial do produto”.
Ao liberar o código fonte em uma licença de código aberto é esperado que seus usuários
se tornem também co-desenvolvedores, com isso a detecção e correção de erros seja
acelerada e a qualidade do software seja melhorada, a medida que mais codesenvolvedores participem da sua evolução.
O núcleo da ferramenta oferece vários pontos de extensão tratados no item 3.1.9, codesenvolvedores podem estender o código para atender uma necessidade específica e se
desejarem, podem compartilhar as novas funcionalidades especializadas.
“De fato, muitos projetos open-source de sucesso tem uma arquitetura
modular, que permite aos usuários estender a funcionalidade do sistema,
sem ter que alterar a funcionalidade do núcleo existente. Isso permite um
projeto open-source ganhe escalabilidade com sua comunidade, enquanto o
original visionário (ou time) retém o controle sobre o produto núcleo”[29].
Ao atender a premissa de código aberto espera-se fomentar o crescimento da
ferramenta, por meio da criatividade de seus co-desenvolvedores, com o
desenvolvimento de novas funcionalidades, de forma modular, e que os erros e
problemas sejam detectados e corrigidos mais rapidamente.
3.1.2. Web como plataforma
Uma dificuldade encontrada nas ferramentas de desenvolvimento de DSLs atuais é que
elas possuem versões específicas para cada sistema operacional, possuem dependências,
precisam ser instaladas e muitas vezes não oferecem uma versão gratuita.
Um das premissas do DSL Encoder é usar a “web como plataforma”, e que seja
desenvolvida “acima do nível de um único dispositivo” por meio de uma aplicação leve,
multiplataforma e de fácil acesso [5]. Taivalsaari e Mikkonen [6] apontam que
10

“aplicações binárias convencionais estão em maior desvantagem comparadas a
software baseado na web porque este pode ser implantado instantaneamente ao redor
do mundo”.
O uso de técnicas com programação JavaScript como AJAX, e JSONP, aliados aos
novos padrões emergentes como HTML5, CSS3 e WebGL estão possibilitando a
criação de aplicações ricas, com funcionalidades e comportamento semelhante ao das
aplicações desktop e “transformando a web numa verdadeira plataforma de
software”[6]. Para atender essa premissa a ferramenta foi desenvolvida utilizando
JavaScript acessando alguns recursos essenciais disponíveis em HTML5.
A linguagem JavaScript foi introduzida pela Netscape em 1995 com o objetivo de
permitir que os desenvolvedores criassem aplicações com interação com o usuário no
lado do cliente. Atualmente é a principal linguagem de programação no lado do cliente
em navegadores web, e segundo uma pesquisa realizada pela RedMonk [30], está se
tornando uma das linguagens mais populares na atualidade.
O DSL Encoder é executado no lado do cliente, não havendo necessidade de interação
com um servidor para usufruir de suas funcionalidades. Após o programa ser carregado
no navegador, sua execução é local.
O emergente padrão HTML5 veio para complementar algumas deficiências existentes
nos padrões HTML anteriores, trazendo várias novas funcionalidades, das quais
podemos destacar Offline Applications e Local Storage [31] como essenciais ao
desenvolvimento da ferramenta.
A funcionalidade Offline Applications permite que aplicações web sejam executadas
mesmo quando uma conexão de rede não está ativa. Depois que a ferramenta é
carregada pela primeira vez, o navegador só carrega novamente os arquivos que
sofreram atualizações. Além de habilitar o uso off-line, evita o carregamento de
arquivos estáticos toda vez que a ferramenta é acessada, tornando mais rápida a sua
inicialização.
O recurso Local Storage é o responsável pelo armazenamento das informações do
usuário. O Local Storage oferece um mecanismo de armazenamento local que se
comporta como um banco de dados de chave-valor, permitindo o armazenar localmente
dados textuais.
As tecnologias utilizadas para o desenvolvimento da ferramenta são nativas dos
navegadores que estão de acordo com as especificações do World Wide Web
Consortium (W3C) [31], não exigindo nenhum recurso adicional, atendendo assim a
premissa “web como plataforma”.
3.1.3. Sistema de Arquivos
Sistema de arquivos, do inglês “filesystem”, é um tipo de armazenamento de dados que
permite manipular uma coleção de arquivos. O sistema de arquivos é responsável por
executar as operações de localização, criação, atualização e exclusão de arquivos e
diretórios.
O DSL Encoder é uma ferramenta onde vários tipos de arquivo são criados pelos
usuários. Além disso, uma das funcionalidades da ferramenta, tratado no item 3.1.7 é a

11

geração de código, onde um ou mais arquivos podem ser gerados a partir de um
programa DSL.
Alguns tipos de arquivos são suportados por padrão pela ferramenta: arquivos com a
extensão “.dsl” representam linguagens específicas de domínio, arquivos com a
extensão “.tpl” representam os templates, arquivos com a extensão “.js” os plug-ins e os
arquivos com a extensão “.json” representam os programas DSL.
Arquivos que representam linguagens, templates e plug-ins ficam agrupados em
diretórios específicos para cada um deles dentro do diretório “core”, localizado na raiz
do sistema de arquivos. Ao criar um projeto na ferramenta, um diretório é criado dentro
do diretório “projects”, também localizado na raiz do sistema de arquivos. Cada projeto
possui pelo menos dois diretórios, “src” onde ficam localizados os programas DSL e
“gen” onde serão armazenados os arquivos gerados automaticamente pela aplicação.
Dessa forma, a presença de um sistema de arquivos é indispensável ao funcionamento
pleno da ferramenta. As políticas de segurança do navegador impedem que aplicações
web nativas tenham acesso ao sistema de arquivos do computador ou dispositivo que
está as executando. O padrão HTML5 proposto pela W3C [31] prevê uma API chamada
Filesystem, que dá acesso a um sistema de arquivos em uma sandbox. No entanto, esta
API não está implementada em todos os maiores navegadores web atuais, o que impede
sua utilização como sistema de arquivos da ferramenta.
Para atender essa premissa foi desenvolvida uma implementação de um sistema de
arquivos, que atende as necessidades da ferramenta, utilizando a funcionalidade
HTML5 Local Storage para a persistência dos dados.
O acesso a esse sistema de arquivos é feito através de uma API chamada
Dsle.FileStorage. Esta API abstrai o mecanismo de armazenamento e é um dos pontos
de extensão da ferramenta. No futuro, quando a API nativa HTML5 Filesystem estiver
implementada pelos maiores navegadores, o mecanismo de armazenamento poderá ser
substituído de forma transparente.
Após o carregamento da aplicação no navegador, esta pode ser executada sem a
necessidade de conexão com a internet, e como o sistema de arquivos é local, dentro da
estrutura de armazenamento de dados do navegador, tudo que o usuário necessita já está
em execução, dispensando chamadas ao servidor.
Para evitar a perda de dados, ou para que o usuário possa levar seus arquivos para outra
máquina e/ou outro navegador, duas funcionalidades de backup foram implantadas na
ferramenta: uma que compacta o sistema de arquivos em um arquivo zip e faz o
download, e outra onde o usuário faz o backup para uma conta de serviço de
armazenamento na nuvem. Atualmente a ferramenta está integrada ao serviço Dropbox,
mas outros serviços podem ser adicionados através de plug-ins.
3.1.4. Editor de Texto
O editor de texto é o principal componente de interação com o usuário da ferramenta,
nele são especificadas as DSLs, são codificados os programas DSL, são criados os
templates e plug-ins. Além disso, os arquivos gerados pelo processamento dos
programas DSL também pode ser modificado no editor de texto. “Apesar do interesse
crescente em interfaces icônicas e métodos de programação visual, o texto é
onipresente no ambiente de computador e sua importância não diminui”[32].
12

Algumas funcionalidades em um editor de texto são essenciais para tornar mais ágil a
escrita de código fonte. Entre as funcionalidades de um editor de texto de código fonte
podemos elencar:

Syntax highlighting: exibe o texto em cores diferentes de acordo com a sintaxe, e
possibilita ao usuário identificar visualmente erros de escrita, executando a
correção enquanto escreve;
Indentação Automática: faz com que o texto seja recuado automaticamente a
cada nova linha inserida, acompanhando a hierarquia do texto que está sendo
escrito. A indentação possibilita uma melhor compreensão do texto facilitando
sua modificação, correção ou otimização.
Live syntax checker: verifica a sintaxe do código fonte que está sendo escrito
baseado na linguagem do arquivo e faz críticas em tempo real caso algum
problema seja encontrado.

Essa funcionalidades possibilitam ao usuário antecipar-se aos erros de interpretação
e/ou compilação e aceleram o desenvolvimento. Para atender a essa premissa foi
adicionado a ferramenta o componente de código aberto Ace [33].
O Ace é um editor de código fonte escrito em JavaScript que poder ser incorporado a
outras aplicações. Ele possui as funcionalidades supra citadas e outras como localizar e
substituir, destaque de parênteses e chaves correspondentes, alterna entre soft tabs e real
tabs, exibe caracteres ocultos, múltiplos cursores de seleção e drag and drop de texto
com o mouse. Essas funcionalidades fazem com que seu comportamento e performance
seja semelhante ao de “editores nativos como Sublime, Vim e TextMate” [33] tornando a
experiência do usuário na ferramenta agradável, oferecendo recursos que aceleram o
desenvolvimento.
3.1.5. DSL Processor
Para tornar possível o desenvolvimento de DSL na ferramenta, foi desenvolvido um
componente escrito em JavaScript orientado a objeto, totalmente desacoplado. Este
componente foi chamado de DSL.JS[26] e liberado sob a licença de código aberto New
BSD.
As motivações para o código aberto foram tratadas no item 3.1.1. Criar um componente
para o desenvolvimento de DSL desacoplado, sem dependências e liberá-lo
individualmente aumenta ainda mais a possibilidade da sua evolução por codesenvolvedores, uma vez que o torna mais simples e permite que seja utilizado por
outras aplicações [29]. D’Souza e Will [34] definem componente como:
“Um pacote coerente de artefatos de software que podem ser
independentemente desenvolvidos e entregues como uma unidade e que
pode ser composto, sem modificação, com outros componentes para
construir algo maior”.
A motivação para transformar essa funcionalidade núcleo em um componente foi
habilitar o reuso. O DSL.JS é responsável por duas funcionalidades principais: Analisar
a especificação da DSL e Validar o programa DSL.

13

Analisar a especificação da DSL
O componente é responsável por analisar o arquivo no formato JSON que contém a
especificação da DSL, verificar se está bem formado e se contém todos os atributos
necessários à criação de uma DSL pela ferramenta. No arquivo de especificação de DSL
são informadas as propriedades que identificam a linguagem, os templates que serão
usados pela linguagem para processamento, os tipos que compõe essa linguagem
chamados de DslType e o tipo principal que corresponde a objeto descrito pela DSL.
Validar o programa DSL
O programa DSL também é escrito no formato JSON e possui duas propriedades
principais, uma que identifica qual DSL ele utiliza e outra que representa o objeto
descrito por essa linguagem. O componente verifica se o objeto está descrito de acordo
com as especificações. Analisa se os valores das propriedades estão de acordo com o
DslType definido e se todos os tipos obrigatórios estão presentes.
Ao encontrar qualquer inconsistência, seja na análise da linguagem, seja na validação do
programa DSL, o componente encerra o processamento e levanta uma exceção, que
deverá ser tratada pela aplicação, informando o que está errado. O DSL Encoder possui
um console tratado no item 3.1.8, nele são apresentados ao usuário todas as
inconsistências encontradas.
3.1.6. Template Engine
Um template engine é responsável por transformar templates em conteúdo, substituindo
as marcações contidas nos mesmos por dados variáveis. O objetivo principal da
ferramenta é a criação de linguagens específicas de domínio e de programas baseados
nessa linguagem. Uma das formas de “executar” os programas DSL é através da
utilização de template engines.
Para atender a essa premissa foram adicionados dois componentes template engine a
ferramenta: json-templates [35] e JavaScript Template [36].
Os templates suportados pelo engine json-templates possuem marcações mais simples e
legíveis por pessoas que não são necessariamente programadores. Suas marcações
simplificadas permitem fazer declarações de condição e repetição sem a necessidade de
um conhecimento mais aprofundado de programação.
A engine JavaScript Template permite inserir trechos de programação escritos em
JavaScript nas marcações do template e trás para o processamento todas as
funcionalidades da linguagem, no entanto, conhecimento em programação é necessário
para o desenvolvimentos de templates suportados por essa engine.
Os arquivos de template que serão utilizados para o processamento de um programa
DSL são definidos no arquivo JSON de especificação da linguagem. Cada linguagem
pode conter um ou mais arquivos de template em sua especificação e para cada arquivo
de template deve ser especificado a engine em que será processado.

14

3.1.7. Code Generator
Uma das motivações para utilização de DSLs é a geração de código, sendo uma recurso
fundamental para qualquer ferramenta de desenvolvimento de DSL. Esta funcionalidade
é atendida pela ferramenta utilizando os recursos template engines (tratado no item
3.1.6), DSL Processor (tratado no item 3.1.5) e sistema de arquivos (tratado no item
3.1.3).
Após a validação de um programa pelo DSL processor, um botão intitulado Generate é
habilitado, e ao ser acionado, o processo de geração de código é iniciado. A ferramenta
tenta localizar um arquivo de template especificado na linguagem DSL, e caso seja
encontrado, aplica o objeto descrito pelo programa DSL sobre o arquivo de template,
utilizando a engine especificada para este template. O resultado é um arquivo de texto,
que será gravado no diretório “gen” dentro do projeto ao qual o programa DSL
pertence.
Cada linguagem pode conter um ou mais arquivos de template, e para cada arquivo de
template, um arquivo de texto é gerado pela ferramenta. Na especificação dos arquivos
de template de uma linguagem, além de especificar qual engine irá realizar o
processamento, é possível especificar um prefixo, um sufixo e uma extensão para o
arquivo de texto gerado.
Kelly e Tolvanen [9] definem gerador de código como “um autômato que acessa
modelos, extrai informações a partir deles, e transforma-os em produção em uma
sintaxe específica”. Na ferramenta, o modelo é o objeto descrito pela DSL e a sintaxe
específica é definida pelo template. Herrington [2] destaca os seguintes benefícios
proporcionados por um gerador de código:


Qualidade: uma vez que a abordagem de geração de código baseado em
templates constrói código de fácil leitura e fácil detecção de erros, e que por
causa da natureza do gerador, os erros encontrados podem ser corrigidos no
template e então o código é gerado novamente, corrigindo os erros.
Consistência: gerando código que utiliza nomes de classes, métodos e
argumentos consistentes.
Produtividade: gerando código mais rápido que escrito a mão, principalmente
para atender as futuras necessidades de mudança, alterando apenas o código
base.
Abstração: uma vez que o projeto é especificado de forma abstrata, sem detalhes
de implementação, o código poderá ser gerado para uma ou mais plataformas de
tecnologia.

Segundo Herrington [2], “Geração de código é outro elo na cadeia evolutiva da
crescente abstração. Com ela, você vai produzir rapidamente código de maior
qualidade, e assim ser capaz de responder às necessidades de mudança com
facilidade”.
3.1.8. Console
Ao escrever código fonte, os desenvolvedores estão sujeitos a cometer erros de escrita.
Estes erros podem variar de erros de sintaxe à operações indevidas que não podem ser
executadas. Com isso, uma forma de acelerar a correção de erros é mostrar ao usuário o
que está errado e sugerir correções.
15

Para atender essa premissa, foi adicionado à ferramenta um console, onde os erros de
compilação podem ser exibidos, permitindo que os usuários corrijam os mesmos
rapidamente.
Na inicialização da ferramenta uma verificação é realizada nos arquivos de linguagem e
plug-ins. Caso sejam encontrados erros, o console apresenta o nome do arquivo e o erro
encontrado.
O processo de validação dos plug-ins é feito inicialmente pela própria engine JavaScript
do navegador, uma vez que estes são escritos na linguagem JavaScript nativa. O
resultado dessa validação é um objeto JavaScript instanciado que corresponde ao
próprio plug-in. A ferramenta então verifica se esse objeto está de acordo com as
diretivas de definição de plug-ins da ferramenta. Caso algum erro seja encontrado
também será informado no console, caso contrário, o método de inicialização do plug-in
é executado.
Para os arquivos de linguagens específicas de domínio e para os programas DSL, que
são escritos no formato JSON, o processo de validação é feito pelo DSL Processor,
descrito no item 3.1.5, e as exceções levantadas durante este processo são exibidas no
console.
No processo de geração de código o console é utilizado para informar também os
resultados de operações positivas, como por exemplo o nome dos arquivos gerados pela
operação e o conteúdo da transformação.
3.1.9. Hot-spots
A ferramenta DSL Encoder se propõe a ser um ambiente integrado de desenvolvimento
extensível e reutilizável, onde usuários possam estendê-la, não só pela alteração de seu
código fonte como também em tempo de execução através de plug-ins. Para isso, a
ferramenta foi projetada na forma de um framework orientado a objeto.
“Frameworks podem reduzir os custos de desenvolvimento de aplicações
uma vez que estes permitem projetistas e implementadores reutilizar suas
experiências na solução de problemas no nível de projeto e
codificação”[37].
Os hot-spots são as partes flexíveis de um framework, são os pontos extensíveis que os
desenvolvedores utilizam para adicionar o seu código e para especificar novas
funcionalidades. A ferramenta foi projetada de forma modularizada e permite que o
usuário estenda o seu funcionamento através de hot-spots bem definidos. Estes pontos
de extensão são tradados no item 3.2.2.
3.1.10. Plug-ins
A utilização de plug-ins dão suporte a extensibilidade, a customização e a evolução da
ferramenta. Adotar um sistema de plug-ins permite que a ferramenta seja estendida,
reconfigurada e adaptada em tempo de execução [38].
A adaptação em tempo de execução “tem recebido considerável atenção nas áreas de
pesquisa, tais como arquitetura de software, engenharia de linha de produto ou sistema
auto-adaptativos” [38] e é requisito necessário em ambientes de desenvolvimento como

16

computação móvel e ubíqua ou sistemas orientados a serviços “para lidar com as
mudanças de contexto” [38].
Uma abordagem de plug-in permite que os desenvolvedores criem aplicações
personalizadas para atender às suas necessidades individuais, onde pequenos aplicativos
se conectam ao núcleo da aplicação em forma de componentes para estender as suas
funcionalidades.
Para atender a premissa de extensibilidade e personalização em tempo de execução foi
adicionado a ferramenta um sistema de plug-ins. Os usuários podem criar seus próprios
plug-ins utilizando a ferramenta para codifica-los, podem instalar plug-ins de terceiros e
podem modificar plug-ins de terceiros para atender as suas necessidades.
Na ferramenta, um plug-in é um objeto JavaScript com algumas propriedades de
identificação (id, name, version, author e description) e pelo menos um método, que é o
de inicialização chamado load().
Na inicialização da ferramenta todos os arquivos de plug-ins são localizados nos
sistema de arquivos, os objetos são instanciados e o método de inicialização de cada um
deles é executados. Ao realizar alterações em um plug-in é necessário reiniciar a
aplicação para poder observar as mudanças. Caso ocorram erros de instanciação ou de
execução, estes serão apresentados no console, e caso estes erros prejudiquem o
funcionamento da ferramenta, a execução de plug-ins na inicialização pode ser suspensa
acrescentando o parâmetro #noplugins à URL de acesso. Um maior detalhamento de
como criar plug-ins será apresentado no item 4.
3.2. Arquitetura da Ferramenta
Esta seção descreve a arquitetura da ferramenta, seus principais componentes e as
interações entre eles. O item 3.2.1 mostra uma visão de alto nível da arquitetura da
ferramenta. O item 3.2.2 detalha os principais componentes da ferramenta que podem
ser utilizados como hot-spots (tratados no item 3.1.9). Por fim, o item 3.2.3. apresenta o
diagrama de sequência do processo de validação e geração de código realizada pela
ferramenta.
3.2.1 Diagrama de Apresentação
A Figura 4 mostra o diagrama de apresentação da arquitetura da ferramenta, após o seu
carregamento no navegador, esta passa a funcionar localmente, sem a necessidade de
novas requisições ao servidor. Através de requisições JSONP a ferramenta pode se
comunicar diretamente com API de terceiros, sem a necessidade de comunicar-se com o
servidor de aplicação, os recursos que possibilitam o funcionamento local da ferramenta
foram tratados no item 3.1.2.

17

Clientes

Servidor de Aplicação
DSL Encoder

Internet

Servidor de API
de Terceiros

Servidor de API
de Terceiros
Comunicação com a Ferramenta
Comunicação com API de terceiros

Figura 4. Diagrama de Apresentação

3.2.1. Componentes
A ferramenta possui um componente principal chamado ide que funciona como um
framework e é composto por outros componentes independentes, sendo cada um deles
um hot-spot da ferramenta, podendo ser reutilizados, na criação de plug-ins ou na
alteração do código do fonte, por usuários que desejam estender a ferramenta para
atender a sua necessidade. “Um dos principais objetivos da engenharia de software é o
reuso” [1] e uma arquitetura baseada em framework habilita o reuso, diminui os
esforços de desenvolvimento e aumentam a qualidade do software. Os principais
componentes do framework são:

ide.console: fornece ao usuário controle sobre o console da ferramenta. Permite
limpar ou adicionar mensagens de log, informação, alerta, erro e sucesso.
ide.dialog: permite ao usuário iniciar caixas de diálogo na ferramenta, por tipo
(alerta, informação, erro ou questionamento) atribuindo ações para os casos de
sucesso ou cancelamento. Além disso permite a inicialização de caixa de diálogo
de entrada de dados, janelas e barras de progresso.
ide.extensions: fornece acesso ao gerenciador de extensões e permite o usuário
fazer o download, instalar e desinstalar linguagens, templates e plug-ins
desenvolvido por terceiros.
ide.fileStorage: fornece uma interface para um implementação de um sistema
de arquivos que será utilizado pela ferramenta. Como visto no item 3.1.3, por
padrão uma implementação desta interface é realizada utilizando o recurso Local
18



Storage do HTML5. Porém outras implementações podem ser realizadas
inclusive em tempo de execução através de plug-ins.
ide.fileTypes: fornece acesso ao registro dos tipos de arquivos da ferramenta. O
usuário pode registrar novos tipos de arquivo ou alterar tipos de arquivos
existentes. Para cada tipo de arquivo é possível definir um método para
validação do arquivo e a linguagem em que o arquivo é escrito para que o editor
de texto (tratado no item 3.14) habilite os recursos syntax highlighter e live
syntax checker.
ide.languages, ide.templates, ide.plugins: fornece acesso ao registro de
linguagens, templates e plug-ins respectivamente. Permite ao usuário localizar,
obter, validar, atualizar, adicionar e remover linguagens, templates e plug-ins
dentro da ferramenta.
ide.tabbar: permite o usuário manipular a área central da interface gráfica da
ferramenta adicionando abas que podem ter conteúdo HTML/JavaScript que
interage com a ferramenta ou abrir um site da web em um iframe dentro da
ferramenta. Além de adicionar novas abas o usuário pode ter acesso as abas que
são adicionadas pela ferramenta, como por exemplo edição de arquivo.
ide.toolbar: permite o usuário manipular a barra de ferramentas, adicionando
botões, e itens de menu, informando o método que será acionado com o evento
de clique. Geralmente utilizado na inicialização de plug-ins criando um botão
que executa a funcionalidade principal dos mesmos.
ide.tree: permite o usuário manipular o componente visual que representa a
árvore de arquivos e diretórios do sistema de arquivos da ferramenta.
ide.ajax: permite o usuário realizar requisições assíncronas utilizando métodos
GET e POST, e consumir API de terceiros utilizando JSONP.
ide.dsl: fornece uma interface para o DSL Processor. Foi utilizado o
componente DSL.JS como implementação desta interface.

A Figura 5 mostra o diagrama de componentes do framework.

Figura 5. Diagrama de Componentes

19

3.2.3. Processo de Validação e Geração de Código
O processo de validação e geração de código (Figura 6) é iniciado com o envio do
programa DSL para o DSL Processor (item 3.1.5). O DSL Processor verifica se o
arquivo é um JSON bem formado, e busca a propriedade “language”, localizado no
início do arquivo, para identificar o DSL em que ele se baseia, ao identificar, tenta
encontrar o arquivo da linguagem específica de domínio no seu sistema de arquivos
“/core/languages/{nome_da_linguagem}.dsl”.
Caso esta seja encontrada, o DSL Processor irá validar a própria linguagem, verificando
se o arquivo é um JSON bem formado e se este arquivo contém todos os requisitos para
descrever uma linguagem específica de domínio, verificará também se o programa DSL
enviado está de acordo com essa descrição e se o objeto na propriedade “main” do
arquivo está de acordo com as especificações da DSL.
A ferramenta tentará localizar no sistema de arquivos os templates informados na
especificação da linguagem e os engines de transformação. Se estes forem encontrados,
a ferramenta irá executá-los e os arquivos gerados serão salvos no diretório
“/projects/{nome_do_projeto}/gen/”.

IDE!

Sistema de
Arquivos!

DSL Processor!

Gerar!

Obter Linguagem!

org.dsle.Math.json!
Linguagem!

Obter Templates!

Templates!

Salvar Arquivos Gerados!

Arquivos Gerados!

Figura 6. Diagrama de Sequência – Validação e Geração de Código

20

4. Uso da Ferramenta
4.1. Especificando uma DSL com JSON
Os arquivos que representam DSL são escritos no formato JSON. Um arquivo JSON
que representa uma DSL deve conter as propriedades descritas na Tabela 2.
Tabela 2. Propriedades JSON para Linguagem Específica de Domínio
Propriedade

Tipo

Descrição

id

string

Um identificador único da linguagem.
Uma boa prática é usar um namespace
como Java Packages para identificar a
linguagem (Ex: “org.dsle.Math”).

name

string

O nome da linguagem (Ex: “Math”)

description

string

A descrição da linguagem.

templates

Array
<DslTemplateOptions>

Um ou mais templates que a
linguagem irá utilizar para transformar
os programas DSL, cada um com suas
opções de engine e nomenclatura dos
arquivos gerados.

types

Array <DslType>

Os tipos DslType que serão cobertos
pela linguagem.

main

DslType

O objeto
linguagem.

principal

DslType

da

A propriedade “templates” deve conter um array de objetos DslTemplateOptions, estas
propriedades são descritas na Tabela 3. A propriedade “types” deve conter um array de
objetos DslType, estas propriedades são descritas na Tabela 4.
Tabela 3. Propriedades JSON para DslTemplateOptions
Propriedade

Tipo

Descrição

id

string

Um identificador único do template. Uma
boa prática é usar um namespace como
Java Packages para identificar a
linguagem (Ex: “org.dsle.Math”).

file

string

O nome do arquivo do template localizado
em
“/core/templates/”
(Ex:
“org.dsle.Math.tpl”).

prefix

string

Prefixo que será adicionado ao nome do
arquivo do programa DSL para compor o
nome
do
arquivo
gerado
(Ex:
“android.auto.”).

suffix

string

Sufixo que será adicionado ao nome do
arquivo do programa DSL para compor o
nome do arquivo gerado (Ex: “.v1_00”).

extension

string

Extensão do arquivo gerado (Ex: “xml”).

engine

string

Nome da engine que será utilizada para
processar o template. As duas engines
padrão são “JSON” e “JAVASCRIPT”.

21

Tabela 4. Propriedades JSON para DslType
Propriedade

Tipo

Descrição

name

string

O nome do tipo que poderá ser usado na
linguagem (Ex: “number1”).

primitiveType

string

O tipo primitivo do DslType. Deve ser
“OBJECT”, “STRING”, “BOOLEAN”,
“NUMERIC” ou “ARRAY”.

required

boolean

Deve ser “true” se o tipo for obrigatório
na linguagem.

items

Array
<DslTypeItem>

Se o tipo primitivo do DslType é
OBJECT, então deve ser especificado um
array de itens (DslTypeItem) que compõe
este objeto.

Se o tipo primitivo do DslType for “OBJECT”, significa que este tipo é formado por um
ou mais DslTypes. Para especificar este objeto é necessário preencher a propriedade
“items” com um array de DslTypeItem, as propriedades do objeto DslTypeItem são
descritas na Tabela 5.
Tabela 5. Propriedades JSON para DslTypeItem
Propriedade

Tipo

Descrição

type

string

O nome do DslType. (Ex: “number1”).

required

boolean

Deve ser “true” se este DslType é
obrigatório no objeto.

4.2. Criando uma linguagem específica de domínio
Para iniciar a ferramenta o usuário deve acessar o endereço http://www.dsle.org. Ao
acessar este endereço em um navegador web compatível com as especificações de
suporte HTML5 do W3C, a ferramenta é carregada para o computador do usuário,
podendo ser utilizada de imediato. A Figura 7 mostra a tela inicial da ferramenta.

Figura 7. Tela inicial da ferramenta

22

Um novo projeto deve ser criado para que o uso da ferramenta possa ser iniciado. O
usuário deve clicar no botão “New Project” na barra de tarefas e digitar um nome para o
projeto na caixa de diálogo conforme a Figura 8.

Figura 8. Novo Projeto

Uma vez que o projeto está criado, ele aparecerá no painel esquerdo, chamado “Project
Explorer” (Figura 9). O usuário deve clicar no botão “New File” na barra de
ferramentas para criar um novo arquivo, no projeto selecionado ou no núcleo da
ferramenta.

Figura 9. Project Explorer

A janela “New File” (Figura 10) permite que o usuário escolha o tipo de arquivo que
está tentando criar. Ele poderá criar um novo programa DSL para o seu projeto atual ou
estender a ferramenta criando novas linguagens, templates e plug-ins.
Para criar uma nova linguagem, o usuário deve selecionar o tipo “Domain-Specific
Language” e digitar um nome para o arquivo. A extensão “.dsl” será adicionada
automaticamente, e o arquivo será salvo no diretório “/core/languages/”. Como
exemplo, será utilizado o nome de arquivo “org.dsle.Math”.

23

Figura 10. New File

Ao clicar no botão “Ok” uma nova aba será aberta para edição do arquivo
“org.dsle.Math.dsl”. O código a seguir deverá ser adicionado ao arquivo. Ao salvar o
arquivo “org.dsle.Math.dsl”, este representará uma nova linguagem no sistema,
identificado pela propriedade “id” do objeto JavaScript contido no arquivo.
{
"id": "org.dsle.Math",
"description": "",
"name": "Math",
"templates": [{
"id": "org.dsle.Math",
"file": "org.dsle.Math.tpl",
"prefix": "",
"suffix": "",
"extension": "html",
"engine": "JAVASCRIPT"
}],
"types": [{
"name":"name",
"primitiveType": "STRING",
"required": true
},{
"name":"number1",
"primitiveType": "NUMERIC",
"required": true
},{
"name":"number2",
"primitiveType": "NUMERIC",
"required": true
},{
"name":"operator",
"primitiveType": "STRING",
"required": true
},{
"name":"math",
"primitiveType": "OBJECT",
"items":[
{
"type": "name",
"required": true
},
{
"type": "number1",
"required": true
},
{
"type": "operator",
"required": true
},
{
"type": "number2",
"required": true
}
]
}],
"main":"math"
}

24

4.3. Criando um template
Para criar um template o usuário deverá clicar no botão “New File” na barra de tarefas e
selecionar o tipo de arquivos template, e digitar um nome para o arquivo (Ex:
“org.dsle.Math”). A extensão “.tpl” será adicionada automaticamente, e ao clicar em
“Ok” arquivo será salvo no diretório “/core/templates”.
O engine de processamento definido na linguagem, para este template, no item 4.2 foi
“JAVASCRIPT” [36], e este aceita código de programação JavaScript entre as tags {%
%}. O objeto “o” no template é o objeto principal descrito pela DSL, e a tag {%= %}
imprime o valor da variável para o conteúdo do template.
O seguinte código deverá ser adicionado e salvo no arquivo:
{%

%}

var result;
switch (o.operator) {
case '+':
result = o.number1 +
break;
case '-':
result = o.number1 break;
case '*':
result = o.number1 *
break;
case '/':
result = o.number1 /
break;
default:
result = 'invalid';
}

o.number2;
o.number2;
o.number2;
o.number2;

<html>
{% if (result == 'invalid')

{ %}

<p style="color: red;">
Operator '{%=o.operator%}' is invalid.
</p>
{% } else { %}
<p style="color: blue;">
{%=o.number1%} {%=o.operator%} {%=o.number2%} = {%=result%}
</p>
{% } %}
</html>

4.3. Criando um plug-in
Para criar um plug-in o usuário deverá clicar no botão “New File” na barra de tarefas e
selecionar o tipo de arquivos plug-in, e digitar um nome para o arquivo (Ex:
“org.dsle.HelloWorld”). A extensão “.js” será adicionada automaticamente, e ao clicar
em “Ok” arquivo será salvo no diretório “/core/plugins”.
Um plug-in é um arquivo que descreve um objeto JavaScript com algumas propriedades
obrigatórias (id, name, version, author, description) e um método obrigatório chamado
load(). Quando a ferramenta é inicializada, todos os objetos JavaScript que representam
plug-ins (contidos no diretório “/core/plugins”) são instanciados e o método load() de
cada um deles é executado, permitindo modificar, adaptar e/ou configurar a ferramenta
em tempo de execução.
25

O seguinte código deverá ser adicionado e salvo no arquivo:
{

}

id: " org.dsle.HelloWorld",
name: "Hello World Plug-in",
version: 0.01,
author: "You",
description: "Prints Hello World in Console.",
load: function () {
ide.console.info('Hello World', 'Another Text.');
}

Este plug-in apenas imprime a mensagem “Hello World” no console da ferramenta.
4.4. Criando um programa DSL
Para criar um novo programa DSL que utiliza a linguagem específica de domínio recém
criada no item 4.2 e o template criado no item 4.3. O usuário deve clicar em “New File”
e selecionar o tipo de arquivo “DSL Script”, e digitar um nome para o arquivo (Ex:
“org.dsle.Math”). A extensão “.json” será adicionada automaticamente, e ao clicar em
“Ok” o arquivo será salvo no diretório “src” dentro do diretório do projeto “/projects/
{nome_projeto}/src/”. O seguinte código deverá ser adicionado e salvo no arquivo:
{
"language":"org.dsle.Math",
"main": {
"name": "Sum",
"number1": 10,
"operator": "*",
"number2": 3
}
}

Os programas DSL são escritos no formato JSON. A propriedade “language” informa a
linguagem específica de domínio em que o programa se baseia e a propriedade “main” é
o objeto descrito pela linguagem.
Ao clicar no botão “Validate” a ferramenta verificará se o arquivo é um JSON bem
formado, tentará localizar a linguagem especificada na propriedade “language” no
sistema de arquivos e ao encontrar irá verificar se o programa DSL está de acordo com
as especificações da linguagem, e caso todos as etapas sejam concluídas com sucesso
uma mensagem de sucesso será mostrada no console da ferramenta como na Figura 11.

Figura 11. Console: Validação Completa

26

Caso haja algum problema nas etapas de validação, como por exemplo se o valor da
propriedade “number2” for trocado de um valor numérico para um valor booleano (ex:
“true”) uma mensagem de erro será exibida no console informando o que deve ser
corrigido como na Figura 12.

Figura 12. Console: Erro de Validação

4.5. Gerando código
Uma vez que o programa DSL é validado, o botão “Generate” na barra de tarefas é
habilitado, tornando possível o processamento dos templates que irá transformar o
objeto descrito pelo programa em conteúdo. Ao clicar no botão “Generate” os arquivos
gerados serão salvos no diretório “gen” dentro do diretório do projeto
“/projects/{nome_projeto}/gen/”. A Figura 13 mostra as mensagens das etapas de
validação e geração de código apresentadas no console.

Figura 13. Console: Geração de Código

Como observado na Figura 13, o nome do arquivo gerado é “org.dsle.Math.json.html” e
seu conteúdo é o resultado do processamento do objeto descrito no programa DSL
criado no item 4.4 e do template criado no item 4.3. O código gerado é o seguinte:
<html>
<p style="color: blue;">
10 * 3 = 30
</p>
</html>

27

5. Estudo de Caso
A fim de destacar o possível ganho de produtividade com a utilização da ferramenta, foi
realizado um estudo de caso em uma empresa que trabalha com o desenvolvimento de
aplicações móveis. Para este estudo de caso, foi escolhido o domínio específico de
“campos de formulários em interfaces do usuário”.
A equipe de front-ends da empresa trabalha com o framework jQuery Mobile [39] para
aplicações web móveis, e com Appcelerator Titanium [40] para o desenvolvimento de
aplicações móveis nativas para as plataformas iOS e Android.
No primeiro momento foi realizada uma análise do domínio para identificar quais
campos de formulário são mais utilizados pela empresa e são comuns a todos os
frameworks, e posteriormente foi identificado qual elemento representa cada um destes
campos. A Tabela 6 mostra o resultado desta análise.
Tabela 6. Campos de Formulário - Mapeamento entre Frameworks
Campos

jQuery Mobile

Appcelerator Titanium

Window

<div data-role="page"/>

Titanium.UI.Window

Form

<form/>

Titanium.UI.View

Label

<label/>

Titanium,UI,Label

Textfield

<input type=”text”/>

Titanium.UI.TextField

Textarea

<textarea/>

Titanium.UI.TextArea

Select

<select/>

Titanium.UI.Picker

Select Option

<option/>

Titanium.UI.PickerRow

Radio Group

<fieldset datarole="controlgroup"/>
<input type="radio"/>

Titanium.UI.Picker
Titanium.UI.PickerRow

Radio Button
Check Box

<input type="checkbox"/>

Titanium.UI.Switch

Slider

<input type="range"/>

Titanium.UI.Slider

Button

<input type="button"/>

Titanium.UI.Button

Posteriormente foram levantadas as propriedades mais utilizadas pela empresa para
formatar cada um destes campos de formulário. Após esse levantamento, foi
identificado em cada um dos frameworks as propriedades comuns para cada um desses
campos de formulário. A Tabela 7 apresenta as propriedades que são comuns a todos os
campos de formulário.

28

Tabela 7. Campos de Formulário - Propriedades Comuns
Propriedade

jQuery Mobile

Appcelerator Titanium

Background color

style="background-color:;"

backgroundColor

Background image

style="background-image:;"

backgroundImage

Background repeat

style="backgroundrepeat:;"

backgroundRepeat

Border color

style="border-color:;"

borderColor

Border radius

style="border-radius:;"

borderRadius

Border width

style="border-width:;"

borderWidth

Enabled

disabled=""

enabled

Font family

style="font-family:;"

Font.fontFamily

Font size

style="font-size:;"

Font.fontSize

Font style

style="font-style:;"

Font.fontStyle

Font weight

style="font-weight:;"

Font.fontWeight

Height

style="height:;"

height

Id

id=""

-

Margin bottom

style="margin-bottom:;"

bottom

Margin left

style="margin-left:;"

left

Margin right

style="margin-right:;"

right

Margin top

style="margin-top:;"

top

Opacity

style="opacity:;"

opacity

Text align

style="text-align:;"

textAlign

Text color

style="color:;"

color

Visible

style="display:;"

visible

Width

style="width:;"

width

Cada um dos elementos de formulário possuem propriedades adicionais. A Tabela 8
apresenta as propriedades adicionais para o elemento “label”. A Tabela 9 para o
elemento “textfield”. A Tabela 10 para o elemento “textarea”. A Tabela 11 para o
elemento “select”. A Tabela 12 para o elemento “selectOption”. A Tabela 13 para o
elemento “radioGroup”. A Tabela 14 o elemento “radioButton”. A Tabela 15 apresenta
para o elemento “checkbox”. A Tabela 16 para o elemento “slider”. Por fim, a Tabela
17 apresenta as propriedades adicionais para o elemento “button”.
Tabela 8. Label - Propriedades Adicionais
Propriedade

jQuery Mobile

Appcelerator Titanium

Text

<label>{text}</label>

text

29

Tabela 9. Textfield - Propriedades Adicionais
Propriedade

jQuery Mobile

Appcelerator Titanium

Editable

readonly="

editable

Hint text

placeholder=""

hintText

Max length

maxlength=""

maxLength

Password

type="password"

passwordMask

Value

value=""

value

Tabela 10. Textarea - Propriedades Adicionais
Propriedade

jQuery Mobile

Appcelerator Titanium

Editable

readonly="

editable

Hint text

placeholder=""

hintText

Max length

maxlength=""

maxLength

Value

<textarea>{value}</textarea>

value

Tabela 11. Select - Propriedades Adicionais
Propriedade

jQuery Mobile

Appcelerator Titanium

Value

-

value

Tabela 12. Select Option - Propriedades Adicionais
jQuery Mobile

Appcelerator
Titanium

Text

<option>{text}</option>

title

Selected

selected=""

-

Value

value="

-

Propriedade

Tabela 13. Radio Group - Propriedades Adicionais
Propriedade

jQuery Mobile

Appcelerator Titanium

Value

-

value

30

Tabela 14. Radio Button - Propriedades Adicionais
Propriedade

jQuery Mobile

Appcelerator Titanium

Checked

checked=""

-

Text

-

title

Value

value=""

-

Tabela 15. Checkbox - Propriedades Adicionais
Propriedade

jQuery Mobile

Appcelerator Titanium

Text

-

title

Value

value=""

value

Tabela 16. Slider - Propriedades Adicionais
jQuery Mobile

Appcelerator Titanium

Min

min=""

min

Max

max=""

max

Value

value=""

value

Propriedade

Tabela 17. Button - Propriedades Adicionais
Propriedade
Text

jQuery Mobile

Appcelerator Titanium

value=""

title

Após essa análise foi criada uma linguagem específica de domínio utilizando os jargões
utilizados pelos front-ends, abstraindo as implementações de cada um dos frameworks.
A linguagem recebeu o nome de “FormUI” e o id “org.dsle.FormUI”. Os DslTypes
criados para a esta linguagem são apresentados na Tabela 18.

31

Tabela 18. DslTypes

DslType

PrimitiveType

DslType

PrimitiveType

align

STRING

password

BOOLEAN

background

OBJECT

radioGroup

OBJECT

border

OBJECT

radioOptions

ARRAY

bottom

STRING

radius

STRING

button

OBJECT

readOnly

BOOLEAN

checkbox

OBJECT

repeat

STRING

checked

BOOLEAN

right

STRING

color

STRING

select

OBJECT

enabled

BOOLEAN

selected

BOOLEAN

family

STRING

selectOptions

ARRAY

font

OBJECT

size

STRING

form

OBJECT

slider

OBJECT

formFields

ARRAY

style

STRING

height

STRING

text

STRING

hint

STRING

textarea

OBJECT

id

STRING

textfield

OBJECT

image

STRING

title

STRING

label

OBJECT

top

STRING

left

STRING

value

STRING

max

NUMERIC

visible

BOOLEAN

maxLength

NUMERIC

weight

STRING

min

NUMERIC

width

STRING

opacity

STRING

window

OBJECT

option

OBJECT

32

Para cada DslType do tipo primitivo “OBJECT” criado, foi necessário especificar quais
DslTypeItems compõe o mesmo. O trecho de código abaixo faz parte do arquivo de
definição da DSL “org.dsle.FormUI.dsl” e mostra como exemplo a definição do tipo
“formfield” dos qual os demais tipos são estendidos. O arquivo completo de definição
da DSL pode ser observado no Anexo I.
{
"name": "formfield",
"primitiveType": "OBJECT",
"items": [{
"type": "align",
"required": false
}, {
"type": "background",
"required": false
}, {
"type": "border",
"required": false
}, {
"type": "bottom",
"required": false
}, {
"type": "color",
"required": false
}, {
"type": "enabled",
"required": false
}, {
"type": "font",
"required": false
}, {
"type": "height",
"required": false
}, {
"type": "id",
"required": true
}, {
"type": "left",
"required": false
}, {
"type": "opacity",
"required": false
}, {
"type": "readOnly",
"required": false
}, {
"type": "right",
"required": false
}, {
"type": "size",
"required": false
}, {
"type": "style",
"required": false
}, {
"type": "top",
"required": false
}, {
"type": "visible",
"required": false
}, {
"type": "weight",
"required": false
}, {
"type": "width",
"required": false
}]
}

O objeto “main” da linguagem específica de domínio “FormUI” é o DslType “form”
que tem como propriedade um identificador (propriedade “id”), um título (propriedade
“title”) e um array de campos (propriedade “formFields”).
32

Depois da criação da DSL, foram criados dois templates para geração de código, um
que gera um arquivo de marcação HTML, para o framework jQuery Mobile e outro que
gera um arquivo JavaScript, para ser utilizado no Appcelerator Titanium. Esses
templates podem visualizados no Anexo II.
De maneira a auxiliar a geração de código pelos templates foram desenvolvidos dois
plug-ins, um que transforma os objetos (DSLType) em notações HTML, sendo chamado
diretamente do template para jQuery Mobile, e outro que transforma os objetos
(DSLType) em notações JavaScript, sendo chamado diretamente do template para
Appcelerator Titanium. Esses plug-ins podem visualizados no Anexo III.
Para testar o ganho de produtividade, foi solicitado a um desenvolvedor front-end,
apenas familiarizado com marcações HTML, que utilizasse a ferramenta para escrever
um programa DSL que descrevesse um formulário de criação de conta em um serviço,
seguindo as diretrizes da DSL especificada. Foram passados ao desenvolvedor front-end
os campos necessários e os atributos de cada um deles, definidos pelo designer de
interfaces. O programa DSL foi nomeado “create_account.json” e continha o seguinte
código:

{
"language":"org.dsle.FormUI",
"main": {
"id":"winCreateAccount",
"title": "Create Account",
"form": {
"id": "frmCreateAccount",
"formItems": [{
"type":"label",
"id": "lblEmail",
"text":"E-mail:",
"for": "email"
},{
"type":"textfield",
"id":"email",
"hint": "enter your e-mail"
},{
"type":"label",
"id": "lblPassword",
"text":"Password:",
"for": "password"
},{
"type":"textfield",
"id":"password",
"hint": "enter your password",
"password": true
},{
"type":"checkbox",
"id":"accept",
"text": "I accept this terms.",
"checked": false
},{
"type":"button",
"id":"btCreateAccount",
"text": "create account"
}
]
}
}
}

Ao clicar no botão “Generate” da ferramenta, foram gerados dois arquivos:
“create_account.html”, contendo o arquivo HTML para o framework jQuery Mobile e
“titanium_create_account.js”, contendo código JavaScript para criação do formulário
33

utilizando Appcelerator Titanium. A Figura 14 mostra o resultado final dos formulários
gerados pela execução da DSL. O código gerado pode ser observado no Anexo IV.

Figura 14. Formulário de Criação de Conta

Posteriormente foi solicitado ao próprio designer, que olhando o programa DSL
original, incluísse um campo para o usuário digitar seu nome completo. O código
abaixo foi adicionado e o resultado pode ser observado na Figura 15.

{

},{

"type":"label",
"id": "lblFullname",
"text":"Full Name:",
"for": "fullname"
"type":"textfield",
"id":"fullname",
"hint": "enter your full name"

}

34

Figura 15. Formulário de Criação de Conta Alterado

Devido a limitações relacionadas ao prazo de realização do experimento, ficou fora do
escopo deste projeto a realização de um experimento formal, a ser executado como
trabalho futuro, com um planejamento de coleta de métricas, avaliações de tempo e
curva de aprendizado e com ambiente configurado para a realização do mesmo.
Sobretudo, foi possível observar a utilidade da DSL criada uma vez que o
desenvolvedor front-end precisou escrever uma única vez, usando menos linhas de
código, e produzindo código fonte para mais de uma plataforma ao mesmo tempo,
mesmo não tendo conhecimento em uma delas. Além disso, aumentar a abstração
permitiu que outra pessoa, que não conhecia detalhes de implementação em nenhuma
das plataformas, mas que era conhecedora do domínio, realizasse modificações no
programa DSL sem nenhuma dificuldade e consequentemente nos códigos fontes
gerados.

6. Considerações finais e trabalhos futuros
Adotar uma abordagem DSL pode trazer ganhos reais de produtividade por habilitar a
geração de código e o reuso. Aumentar o nível de abstração para o idioma do domínio
de aplicação possibilita que usuários com conhecimento do domínio mas sem
conhecimento em programação possam escrever programas DSL, por adotar uma
linguagem mais direta e intuitiva. O processo de desenvolvimento de uma linguagem
específica é custoso, no entanto, este processo pode ser acelerado e ter seus custos
reduzidos com a utilização de ferramentas especializadas, que podem variar de um
simples interpretador a um ambiente integrado de desenvolvimento [3][4].
Sobretudo, existem poucas ferramentas para o desenvolvimento e implementação de
linguagens específicas de domínio, quando comparadas as ferramentas para linguagens
de programação de propósito geral. Estas ferramentas geralmente possuem
35

dependências a nível de sistemas operacionais e precisam ser instaladas para que
possam ser executadas.
Este artigo apresentou a ferramenta DSL Encoder, um ambiente integrado de
desenvolvimento de linguagens específicas de domínio que tem a “web como
plataforma”[5], de código aberto, que pode ser estendido e aperfeiçoado por seus
usuários em tempo de execução através da colaboração no desenvolvimento de novas
DSLs, templates, plug-ins e através da integração com outros serviços da web [18].
O objetivo do DSL Encoder é facilitar o acesso a este tipo de ferramenta, possibilitando
que usuários conectados a internet, possam por em prática os conceitos de geração de
código e reuso de software sem a necessidade de instalar nenhum software adicional
além do navegador.
Como trabalhos futuros ficam as seguintes atividades: Realizar um experimento formal
do uso da ferramenta; Realizar um estudo comparativo com outras ferramentas de
desenvolvimento de DSL; Criação de plug-ins que implementem o sistema de arquivos
da ferramenta utilizando APIs de serviços de cloud storage como Dropbox [41],
SugarSync [42], Google Drive [43], entre outros, possibilitando o armazenamento dos
arquivos diretamente na nuvem; e a Criação de plug-ins que implementem
versionamento de código utilizando APIs de serviços de repositório de código fonte
como o GitHub [44].

7. Referências
[1] Barreto, C. G. (2006). Agregando Frameworks de Infra-Estrutura em uma
Arquitetura Baseada em Componentes: Um Estudo de Caso no Ambiente
AulaNet. Rio de Janeiro.
[2] Herrington, Jack (2003). Code-Generation Techniques for Java. Online
http://www.onjava.com/pub/a/onjava/2003/09/03/generation.html.
[3] Van Deursen, A., Klint, P., & Visser, J. (2000). Domain-specific languages: an
annotated bibliography. ACM Sigplan Notices, 35(6), 26-36.
[4] Mernik, M., Heering, J., & Sloane, A. M. (2005). When and how to develop
domain-specific languages. ACM computing surveys (CSUR), 37(4), 316-344.
[5] Oreilly, T. (2007). What is Web 2.0: Design patterns and business models for
the next generation of software. Communications & strategies, (1), 17.
[6] Taivalsaari, A., & Mikkonen, T. (2011, August). The web as an application
platform: The saga continues. In Software Engineering and Advanced
Applications (SEAA), 2011 37th EUROMICRO Conference on (pp. 170-174).
IEEE.
[7] Meira, S. R., Buregio, V. A., Nascimento, L. M., Figueiredo, E., Neto, M.,
Encarnação, B., & Garcia, V. C. (2011, July). The Emerging Web of Social
Machines. In Computer Software and Applications Conference (COMPSAC),
2011 IEEE 35th Annual (pp. 26-27). IEEE.

36

[8] Yu, S., & Woodard, C. J. (2009, January). Innovation in the programmable web:
Characterizing the mashup ecosystem. In Service-Oriented Computing–ICSOC
2008 Workshops (pp. 136-147). Springer Berlin Heidelberg.
[9] Kelly, S., & Tolvanen, J. P. (2008). Domain-specific modeling: enabling full
code generation. Wiley-IEEE Computer Society Press.
[10] Ross, D. T. (1978, June). Origins of the APT language for automatically
programmed tools. In History of programming languages I (pp. 279-338). ACM.
[11] Knuth, D. E. (1964). Backus normal form vs. backus naur form.
Communications of the ACM, 7(12), 735-736.
[12] Fowler, M. (2010). Domain-specific languages. Addison-Wesley Professional.
[13] Bray, T., Paoli, J., Sperberg-McQueen, C. M., Maler, E., & Yergeau, F. (1997).
Extensible markup language (XML). World Wide Web Journal, 2(4), 27-66.
[14] JavaScript Object Notation – JSON. Online http://www.json.org/.
[15] Ben-Kiki, O., Evans, C., & Ingerson, B. (2001). YAML Ain't Markup
Language (YAML™) Version 1.1. Working Draft 2008-05, 11.
[16] Fowler, M. (2005). A language workbench in action-MPS. Online
http://martinfowler.com/articles/mpsAgree.html.
[17] Maximilien, E. M., Ranabahu, A., & Gomadam, K. (2008). An online platform
for web apis and service mashups. Internet Computing, IEEE, 12(5), 32-43.
[18] Duvander, Adam (2012). 8,000 APIs: Rise of the Enterprise. Online
http://blog.programmableweb.com/2012/11/26/8000-apis-rise-of-the-enterprise/.
[19] Duvander, Adam (2012). The New API: Apps, Partners, Income. Online
http://blog.programmableweb.com/2012/06/13/the-new-api-apps-partnersincome.
[20] Fielding, R. (2000). Representational state transfer. Architectural Styles and the
Design of Netowork-based Software Architecture, 76-85.
[21] Duvander, Adam (2011). 1 in 5 APIs Say “Bye XML”. Online
http://blog.programmableweb.com/2011/05/25/1-in-5-apis-say-bye-xml/.
[22] Duvander, Adam (2012). 5,000 APIs: Facebook, Google and Twitter Are
Changing the Web. Online http://blog.programmableweb.com/2012/02/06/5000apis-facebook-google-and-twitter-are-changing-the-web/.
[23] Programmable
Web.
API
http://www.programmableweb.com/apis/.

Dashboard.

Online

[24] Duvander, Adam (2012). 6,000 APIs: It’s Business, It’s Social and It’s
Happening
Quickly.
Online
http://blog.programmableweb.com/2012/05/22/6000-apis-its-business-its-socialand-its-happening-quickly.
[25] Brandon, Lorinda (2013). APIs as a Competitive Advantage. Disponível em
http://blog.programmableweb.com/2013/01/09/apis-as-a-competitiveadvantage/.
37

[26] Maia,
Bruno.
DSL
JavaScript
https://github.com/brunoleaomaia/dsl.js.

Framework.

Online

[27] Raymond, E. (1999). The cathedral and the bazaar. Knowledge, Technology &
Policy, 12(3), 23-49.
[28] The BSD 2-Clause License. Online http://opensource.org/licenses/BSD-2Clause/.
[29] O’Reilly, Tim (1999). Lessons From Open-Source Software Development.
Communications of the ACM, 42(4), 32-37.
[30] The RedMonk (2012). Programming Language Rankings.
http://redmonk.com/sogrady/2012/09/12/language-rankings-9-12/.

Online

[31] World Wide Web Consortium (2011). HTML5 Specification. W3C Working
Draft. Online http://www.w3.org/TR/html5/.
[32] Raymond, D. R. (1992). Flexible text display with lector. Computer, 25(8), 4960.
[33] Ace - The High Performance Code Editor for the Web. Online
http://ace.ajax.org.
[34] D'souza, D. F., & Wills, A. C. (1998). Objects, components, and frameworks
with UML: the catalysis approach (Vol. 1). Reading: Addison-Wesley.
[35] JSON Templates. Online https://code.google.com/p/json-template/.
[36] JavaScript Template. Online https://github.com/blueimp/JavaScript-Templates/.
[37] Crespo, S., Fontoura, M., & Lucena, C. J. Using Viewpoints, Frameworks, and
Domain-Specific Languages to Enhance Software Reuse. In European Reuse
Workshop-ERW (Vol. 98).
[38] Wolfinger, R., Reiter, S., Dhungana, D., Grunbacher, P., & Prahofer, H. (2008,
February). Supporting runtime system adaptation through product line
engineering and plug-in techniques. In Composition-Based Software Systems,
2008. ICCBSS 2008. Seventh International Conference on (pp. 21-30). IEEE.
[39] jQuery Mobile: Touch-Optimized Web Framework for Smartphones & Tablets.
Online http://jquerymobile.com/.
[40] Appcelerator
Inc.
The
http://www.appcelerator.com/

Mobile

First

Platform.

Online

[41] Dropbox - File Storage Service. Online http://www.dropbox.com/.
[42] SugarSync - File Storage Service. Online http://www.sugarsync.com/.
[43] Google Drive - File Storage Service. Online http://drive.google.com/.
[44] GitHub - Online project hosting using Git. Online http://www.github.com/.

38

Anexo I – Definição da DSL
org.dsle.FormUi.dsl
{
"id": "org.dsle.FormUI",
"description": "",
"name": "Forms",
"templates": [{
"id": "org.dsle.formUi.jQueryMobile",
"file": "org.dsle.formUi.jQueryMobile.tpl",
"prefix": "",
"suffix": "_mobile",
"extension": "html",
"engine": "JAVASCRIPT"
},{
"id": "org.dsle.formUi.Titanium",
"file": "org.dsle.formUi.Titanium.tpl",
"prefix": "",
"suffix": "",
"extension": "js",
"engine": "JAVASCRIPT"
}],
"types": [{
"name": "align",
"primitiveType": "STRING"
}, {
"name": "bottom",
"primitiveType": "STRING"
}, {
"name": "checked",
"primitiveType": "BOOLEAN"
}, {
"name": "color",
"primitiveType": "STRING"
}, {
"name": "enabled",
"primitiveType": "BOOLEAN"
}, {
"name": "family",
"primitiveType": "STRING"
}, {
"name": "for",
"primitiveType": "STRING"
}, {
"name": "height",
"primitiveType": "STRING"
}, {
"name": "hint",
"primitiveType": "STRING"
}, {
"name": "id",
"primitiveType": "STRING"
}, {
"name": "image",
"primitiveType": "STRING"
}, {
"name": "left",
"primitiveType": "STRING"
}, {
"name": "max",
"primitiveType": "NUMERIC"
}, {
"name": "maxLength",
"primitiveType": "NUMERIC"
}, {
"name": "min",
"primitiveType": "NUMERIC"
}, {
"name": "opacity",
"primitiveType": "STRING"
}, {

39

"name": "password",
"primitiveType": "BOOLEAN"
}, {
"name": "radius",
"primitiveType": "STRING"
}, {
"name": "readOnly",
"primitiveType": "BOOLEAN"
}, {
"name": "repeat",
"primitiveType": "STRING"
}, {
"name": "right",
"primitiveType": "STRING"
}, {
"name": "selected",
"primitiveType": "BOOLEAN"
}, {
"name": "size",
"primitiveType": "STRING"
}, {
"name": "style",
"primitiveType": "STRING"
}, {
"name": "text",
"primitiveType": "STRING"
}, {
"name": "title",
"primitiveType": "STRING"
}, {
"name": "top",
"primitiveType": "STRING"
}, {
"name": "value",
"primitiveType": "STRING"
}, {
"name": "visible",
"primitiveType": "BOOLEAN"
}, {
"name": "weight",
"primitiveType": "STRING"
}, {
"name": "width",
"primitiveType": "STRING"
}, {
"name": "background",
"primitiveType": "OBJECT",
"items": [{
"type": "color",
"required": false
}, {
"type": "image",
"required": false
}, {
"type": "repeat",
"required": false
}]
}, {
"name": "background",
"primitiveType": "OBJECT",
"items": [{
"type": "color",
"required": false
}, {
"type": "image",
"required": false
}, {
"type": "repeat",
"required": false
}]
}, {
"name": "border",
"primitiveType": "OBJECT",
"items": [{
"type": "color",
"required": false
}, {
"type": "width",
"required": false
}, {
"type": "radius",
"required": false
}]
}, {
"name": "font",

40

"primitiveType": "OBJECT",
"items": [{
"type": "family",
"required": false
}, {
"type": "size",
"required": false
}, {
"type": "style",
"required": false
}, {
"type": "weight",
"required": false
}]
}, {
"name": "formItems",
"primitiveType": "ARRAY",
"arrayType": "OBJECT",
"defaultType": "textfield"
}, {
"name": "formfield",
"primitiveType": "OBJECT",
"items": [{
"type": "align",
"required": false
}, {
"type": "background",
"required": false
}, {
"type": "border",
"required": false
}, {
"type": "bottom",
"required": false
}, {
"type": "color",
"required": false
}, {
"type": "enabled",
"required": false
}, {
"type": "font",
"required": false
}, {
"type": "height",
"required": false
}, {
"type": "id",
"required": true
}, {
"type": "left",
"required": false
}, {
"type": "opacity",
"required": false
}, {
"type": "readOnly",
"required": false
}, {
"type": "right",
"required": false
}, {
"type": "size",
"required": false
}, {
"type": "style",
"required": false
}, {
"type": "top",
"required": false
}, {
"type": "visible",
"required": false
}, {
"type": "weight",
"required": false
}, {
"type": "width",
"required": false
}]
}, {
"name": "label",
"primitiveType": "OBJECT",
"extends":"formfield",
"items": [{

41

"type": "text",
"required": true
},{
"type": "for",
"required": false
}]
}, {
"name": "textfield",
"primitiveType": "OBJECT",
"extends": "formfield",
"items": [{
"type": "hint",
"required": false
},{
"type": "maxLength",
"required": false
},{
"type": "password",
"required": false
},{
"type": "readOnly",
"required": false
},{
"type": "value",
"required": false
}]
}, {
"name": "textarea",
"primitiveType": "OBJECT",
"extends": "formfield",
"items": [{
"type": "hint",
"required": false
},{
"type": "maxLength",
"required": false
},{
"type": "readOnly",
"required": false
},{
"type": "value",
"required": false
}]
}, {
"name": "option",
"primitiveType": "OBJECT",
"extends":"formfield",
"items": [{
"type": "selected",
"required": false
},{
"type": "text",
"required": true
},{
"type": "value",
"required": false
}]
}, {
"name": "selectOptions",
"primitiveType": "ARRAY",
"arrayType": "OBJECT",
"defaultType": "option"
}, {
"name": "select",
"primitiveType": "OBJECT",
"extends":"formfield",
"items": [{
"type": "value",
"required": false
},{
"type": "selectOptions",
"required": true
}]
}, {
"name": "checkbox",
"primitiveType": "OBJECT",
"extends":"formfield",
"items": [{
"type": "text",
"required": true
},{
"type": "checked",
"required": true
},{
"type": "value",

42

"required": false
}]
}, {
"name": "slider",
"primitiveType": "OBJECT",
"extends":"formfield",
"items": [{
"type": "min",
"required": true
},{
"type": "max",
"required": true
},{
"type": "value",
"required": false
}]
}, {
"name": "button",
"primitiveType": "OBJECT",
"extends":"formfield",
"items": [{
"type": "text",
"required": true
}]
}, {
"name": "form",
"primitiveType": "OBJECT",
"extends":"formfield",
"items": [{
"type": "formItems",
"required": true
}]
}, {
"name": "window",
"primitiveType": "OBJECT",
"extends":"formfield",
"items": [{
"type": "form",
"required": true
}, {
"type": "title",
"required": true
}]
}],
"main": "window"
}

43

Anexo II – Templates
org.dsle.FormUi.jQueryMobile.tpl
<!DOCTYPE html>
<html>
<head>
<title>{%=o.title%}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.js"></script>
</head>
<body>
<div data-role="page" id="{%=o.form.id%}">
<div data-role="header">
<h1>{%=o.title%}</h1>
</div>
<div data-role="content">
<form>
{%
for (var i = 0; i < o.form.formItems.length; i++) {
print('\t\t\t\t' + ide.formUi.getHtml(o.form.formItems[i]) + '\n',true)
}
%}
</form>
</div>
</div>
</body>
</html>

org.dsle.FformUi.Titanium.tpl
function {%=o.id%} () {
var main = Ti.UI.createWindow({
backgroundColor: '#fff'
});
var _{%=o.id%} = Ti.UI.createWindow({
backgroundColor: '#fff',
title: '{%=o.title%}'
});
var _{%=o.form.id%} = Ti.UI.createScrollView({
layout: 'vertical'
});
{%
for (var i = 0; i < o.form.formItems.length; i++) {
print('\t'+ide.formUi.getTitanium(o.form.formItems[i])+'\n', true)
print('\t_'+o.form.id+'.add(_'+o.form.formItems[i].id+');\n\n', true)
}
%}
_{%=o.id%}.add(_{%=o.form.id%});
if (Ti.Platform.osname == 'iphone') {
var navGroup = Ti.UI.iPhone.createNavigationGroup({
window:_{%=o.id%}
});
main.add(navGroup);
return main;
} else {
return _{%=o.id%};
}
}
module.exports = {%=o.id%};

44

Anexo III – Plug-ins
org.dsle.FormUI.js
{
id: 'org.dsle.FormUI',
name: 'FormUI',
load: function() {
ide.formUi = ide.formUi || {};
ide.formUi.getHtmlTag = function(o) {
var html = '<'+o.tag, style='style="';
for (var i = 0; i < o.attrs.length; i++) {
html += ' '+o.attrs[i].name+'="'+o.attrs[i].value+'"';
};
for (var i = 0; i < o.style.length; i++) {
style += ' '+o.style[i].name+': '+o.style[i].value+';';
};
html += ' '+style+'"';
if (o.selfClose) {
html += '/>';
} else {
html += '>';
html += o.text || '';
html += '</'+o.tag+'>'
}
return html;
}
ide.formUi.getHtml = function(item) {
var html = '',
attrs = new Array();
style = new Array();
function _a(name, value){
attrs.push({name: name, value: value});
}
function _s(name, value){
style.push({name: name, value: value});
}
if (item.align) _s('text-align', item.align);
if (item.background && item.background.color) _s('background-color',
item.background.color);
if (item.background && item.background.image) _s('background-image', 'url(' +
item.background.image + ')');
if (item.background && item.background.repeat) _s('background-repeat',
item.background.image);
if (item.bottom) _s('margin-bottom', item.bottom);
if (item.border && item.border.color) _s('border-color', item.border.color);
if (item.border && item.border.width) _s('border-width', item.border.width);
if (item.border && item.border.radius) _s('border-radius', item.border.radius);
if (item.color) _s('color',item.color);
if (item.enabled === false) _a('disabled', 'disabled');
if (item.font && item.font.family) _s('font-family', item.font.family);
if (item.font && item.font.size) _s('font-size', item.font.size);
if (item.font && item.font.style) _s('font-style', item.font.style);
if (item.font && item.font.weight) _s('font-weight', item.font.weight);
if (item.id) _a('id',item.id);
if (item.hint) _a('placeholder', item.hint);
if (item.height) _s('height',item.height);
if (item.left) _s('margin-left', item.left);
if (item.opacity) _s('opacity', item.opacity);
if (item.readOnly) _a('readonly', 'readonly');
if (item.right) _s('margin-right', item.right);
if (item.top) _s('margin-right', item.top);
if (item.visible === false) _s('display', 'none');
if (item.width) _s('width', item.width);
switch(item.type) {
//LABEL
case 'label':
if (item.for) _a('for', item.for);
return this.getHtmlTag({
tag:'label',
attrs: attrs,
style: style,
text: (item.text) || '',
selfClose: false

45

});
break;
//TEXTFIELD
case 'textfield':
_a('type',((item.password)?'password':'text'));
if (item.value) _a('value', item.value);
if (item.maxLength) _a('maxlength', item.maxLength);
return this.getHtmlTag({
tag:'input',
attrs: attrs,
style: style,
selfClose: true
});
break;
//TEXTAREA
case 'textarea':
return 'var _'+item.id+';';
if (item.maxLength) _a('maxlength', item.maxLength);
return this.getHtmlTag({
tag:'textarea',
attrs: attrs,
style: style,
text: item.value || '',
selfClose: false
});
break;
//OPTION
case 'option':
return 'var _'+item.id+';';
if (item.value) _a('value', item.value);
if (item.selected) _a('selected', 'selected');
return this.getHtmlTag({
tag:'option',
attrs: attrs,
style: style,
text: item.text || '',
selfClose: false
});
break;
//SELECT
case 'select':
return 'var _'+item.id+';';
item.text = '';
for (var i = 0; i < item.selectOptions.length; i++) {
if (typeof item.value !== 'undefined') {
if (item.value === item.selectOptions[i].value)
item.selectOptions[i].selected = true;
}
item.selectOptions[i].type = 'option';
item.text += this.getHtml(item.selectOptions[i]);
};
return this.getHtmlTag({
tag:'select',
attrs: attrs,
style: style,
text: item.text || '',
selfClose: false
});
break;
//CHECKBOX
case 'checkbox':
_a('type', 'checkbox');
if (item.value) _a('value', item.value);
if (item.checked) _a('checked', 'checked');
return this.getHtmlTag({
tag: 'fieldset',
attrs: [],
style: [],
selfClose: false,
text: this.getHtmlTag({
tag:'input',
attrs: attrs,
style: style,
selfClose: true
}) + this.getHtmlTag({
tag:'label',
attrs:[{name: "for", value: item.id}],
style:[],
text: (item.text) || '',
selfClose: false

46

})
});
break;
//SLIDER
case 'slider':
_a('type', 'range');
if (item.value) _a('value', item.value);
if (item.max) _a('max', item.max);
if (item.min) _a('min', item.min);
return this.getHtmlTag({
tag:'input',
attrs: attrs,
style: style,
selfClose: true
});
break;
//BUTTON
case 'button':
_a('type','button');
if (item.text) _a('value', item.text);
return this.getHtmlTag({
tag:'input',
attrs: attrs,
style: style,
selfClose: true
});
break;

}

default:
return '<!-- TYPE ['+item.type+'] NOT FOUND -->';

}
}
}

org.dsle.FormUi.Titanium.js
{
id: 'org.dsle.FormUI.Titanium',
name: 'FormUI Titanium',
load: function() {
ide.formUi = ide.formUi || {};
ide.formUi.getTitaniumObject = function(o) {
var js = '';
js += 'var _'+o.id+' = Ti.UI.'+o.createFn+'('+JSON.stringify(o.config)+');'
return js;
}
ide.formUi.getTitanium = function(item) {
var config = {};
function _c(name, value){
config[name] = value;
}
if (item.align) _c('textAlign', item.align);
if (item.background && item.background.color) _c('backgroundColor',
item.background.color);
if (item.background && item.background.image) _c('backgroundImage',
item.background.image);
if (item.background && item.background.repeat) _c('backgroundRepeat',
item.background.repeat);
if (item.bottom) _c('bottom', item.bottom);
if (item.border && item.border.color) _c('borderColor', item.border.color);
if (item.border && item.border.width) _c('borderWidth', item.border.width);
if (item.border && item.border.radius) _c('borderRadius', item.border.radius);
if (item.color) _c('color',item.color);
if (item.enabled === false) _c('enabled', false);
if (item.font) _c('font', {});
if (item.font && item.font.family) config.font.fontFamily = item.font.family;
if (item.font && item.font.size) config.font.fontSize = item.font.size;
if (item.font && item.font.style) config.font.fontStyle, item.font.style;
if (item.font && item.font.weight) config.font.fontWeight, item.font.weight;
if (item.hint) _c('hintText', item.hint);
if (item.height) _c('height',item.height);
if (item.left) _c('left', item.left);

47

if
if
if
if
if
if

(item.opacity) _c('opacity', item.opacity);
(item.readOnly === true) _c('editable', false);
(item.right) _c('right', item.right);
(item.top) _c('top', item.top);
(item.visible === false) _c('visible', false);
(item.width) _c('width', item.width);

switch(item.type) {
//LABEL
case 'label':
_c('text', item.text || '');
return this.getTitaniumObject({
id: item.id,
createFn: 'createLabel',
config: config
});
break;
//TEXTFIELD
case 'textfield':
_c('passwordMask',(item.password));
if (item.value) _c('value', item.value);
if (item.maxLength) _c('maxlength', item.maxLength);
if (!item.border) _c('borderStyle', 'rounded');
return this.getTitaniumObject({
id: item.id,
createFn: 'createTextField',
config: config
});
break;
//TEXTAREA
case 'textarea':
if (item.value) _c('value', item.value);
if (item.maxLength) _c('maxlength', item.maxLength);
if (!item.border) _c('borderStyle', 'rounded');
return this.getTitaniumObject({
id: item.id,
createFn: 'createTextArea',
config: config
});
break;
//CHECKBOX
case 'checkbox':
var js = '';
_c('layout', 'horizontal');
_c('height', 'size');
js = this.getTitaniumObject({
id: item.id,
createFn: 'createView',
config: config
});
js += '\n\t';
js += this.getTitaniumObject({
id: '_'+item.id,
createFn: 'createSwitch',
config: { value: (item.checked) }
});
js += '\n\t';
js += this.getTitaniumObject({
id: '__'+item.id,
createFn: 'createLabel',
config: { text: item.text || '' }
});
js += '\n\t';
js += '_'+item.id+'.add(__'+item.id+');'
js += '\n\t';
js += '_'+item.id+'.add(___'+item.id+');'
return js;
break;
//SLIDER
case 'slider':
if (item.value) _c('value', item.value);
if (item.max) _c('max', item.max);
if (item.min) _c('min', item.min);
return this.getTitaniumObject({
id: item.id,
createFn: 'createSlider',
config: config
});
break;

48

//BUTTON
case 'button':
_c('title', item.text || '');
return this.getTitaniumObject({
id: item.id,
createFn: 'createButton',
config: config
});
break;

}

default:
return 'var _'+item.id+'; //TYPE NOT FOUND';

}
}
}

49

Anexo IV – Arquivos Gerados
create_account_mobile.html
<!DOCTYPE html>
<html>
<head>
<title>Create Account</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.3.1/jquery.mobile1.3.1.min.css" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.3.1/jquery.mobile-1.3.1.js"></script>
</head>
<body>
<div data-role="page" id="frmCreateAccount">
<div data-role="header">
<h1>Create Account</h1>
</div>
<div data-role="content">
<form>
<label id="lblEmail" for="email" style="">E-mail:</label>
<input id="email" placeholder="enter your e-mail" type="text" style=""/>
<label id="lblPassword" for="password" style="">Password:</label>
<input id="password" placeholder="enter your password" type="password" style=""/>
<fieldset style=""><input id="accept" type="checkbox" style=""/><label for="accept"
style="">I accept this terms.</label></fieldset>
<input id="btCreateAccount" type="button" value="create account" style=""/>
</form>
</div>
</div>
</body>
</html>

create_account.js
function winCreateAccount () {
var main = Ti.UI.createWindow({
backgroundColor: '#fff'
});
var _winCreateAccount = Ti.UI.createWindow({
backgroundColor: '#fff',
title: 'Create Account'
});
var _frmCreateAccount = Ti.UI.createScrollView({
layout: 'vertical'
});
var _lblEmail = Ti.UI.createLabel({"text":"E-mail:"});
_frmCreateAccount.add(_lblEmail);
var _email = Ti.UI.createTextField({"hintText":"enter your email","borderStyle":"rounded"});
_frmCreateAccount.add(_email);
var _lblPassword = Ti.UI.createLabel({"text":"Password:"});
_frmCreateAccount.add(_lblPassword);
var _password = Ti.UI.createTextField({"hintText":"enter your
password","passwordMask":true,"borderStyle":"rounded"});
_frmCreateAccount.add(_password);
var _accept = Ti.UI.createView({"layout":"horizontal","height":"size"});
var __accept = Ti.UI.createSwitch({"value":false});
var ___accept = Ti.UI.createLabel({"text":"I accept this terms."});
_accept.add(__accept);
_accept.add(___accept);
_frmCreateAccount.add(_accept);

50

var _btCreateAccount = Ti.UI.createButton({"title":"create account"});
_frmCreateAccount.add(_btCreateAccount);

_winCreateAccount.add(_frmCreateAccount);
if (Ti.Platform.osname == 'iphone') {
var navGroup = Ti.UI.iPhone.createNavigationGroup({
window:_winCreateAccount
});
main.add(navGroup);
return main;
} else {
return _winCreateAccount;
}
}
module.exports = winCreateAccount;

51