Exemplo 2
Objetivo: Demonstrar o uso de uma AST. Criar uma árvore para
onde serão jogados os valores antes de interpretar ou gerar
código
1. Criar novo projeto Java
2. Criar arquivo conta.math
3. Criar uma AST para o domínio
3.1. Criar uma classe Termo (enum Operacao, e dois campos, operacao e valor)
3.2. Criar uma classe Conta (lista de termos)
4. Criar arquivo MathParser.java, com um método parse(arquivo) (nao esquecer de colocar
linha.readLine no final)
5. Criar uma classe principal para usar o parser e interpretar a conta
6. Mudar o formato de entrada para ilustrar que o programa principal não precisa mudar
7. Adicionar uma checagem qualquer (divisão por zero não pode, mostrando a linha)
Exemplo 3
Objetivo: Demonstrar o problema causado pelo uso de referências
1. Estender arquivo conta.math para incluir o armazenamento de uma variável, constante
2. Adicionar uma operacão e um campo para armazenar a variável, e modificar o tipo do valor
public String valorOuVariavel;
public String nomeVariavel;
3. Estender o parser
3.1. Método para interpretar a nova operacao
4. Estender o principal
4.2. Método pegaValor, pra buscar nas variaveis já definidas
Exemplo 4
Objetivo: Demonstrar como um modelo orientado a objetos pode
facilitar na hora de realizar ações. O parser continua
precisando varrer em busca das referências, mas uma vez lido,
fica mais fácil
1. Criar um metamodelo
Conta (List<Termo> termos, List<Variavel> variaveis)
Termo (enum Operacao, Operacao operacao, Conteudo conteudo)
Variavel (String nome, Conteudo conteudo)
Conteudo (int valor, Variavel variavel, boolean eVariavel)
2. Modificar o parser para ler nesse metamodelo
3. Modificar o principal para usar o metamodelo pra resolver a conta
Exemplo 5
Objetivo: Demonstrar que hoje em dia é mais fácil fazer esse
tipo de parser, com por exemplo xText
1. Criar novo projeto xText
2. Explicar mais ou menos o que tem no projeto
3. Mostrar que sintaxe abstrata e concreta é junto
4. Mostrar que gera o metamodelo OO (Ecore)
Problema :
(expressoes += Expressao)*;
Expressao :
Armazena |
Operacao;
Armazena :
"Armazene" termo=INT;
Operacao :
sinal=SinalMatematico termo=INT;
String SinalMatematico :
"+" | "-" | "*" | "/";
<?xml version="1.0"?>
<workflow>
<component file="math/parser/Parser.oaw">
<modelFile value="conta.math"/>
<outputSlot value="conta"/>
</component>
<component class="math.Executa"
slotConta="conta" />
</workflow>
float resultado = 0;
Exemplo 6
Objetivo: Demonstrar como XML pode ser usado para interpretar
modelos
1. Fazer um exemplo de XML
<conta>
<inicial>10</inicial>
<soma>20</soma>
<subtracao>10</subtracao>
</conta>
Vector<JBuilderModel> v = builder.getRootFolder().getRootModels();
for (JBuilderModel model : v) {
if (model.getMeta().getName().equals("ModeloDeAtividades"))
interpretarModeloAtividades(model);
else if (model.getMeta().getName().equals("Organograma"))
interpretarOrganograma(model);
}
pw.flush();
pw.close();
JOptionPane.showMessageDialog(null, "Pronto!");
Exemplo 9
Objetivo: Demonstrar como realizar transformações procedurais
utilizando EMF e xText
1. Criar novo projeto openArchitectureWare
2. Criar uma classe que estende AbstractWorkflowComponent2
if (expressao.eClass().getName().equals("Armazena")) {
expressao.eSet(expressao.eClass().getEStructuralFeature(
"termo"), valor + 2);
} else {
String sinal = (String) expressao.eGet(expressao.eClass()
.getEStructuralFeature("sinal"));
if (sinal.equals("+")) {
expressao.eSet(expressao.eClass().getEStructuralFeature(
"sinal"), "-");
} else if (sinal.equals("*")) {
expressao.eSet(expressao.eClass().getEStructuralFeature(
"termo"), valor * 2);
}
}
}
3. Criar o workflow
<?xml version="1.0"?>
<workflow>
<component file="math/parser/Parser.oaw">
<modelFile value="model.math"/>
<outputSlot value="conta"/>
</component>
<component class="math.Executa"
slotConta="conta" />
</workflow>
Exemplo 10
Objetivo: Demonstrar como é feita a transformação declarativa
utilizando xTend
1. Cria novo projeto openArchitectureWare
2. Cria uma nova transformação.ext
2.1. Crie o seguinte arquivo (UMA REGRA DE CADA VEZ!)
import math;
incrementaArmazena(Expressao expressao) :
if (expressao.metaType == Armazena)
then expressao.setTermo(expressao.termo + 2);
trocaSomaPorSubtracao(Expressao expressao) :
if (((Operacao)expressao).sinal == "+")
then ((Operacao)expressao).setSinal("-");
dobraValorDeMultiplicacao(Expressao expressao) :
if (((Operacao)expressao).sinal == "*")
then expressao.setTermo(expressao.termo * 2);
adicionaExpressao(Problema problema):
let e = new Operacao:
e.setSinal("+") ->
e.setTermo(1234) ->
problema.expressoes.add(e);
ModeloOO:
"ModeloOO" name=ID "["
(classes+=Classe)*
"]";
Classe:
"classe" name=ID "{"
(membros+=Membro ";")*
"}";
Membro:
Atributo | Referencia;
Atributo:
tipo=TipoOO name=ID;
Referencia:
"->" ref=[Classe] name=ID;
ModeloER:
"ModeloER" name=ID "["
(tabelas+=Tabela)*
"]";
Tabela:
"tabela" name=ID ":"
(colunas+=Coluna ";")*
(restricoes+=Restricao ";")*
";";
Coluna:
name=ID tipo=TipoER;
Restricao:
RestricaoChavePrimaria | RestricaoChaveEstrangeira;
RestricaoChavePrimaria:
"PRIM" coluna=[Coluna];
RestricaoChaveEstrangeira:
"ESTR" coluna=[Coluna] "->" tabelaEstrangeira=[Tabela] "." colunaEstrangeira=[Coluna];
5. Fazer o workflow
<?xml version="1.0"?>
<workflow>
<component file="ooer/parser/Parser.oaw">
<modelFile value="modeloOO.ooer"/>
<outputSlot value="modeloOO"/>
</component>
<component class="principal.ImprimeModelo"
slotModelo="modeloERGerado" />
</workflow>
Exemplo 12
Objetivo: Demonstrar a geração de código com GME
public class GeraQuestionario implements BONComponent {
PrintWriter pw;
public GeraQuestionario() {
try {
pw = new PrintWriter(new FileWriter("Questionario.java"));
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e.getMessage());
}
}
@Override
public void invokeEx(JBuilder builder, JBuilderObject focus,
Collection selected, int param) {
Vector<JBuilderModel> v = builder.getRootFolder().getRootModels();
for (JBuilderModel model : v) {
if (model.getMeta().getName().equals("ModeloDeDecisoes")) {
geraQuestionario(model);
}
}
pw.flush();
pw.close();
JOptionPane.showMessageDialog(null, "Pronto!");
}
@Override
public void registerCustomClasses() {
// TODO Auto-generated method stub
Exemplo 13
Objetivo: Demonstrar a geração de código com GME, usando
patterns (templates)
$!EVAL_FORALL("R:Mensagem","$!TO_FILE("html/$Name.html")\
<html>\n\
<body>\n\
$Name<br/>\n\
$!EVAL_FORALL("Dst:Link","<a href=\"\
$Name.html\
\">Continua</a><br/>\n")\
</body>\n\
</html>\n")
$!EVAL_FORALL("R:Questao","$!TO_FILE("html/$Name.html")\
<html>\n\
<body>\n\
$Name?<br/>\n\
$!DEFINE("CONT","1")\
$!EVAL_FORALL("Dst:Resposta","<a href=\"\
$Name.html\
\">Opção $!POSTINCR(CONT)</a><br/>\n")\
</body>\n\
</html>\n")
Exemplo 14
Objetivo: Demonstrar o uso do GMF para criação de linguagens e
ferramentas de modelagem visual
1. Criar novo projeto GMF
2. Criar uma máquina de estados simples, pra começar
8. Adicionar um audit constraint para não deixar criar mais de um estado inicial
Exemplo 15
Objetivo: Demonstrar as funcionalidades da linguagem xText
1. Criar novo projeto xText
2. Criar linguagem para máquina de estados
MaquinaDeEstados :
(eventos+=Evento)*
(estados+=Estado)*;
Evento :
"evento" name=ID ";";
Estado :
"estado" tipo=TipoEstado name=ID "{"
"caracteristicas" ":"
(caracteristicas+=Caracteristica ";")*
"transicoes" ":"
(transicoes+=Transicao ";")*
"}"
;
String TipoEstado :
"inicial" | "intermediario" | "final"
;
Caracteristica :
name=STRING ":" expressao=STRING
;
Transicao :
evento=[Evento] "->" estado=[Estado]
;
context Transicao ERROR "Não pode existir transição para o estado inicial!" :
this.estado.tipo != "inicial";
//context Transicao if(this.estado.tipo == "inicial") ERROR "Não pode existir transição para o
estado inicial 2!" :
// false;
context Transicao ERROR "Não pode existir transição partindo de estado final!" :
((Estado)this.eContainer).tipo != "final";
//context Estado ERROR "Não podem existir transições partindo do estado final 2!" :
// this.tipo == "final"?this.transicoes.isEmpty:true;
context Estado ERROR "Deve existir uma (e somente uma) transição saindo do estado inicial!" :
this.tipo == "inicial"?this.transicoes.size==1:true;
context Evento ERROR "Não podem existir dois eventos com o mesmo nome: " + this.name :
((MaquinaDeEstados)this.eContainer).eventos.select(e|e.name == this.name).size == 1;
context Estado ERROR "Não podem existir dois estados com o mesmo nome: " + this.name :
((MaquinaDeEstados)this.eContainer).estados.select(e|e.name == this.name).size == 1;
context Estado if(this.tipo!="inicial") WARNING "Não há nenhuma transição para este estado:
"+this.name :
((MaquinaDeEstados)this.eContainer).estados.transicoes.exists(t|t.estado == this);
context Transicao ERROR "Já existe outra transição para o mesmo evento!" :
((Estado)this.eContainer).transicoes.select(t|t.evento == this.evento).size == 1;
5. Estender o auto-complete:
List[Proposal] completeTransicao_estado(Transicao t, String prefix) :
t.allVisibleElements().typeSelect(Estado).select(e|e.tipo !=
"inicial").collect(x|newProposal(x.label(),x.id(),x.image()));
Exemplo 16
Objetivo: Demonstrar as funcionalidades da linguagem ATL
1. Criar novo projeto ATL
2. Criar dois metamodelos: familias e pessoas
rule MembroParaHomem {
from m : familias!Membro (not m.eMulher())
to h : pessoas!Homem (
nomeCompleto <- m.nome + ' ' +m.sobrenome()
)
}
rule MembroParaMulher {
from m : familias!Membro (m.eMulher())
to h : pessoas!Mulher (
nomeCompleto <- m.nome + ' ' +m.sobrenome()
)
}
Exemplo 17
Objetivo: Demonstrar as funcionalidades da linguagem xTend
1. Criar novo projeto oaw
2. Criar extensões
import maquinaestados;
import maquinaEstados;
3. Criar workflow
<workflow>
<component file="me/parser/Parser.oaw">
<modelFile value="maquinaEstados.me"/>
<outputSlot value="maquinaEstados"/>
</component>
<component id="xmiParser"
class="org.openarchitectureware.emf.XmiReader">
<modelFile value="maquinaEstados.maquinaEstados"/>
<metaModelPackage value="maquinaEstados.MaquinaEstadosPackage"/>
<outputSlot value="maquinaEstados2"/>
<firstElementOnly value="true"/>
</component>
<component id="transforma" class="oaw.xtend.XtendComponent">
<metaModel id="mm"
class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<invoke value="transforma::adicionaEstadoEmergencia(maquinaEstados)"/>
</component>
</workflow>
4. Exercícios
4.1. Não criar transicao a partir do estado inicial
4.2. Não criar transicao a partir do estado de emergencia
Exemplo 18
Objetivo: Demonstrar as funcionalidades do JET
1. Criar novo projeto Java
2. Adicionar natureza JET ao projeto
3. Ajustar as propriedades JET do projeto
4. Criar novo arquivo helloworld.txtjet
Hello, world!
Exemplo 20
Objetivo: Mostrar como gerar código Java
1. Criar novo projeto JET
2. Fazer um diagrama de classes no sample.xml
3. Gerar JavaBeans
3.1. Gerar setters e getters (usar anotações nos atributos)
4. Criar métodos abstratos no sample.xml
4.1. Adicionar parametros, exceções, visibilidade, modificador static
5. Demonstrar o uso do userRegion
5.1. Tag unmodifiedMarker="@generated"
Exemplo 21
Objetivo: Mostrar como gerar código a partir de modelo EMF
1. Criar novo projeto JET
2. Estender a ferramenta de estados para incluir ações
3. Criar um modelo de exemplo (refrigerador)
4. Adicionar model loader org.eclipse.jet.emf no plugin.xml
5. Criar templates para anotações e uma classe da máquina de estados
Anotações:
package gerado;
import java.util.HashMap;
import java.util.Map.Entry;
</c:initialCode>
// fim <c:get select="$acao/@metodoAcao"/>
</c:userRegion>
}
</c:iterate>
</c:iterate>
Exemplo 22
Objetivo: Demonstrar a linguagem xPand, usando um modelo xText
1. Criar novo projeto xText (deixar pra gerar o generator)
2. Criar uma linguagem simples para famílias
Familia :
"Familia" sobrenome=STRING "("
pai=Pai
mae=Mae
(filhos += Filho)*
")"
;
«IMPORT familia»
«DEFINE main FOR Familias»
«FILE "familias.txt"»
«FOREACH this.familias AS f-»
«EXPAND familia FOR f-»
«ENDFOREACH-»
«ENDFILE-»
«ENDDEFINE»
«ENDDEFINE»
transforma(Familias f) :
f.familias.criaFilho() ->
f.familias.trocaEsposa();
trocaEsposa(Familia f) :
f.mae.setNome("Nova esposa");
numeroFilhos(Familia f) :
f.filhos.size;
sobrenome(emf::EObject o):
((Familia)o.eContainer).sobrenome;
nomeCompleto(Pai p) :
p.nome + " " + p.sobrenome();
nomeCompleto(Mae m) :
m.nome + " " + m.sobrenome();
nomeCompleto(Filho f) :
f.nome + " " + f.sobrenome();
nomeCitacao(Pai p) :
p.sobrenome().toUpperCase()+", "+p.nome.subString(0,1)+"."
;
Exemplo 23
Objetivo: Demonstrar a linguagem xPand, usando um modelo xText
mais complexo (máquina de estados)
1. Criar novo projeto oAW
2. Modificar o exemplo para ter ações
3. Criar um exemplo de máquina de estados textual (despertador)
evento liga;
evento ligaAlarme;
evento desligaAlarme;
evento toca;
evento soneca;
evento fimsoneca;
«IMPORT maquinaestados»
«EXTENSION me::Extensions»
5. Testar o exemplo
6. Adicionar estado final e transições
import maquinaestados;
adicionaEstadoFinal(MaquinaDeEstados me) :
me.eventoFinal() ->
me.estadoFinal() ->
me.estados.select(e|e.tipo == "intermediario").transicaoParaEstadoFinal();
7. Recipes
7.1. Adicionar referências aos plugins *recipe
7.2. Criar um RecipeCreator
package recipes;
@Override
protected Collection<org.openarchitectureware.recipe.core.Check> createRecipes(
Object modelSlotContent, String appProject) {
List<Check> checks = new ArrayList<Check>();
cc.addChild(javaClassExistenceCheck);
cc.addChild(javaSuperclassCheck);
checks.add(cc);
return checks;
}
7.4. Testar
7.5. Mostrar as possíveis checks no próprio Eclipse
Exemplo 24
Objetivo: Demonstrar a linguagem xPand, usando um modelo EMF
(máquina de estados)
1. Criar novo projeto oAW
1.1. Copiar a máquina de estados de outro exemplo
1.2. Inserir dependência com Exemplo14
2. Criar um workflow
<?xml version="1.0"?>
<workflow>
<property name='modelFile' value='src/default.maquinaestados' />
<property name='targetDir' value='src-gen/'/>
<!-- set up EMF for standalone execution -->
<bean class="org.eclipse.mwe.emf.StandaloneSetup" >
<platformUri value=".."/>
</bean>
<?xml version="1.0"?>
<workflow>
<property name='modelFile' value='src/default.maquinaestados' />
<property name='targetDir' value='src-gen/'/>
<!-- set up EMF for standalone execution -->
<bean class="org.eclipse.mwe.emf.StandaloneSetup" >
<platformUri value=".."/>
</bean>
import maquinaEstados;
corrigeNome(String str) :
str.replaceAll(" ","_");
5. Template principal
«IMPORT maquinaEstados»
«EXTENSION extensions»
import java.util.HashMap;
import java.util.Map.Entry;
Exemplo 25
Objetivo: Demonstrar as possibilidades de padrões para
integração entre código gerado e não-gerado
1. Criar novo projeto JET
2. Criar um projeto JET.Gerado
3. Código gerado chama código não-gerado
3.1. Criar uma classe ListaOrdenada, e gerar código pra ela
4. Código não-gerado chama código gerado
4.1. Fazer uma classe ListaOrdenada2, e gerar os comparators
5. Factory
5.1. Fazer exemplo de DAO
5.1.1. sample.xml
5.1.2. Fazer DAO abstrato e fábrica abstrata
5.1.3. Fazer templates dos DAOs concretos e fábricas concretas
5.1.4. Testar
5.1.5. Fazer um template de criador de fábricas concretas