52
1 DSL Encoder: Uma ferramenta web para desenvolvimento de linguagens específicas de domínio Bruno F. Leão Maia 1 , Vinicius Cardoso Garcia 1,2 , Leandro M. Nascimento 1,3 1 Centro de Estudos Avançados do Recife (C.E.S.A.R.) Recife – Pernambuco – Brasil 2 Centro de Informática (CIn) – Universidade Federal de Pernambuco - UFPE Recife – Pernambuco – Brasil 3 Departamento de Estatística e Informática (DEINFO) - Universidade Federal Rural de Pernambuco - UFRPE Recife – Pernambuco – Brasil [email protected], [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].

DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

Embed Size (px)

DESCRIPTION

Artigo apresentado como pré-requisito para conclusão do Mestrado Profissional em Engenharia de Software do CESAR.EDU, Recife, Brasil.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.

Citation preview

Page 1: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

1

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 1Centro de Estudos Avançados do Recife (C.E.S.A.R.)

Recife – Pernambuco – Brasil

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

3Departamento de Estatística e Informática (DEINFO) - Universidade Federal Rural de Pernambuco - UFRPE

Recife – Pernambuco – Brasil

[email protected], [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].

Page 2: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

2

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 general-purpose 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 é

Page 3: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

3

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 auto-documentados, 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 (domain-model), 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

Page 4: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

4

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

Page 5: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

5

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

Ferramenta Dependências Gratuita Sistemas Operacionais Suportados

MetaEdit+ (MetaCase) Não Windows, Linux e Mac OS X

GME (Vanderbilt University) Sim Windows

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

Page 6: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

6

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 co-desenvolvedores 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

Page 7: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

7

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].

Fonte: Programmable Web[21]

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

0%#

5%#

10%#

15%#

20%#

25%#

2006# 2007# 2008# 2009# 2010# 2011#

Porcentagem+de+novas+APIs++com+suporte+somente+a+JSON+

70%$

75%$

80%$

85%$

90%$

95%$

2009$ 2010$ 2011$

Porcentagem de APIs com suporte a XML

Page 8: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

8

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).

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].

REST 68%

XML-RPC 2%

JavaScript 5%

OUTROS 2%

SOAP 23%

Protocolos usados por Web APIs

Page 9: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

9

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 plug-ins tanto podem adicionar novas funcionalidades a ferramenta como conectá-la a outros serviços da web através do consumo de APIs de terceiros.

2,30% 6,90% 8,50% 10,00% 11,50% 12,30% 13,10%

29,20% 34,60% 35,40%

85,40%

PubSubHubbub OAuth 1.0a Webhooks

WS-* CORS

WebSockets RSS/Atom feeds

SOAP OAuth 2 JSONP

REST

Que tecnologia você usou em 2012?

Page 10: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

10

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 co-desenvolvedores participem da sua evolução. O núcleo da ferramenta oferece vários pontos de extensão tratados no item 3.1.9, co-desenvolvedores 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

Page 11: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

11

“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

Page 12: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

12

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].

Page 13: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

13

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 co-desenvolvedores, 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.

Page 14: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

14

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.

Page 15: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

15

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.

Page 16: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

16

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

Page 17: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

17

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.

Page 18: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

18

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

ClientesServidor de Aplicação

DSL Encoder

Servidor de API de Terceiros

Internet

Comunicação com a Ferramenta

Comunicação com API de terceiros

Servidor de API de Terceiros

Page 19: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

19

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

Page 20: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

20

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/”.

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

IDE! DSL Processor! Sistema de Arquivos!

Gerar! Obter Linguagem!

Linguagem!

Obter Templates!

Templates!

Salvar Arquivos Gerados!

Arquivos Gerados!

org.dsle.Math.json!

Page 21: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

21

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 principal DslType da linguagem.

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”.

Page 22: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

22

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

Page 23: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

23

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”.

Page 24: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

24

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" }

Page 25: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

25

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 + o.number2; break; case '-': result = o.number1 - o.number2; break; case '*': result = o.number1 * o.number2; break; case '/': result = o.number1 / o.number2; break; default: result = 'invalid'; } %} <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.

Page 26: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

26

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

Page 27: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

27

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>

Page 28: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

28

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 data-role="controlgroup"/> Titanium.UI.Picker

Radio Button <input type="radio"/>

Titanium.UI.PickerRow

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.

Page 29: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

29

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="background-repeat:;" 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

Page 30: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

30

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

Propriedade jQuery Mobile Appcelerator

Titanium

Text <option>{text}</option> title

Selected selected="" -

Value value=" -

Tabela 13. Radio Group - Propriedades Adicionais Propriedade jQuery Mobile Appcelerator Titanium

Value - value

Page 31: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

31

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

Propriedade jQuery Mobile Appcelerator Titanium

Min min="" min

Max max="" max

Value value="" value

Tabela 17. Button - Propriedades Adicionais

Propriedade jQuery Mobile Appcelerator Titanium

Text 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.

Page 32: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

32

Tabela 18. DslTypes

DslType PrimitiveType

align STRING

background OBJECT

border OBJECT

bottom STRING

button OBJECT

checkbox OBJECT

checked BOOLEAN

color STRING

enabled BOOLEAN

family STRING

font OBJECT

form OBJECT

formFields ARRAY

height STRING

hint STRING

id STRING

image STRING

label OBJECT

left STRING

max NUMERIC

maxLength NUMERIC

min NUMERIC

opacity STRING

option OBJECT

DslType PrimitiveType

password BOOLEAN

radioGroup OBJECT

radioOptions ARRAY

radius STRING

readOnly BOOLEAN

repeat STRING

right STRING

select OBJECT

selected BOOLEAN

selectOptions ARRAY

size STRING

slider OBJECT

style STRING

text STRING

textarea OBJECT

textfield OBJECT

title STRING

top STRING

value STRING

visible BOOLEAN

weight STRING

width STRING

window OBJECT

Page 33: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

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”).

Page 34: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

33

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

Page 35: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

34

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" }

Page 36: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

35

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

Page 37: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

36

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.

Page 38: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

37

[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-partners-income.

[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/5000-apis-facebook-google-and-twitter-are-changing-the-web/.

[23] Programmable Web. API Dashboard. Online http://www.programmableweb.com/apis/.

[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-social-and-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-competitive-advantage/.

Page 39: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

38

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

[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-2-Clause/.

[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. Online http://redmonk.com/sogrady/2012/09/12/language-rankings-9-12/.

[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), 49-60.

[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 Mobile First Platform. Online http://www.appcelerator.com/

[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/.

Page 40: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

39

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" }, {

Page 41: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

40

"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",

Page 42: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

41

"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": [{

Page 43: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

42

"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",

Page 44: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

43

"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" }

Page 45: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

44

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.mobile-1.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%};

Page 46: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

45

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

Page 47: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

46

}); 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

Page 48: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

47

}) }); 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);

Page 49: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

48

if (item.opacity) _c('opacity', item.opacity); if (item.readOnly === true) _c('editable', false); if (item.right) _c('right', item.right); if (item.top) _c('top', item.top); if (item.visible === false) _c('visible', false); if (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;

Page 50: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

49

//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'; } } } }

Page 51: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

50

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.mobile-1.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 e-mail","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);

Page 52: DSL Encoder - Uma ferramenta web para desenvolvimento de linguagens específicas de domínio

51

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;