Der EMF-generierte Code. 7. November 2012



Ähnliche Dokumente
Java: Vererbung. Teil 3: super()

Programmieren in Java

Testen mit JUnit. Motivation

Objektorientierte Programmierung

Komponententest. Testen von Software Systemen. Übung 02 SS 2009 Version:

Einführung in die Programmierung

Einführung in Javadoc

Definition von domänenspezifischen Sprachen mit Xtext: Einführung. 19. November 2014

Java Einführung Umsetzung von Beziehungen zwischen Klassen. Kapitel 7

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Einführung in die Informatik Tools

Große Übung Praktische Informatik 1

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Javakurs zu Informatik I. Henning Heitkötter

U08 Entwurfsmuster (II)

Was ist EMF? Wie wird EMF eingesetzt? Was ist ecore? Das Generatormodell Fazit

Swp08-6 Verantwortliche: Yundensuren, Baigalmaa. Testkonzept

Software Engineering II

SEP 114. Design by Contract

Test-Driven Design: Ein einfaches Beispiel

Software-Engineering Software-Management

Testen von graphischen Benutzeroberflächen. 26. Juni 2013

Folge 18 - Vererbung

Software Entwicklung II (SS12)

Java Einführung Abstrakte Klassen und Interfaces

Drei-Schichten-Architektur. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 16: 3-Schichten-Architektur 1 Fachkonzept - GUI

Der lokale und verteilte Fall

Java-Schulung Grundlagen

Themen. Web Service - Clients. Kommunikation zw. Web Services

Übung: Verwendung von Java-Threads

Internet Explorer Version 6

Objektorientierte Programmierung. Kapitel 12: Interfaces

Klausur zur Einführung in die objektorientierte Programmierung mit Java

Software Engineering. Zur Architektur der Applikation Data Repository. Franz-Josef Elmer, Universität Basel, HS 2015

Das erste Programm soll einen Text zum Bildschirm schicken. Es kann mit jedem beliebigen Texteditor erstellt werden.

Code-Erzeugung aus UML-Klassendiagrammen

Willkommen zur Vorlesung. Objektorientierte Programmierung Vertiefung - Java

WebService in Java SE und EE

Individuelle Erweiterung des generierten Codes. 16. Januar 2013

Einführung in die Programmierung für Wirtschaftsinformatik

Musterlösung zur Vorlesung Modellbasierte Softwareentwicklung Wintersemester 2014/2015 Übungsblatt 9

Praktische Übung 'JUnit-Test'

Innere Klassen in Java

Motivation Grundlagen Technologien Manipulation Ecore Genmodell Demo Persistenz Notification Ausblick GMF Fazit / Quellen

Prinzipien Objektorientierter Programmierung

Programmierkurs Java

Aufgabenblatt Nr. 5 Generizität und TicTacToe

Probeklausur Softwareengineering SS 15

7. Objektorientierte Softwareentwicklung/3. Informatik II für Verkehrsingenieure

Testen von graphischen Benutzeroberflächen. 24. Juni 2015

3 Objektorientierte Konzepte in Java

JUnit - Test Driven Development. Bernhard Frey, Thorsten Stratmann, Jackson Takam, Michel Müller 1

Java Kurs für Anfänger Einheit 5 Methoden

Fortgeschrittenes Programmieren mit Java. Test Driven Development

Delegatesund Ereignisse

Kapitel 6. Vererbung

Lösungsvorschläge. zu den Aufgaben im Kapitel 4

Objektorientierte Programmierung

Algorithmen und Datenstrukturen

Java Einführung Collections

II. Grundlagen der Programmierung. 9. Datenstrukturen. Daten zusammenfassen. In Java (Forts.): In Java:

Fachdidaktik der Informatik Jörg Depner, Kathrin Gaißer

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

C# im Vergleich zu Java

WPF Steuerelemente Listbox, ComboBox, ListView,

Objektorientierte Programmierung

Kapitel 6. Vererbung

Java Reflection. Meta-Programmierung mit der java.lang.reflection API. Prof. Dr. Nikolaus Wulff

Client-Server-Beziehungen

Softwaretechnologie -Wintersemester 2013/ Dr. Günter Kniesel

Softwaretechnologie - Wintersemester 2012/ Dr. Günter Kniesel

Daniel Warneke Ein Vortrag im Rahmen des Proseminars Software Pioneers

Es sollte die MS-DOS Eingabeaufforderung starten. Geben Sie nun den Befehl javac ein.

