• Nenhum resultado encontrado

Exemplo 1 Objetivo: Demonstrar como fazer um interpretador simples

N/A
N/A
Protected

Academic year: 2021

Share "Exemplo 1 Objetivo: Demonstrar como fazer um interpretador simples"

Copied!
26
0
0

Texto

(1)

Objetivo: Demonstrar como fazer um interpretador simples

1. Criar novo projeto Java 2. Criar arquivo conta.math

3. Criar classe InterpretaMath.java

5. Criar um LineNumberReader/FileReader para o arquivo de entrada 6. Fazer o interpretador (cuidado com loop infinito)

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

(2)

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 : "+" | "-" | "*" | "/";

5. Fazer deploy e testar

6. Criar um novo projeto oaw vazio

7. Criar o arquivo, e testar as features do editor 8. 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. Criar novo objeto que extends AbstractWorkflowComponent2 8.3. Implementar métodos abstratos

8.4. No checkConfiguration, testar se slot está vazio 8.5. 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 ...

}

(3)

}

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

(4)

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

(5)

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

(6)

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)"/>

(7)

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)

(8)

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>

(9)

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() + "\");"); }

(10)

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

(11)

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

(12)

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 :

(13)

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

(14)

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;

(15)

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>

(16)

<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. Criar novo projeto Java

2. Adicionar natureza JET ao projeto 3. Ajustar as propriedades JET do projeto 4. 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?

(17)

Objetivo: Demonstrar o uso do JET e as tags

1. Criar novo projeto JET

2. Adicionar model loader org.eclipse.jet.emfxml no plugin.xml 3. Criar um conteúdo no sample.xml

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

(18)

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:

<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=" else">

if(evento.equals("<c:get select="$transicao/@nome"/>") && estadoAtual == <f:uc><c:get select="$transicao/origem/@nome" /></f:uc>)

(19)

</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)" />

(20)

* 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

(21)

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;

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:

(22)

}

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

(23)

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

(24)

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

(25)

</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());

(26)

} }

}

«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

Referências

Documentos relacionados

Ainda, em relação ao tempo total de contatos, foi medido o tempo de expressão do comportamento de “bri- ga”, expresso em porcentagem (Fig. Observa-se uma atividade

Effects of Continuance, Affective, and Moral Commitment on the Withdrawal Process: An Evaluation of Eight Structural Equation Models.. The Academy of

As cadeias laterais variam em certo nível entre as diferentes formas de clorofila encontradas em diferentes organismos, mas todas possuem uma cadeia fitol (um terpeno ) ligada

(Henriettea e Henriettella (Melastomataceae; Miconieae) no Rio de Janeiro, Brasil) É apresentado o tratamento taxonômico dos gêneros Henriettea e Henriettella na flora do estado do

A folha adulta é de tamanho médio, orbicular, com cinco lóbulos; limbo verde-escuro, plano, bolhosidade elevada; página inferior com baixa densidade de pêlos

Contudo, acreditamos que com essa atividade, conseguimos alcançar os objetivos destacados no início, contribuindo para levar uma Física mais atual para sala de aula, que possa dar

Um outro sistema robótico do tipo rodas, figura 10, é utilizado para inspecionar e limpar a superfície interna de dutos de concreto (Saenz, Elkmann, Stuerze, Kutzner, &amp;

• Capacitação e Transferência da metodologia do Sistema ISOR ® para atividades de Coaching e/ou Mentoring utilizando o método das 8 sessões;.. • Capacitação e Transferência