Exemplo 1
Objetivo: Demonstrar como fazer um interpretador simples
1.
2.
3.
5.
6.
7.
Criar novo projeto Java
Criar arquivo conta.math
Criar classe InterpretaMath.java
Criar um LineNumberReader/FileReader para o arquivo de entrada
Fazer o interpretador (cuidado com loop infinito)
Fazer agora um gerador de código para este arquivo
7.1. Criar um PrintWriter/FileWriter para jogar o programa gerado
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.
2.
3.
4.
Criar novo projeto xText
Explicar mais ou menos o que tem no projeto
Mostrar que sintaxe abstrata e concreta é junto
Mostrar que gera o metamodelo OO (Ecore)
Problema :
(expressoes += Expressao)*;
Expressao :
Armazena |
Operacao;
Armazena :
"Armazene" termo=INT;
Operacao :
sinal=SinalMatematico termo=INT;
String SinalMatematico :
"+" | "-" | "*" | "/";
5.
6.
7.
8.
Fazer deploy e testar
Criar um novo projeto oaw vazio
Criar o arquivo, e testar as features do editor
Fazer um interpretador
8.1. Criar um arquivo de workflow
<?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>
8.2.
8.3.
8.4.
8.5.
Criar novo objeto que extends AbstractWorkflowComponent2
Implementar métodos abstratos
No checkConfiguration, testar se slot está vazio
Conteúdo do método invoke
protected void invokeInternal(WorkflowContext ctx, ProgressMonitor monitor,
Issues issues) {
EObject conta = (EObject) ctx.get(slotConta);
EList<EObject> conteudoRaiz = conta.eContents();
float resultado = 0;
for (EObject expressao : conteudoRaiz) {
Integer valor = (Integer) expressao.eGet(expressao.eClass()
.getEStructuralFeature("termo"));
if (expressao.eClass().getName().equals("Armazena")) {
System.out.println(" Armazena " + valor);
resultado = valor.floatValue();
} else {
String sinal = (String) expressao.eGet(expressao.eClass()
.getEStructuralFeature("sinal"));
if (sinal.equals("+")) {
System.out.println(" Soma " + valor);
resultado = resultado + valor.floatValue();
} else ...
}
System.out.println("=" + resultado);
}
}
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>
2. Fazer um interpretador XML baseado em DOM
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("bla");
NodeList list = doc.getFirstChild().getChildNodes();
for(int i=0 ; i<list.getLength(); i++) {
Node n = list.item(i);
if(n.getNodeName().equals("inicial"))
System.out.println("inicial "+n.getTextContent());
else if(n.getNodeName().equals("soma"))
System.out.println("soma "+n.getTextContent());
else if(n.getNodeName().equals("subtracao"))
System.out.println("subtracao "+n.getTextContent());
}
Exemplo 7
Objetivo: Demonstrar os conceitos de metamodelagem na ferramenta
GME
1. Fazer o seguinte metamodelo
2. Explicar os conceitos da ferramenta, de metamodelagem, atributos, aspectos, ícones, constraints, etc, etc...
3. Fazer devagar, um elemento de cada vez
4. Deixar por último a parte da referência
Exemplo 8
Objetivo: Demonstrar o uso da API BON de metamodelagem para
interpretar modelos no GME
1. Criar novo projeto Java
2. Adicionar referência para gme.jar
3. Criar uma nova classe que implementa BonComponent
3.1. Implementar os métodos faltantes
4. Registrar o componente e testar
4.1. Não esqueça de rodar o programa de registro como administrador
O componente vai escrever um arquivo de saída (no desktop).
- Listar organograma completo (com superiores, e papéis)
- Listar atividades, tarefas e papéis associados
- Listar tarefas de cada pessoa
- ...
Começo do interpretador:
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
EObject conta = (EObject) ctx.get(slotConta);
EList<EObject> conteudoRaiz = conta.eContents();
// Soma dois quando armazena
// Transforma adição em subtração
// Duplica o valor da multiplicação
for (EObject expressao : conteudoRaiz) {
Integer valor = (Integer) expressao.eGet(expressao.eClass()
.getEStructuralFeature("termo"));
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>
4. Para testar, copia o executa do exemplo 5
4.1. E atualiza o 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;
transforma (Problema problema) :
problema.expressoes.incrementaArmazena() ->
problema.expressoes.select(e|e.metaType == Operacao).trocaSomaPorSubtracao() ->
problema.expressoes.select(e|e.metaType == Operacao).dobraValorDeMultiplicacao() ->
problema.adicionaExpressao();
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);
3. Copia o Executa e Workflow do Exemplo9
3.1. Acrescenta a chamada para a transformação
<component id="transforma2" class="oaw.xtend.XtendComponent">
<metaModel id="mm"
class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<invoke value="Transforma2::transforma(conta)"/>
</component>
Exemplo 11
Objetivo: Demonstrar transformações mais complexas utilizando
xText / xTend
1. Criar um novo projeto xText
2. Criar uma dsl para modelos OO e modelos ER
// specify your DSL grammar rules here ...
// IMPORTANT: You should change the property 'overwrite.pluginresources=true' in the properties
file to 'overwrite.pluginresources=false' AFTER first generation
Modelo : ModeloOO | ModeloER;
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;
// Deixar sem a String, pra mostrar
String TipoOO:
"texto" | "inteiro" | "real";
ModeloER:
"ModeloER" name=ID "["
(tabelas+=Tabela)*
"]";
Tabela:
"tabela" name=ID ":"
(colunas+=Coluna ";")*
(restricoes+=Restricao ";")*
";";
Coluna:
name=ID tipo=TipoER;
// Deixar sem a String, pra mostrar
String TipoER:
"VARCHAR" | "INT" | "REAL";
Restricao:
RestricaoChavePrimaria | RestricaoChaveEstrangeira;
RestricaoChavePrimaria:
"PRIM" coluna=[Coluna];
RestricaoChaveEstrangeira:
"ESTR" coluna=[Coluna] "->" tabelaEstrangeira=[Tabela] "." colunaEstrangeira=[Coluna];
3. Fazer um interpretador (AbstractWorkflowComponent2) que imprime os modelos
4. Fazer uma transformação OO->ER (UMA PARTE DE CADA VEZ)
import linguagemooer;
create ModeloER transformaOOER (ModeloOO modeloOO) :
this.setName(modeloOO.name+"Gerado") ->
this.tabelas.addAll(modeloOO.classes.tabela())
;
create Tabela tabela(Classe classe) :
this.setName("Tabela_"+classe.name) ->
this.colunas.add(chavePrimaria(classe)) ->
this.restricoes.add(restricaoChavePrimaria(chavePrimaria(classe))) ->
this.colunas.addAll(classe.membros.select(e|e.metaType.name=="linguagemooer::Atributo").c
oluna()) ->
this.colunas.addAll(classe.membros.select(e|e.metaType.name=="linguagemooer::Referencia")
.colunaChaveEstrangeira()) ->
this.restricoes.addAll(classe.membros.select(e|e.metaType.name=="linguagemooer::Referenci
a").restricaoChaveEstrangeira())
;
create Coluna chavePrimaria(Classe classe) :
this.setName(classe.name + "Id") ->
this.setTipo("INT")
;
create RestricaoChavePrimaria restricaoChavePrimaria(Coluna coluna) :
this.setColuna(coluna)
;
create Coluna coluna(Membro membro) :
this.setName("Coluna_"+membro.name) ->
this.setTipo(tipoER((Atributo)membro))
;
String tipoER(Atributo atributo) :
if(atributo.tipo == "texto")
then "VARCHAR"
else if(atributo.tipo == "inteiro")
then "INT"
else "REAL"
;
create Coluna colunaChaveEstrangeira(Membro referencia) :
this.setName(referencia.name) ->
this.setTipo("INT")
;
create RestricaoChaveEstrangeira restricaoChaveEstrangeira(Membro referencia) :
this.setColuna(colunaChaveEstrangeira(referencia)) ->
this.setTabelaEstrangeira(tabela(((Referencia)referencia).ref)) ->
this.setColunaEstrangeira(chavePrimaria(((Referencia)referencia).ref))
;
5. Fazer o workflow
<?xml version="1.0"?>
<workflow>
<component file="ooer/parser/Parser.oaw">
<modelFile value="modeloOO.ooer"/>
<outputSlot value="modeloOO"/>
</component>
<component id="transforma" class="oaw.xtend.XtendComponent">
<metaModel id="mm"
class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<invoke value="transforma::transformaOOER(modeloOO)"/>
<outputSlot value="modeloERGerado"/>
</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!");
}
private void geraQuestionario(JBuilderModel modeloDecisoes) {
pw.println("import java.io.*;");
pw.println("public class Questionario {");
pw.println("static BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));");
Vector<JBuilderObject> elementos = modeloDecisoes.getChildren();
for (JBuilderObject elemento : elementos) {
if (elemento.getMeta().getName().equals("Questao"))
geraMetodoQuestao((JBuilderAtom) elemento);
else if (elemento.getMeta().getName().equals("Mensagem"))
geraMetodoMensagem((JBuilderAtom) elemento);
}
pw.println("public static void main(String[] args) throws IOException {");
Vector<JBuilderAtom> inicio = modeloDecisoes.getAtoms("Inicio");
Vector<JBuilderConnection> inicioConexao = inicio.firstElement()
.getOutConnections("InicioConexao");
JBuilderAtom elemento = (JBuilderAtom) inicioConexao.firstElement()
.getDestination();
pw.println(arrumaNome(elemento.getName()) + "();");
pw.println("}");
pw.println("}");
}
private void geraMetodoQuestao(JBuilderAtom questao) {
pw.println("private static void " + arrumaNome(questao.getName()) + "() throws
IOException {");
pw.print("System.out.println(\"");
pw.print(questao.getName());
pw.println("\");");
Vector<JBuilderConnection> respostasConnections = questao
.getOutConnections("Resposta");
int i = 1;
for (JBuilderConnection resposta : respostasConnections) {
pw.println("System.out.println(\"" + (i++) + ": "
+ resposta.getName() + "\");");
}
pw.println("int op = Integer.parseInt(br.readLine());");
i = 1;
for (JBuilderConnection resposta : respostasConnections) {
pw.println("if(op == " + (i++) + ") {");
pw.println(arrumaNome(resposta.getDestination().getName()) + "();");
pw.println("return;");
pw.println("}");
}
pw.println("}");
}
private void geraMetodoMensagem(JBuilderAtom mensagem) {
pw.println("private static void " + arrumaNome(mensagem.getName()) + "() throws
IOException {");
pw.println("System.out.println(\"" + mensagem.getName() + "\");");
pw.println("br.readLine();");
Vector<JBuilderConnection> links = mensagem.getOutConnections("Link");
if (!links.isEmpty())
pw.println(arrumaNome(links.firstElement().getDestination()
.getName())
+ "();");
pw.println("}");
}
private String arrumaNome(String nome) {
return nome.replaceAll(" ", "").replaceAll("\\?", "").replaceAll("!",
"").replaceAll("ç", "c").replaceAll("ê", "e").replaceAll(",",
"").replaceAll("ã", "a").replaceAll("-", "");
}
@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
3. Mudar para ficar redondo os retângulos, e as transições terem setas
4. Adicionar características do estado
4.1. Modificar para ter um compartimento nos estados com as características
4.1.1. gmftool: novo creation tool
4.1.2. gmfgraph: novo diagram label, novo compartment
4.1.3. gmfmap: novo compart mapping, novo child ref, novo node mapping, novo label mapping
5.Modificar os ícones
5.1. Substituir os gifs no edit
5.2. Apagar o projeto do diagram, apagar os plugins .jar
5.3. Gerar de novo, sem nenhum plugin instalado
6. Adicionar estados inicial e final
6.1. Não esquecer de transformar Estado em abstract
6.2. Modificar os nós Estado para EstadoIntermediario
6.3. Criar as ferramentas, graphs e mappings para os novos estados
7. Adicionar link constraints para não criar transições erradas nos estados inicial e final
if (source instanceof maquinaEstados.EstadoFinal)
return false;
if (target instanceof maquinaEstados.EstadoInicial)
return false;
if (source instanceof maquinaEstados.EstadoInicial) {
java.util.List<maquinaEstados.Transicao> todasTransicoes = container.getTransicoes();
for(maquinaEstados.Transicao t:todasTransicoes) {
if(t.getOrigem() == source) return false;
}
}
8. Adicionar um audit constraint para não deixar criar mais de um estado inicial
java.util.List<maquinaEstados.Estado> estados = context.getEstados();
int cont = 0;
for(maquinaEstados.Estado e : estados) {
if(e instanceof maquinaEstados.EstadoInicial) cont++;
}
if(cont > 1) return org.eclipse.core.runtime.Status.CANCEL_STATUS;
return org.eclipse.core.runtime.Status.OK_STATUS;
9. Para comparar com GME, fazer um exemplo de modelo de decisões
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]
;
3. Criar checagens – UMA DE CADA VEZ
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 MaquinaDeEstados ERROR "Deve haver um (e somente um) estado inicial!" :
this.estados.select(e|e.tipo == "inicial").size == 1;
//context Estado if(this.tipo=="inicial") ERROR "Deve haver um (e somente um) estado inicial 2!"
:
//
((MaquinaDeEstados)this.eContainer).estados.select(e|e.tipo == "inicial").size == 1;
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;
4. Fazer ícones especiais, e corrigir os labels padrão
4.1. EditorExtensions.ext
label(Estado this): "estado" + this.name;
label(Evento this): "evento" + this.name;
label(Transicao this): this.evento.name + "->" + this.estado.name;
image(Estado this): this.tipo == "inicial" ? "keyword.gif" : "default.gif";
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()));
List[Proposal] completeTransicao_evento(Estado estado, String prefix) :
estado.allVisibleElements().typeSelect(Evento).select(e|estado.transicoes.forAll(t2|t2.ev
ento != e)).collect(x|newProposal(x.label(),x.id(),x.image()));
//estado.allVisibleElements().typeSelect(Evento).removeAll(estado.transicoes.collect(t2|t
2.evento)).collect(x|newProposal(x.label(),x.id(),x.image()));
6. Para comparar com GMF/GME, fazer modelo de decisões
Exemplo 16
Objetivo: Demonstrar as funcionalidades da linguagem ATL
1. Criar novo projeto ATL
2. Criar dois metamodelos: familias e pessoas
3. Criar um novo ATL file
module familiasParaPessoas; -- Module Template
create SAIDA : pessoas from ENTRADA : familias;
helper context familias!Membro def: eMulher() : Boolean =
self.eMae() or self.eFilha();
helper context familias!Membro def: eMae() : Boolean =
if (not self.refImmediateComposite().mae.oclIsUndefined()) then
if (self.refImmediateComposite().mae = self) then
true
else
false
endif
else
false
endif;
helper context familias!Membro def: eFilha() : Boolean =
if (self.refImmediateComposite().filhas.includes(self)) then
true
else
false
endif;
helper context familias!Membro def: sobrenome() : String =
self.refImmediateComposite().sobrenome;
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()
)
}
4. Criar um novo Run configuration
Exemplo 17
Objetivo: Demonstrar as funcionalidades da linguagem xTend
1. Criar novo projeto oaw
2. Criar extensões
import maquinaestados;
adicionaEstadoEmergencia( MaquinaDeEstados this ):
this.eventos.add(eventoEmergencia()) ->
this.estados.add(estadoEmergencia()) ->
this.estados.adicionaTransicaoParaEmergencia();
create Evento eventoEmergencia():
this.setName("emergencia");
create Estado estadoEmergencia():
this.setName("emergencia");
create Transicao adicionaTransicaoParaEmergencia(Estado estado):
estado.transicoes.add(this) ->
this.setEvento(eventoEmergencia()) ->
this.setEstado(estadoEmergencia());
import maquinaEstados;
adicionaEstadoEmergencia( MaquinaDeEstados this ):
this.estados.add(estadoEmergencia()) ->
this.estados.adicionaTransicaoParaEmergencia();
create EstadoIntermediario estadoEmergencia():
this.setNome("emergencia");
create Transicao adicionaTransicaoParaEmergencia(Estado estado):
((MaquinaDeEstados)estado.eContainer).transicoes.add(this) ->
this.setNome("emergencia") ->
this.setOrigem(estado) ->
this.setDestino(estadoEmergencia());
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>
<component id="transforma" class="oaw.xtend.XtendComponent">
<metaModel id="mm"
class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<invoke value="transforma2::adicionaEstadoEmergencia(maquinaEstados2)"/>
</component>
<component id="write" class="org.eclipse.mwe.emf.Writer">
<useSingleGlobalResourceSet value="true"/>
<modelSlot value="maquinaEstados"/>
<uri value="/Users/daniel/Desktop/workspace/Exemplo17/dump.xmi"/>
</component>
<component id="write" class="org.eclipse.mwe.emf.Writer">
<useSingleGlobalResourceSet value="true"/>
<modelSlot value="maquinaEstados2"/>
<uri value="/Users/daniel/Desktop/workspace/Exemplo17/dump2.xmi"/>
</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.
2.
3.
4.
Criar novo projeto Java
Adicionar natureza JET ao projeto
Ajustar as propriedades JET do projeto
Criar novo arquivo helloworld.txtjet
<%@ jet package="hello" class="HelloWorldTemplate" %>
Hello, world!
5. Criar uma classe principal e executar o exemplo
HelloWorldTemplate helloworld = new HelloWorldTemplate();
String result = helloworld.generate(null);
System.out.println(result);
6. Mostrar <%=argument%> String (novo arquivo)
7. Mostrar <%=argument%> List, criando um XML com conteúdo (novo arquivo)
8. E se for gerar um JSP? startTag=”<$” endTag=”$>” (novo arquivo)
8.1. Mostrar rodando, e explicar com calma
9. Mostrar mais detalhes sobre o gerador gerado, objetos que dá pra usar (stringBuffer) (novo
arquivo)
10. Mostrar como mudar o gerador gerado (skeleton)
public class CLASS implements IGerador {
/* Minha classe geradora */
public String gerar(Object argumento) {
return "";
}
}
11. Mostrar include <%@ include file=”bla” %>
11.1. Mostrar inclusão de .txt
11.2. Mostrar inclusão de .jetf
12. O include anterior é chamado durante tradução. E se eu quiser executar o template e copiar o
resultado?
12.1. Inserir scriplets pra chamar a classe gerada explicitamente
Exemplo 19
Objetivo: Demonstrar o uso do JET e as tags
1.
2.
3.
4.
Criar novo projeto JET
Adicionar model loader org.eclipse.jet.emfxml no plugin.xml
Criar um conteúdo no sample.xml
Criar um gerador de exemplo
<c:iterate select="/root/familia" var="familia">
Familia: <c:get select="$familia/@sobrenome" />
Pai: <c:get select="$familia/pai/@nome" />
Mãe: <c:get select="$familia/mae/@nome" />
<c:if test="$familia/filho">
Filhos: <c:iterate select="$familia/filho" var="filho" delimiter=","
><c:get select="$filho/@nome" /></c:iterate>
</c:if>
</c:iterate>
5. Mostrar como incluir outros templates
<c:include template="templates/anotacoes.jet" />
6. Mostrar como é possível anotar o modelo de entrada
6.1. Mostrar o dump.xml para ver a saída
<c:iterate select="/root/familia" var="familia">
<c:set select="$familia/pai" name="nomeCompleto"><c:get select="$familia/pai/@nome" />
<c:get select="$familia/@sobrenome" /></c:set>
<c:set select="$familia/mae" name="nomeCompleto"><c:get select="$familia/mae/@nome" />
<c:get select="$familia/@sobrenome" /></c:set>
<c:iterate select="$familia/filho" var="filho">
<c:set select="$filho" name="nomeCompleto"><c:get select="$filho/@nome" /> <c:get
select="$familia/@sobrenome" /></c:set>
</c:iterate>
<c:addElement select="/root" name="pessoa" var="pessoaPai" />
<c:set select="$pessoaPai" name="genero">Homem</c:set>
<c:set select="$pessoaPai" name="nome"><c:get select="$familia/pai/@nome" /></c:set>
<c:set select="$pessoaPai" name="sobrenome"><c:get select="$familia/@sobrenome"
/></c:set>
<c:addElement select="/root" name="pessoa" var="pessoaMae" />
<c:set select="$pessoaMae" name="genero">Mulher</c:set>
<c:set select="$pessoaMae" name="nome"><c:get select="$familia/mae/@nome" /></c:set>
<c:set select="$pessoaMae" name="sobrenome"><c:get select="$familia/@sobrenome"
/></c:set>
<c:iterate select="$familia/filho" var="filho">
<c:addElement select="/root" name="pessoa" var="pessoaFilho" />
<c:set select="$pessoaFilho" name="genero">Homem</c:set>
<c:set select="$pessoaFilho" name="nome"><c:get select="$filho/@nome" /></c:set>
<c:set select="$pessoaFilho" name="sobrenome"><c:get select="$familia/@sobrenome"
/></c:set>
</c:iterate>
</c:iterate>
7. Mostrar as tags ws:project e ws:folder
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.
2.
3.
4.
5.
Criar novo projeto JET
Estender a ferramenta de estados para incluir ações
Criar um modelo de exemplo (refrigerador)
Adicionar model loader org.eclipse.jet.emf no plugin.xml
Criar templates para anotações e uma classe da máquina de estados
Anotações:
<c:iterate select="/MaquinaDeEstados/EstadoInicial" var="estado">
<c:set select="$estado" name="nome">INICIAL</c:set>
<c:set select="$estado" name="constante">0</c:set>
</c:iterate>
<% int constanteEstado = 1; %>
<c:iterate select="/MaquinaDeEstados/EstadoIntermediario" var="estado">
<c:set select="$estado" name="constante"><%=constanteEstado++%></c:set>
</c:iterate>
<c:iterate select="/MaquinaDeEstados/EstadoFinal" var="estado">
<c:set select="$estado" name="constante"><%=constanteEstado++%></c:set>
</c:iterate>
<% constanteEstado = 1; %>
<c:iterate select="/MaquinaDeEstados/EstadoFinal" var="estado">
<c:if test="not($estado/@nome)">
<c:set select="$estado" name="nome">FINAL_<%=constanteEstado++%></c:set>
</c:if>
</c:iterate>
<c:iterate select="/MaquinaDeEstados/estados" var="estado">
<c:iterate select="$estado/acoes" var="acao">
<c:set select="$acao" name="metodoAcao"><f:replaceAll value=" " replacement="_"><c:get
select="$acao/@nome" /></f:replaceAll></c:set>
</c:iterate>
</c:iterate>
Template da máquina de estados:
package gerado;
import java.util.HashMap;
import java.util.Map.Entry;
public class MaquinaEstados {
// estado inicial
private final static int INICIAL = 0;
// estados intermediarios e finais
<c:iterate select="/MaquinaDeEstados/EstadoIntermediario" var="estado">
private final static int <f:uc><c:get select="$estado/@nome" /></f:uc> = <c:get
select="$estado/@constante" />;
</c:iterate>
<c:iterate select="/MaquinaDeEstados/EstadoFinal" var="estado">
private final static int <f:uc><c:get select="$estado/@nome" /></f:uc> = <c:get
select="$estado/@constante" />;
</c:iterate>
private int estadoAtual = 0;
private HashMap<String,String> caracteristicas = new HashMap<String,String>();
public void disparaEvento(String evento) {
System.out.println("Evento:" + evento);
<c:iterate select="/MaquinaDeEstados/transicoes" var="transicao" delimiter="
if(evento.equals("<c:get select="$transicao/@nome"/>") && estadoAtual ==
<f:uc><c:get select="$transicao/origem/@nome" /></f:uc>)
else">
estadoAtual = <f:uc><c:get select="$transicao/destino/@nome" /></f:uc>;
</c:iterate>
mudaCaracteristicas();
executaAcoes();
}
private void mudaCaracteristicas() {
<c:iterate select="/MaquinaDeEstados/estados" var="estado" delimiter="
else">
if(estadoAtual == <f:uc><c:get select="$estado/@nome" /></f:uc>) {
<c:iterate select="$estado/caracteristicas" var="caracteristica">
caracteristicas.put("<c:get select="$caracteristica/@nome"/>","<c:get
select="$caracteristica/@expressao"/>");
</c:iterate>
}
</c:iterate>
}
private void executaAcoes() {
<c:iterate select="/MaquinaDeEstados/estados" var="estado">
<c:if test="$estado/acoes">
if(estadoAtual == <f:uc><c:get select="$estado/@nome" /></f:uc>) {
<c:iterate select="$estado/acoes" var="acao">
<c:get select="$acao/@metodoAcao"/>();
</c:iterate>
}
</c:if>
</c:iterate>
}
<c:iterate select="/MaquinaDeEstados/estados" var="estado">
<c:iterate select="$estado/acoes" var="acao">
private void <c:get select="$acao/@metodoAcao"/>() {
<c:userRegion>
// inicio <c:get select="$acao/@metodoAcao"/>
<c:initialCode>
// ... insira o código aqui ...
</c:initialCode>
// fim <c:get select="$acao/@metodoAcao"/>
</c:userRegion>
}
</c:iterate>
</c:iterate>
public void imprimeEstadoAtual() {
<c:iterate select="/MaquinaDeEstados/estados" var="estado" delimiter="
else">
if(estadoAtual == <f:uc><c:get select="$estado/@nome" /></f:uc>)
System.out.println("Estado atual: <c:get select="$estado/@nome" />");
</c:iterate>
}
public void imprimeCaracteristicas() {
for(Entry<String,String> e : caracteristicas.entrySet()) {
System.out.println(e.getKey()+": "+e.getValue());
}
}
}
6. Fazer a versão abstrata
7. Demonstrar que dá pra incluir um template no outro
<f:indent text="
" depth="1">
/*
* Máquina de estados gerada
* Data: <f:formatNow pattern="dd/MM/yyyy : EEE" />
* Número de estados: <c:get select="count(/MaquinaDeEstados/estados)" />
* Número de estados finais: <c:get select="count(/MaquinaDeEstados/EstadoFinal)" />
* Número de estados intermediários: <c:get select="count(/MaquinaDeEstados/EstadoIntermediario)"
/>
* Número de transições: <c:get select="count(/MaquinaDeEstados/transicoes)" />
*/
</f:indent>
8. Fazer o gerador de htmls para o exercício do modelo de decisões
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
Familias : (familias += Familia)*;
Familia :
"Familia" sobrenome=STRING "("
pai=Pai
mae=Mae
(filhos += Filho)*
")"
;
Pai: "pai" "=" nome=STRING;
Mae: "mae" "=" nome=STRING;
Filho: "filho" "=" nome=STRING;
3. Criar um gerador simples
«IMPORT familia»
«DEFINE main FOR Familias»
«FILE "familias.txt"»
«FOREACH this.familias AS f-»
«EXPAND familia FOR f-»
«ENDFOREACH-»
«ENDFILE-»
«ENDDEFINE»
«DEFINE familia FOR Familia-»
====== Família «sobrenome» ==========
Pai: «pai.nome»
Mãe: «mae.nome»
«IF !filhos.isEmpty-»
=========== Filhos =============
«FOREACH filhos AS filho-»
«filho.nome»
«ENDFOREACH-»
«ENDIF-»
«ENDDEFINE»
4. Mostrar que dá pra transformar pra ajudar na geração
transforma(Familias f) :
f.familias.criaFilho() ->
f.familias.trocaEsposa();
create Filho criaFilho(Familia f) :
f.filhos.add(this) ->
this.setNome("Filho da familia "+f.sobrenome);
trocaEsposa(Familia f) :
f.mae.setNome("Nova esposa");
5. Mostrar que dá pra fazer extensões e ajudar na geração
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
evento
evento
evento
evento
evento
liga;
ligaAlarme;
desligaAlarme;
toca;
soneca;
fimsoneca;
estado inicial inicio {
caracteristicas:
transicoes:
liga -> ligado;
acoes:
}
estado intermediario ligado {
caracteristicas:
"horario" : "nenhum";
"caixa de som" : "desligada";
transicoes:
ligaAlarme -> alarmeLigado;
acoes:
}
estado intermediario alarmeLigado {
caracteristicas:
"horario" : "especificado";
"caixa de som" : "desligada";
transicoes:
desligaAlarme -> ligado;
toca -> tocando;
acoes:
especificaHorario;
}
estado intermediario tocando {
caracteristicas:
"horario" : "especificado";
"caixa de som" : "ligada";
transicoes:
soneca -> soneca;
desligaAlarme -> ligado;
acoes:
tocaSom;
}
estado intermediario soneca {
caracteristicas:
"horario" : "especificado";
"caixa de som" : "desligada";
transicoes:
fimsoneca -> tocando;
desligaAlarme -> ligado;
acoes:
comecaContagemSoneca;
}
4. Criar um gerador similar ao exemplo21
«IMPORT maquinaestados»
«EXTENSION me::Extensions»
«DEFINE main FOR MaquinaDeEstados»
«FILE "MaquinaDeEstadosAbstrata.java"-»
import java.util.HashMap;
import java.util.Map.Entry;
public abstract class MaquinaDeEstadosAbstrata {
public enum Estado {«FOREACH estados AS estado SEPARATOR ","-»
«estado.nomeConstanteEstado()-»«ENDFOREACH-» };
private Estado estadoAtual = Estado.«estados.selectFirst(estado|estado.tipo ==
"inicial").nomeConstanteEstado()»;
private HashMap<String,String> caracteristicas = new HashMap<String,String>();
«FOREACH eventos AS evento-»
public void «evento.name»() {
«FOREACH estados AS estado-»
«FOREACH estado.transicoes.select(t|t.evento == evento) AS transicao-»
if(estadoAtual == Estado.«estado.nomeConstanteEstado()-») {
estadoAtual = Estado.«transicao.estado.nomeConstanteEstado()-»;
«FOREACH transicao.estado.acoes AS acao-»
«acao.name»();
«ENDFOREACH-»
«FOREACH transicao.estado.caracteristicas AS caracteristica-»
caracteristicas.put("«caracteristica.name»","«caracteristica.expressao»");
«ENDFOREACH-»
}
«ENDFOREACH-»
«ENDFOREACH-»
}
«ENDFOREACH-»
«FOREACH estados.acoes AS acao-»
protected abstract void «acao.name»();
«ENDFOREACH»
public void imprimeEstadoAtual() {
System.out.println("Estado:"+ estadoAtual);
for(Entry<String,String> e : caracteristicas.entrySet()) {
System.out.println(e.getKey()+": "+e.getValue());
}
}
}
«ENDFILE»
«ENDDEFINE»
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();
create Evento eventoFinal(MaquinaDeEstados me) :
me.eventos.add(this) ->
this.setName("desliga");
create Estado estadoFinal(MaquinaDeEstados me) :
me.estados.add(this) ->
this.setName("desligado") ->
this.setTipo("final");
create Transicao transicaoParaEstadoFinal(Estado e) :
this.setEvento(eventoFinal((MaquinaDeEstados)e.eContainer)) ->
this.setEstado(estadoFinal((MaquinaDeEstados)e.eContainer)) ->
e.transicoes.add(this);
6. Questão: como garantir que a classe abstrata será implementada?
6.1. Opção 1: hack
static {
if(false) {
MaquinaDeEstadosAbstrata me = new MaquinaDeEstadosConcreta();
}
}
7. Recipes
7.1. Adicionar referências aos plugins *recipe
7.2. Criar um RecipeCreator
package recipes;
public class RecipeCreator extends RecipeCreationComponent {
@Override
protected Collection<org.openarchitectureware.recipe.core.Check> createRecipes(
Object modelSlotContent, String appProject) {
List<Check> checks = new ArrayList<Check>();
CompositeCheck cc = new CompositeCheck(
"Implementação concreta da máquina de estados.",
"Implementação concreta da máquina de estados.");
JavaClassExistenceCheck javaClassExistenceCheck = new JavaClassExistenceCheck(
"Você deve prover uma implementação concreta", appProject,
"principal.MaquinaDeEstadosConcreta");
javaClassExistenceCheck
.setLongDescription("Você deve prover uma implementação concreta");
JavaSupertypeCheck javaSuperclassCheck = new JavaSupertypeCheck(
"A implementação concreta deve estender MaquinaDeEstadosAbstrata",
appProject, "principal.MaquinaDeEstadosConcreta",
"gerado.MaquinaDeEstadosAbstrata");
cc.addChild(javaClassExistenceCheck);
cc.addChild(javaSuperclassCheck);
checks.add(cc);
return checks;
}
}
7.3. Adicionar chamada no workflow
<component id="recipe" class="recipes.RecipeCreator">
<appProject value="Exemplo23"/>
<modelSlot value="theModel"/>
<recipeFile value="recipes.recipes"/>
</component>
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>
<!-- ler modelo de dados -->
<component class="org.eclipse.mwe.emf.Reader">
<uri value="${modelFile}" />
<modelSlot value="modelo" />
</component>
<component id="transforma" class="oaw.xtend.XtendComponent">
<metaModel id="mm"
class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<invoke value="transforma::corrigeNomeEstados(modelo)"/>
</component>
<!-- gerar codigo para modelo de dados -->
<component class="org.openarchitectureware.xpand2.Generator">
<metaModel id="mm"
class="org.openarchitectureware.type.emf.EmfMetaModel">
<metaModelFile value="model/maquinaEstados.ecore"/>
</metaModel>
<expand
value="Main::main FOR modelo" />
<genPath value='${targetDir}'/>
</component>
</workflow>
3. Transformação para corrigir nomes de estados em branco
<?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>
<!-- ler modelo de dados -->
<component class="org.eclipse.mwe.emf.Reader">
<uri value="${modelFile}" />
<modelSlot value="modelo" />
</component>
<component id="transforma" class="oaw.xtend.XtendComponent">
<metaModel id="mm"
class="org.eclipse.m2t.type.emf.EmfRegistryMetaModel"/>
<invoke value="transforma::corrigeNomeEstados(modelo)"/>
</component>
<!-- gerar codigo para modelo de dados -->
<component class="org.openarchitectureware.xpand2.Generator">
<metaModel id="mm"
class="org.openarchitectureware.type.emf.EmfMetaModel">
<metaModelFile value="model/maquinaEstados.ecore"/>
</metaModel>
<expand
value="Main::main FOR modelo" />
<genPath value='${targetDir}'/>
</component>
</workflow>
4. Extensões para ajudar
import maquinaEstados;
corrigeNome(String str) :
str.replaceAll(" ","_");
5. Template principal
«IMPORT maquinaEstados»
«EXTENSION extensions»
«DEFINE main FOR MaquinaDeEstados»
«FILE "gerado/MaquinaDeEstadosAbstrata.java"-»
package gerado;
import java.util.HashMap;
import java.util.Map.Entry;
public abstract class MaquinaDeEstadosAbstrata {
public enum Estado {«FOREACH estados AS estado SEPARATOR ","-»
«estado.nome-»«ENDFOREACH-» };
private Estado estadoAtual = Estado.«estados.typeSelect(EstadoInicial).first().nome»;
private HashMap<String,String> caracteristicas = new HashMap<String,String>();
«FOREACH transicoes.collect(t|t.nome).toSet() AS evento-»
public void evento_«evento.corrigeNome()»() {
System.out.println("Evento: «evento.corrigeNome()»");
«FOREACH estados AS estado-»
«FOREACH transicoes.select(t|t.nome == evento && t.origem == estado) AS transicao»
if(estadoAtual == Estado.«estado.nome-») {
estadoAtual = Estado.«transicao.destino.nome-»;
«FOREACH transicao.destino.acoes AS acao-»
«acao.nome.corrigeNome()»();
«ENDFOREACH-»
«FOREACH transicao.destino.caracteristicas AS caracteristica-»
caracteristicas.put("«caracteristica.nome»","«caracteristica.expressao»");
«ENDFOREACH-»
}
«ENDFOREACH-»
«ENDFOREACH-»
}
«ENDFOREACH-»
«FOREACH estados.acoes AS acao-»
protected abstract void «acao.nome.corrigeNome()»();
«ENDFOREACH»
public void imprimeEstadoAtual() {
System.out.println("Estado:"+ estadoAtual);
for(Entry<String,String> e : caracteristicas.entrySet()) {
System.out.println(e.getKey()+": "+e.getValue());
}
}
}
«ENDFILE»
«ENDDEFINE»
6. Fazer o exemplo do modelo de decisões, para comparar, gerando um html
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
Download

Scripts