Technische Hochschule Georg Agricola WORKSHOP TEIL 3. IKT (Informations- und Kommunikationstechnik) an einer MorseApp erklärt

Das Test-Framework JUnit ETIS SS04

Vorkurs C++ Programmierung

Übungen zu Softwaretechnik

Dieses Tutorial gibt eine Übersicht der Form Klassen von Struts, welche Besonderheiten und Unterschiede diese aufweisen.

public class SternchenRechteckGefuellt {

Übung Grundlagen der Programmierung. Übung 03: Schleifen. Testplan Testergebnisse

Java - Programmierung - Objektorientierte Programmierung 1

Starthilfe für C# Inhaltsverzeichnis. Medien- und Kommunikationsinformatik (B.Sc.) Alexander Paharukov. Informatik 3 Praktikum

Arbeiten mit UMLed und Delphi

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

Factory Method (Virtual Constructor)

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 22

WhiteStarUML Tutorial

SEW Übung EMFText. 1 Aufgabe. 2 Domänenbeschreibung. 3 Installation von Eclipse/EMFText. 4 Schritt-für-Schritt Anleitung. 4.

Programmieren in Java

TCP/IP Programmierung. C# TimeServer Java6 TimeClient

Unsere Webapplikation erweitern

Software Engineering Klassendiagramme Assoziationen

Software Engineering Klassendiagramme Einführung

Assoziation und Aggregation

Pakete dienen dazu, die Software eines Projektes in größere inhaltlich zusammengehörige Bereiche mit eigenem Namen einzuteilen (siehe Java API).

Es wird das Struts <html:option> Element erläutert und anhand von kleinen Beispielen der Umgang veranschaulicht.

Transkript:

Der EMF-generierte Code 7. November 2012

Überblick Wie sieht der aus einem EMF-Modell generierte Code aus? Wie ist die Beziehung zwischen Modell und Code? Wie kann generierter Code durch handgeschriebenen erweitert bzw. ersetzt werden? Wie kann ein Instanzmodell erstellt werden? Durch einen Instanzeditor Anwendung der generierten Klassen Durch Anwendung von reflektiven Methoden auf dem EMF- Modell Welcher Test-Code wird erstellt? Taentzer Modellgetriebene Softwareentwicklung 132

Eclipse Modeling Framework (EMF) EMF Klassendiagramm EMF Generator basierend auf JET Java Klassen zur Manipulation des Modells benutzt einfacher baumbasierter Editor Taentzer Modellgetriebene Softwareentwicklung 133

Struktur des generierten Codes Struktur des Modellcodes: Schnittstellenklassen Implementierungsklassen weitere nützliche Klassen weitere Dateien, um den Code als Eclipse-Plugin zu benutzen META-INF/MANIFEST.MF: alle wichtigen Einstellung zum Plugin plugin.xml: Identifizierung des Plugins und Beziehungen zu anderen Taentzer Modellgetriebene Softwareentwicklung 134

Modellierte Klassen Dozent.java: für eine modellierte Klasse wird erzeugt: eine Schnittstellenklasse eine Implementierungsklasse create-methode in der Factory- Klasse public interface Dozent extends EObject { DozentImpl.java: public class DozentImpl extends EObjectImpl implements Dozent { Taentzer Modellgetriebene Softwareentwicklung 135

Abstrakte Klassen Lehrveranstaltung.java: Für eine abstrakte Klasse wird erzeugt: eine Schnittstellenklasse eine abstrakte Impl-Klasse keine create-methode in der Factory-Klasse public interface Lehrveranstaltung extends EObject { LehrveranstaltungImpl.java: public abstract class LehrveranstaltungImpl extends EObjectImpl implements Lehrveranstaltung { Taentzer Modellgetriebene Softwareentwicklung 136

Abstrakte und Schnittstellenklassen Abstrakte Klasse: in EClass: Attribut abstract = true im generierten Code: abstrakte Implementierungsklasse keine create-methode in der Factory Schnittstellenklasse: in EClass: Attribut interface = true Attribut instanceclass nicht gesetzt im generierten Code: keine Implementierungsklasse, aber Schnittstellenklasse keine create-methode in der Factory Taentzer Modellgetriebene Softwareentwicklung 137

Vererbung Uebung.java: Vererbung von EObject und EObjectImpl Mehrfachvererbung im Modell - Mehrfachvererbung der entsprechenden Schnittenstellen, Impl.- Klasse erbt von nur einer Impl.-Klasse public interface Uebung extends Lehrveranstaltung UebungImpl.java: public class UebungImpl extends LehrveranstaltungImpl implements Uebung Taentzer Modellgetriebene Softwareentwicklung 138

Structural Features: Zugriffsmethoden Dozent.name Für jedes Attribut und jede Referenz: eine getter-methode falls changeable = true: eine setter-methode Dozent.java: public interface Dozent extends EObject {... String getname(); void setname(string value);... Taentzer Modellgetriebene Softwareentwicklung 139

DozentImpl.java: Einfache Attribute protected static final String NAME_EDEFAULT = null; protected String name = NAME_EDEFAULT; public String getname() { return name; public void setname(string newname) { String oldname = name; name = newname; if (enotificationrequired()) enotify(new ENotificationImpl(this,Notification.SET, VorlesungsverzeichnisPackage.DOZENT_NAME, oldname, name)); Taentzer Modellgetriebene Softwareentwicklung 140

Subject-Observer-Prinzip Subject Observer Observer Observer Observer Subject: Objekt aus dem EMF-Modell Observer: andere Objekte, die das EMF-Objekt benutzen Observer müssen sich als Listener anmelden. bei Änderung des Subjects: Benachrichtungung an alle Observer Observer in EMF: Adapter Taentzer Modellgetriebene Softwareentwicklung 141

Unidirektionale Referenzen Falls resolveproxies = true: Zusätzlicher Code zur Behandlung von Proxy-Objekten VorlesungImpl.java: protected EList<Uebung> uebung = null; public EList<Uebung> getuebung() { if (uebung == null) { uebung = new EObjectEList(Uebung.class, this, VorlesungsverzeichnisPackage.VORLESUNG UEBUNG); return uebung; Taentzer Modellgetriebene Softwareentwicklung 142

Bidirektionale Referenzen LehrveranstaltungImpl.java: public void setdozent(dozent newdozent) { if (newdozent!= dozent) { NotificationChain msgs = null; if (dozent!= null) msgs = ((InternalEObject)dozent).eInverseRemove(this, VorlesungsverzeichnisPackage.DOZENT LV, Dozent.class, msgs); if (newdozent!= null) msgs = ((InternalEObject)newDozent).eInverseAdd(this, VorlesungsverzeichnisPackage.DOZENT LV, Dozent.class, msgs); msgs = basicsetdozent(newdozent, msgs); if (msgs!= null) msgs.dispatch(); else if (enotificationrequired()) enotify(new ENotificationImpl(this, Notification.SET, VorlesungsverzeichnisPackage.LEHRVERANSTALTUNG DOZENT, newdozent, newdozent)); Taentzer Modellgetriebene Softwareentwicklung 143

Factories Eine Factory ist die zentrale Klasse, in der neue Objekte angelegt werden. VorlesungsverzeichnisFactory.java: public interface VorlesungsverzeichnisFactory extends EFactory { Vorlesungen createvorlesungen(); Dozent createdozent(); Raum createraum(); Vorlesung createvorlesung(); Seminar createseminar(); Übung createübung(); Raumverzeichnis createraumverzeichnis(); Hörsaal createhörsaal(); Seminarraum createseminarraum(); VorlesungsverzeichnisPackage getvorlesungsverzeichnispackage(); Taentzer Modellgetriebene Softwareentwicklung 144

Factories Es kann mehrere Implementierungen für eine Factory geben. Es gibt eine DefaultFactory. public class VorlesungsverzeichnisFactoryImpl extends EFactoryImpl implements VorlesungsverzeichnisFactory { public static VorlesungsverzeichnisFactory init() { try { VorlesungsverzeichnisFactory thevorlesungsverzeichnisfactory = (VorlesungsverzeichnisFactory)EPackage.Registry.INSTANCE. getefactory("http://vorlesungsverzeichnis"); if (thevorlesungsverzeichnisfactory!= null) { return thevorlesungsverzeichnisfactory; catch (Exception exception) { EcorePlugin.INSTANCE.log(exception); return new VorlesungsverzeichnisFactoryImpl(); Taentzer Modellgetriebene Softwareentwicklung 145

Codeerweiterung An verschiedensten Stellen sind Codeerweiterungen wünschenswert. Mit EMF kann kein Verhalten modelliert werden -> Codeerweiterung Nach der Codeerweiterung muss eine erneute Codegenerierung möglich sein. Generierte Methoden haben ein @generated Tag. /** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public boolean checkkonsistenz() { // TODO: implement this method // Ensure that you remove @generated or mark it @generated NOT throw new UnsupportedOperationException(); Nach manueller Codeerweiterung muss das Tag @generated NOT gesetzt werden. Taentzer Modellgetriebene Softwareentwicklung 146

Beispiel: Codeerweiterung RaumImpl.java: public boolean checkkonsistenz() { EList<Lehrveranstaltung> lvlist = this.getveranstaltung(); for (Lehrveranstaltung lv1 : lvlist) { for (Lehrveranstaltung lv2 : lvlist) { if (lv1!= null && lv2!= null) { if (lv1!= lv2) { if ((lv1.getzeit() == lv2.getzeit()) && (lv1.gettag() == lv2.gettag())) return false; // if // if // for // for return true; // checkkonsistenz Taentzer Modellgetriebene Softwareentwicklung 147

Erstellung eines Instanzmodells Beispiel: Erstellung eines Vorlesungsverzeichnisses VorlesungsverzeichnisBeispiel.java: import org.eclipse.emf.common.util.uri; import org.eclipse.emf.ecore.resource.resource; import org.eclipse.emf.ecore.resource.resourceset; import org.eclipse.emf.ecore.resource.impl.resourcesetimpl; import org.eclipse.emf.ecore.xmi.impl.xmiresourcefactoryimpl; import vorlesungsverzeichnis.*; import vorlesungsverzeichnis.impl.*; //... // Create a resource set to hold the resources. ResourceSet resourceset = new ResourceSetImpl(); // Register the appropriate resource factory to handle all file extensions. resourceset.getresourcefactoryregistry().getextensiontofactorymap().put (Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl()); // Register the package to ensure it is available during loading. resourceset.getpackageregistry().put (VorlesungsverzeichnisPackage.eNS_URI, VorlesungsverzeichnisPackage.eINSTANCE); //... Taentzer Modellgetriebene Softwareentwicklung 148

Erstellung eines Instanzmodells Beispiel: Erstellung eines Vorlesungsverzeichnisses VorlesungsverzeichnisBeispiel.java: //... // If there are no arguments, emit an appropriate usage message. if (args.length == 0) { System.out.println("Enter a list of file paths or URIs that have content like this:"); try { Resource resource = resourceset.createresource(uri.createuri("http://my.vorlesungsverzeichnis")); Verzeichnis root = VorlesungsverzeichnisFactory.eINSTANCE.createVerzeichnis(); resource.getcontents().add(root); resource.save(system.out, null); //Ab hier eigener Code Taentzer Modellgetriebene Softwareentwicklung 149

Erstellung eines eignen Modells Beispiel: Erstellung eines Vorlesungsverzeichnisses VorlesungsverzeichnisBeispiel.java: //... VorlesungsverzeichnisFactory vfactory = VorlesungsverzeichnisFactory.eINSTANCE; Verzeichnis vorlesungen = vfactory.createverzeichnis(); //erstelle ein Raumverzeichnis Raumverzeichnis verzeichnis = vfactory.createraumverzeichnis(); vorlesungen.setraumverzeichnis(verzeichnis); //erstelle einen Raum Raum r = vfactory.createhoersaal(); verzeichnis.getraum().add(r); //erstelle eine Vorlesung Vorlesung vl1 = vfactory.createvorlesung(); vl1.settag(tag.di); vl1.setzeit(zeit.zwei); vorlesungen.getlv().add(vl1); //... Taentzer Modellgetriebene Softwareentwicklung 150

Aufruf einer eignen Methode Beispiel: Erstellung eines Vorlesungsverzeichnisses VorlesungsverzeichnisBeispiel.java: //... Boolean c = true; List<Raum> raeume = verzeichnis.getraum(); for (Raum raum : raeume) { c = c && raum.checkkonsistenz(); if (c) System.out.println("Alle Räume sind konsistent belegt."); else System.out.println("Es gibt min. einen Raum mit inkonsistenter Belegung."); //... Taentzer Modellgetriebene Softwareentwicklung 151

Einlesen eines Instanzmodells public static void main(string[] args) { VorlesungsverzeichnisPackageImpl.init(); Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap(). put("vorlesungsverzeichnis", new XMIResourceFactoryImpl()); ResourceSet resourceset = new ResourceSetImpl(); URI fileuri = URI.createURI("src/Test.vorlesungsverzeichnis"); Resource resource = resourceset.getresource(fileuri, true); Vorlesungsverzeichnis vz = (Vorlesungsverzeichnis) resource.getcontents().get(0); //main Taentzer Modellgetriebene Softwareentwicklung 152

JUnit Prinzipien: Zu jeder verfassten Klasse eine Testklasse entwerfen. Testcode und Anwendungscode sind strikt getrennt. Zum Schreiben von Tests werden lediglich benötigt: (TestSuite), TestCase, Assert Testsuiten dienen dazu, verschiedene Tests in einer bestimmten Reihenfolge aufzurufen. Suiten können dazu verwendet werden, verschiedene Klassen eines Paketes bzw. Projektes auf einmal zu testen. Pakettests, Klassentests, Methodentests public class VorlesungsverzeichnisTests extends TestSuite { Taentzer Modellgetriebene Softwareentwicklung 153

Definition von Testfällen Testfälle werden in einer normalen Klasse erstellt. Framework führt die definierten Testfälle aus. Jeder Test wird gekapselt: Es kann ein Fixture definiert werden. Damit wird ein wiederverwendbares Testobjekt festgehalten. Verschiedene Tests nutzen keine gemeinsamen Daten im Fixture. Jeder Test hat sein eigenes Fixture. Assert für den Vergleich von Soll- mit Istwerten Wir prüfen, ob das Ergebnis eines Tests ein bestimmtes Ergebnis zurückliefert. Typische Assert-Methoden: asserttrue, assertequal, assertnull Taentzer Modellgetriebene Softwareentwicklung 154

Beispiel für einen Testfall public class SeminarraumTest extends RaumTest { protected VorlesungsverzeichnisFactory vfactory = VorlesungsverzeichnisFactory.eINSTANCE;... public static void main(string[] args) { TestRunner.run(SeminarraumTest.class); @Override protected void setup() throws Exception { setfixture(vfactory.createseminarraum()); public void testcheckconsistency() { asserttrue(this.getfixture().checkkonsistenz());... abstract class RaumTest extends TestCase Taentzer Modellgetriebene Softwareentwicklung 155

Beispiel für einen zweiten Testfall HoersaalTest.java: public class HoersaalTest {... public void setup() throws Exception{ VorlesungsverzeichnisFactory vfactory = VorlesungsverzeichnisFactory.eINSTANCE; Vorlesungen vorlesungen = vfactory.createvorlesungen(); Raumverzeichnis verzeichnis = vfactory.createraumverzeichnis(); vorlesungen.setraumverzeichnis(verzeichnis); Raum raum = vfactory.createhoersaal(); verzeichnis.getraum().add(raum);... Vorlesung vl1 = vfactory.createvorlesung(); vl1.settag(tag.di); vl1.setzeit(zeit.zwei); vl1.setraum(raum); vorlesungen.getlv().add(vl1); Taentzer Modellgetriebene Softwareentwicklung 156

Beispiel für einen zweiten Testfall HoersaalTest.java:... Vorlesung vl2 = vfactory.createvorlesung(); vl2.settag(tag.di); vl2.setzeit(zeit.zwei); vl2.setraum(raum); vorlesungen.getlv().add(vl2); setfixture(raum); //setup()... Taentzer Modellgetriebene Softwareentwicklung 157

Beispiel für einen zweiten Testfall RaumTest.java: public void testcheckkonsistenz() { // TODO: implement this operation test method // Ensure that you remove @generated or mark it @generated NOT asserttrue(getfixture().checkkonsistenz()); Taentzer Modellgetriebene Softwareentwicklung 158

Wie wird generiert? Applikation Domänenspezif. Modell transformiert in Code modelliert mit Generator MDD-Infrastruktur Domänenspezifische Modellierungssprache Generator Templates (Modell-zu-Code Tr. ) Wie wird dieser allgemeine Ansatz durch EMF konkretisiert? Taentzer Modellgetriebene Softwareentwicklung 159

Zusammenfassung Die Beziehung zwischen Modell und Code ist recht direkt. Die Codegenerierung lässt sich gut durch das EMF-Modell steuern. Der generierte Code hat eine gute Qualität: Java-Konventionen werden eingehalten. Code Smells werden vermieden, wo möglich. Passende Design-Patterns werden verwendet. Generierter Code kann durch handgeschriebenen so erweitert werden, dass der Generator diesen nicht überschreibt. Taentzer Modellgetriebene Softwareentwicklung 160