• Ingen resultater fundet

Advanced Topics in Software Engineering

N/A
N/A
Info
Hent
Protected

Academic year: 2022

Del "Advanced Topics in Software Engineering"

Copied!
30
0
0

Indlæser.... (se fuldtekst nu)

Hele teksten

(1)

Advanced Topics in

Software Engineering (02265)

Ekkart Kindler

(2)

Ekkart Kindler

2 ATSE (02265), L05: Model to Text Transformations

V. Transformations

(3)

Ekkart Kindler

Motivation (cf. Vision)

Place Transition

1 source 1 target

Arc

* PetriNet

Token

* Node

Object

Analysis

Design

Implementation

Coding

Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName

Bundle-SymbolicName: APetriNetEditorIn15Minutes.diagr Bundle-Version: 1.0.0.qualifier

Bundle-ClassPath: .

Bundle-Activator: PetriNets.diagram.part.PetriNetDiagr Bundle-Vendor: %providerName

Bundle-Localization: plugin Export-Package: PetriNets.diagram.edit.parts,

PetriNets.diagram.part, PetriNets.diagram.providers Require-Bundle: org.eclipse.core.runtime,

org.eclipse.core.resources, org.eclipse.core.expressions, org.eclipse.jface, org.eclipse.ui.ide, org.eclipse.ui.views, org.eclipse.ui.navigator, org.eclipse.ui.navigator.resources, org.eclipse.emf.ecore, org.eclipse.emf.ecore.xmi, org.eclipse.emf.edit.ui, org.eclipse.gmf.runtime.emf.core, org.eclipse.gmf.runtime.emf.commands.core, org.eclipse.gmf.runtime.emf.ui.properties, org.eclipse.gmf.runtime.diagram.ui, org.eclipse.gmf.runtime.diagram.ui.properties, org.eclipse.gmf.runtime.diagram.ui.providers, org.eclipse.gmf.runtime.diagram.ui.providers.ide, org.eclipse.gmf.runtime.diagram.ui.render, org.eclipse.gmf.runtime.diagram.ui.resources.ed org.eclipse.gmf.runtime.diagram.ui.resources.e APetriNetEditorIn15Minutes;visibility:=reexpor

package PetriNets.impl;

