Ferramenta para Conversão de Interfaces Java Swing para Interfaces Web Aluno: Silvio Gonçalves Neto Orientador: Matheus Carvalho Viana Roteiro • • • • • • • • • • Introdução Objetivos Fundamentação Teórica Trabalhos Correlatos Requisitos Especificação Implementação Operacionalidade da Ferramenta Resultados e Discussões Conclusões e Sugestões Introdução • Demanda crescente por sistemas web devido a vantagens em relação a plataforma desktop. • Contudo as empresas operam com sistemas desktop e o processo de conversão tende a ser caro e demorado • Portanto, é necessária uma forma eficiente de efetuar essa conversão Objetivos Objetivo Geral: • Desenvolver uma ferramenta que auxilie na conversão de interfaces Java Swing para interfaces web baseadas em HTML, CSS e JavaScript. Objetivos Específicos: • conversão de componentes Java Swing para componentes HTML; • conversão dos tratamentos de eventos mais comuns da interface Java para JavaScript; • meio automatizado para atualização da interface de sistemas Java existentes para web; • testar a viabilidade de converter componentes gráficos desktop para web. Fundamentação Teórica Analisador Léxico/Sintático • Analisador léxico identifica símbolos (tokens) dentro do código fonte. • Analisador sintático verifica se a ordens dos tokens faz sentido para a linguagem em questão. Fundamentação Teórica Geradores de Código • Programas que geram código de outros programas. • Visam Qualidade e Produtividade. • Podem ser construídos com base em templates. • Templates definem a estrutura do código a ser gerado Fundamentação Teórica Gerador de Código com Templates Fundamentação Teórica Interface Java Swing x Web Trabalhos Correlatos SwingToHtml (SEVERO, 2008) Trabalhos Correlatos DelphiToWeb (SOUZA, 2005) Trabalhos Correlatos Converte Forms (SCHVEPE, 2006) Desenvolvimento • Requisitos • Especificação • Implementação • Operacionalidade da Ferramenta • Resultados e Discussões Requisitos Requisitos Funcionais RF01: efetuar análise léxica e sintática dos arquivos de entrada RF02: converter componentes Java Swing para HTML RF03: converter os tratamentos de evento de Java para JavaScript Requisitos Requisitos Não-Funcionais RNF01: possuir interface de fácil usabilidade RNF02: utilizar o MoDisco para analisar o código Java RNF03: utilizar templates e o motor Acceleo para fazer a geração do código RNF04: utilizar HTML 5 para formatação dos arquivos de saída RNF05: utilizar CSS 3 para aplicar estilo nos arquivos de saída Especificação Diagrama de Casos de Uso Especificação Diagrama de Componentes Implementação Ferramentas utilizadas: • IDE Eclipse Modeling • MoDisco • Acceleo Implementação MoDisco Implementação MoDisco public class Exemplo extends JFrame { public Exemplo() { JButton btn = new JButton("botao"); <ownedElements xsi:type="java:ClassDeclaration" name="Exemplo" > <modifier visibility="public"/> <bodyDeclarations xsi:type="java:ConstructorDeclaration“ name="Exemplo"> <body originalCompilationUnit="//@compilationUnits.0"> <statements xsi:type="java:VariableDeclarationStatement" > <type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.4"/> <fragments name="btn"> <initializer xsi:type="java:ClassInstanceCreation“ method="//@ownedElements.1/@ownedPackages.0/@ownedElements.4/@bo dyDeclarations.0"> <arguments xsi:type="java:StringLiteral" escapedValue="&quot; botao&quot;"/> <type type="//@ownedElements.1/@ownedPackages.0/@ownedElements.4"/> </initializer> </fragments> </statements> Implementação Acceleo Implementação Acceleo: templates Implementação Acceleo: templates Implementação Acceleo [template public generateApp(modelo : Model)] [comment @main/] [genCss('form.css') /] [genJs('utils.js') /] [for (compUnit : CompilationUnit | modelo.compilationUnits)] [genHtml(compUnit) /] [/for] [/template] Implementação Acceleo: templates [template public genCss(fileName : String)] [file (fileName, false, 'UTF-8')] *{ margin:0; padding:0; list-style:none; vertical-align:baseline; } .j-label { white-space: nowrap; } .j-textfield, .j-passwordfield { padding: 2px; } .temMenu { position: absolute; margin-top: 60px; } .flow-layout-center { text-align: center; } .flow-layout-right { text-align: right; } .flow-layout-left { text-align: left; } .flow-layout > * { display: inline-block; } [/file] [/template] [template public genHtml(compUnit : CompilationUnit)] [for (classe : ClassDeclaration | compUnit.types -> filter(ClassDeclaration))] [if (classe.superClass <> null and classe.superClass.type.name.toUpper() = 'JFRAME')] [file (compUnit.name.replace('.java', '.html'), false, 'UTF-8')] <!DOCTYPE html> <html><head> <title>[genTitle(bodyDec) /]</title> <link rel="stylesheet" href="bootstrap.min.css" /> <script src="bootstrap.min.js"></script> <script src="utils.js"></script> </head> <body> [genMenu(bodyDec) /] <form action="#" method="post" class="form-horizontal"> [genComponentes(bodyDec) /] </form> </body> </html> [/file][/if][/for] [/template] Implementação Acceleo: templates [template public genComponentes(declarations : Sequence(BodyDeclaration))] [for (ctor : ConstructorDeclaration | declarations -> filter(ConstructorDeclaration))] [if (ctor._body.getFromJFrame('setLayout') -> getTipoLayout('BorderLayout'))] ... [else] <div class="container-fluid . . .> [for (exp : ExpressionStatement | ctor._body.getFromJFrame('add'))] [let metodo : MethodInvocation = exp.expression] [if (metodo.arguments -> filter(SingleVariableAccess) -> size() = 1)] [for (singleVar : SingleVariableAccess | metodo.arguments -> filter(SingleVariableAccess))] [definirComponente(singleVar.getNomeComponente(), singleVar.variable.oclAsType(VariableDeclarationFragment), ctor._body) /] [/for] [/if] [/let] [/for] </div> [/if] [/for] [/template] [template public definirComponente(nome : String, frag : VariableDeclarationFragment, bodyBlock : Block)] [let nomeComponente : String = nome.toUpper()] [if (nomeComponente = 'JPANEL')] ... [elseif (nomeComponente = 'JBUTTON')] [genButton(frag) /] [/if] ... [/let] [/template] [template public genButton(frag : VariableDeclarationFragment)] <button type="button" class="btn btn-primary" [genEstiloComponente(frag, false) /] [genId(frag) /]>[getTextoComponente(frag) /]</button> [genButtonAction(frag) /] ... [/template] [template private genButtonAction(frag : VariableDeclarationFragment)] [if (frag.getMetodoPorNome('addActionListener') -> notEmpty())] [let var : SingleVariableAccess = frag.getMetodoPorNome('addActionListener') -> first()] [if (var.eContainer(MethodInvocation) <> null)] <script type="text/javascript"> $(function() { $('#[frag.name /]').click(function() { // TODO }); }); </script> [/if] [/let] [/if] [/template] Implementação Acceleo: templates [template public genEstiloComponente(frag : VariableDeclarationFragment, temHeight : Boolean)] [let metodo : MethodInvocation = frag.getMetodoPorNome('setbounds') -> at(1).eContainer(MethodInvocation)] [if (metodo.arguments -> size() = 4)] [let x : NumberLiteral = metodo.arguments -> at(1)] [let y : NumberLiteral = metodo.arguments -> at(2)] [let width : NumberLiteral = metodo.arguments -> at(3)] [let height : NumberLiteral = metodo.arguments -> at(4)] style="position:absolute;left:[x.tokenValue /]px;top:[y.tokenValue /]px;width:[width.tokenValue /]px;[if (temHeight)]height:[height.tokenValue /]px;[/if]“ [/let][/let][/let][/let] [/if] [/let] [/template] Operacionalidade da Implementação Operacionalidade da Implementação Resultados e Discussões • Testes com a ferramenta geraram interfaces web equivalentes às interfaces originais – Os componentes Swing viram elementos HTML – A aparência é definida em um arquivo CSS – A chamada dos eventos é gerada em JavaScript • A geração de código provê maior eficiência e qualidade na conversão da interface Resultados e Discussões SwingToHtml DelphiToWeb Converte Forms SwingToWeb sim não sim sim sim sim sim sim plataforma aplicativo independente aplicativo independente aplicativo independente IDE Eclipse Entrada Java Delphi PL/SQL Java saída HTML; JavaScript Características uso de templates para conversão da interface uso de analisadores léxico/sintático HTML; arquivo arquivos .java .LZT; XML HTML; CSS; JavaScript Conclusões e Sugestões • O MoDisco facilitou a construção ferramenta, pois não foi necessário implementar o analisador léxico/sintático • A construção de templates do Acceleo simplificou o processo de conversão do código • A ferramenta não converte todos os componentes de interface • Implementado apenas a chamada dos eventos não o código interno do mesmo Conclusões e Sugestões • Implementar a conversão do código Java dentro dos tratamentos de evento • Implementar a conversão de componentes não tratados pela ferramenta • Implementar a conversão de componentes Java Swing que estão codificados em métodos além do construtor da classe • Implementar um tratamento de erros na ferramenta afim de avisar ao utilizador sobre problemas que possam estar ocorrendo