public class PetriNetImpl extends EObjectImpl implements PetriNet { protected EList<PetriNets.Object> object;

protected PetriNetImpl() { super();

}

protected EClass eStaticClass() { return PetriNetsPackage.Literals.PETRI_NET;

}

public EList<PetriNets.Object> getObject() { if (object == null) {

object = new EObjectContainmentEList<PetriNets.Object>(Petri }

return object;

}

public NotificationChain eInverseRemove(InternalEObject otherEnd, int switch (featureID) {

case PetriNetsPackage.PETRI_NET__OBJECT:

return ((InternalEList<?>)getObject()).basicRemove(otherEn }

return super.eInverseRemove(otherEnd, featureID, msgs);

}

public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) {

case PetriNetsPackage.PETRI_NET__OBJECT:

return getObject();

}

return super.eGet(featureID, resolve, coreType);

Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName

Bundle-SymbolicName: APetriNetEditorIn15Minutes.diagr Bundle-Version: 1.0.0.qualifier

Bundle-ClassPath: .

Bundle-Activator: PetriNets.diagram.part.PetriNetDiagr Bundle-Vendor: %providerName

Bundle-Localization: plugin Export-Package: PetriNets.diagram.edit.parts,

PetriNets.diagram.part, PetriNets.diagram.providers Require-Bundle: org.eclipse.core.runtime,

org.eclipse.core.resources, org.eclipse.core.expressions, org.eclipse.jface, org.eclipse.ui.ide, org.eclipse.ui.views, org.eclipse.ui.navigator, org.eclipse.ui.navigator.resources, org.eclipse.emf.ecore, org.eclipse.emf.ecore.xmi, org.eclipse.emf.edit.ui, org.eclipse.gmf.runtime.emf.core, org.eclipse.gmf.runtime.emf.commands.core, org.eclipse.gmf.runtime.emf.ui.properties, org.eclipse.gmf.runtime.diagram.ui, org.eclipse.gmf.runtime.diagram.ui.properties, org.eclipse.gmf.runtime.diagram.ui.providers, org.eclipse.gmf.runtime.diagram.ui.providers.ide, org.eclipse.gmf.runtime.diagram.ui.render, org.eclipse.gmf.runtime.diagram.ui.resources.ed org.eclipse.gmf.runtime.diagram.ui.resources.e APetriNetEditorIn15Minutes;visibility:=reexpor

package PetriNets.impl;

public class PetriNetImpl extends EObjectImpl implements PetriNet { protected EList<PetriNets.Object> object;

protected PetriNetImpl() { super();

}

protected EClass eStaticClass() { return PetriNetsPackage.Literals.PETRI_NET;

}

public EList<PetriNets.Object> getObject() { if (object == null) {

object = new EObjectContainmentEList<PetriNets.Object>(Petri }

return object;

}

public NotificationChain eInverseRemove(InternalEObject otherEnd, int switch (featureID) {

case PetriNetsPackage.PETRI_NET__OBJECT:

return ((InternalEList<?>)getObject()).basicRemove(otherEn }

return super.eInverseRemove(otherEnd, featureID, msgs);

}

public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) {

case PetriNetsPackage.PETRI_NET__OBJECT:

return getObject();

}

return super.eGet(featureID, resolve, coreType);

(4)

Ekkart Kindler

4 ATSE (02265), L05: Model to Text Transformations

Motivation

 If we want to get software automatically from models, we need to have a technology for

transforming models into code

 Programming this transformation manually is very error prone (and not in the spirit of our endavour)

 In esssence, we need a technology for transforming

Models to Text: M2T-transformation

(5)

Ekkart Kindler

1. M2T-Transformations

 Main idea: Template

Dear <Name>,

we are pleased to inform you that you you will be refunded

<amount> in income tax.

The reason is that <reason>.

Best regards,

<clerkname>

Standard text in which some

“specifics” will be filled in

(attributes/parameters/fields).

(6)

Ekkart Kindler

6 ATSE (02265), L05: Model to Text Transformations

Java Emitter Templates (JET)

 There are different concrete tempalte technologies (JET, Xpand, Acceleo) that are made for transformin models into some form of text

 The ideas will be presented based on the Java

Emitter Templates (JET)

(7)

Ekkart Kindler

1.1 Example: Component Definition

%--- Overview of component definition

%--- The components name is "Move".

The automaton has 4 states:

init (initial) walk

running standing

%---

(8)

Ekkart Kindler

8 ATSE (02265), L05: Model to Text Transformations

Example: ”template” it

%--- Overview of component definition

%--- The components name is "Move".

The automaton has 4 states:

init (initial) walk

running standing

%---

(9)

Ekkart Kindler

Example: ”template” it more

%--- Overview of component definition

%--- The components name is "Move".

The automaton has 4 states:

init (initial) walk

running standing

%---

%--- Overview of component definition

%--- The components name is "<name>".

The automaton has <no-states>

states:

<foreach state>

<state.name> <initial>

<hcaerof>

%---

(10)

Ekkart Kindler

10 ATSE (02265), L05: Model to Text Transformations

Example: Java it

%--- Overview of component definition

%---

The components name is "< c.getName() >".

The automaton has

< c.getAutomaton().getState().size() > states:

< for (State s:c.getAutomaton().getState() ) { >

< s.getName() > < s.isIntial() ? "(initial)" : "" >

< } >

%---

(11)

Ekkart Kindler

Example: JET it

<%@ jet package="translated" class="SimpleAutomaton"

imports="dk.dtu.imm.se2e09.casetool.componentdefinition.*"

%> %>

%--- Overview of component definition

%---

<%

ComponentDefinition c = (ComponentDefinition) argument;

Automaton a = c.getAutomaton();

%>

The components name is "<%= c.getName() %>".

The automaton has <%= a.getState().size() %> states:

<% for (State s:a.getState()) { %>

<%= s.getName() %> <%= s.isIntial() ? "(initial)" : "" %>

<% } %>

%---

(12)

Ekkart Kindler

12 ATSE (02265), L05: Model to Text Transformations

Example: Lessons learned

 Principle behind JET is simple

 The final JET-template is not very readable

 But it is not difficult to ”work through” it

(see later: class that does transformation)

 Always start from a concrete example, that you turn

into a template

(13)

Ekkart Kindler

1.2 Concepts

<%@ jet package="translated" class="SimpleAutomaton"

imports="dk.dtu.imm.se2e09.casetool.componentdefinition.*"

%> %>

%--- Overview of component definition

%---

<%

ComponentDefinition c = (ComponentDefinition) argument;

Automaton a = c.getAutomaton();

%>

The components name is "<%= c.getName() %>".

The automaton has <%= a.getState().size() %> states:

<% for (State s:a.getState()) { %>

<%= s.getName() %> <%= s.isIntial() ? "(initial)" : "" %>

<% } %>

%---

JET directive:

Actually from this JET-Template, a Java class will be generated that does the actual transformation.

These directives tell the name, package and imports for the generated class that

generates the actual output.

If you want to see this class, go to your runtime workbench and have a look into the hidden JET project (.JET-Automaton in our case) in the

navigator view.

(14)

Ekkart Kindler

14 ATSE (02265), L05: Model to Text Transformations

Concepts

<%@ jet package="translated" class="SimpleAutomaton"

imports="dk.dtu.imm.se2e09.casetool.componentdefinition.*"

%> %>

%--- Overview of component definition

%---

<%

ComponentDefinition c = (ComponentDefinition) argument;

Automaton a = c.getAutomaton();

%>

The components name is "<%= c.getName() %>".

The automaton has <%= a.getState().size() %> states:

<% for (State s:a.getState()) { %>

<%= s.getName() %> <%= s.isIntial() ? "(initial)" : "" %>

<% } %>

%---

Text snippet directly going to the text-output

(including all spaces, tabs,

and line feeds!)

(15)

Ekkart Kindler

Concepts

<%@ jet package="translated" class="SimpleAutomaton"

imports="dk.dtu.imm.se2e09.casetool.componentdefinition.*"

%> %>

%--- Overview of component definition

%---

<%

ComponentDefinition c = (ComponentDefinition) argument;

Automaton a = c.getAutomaton();

%>

The components name is "<%= c.getName() %>".

The automaton has <%= a.getState().size() %> states:

<% for (State s:a.getState()) { %>

<%= s.getName() %> <%= s.isIntial() ? "(initial)" : "" %>

<% } %>

%---

JET Scriptlet: Must

altogether give a legal Java method body!

The object passed to the template as an argument when the template is

started.

In principle, we can use all

Java commands and all

classes we want; don’t

forget to import them!

(16)

Ekkart Kindler

16 ATSE (02265), L05: Model to Text Transformations

Concepts

<%@ jet package="translated" class="SimpleAutomaton"

imports="dk.dtu.imm.se2e09.casetool.componentdefinition.*"

%> %>

%--- Overview of component definition

%---

<%

ComponentDefinition c = (ComponentDefinition) argument;

Automaton a = c.getAutomaton();

%>

The components name is "<%= c.getName() %>".

The automaton has <%= a.getState().size() %> states:

<% for (State s:a.getState()) { %>

<%= s.getName() %> <%= s.isIntial() ? "(initial)" : "" %>

<% } %>

%---

JET/Java expression: must

return a String (or something that can be “used” as a

String).

More technically, it must

be possible to append

the return value to a

Java StringBuffer

(see later).

(17)

Ekkart Kindler

More details

Other JET directives:

 inlcude:

<%@ include file="anotherTemplate.jet" %>

 skeleton:

Defines the skeleton class to be used (later)

 startTag, endTag:

used to replace <% and %> as start and end tags.

 nlString:

defines the String serving as a newline

Note: Scriptlets, and

expressions in this

template will also be

resolved!

(18)

Ekkart Kindler

18 ATSE (02265), L05: Model to Text Transformations

1.3 Using a template

Up to now:

 What is a template

 What does it mean

Question now:

 How do we start (and configure) a transformation for such a template?

 What happens behind the scenes?

(19)

Ekkart Kindler

Some code snippets

import org.eclipse.emf.codegen.jet.JETEmitter;

import org.eclipse.emf.codegen.jet.JETException;

...

ComponentDefinition c = ...

JETEmitter emitter = new JETEmitter(uriOfTemplate,

getClass().getClassLoader());

emitter.addVariable(

"CASETOOL", "dk.dtu.imm.se2e09.casetool");

emitter.addVariable(

"EMF_COMMON", "org.eclipse.emf.common");

String result = emitter.generate(

monitor, new Object[] { c });

Generate and initialize

generator class from JET-

template.

(20)

Ekkart Kindler

20 ATSE (02265), L05: Model to Text Transformations

Generated Class (snippets)

package translated;

import dk.dtu.imm.se2e09.casetool.componentdefinition.*;

public class SimpleAutomaton { ...

protected final String TEXT_1 = "%---…" + NL +

" Overview of component definition" + NL + "%---…";

protected final String TEXT_2 =

NL + NL + "The components name is \"";

protected final String TEXT_3 =

"\"." + NL + "" + NL + "The automaton has ";

protected final String TEXT_4 = " state(s):";

protected final String TEXT_5 = NL + " ";

protected final String TEXT_6 = " ";

protected final String TEXT_7 = NL + " …" + NL + "%---…";

(21)

Ekkart Kindler

Generated Class (ctnd.)

public String generate(Object argument) {

final StringBuffer stringBuffer = new StringBuffer();

stringBuffer.append(TEXT_1);

ComponentDefinition component = (ComponentDefinition) argument;

Automaton automaton = component.getAutomaton();

stringBuffer.append(TEXT_2);

stringBuffer.append( component.getName() );

stringBuffer.append(TEXT_3);

stringBuffer.append( automaton.getState().size() );

stringBuffer.append(TEXT_4);

for (State state : automaton.getState()) { stringBuffer.append(TEXT_5);

stringBuffer.append( state.getName() );

stringBuffer.append(TEXT_6);

stringBuffer.append( state.isInitial() ? "(initial)" : "" );

}

stringBuffer.append(TEXT_7);

return stringBuffer.toString();

}

(22)

Ekkart Kindler

22 ATSE (02265), L05: Model to Text Transformations

1.4 Skeleton

Now:

 We know how to use the generator

 We know how the generated generator class looks

Question now:

 Can we adapt or change the generation of the generator

class (might be interesting, once we call generators from

other templates)

(23)

Ekkart Kindler

Standard skeleton

public class CLASS {

public String generate(Object argument) {

return "";

}

}

(24)

Ekkart Kindler

24 ATSE (02265), L05: Model to Text Transformations

Change skeleton

public class CLASS extends MyClass {

private WhatEverType attribute;

public OtherType myMethod() {... }

// Some comment.

public String generate(Object argument) {

return "";

}

}

(25)

Ekkart Kindler

Skeleton  Extends

In JET2, the skeleton was replaced by the extends tag:

<%@ jet extends="dk.dtu.imm.se.ecno.generator.

SomeBaseClass" %>

The generated class that generates the result extends the class (which is given by a fully quantified name).

What we implemented in the skeleton can be

implemented in this super class.

(26)

Ekkart Kindler

26 ATSE (02265), L05: Model to Text Transformations

1.5 JET Summary

a template?!

one template?!

public class Student {

private String name;

}

public class Grade {

private String course;

private int value;

}

h o w ?

private List<Grade> grades;

Idea: use templates!

(27)

Ekkart Kindler

Summary

Template Template

Template

Model

Resulting code

generated manually

Resulting code

Existing code Existing

code

Student

Grade

Resulting code Merged

code JMerger

public class _____ { private String _____;

}

(28)

Ekkart Kindler

28 ATSE (02265), L05: Model to Text Transformations

Template for result

public class Student {

private String name;

private List<Grade> grades;

}

h o w ?

<%@ jet package="codegen" class="ClassGenerator" imports="org.eclipse.emf.ecore.*" %>

<% EPackage pack = EmfHelper.loadModel(argument); %>

<% for (EClassifier eClassifier : pack.getEClassifiers()) { %>

public <%= eClassifier.abstract ? "abstract" : "" %> class <%= eClassifier.getName()%> {

<% for (EAttribute eAttribute : ((EClass)eClassifier).getEAttributes()) { %>

private <%= eAttribute.getEType().getInstanceTypeName()%> <%= eAttribute.getName()%>;

<% } %>

}

<% } %>

Directives <%@ jet … %>

(2 types): <%@ include file="…" %>

Scriptlets: <% (arbitrary java code) %>

e.g.: <% String s = “Hello, transformation world!"; %>

Expressions: <%= (java expression) %>

e.g.: <%= (s.length() > 0 ? "<null>" : s + "!") %>

(notice the similarity to jsp, php, asp, …)

(29)

Ekkart Kindler

Discussion M2T/JET

Advantages

 Independent of generated language

 No need for a precise model of the languages syntax

 Flexible

 Easy to get started

 Works for any Java structure (not restricted to EMF)

(30)

Ekkart Kindler

30 ATSE (02265), L05: Model to Text Transformations

Discussion M2T

Disadvantages

 Templates become easily unreadable (mix of two languages)

 hard to debug (error messages not too helpful, either)

 No guarantee that generated text is syntactically correct

 After generation no relation between model and text (unless you explicitly do something about it tutorial)

 Regeneration overwrites manual changes

 JET technology is bound to Eclipse!

(used in EMF)

Can be overcome in combination with other technologies: e.g. JMerge

Discussion: Other ways out?

Referencer

RELATEREDE DOKUMENTER

resources and concrete agents are problematic (business trip, vacations, sick leave, etc.)..

‣ [Remote Object References] other objects can invoke the methods of a remote object if they have access to its remote object reference.. ‣ [Remote Interfaces] every

Due to the difficulty involved in the design and development of complex software systems, wide ranges of software engineering paradigms have been developed, such as

 In some situtations (when using GMF), you can use Recording commands – basically programming as usual except for the set up (tutorial 2).  When changes are made in a GMF

public Object eGet(int featureID, boolean resolve, boolean coreType) { switch (featureID) {..

3.1.3.10 template&lt;class T, class V, int N&gt; const V operator ∗ (float k, const ArithVec&lt; T, V, N &gt; &amp; v) [inline].. Multiply float

 Like EMOF, CMOF can be defined in terms of its own concepts (or in terms of EMOF)..

 Concepts and underlying theory of Model-based Software Engineering (with focus on the meta-level).  Relation between the concepts and rationale