WIRTSCHAFTSINFORMATIK Westfälische Wilhelms-Universität Münster WIRTSCHAFTS INFORMATIK “A platform for professional model-driven software development.” Präsentation im Rahmen des Seminars „Software Engineering“ WS 08/09 Jan Schürmeier [email protected] 06.01.2009 Gliederung WIRTSCHAFTS INFORMATIK Einführung Grundlagen der modellgetriebenen Softwareentwicklung - Motivation und Ziele - MDSD vs MDA - MDA-Standard der Object Management Group Das openArchitectureWare Generator Framework - Allgemeine Funktionsweise - Komponenten Anwendungsbeispiel 2 Gliederung WIRTSCHAFTS INFORMATIK Einführung Grundlagen der modellgetriebenen Softwareentwicklung - Motivation und Ziele - MDSD vs MDA - MDA-Standard der Object Management Group Das openArchitectureWare Generator Framework - Allgemeine Funktionsweise - Komponenten Anwendungsbeispiel 3 Einführung WIRTSCHAFTS INFORMATIK Modellgetriebene Softwareentwicklung als logisch nächster Schritt in der Evolution der Softwareentwicklung Grundgedanke des modellgetriebenen Vorgehens: - Stärkere Gewichtung der Modelle im Entwicklungsprozess - Vollständige Abbildung der Anwendung im Modell - Automatische Codegenerierung openArchitectureWare - Framework zur Ermöglichung und Unterstützung modellgetriebener Softwareentwicklung - Ursprung: b+m Informatik AG - Später: Open-Source Projekt 4 Gliederung WIRTSCHAFTS INFORMATIK Einführung Grundlagen der modellgetriebenen Softwareentwicklung - Motivation und Ziele - MDSD vs MDA - MDA-Standard der Object Management Group Das openArchitectureWare Generator Framework - Allgemeine Funktionsweise - Komponenten Anwendungsbeispiel 5 Motivation und Ziele WIRTSCHAFTS INFORMATIK Automatisierung des Entwicklungsprozesses Höhere Effizienz Trennung von fachlichen Anforderungen und technischen Details Wiederverwendbarkeit Verbesserung der Softwarequalität Einfachere Migration 6 MDSD vs. MDA WIRTSCHAFTS INFORMATIK Model Driven Software Development (MDSD) - Ziel: Bereitstellung von praktisch einsetzbaren Bausteinen für Softwareentwicklungsprozesse Model Driven Architecture (MDA) - Einschränkungen (z.B. Fokussierung auf UML-basierte Modellierungssprachen) - Ziele: Interoperabilität zwischen MDA-Werkzeugen Standardisierung von Modellen - Standardisierungsinitiative der OMG zum Thema MDSD 7 MDA-Standard der Object Management Group WIRTSCHAFTS INFORMATIK 8 Meta Object Facility WIRTSCHAFTS INFORMATIK 9 Metamodellierung WIRTSCHAFTS INFORMATIK 10 Gliederung WIRTSCHAFTS INFORMATIK Einführung Grundlagen der modellgetriebenen Softwareentwicklung - Motivation und Ziele - MDSD vs MDA - MDA-Standard der Object Management Group Das openArchitectureWare Generator Framework - Allgemeine Funktionsweise - Komponenten Anwendungsbeispiel 11 openArchitectureWare - Details WIRTSCHAFTS INFORMATIK Teil der Eclipse Foundation Integration in Eclipse Entwicklungsumgebung über Plug-Ins „tool for building MDSD/MDA tools“ Funktionen: Modellprüfungen, Transformationen, Generierung von Quellcode Verarbeitung verschiedenster Modellformate: - EMF - XMI Dialekte - Eclipse UML2 XMI - XML 12 openArchitectureWare – Allg. Funktionsweise WIRTSCHAFTS INFORMATIK UML-Modell export *.XMI Workflow-Datei laden XMI-Instantiator Hauptspeicher Modell Templates ausführen Template-Engine anwenden Start-Template generieren Generierter Quellcode 13 openArchitectureWare - Komponenten WIRTSCHAFTS INFORMATIK Kernmodule: - Workflow - Xpand - Xtend - Check Weitere: - Xtext - Recipe Basis: Expression Language (EL) und XML Erweiterbarkeit durch Implementierung von JavaMethoden 14 openArchitectureWare - Workflow WIRTSCHAFTS INFORMATIK „Herzstück“ von oAW → Ablaufsteuerung Speicherung in workflow.oaw , workflow.properties Beispiel: <workflow> <!--- read model --> <component class="oaw.emf.XmiReader"> <modelFile value ="${uml2ModelFile}" /> <outputSlot value="model" /> </component> <!--- generate code --> <component id="generator" class="oaw.xpand2.Generator" skipOnErrors="true"> <expand value="templates::Root::Root FOR model" /> </component> </workflow> 15 openArchitectureWare - Xpand WIRTSCHAFTS INFORMATIK Generierung von Ausgaben auf Basis von Vorlagen (Templates) Speicherung in *.xpt Dateien Beispiel: «EXTENSION Xtend» «DEFINE javaClass FOR uml::Class» «FILE fileName()» package «javaPackage()»; public class «name» { «FOREACH attribute AS a» «a.type.fqn()» «a.name» «ENDFOREACH» «ENDFILE» «ENDDEFINE» 16 openArchitectureWare - Xtend WIRTSCHAFTS INFORMATIK Funktion: Beschreibung von Transformationen und Metamodellierung Speicherung in *.ext Datei Syntax: private cached ReturnType extensionName(ParamType1 paramName1, ...) : expression-using-params; Beispiel: String upperName(uml::NamedElement ne): me.name.toUpperCase(); private boolean hasName(uml::NamedElement ne): ne.name != null; 17 openArchitectureWare - Check WIRTSCHAFTS INFORMATIK Definition von Modellprüfungen zur Modellvalidierung Speicherung in *.chk Dateien Syntax: context TypeName [if guard-predicate] (ERROR|WARNING) msg-expression: predicate; Beispiel: context JavaClass ERROR 'A javaClass must not have more than one superclass.': superClass.size <=1; 18 openArchitectureWare – Recipe & Xtext WIRTSCHAFTS INFORMATIK Recipe Framework - Prüfung auf Vollständigkeit der Implementierung - Prinzip: abstrakte Klassen - Übersicht mittels spezieller Eclipse-View Xtext - Möglichkeit der Konstruktion eigener Metamodelle - Grammatik: ähnlich zu EBNF - Ziel: Beschleunigung der Entwicklung und Wartung von Metamodellen 19 Gliederung WIRTSCHAFTS INFORMATIK Einführung Grundlagen der modellgetriebenen Softwareentwicklung - Motivation und Ziele - MDSD vs MDA - MDA-Standard der Object Management Group Das openArchitectureWare Generator Framework - Allgemeine Funktionsweise - Komponenten Anwendungsbeispiel 20 Vorbereitung WIRTSCHAFTS INFORMATIK Modellierung des UML-Diagramms (z.B. mittels ext. UMLTool) 21 Definition der Metaklassen WIRTSCHAFTS INFORMATIK Entity.java package oaw4.demo.classic.uml.meta; public class Entity extends org.openarchitectureware.meta.uml.classifier.Class { //nothing to do in the simplest case } Key.java package oaw4.demo.classic.uml.meta; public class Key extends org.openarchitectureware.meta.uml.classifier.Attribute { } Metamappings.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE MetaMap SYSTEM "http://www.openarchitectureware.org/dtds/metamap.dtd"> <MetaMap> <Mapping> <Map>Entity</Map> <To>oaw4.demo.classic.uml.meta.Entity</To> </Mapping> <Mapping> <Map>Key</Map> <To>oaw4.demo.classic.uml.meta.Key</To> </Mapping> </MetaMap> 22 Definition des Workflows WIRTSCHAFTS INFORMATIK Workflow.oaw <?xml version="1.0" encoding="UTF-8"?> <workflow> <property file="workflow.properties"/> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicstart.oaw"> <metaEnvironmentSlot value="me"/> <instantiatorEnvironmentSlot value="ie"/> </cartridge> <component class="org.openarchitectureware.core.frontends.xmi.workflow.XMIInstantiator"> <instantiatorEnvironmentSlot value="ie"/> <modelFile value="${model.xmi}"/> <xmlMapFile value="${toolMappingFile}"/> <metaMapFile value="${metaMapFile}"/> <toolAdapterClassname value="${toolAdapterClassname}"/> <moduleFile value="${moduleFile}"/> <outputSlot value ="model" /> </component> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicinit.oaw"> <metaEnvironmentSlot value="me"/> </cartridge> <component class="org.openarchitectureware.check.CheckComponent"> <metaModel class="org.openarchitectureware.type.impl.java.JavaMetaModel"> <typeStrategy class="org.openarchitectureware.type.impl.oawclassic.OAWClassicStrategy" convertPropertiesToLowerCase="false"/> </metaModel> <checkFile value="java::AssociationChecks"/> <expression value="me.getElements('ModelElement')"/> <abortOnError value="true"/> </component> <component id="dirCleaner“ class="org.openarchitectureware.workflow.common.DirectoryCleaner" skipOnErrors="true"> <directories value="${srcGenPath}"/> </component> <component id="generator" class="org.openarchitectureware.xpand2.Generator" skipOnErrors="true"> <metaModel class="org.openarchitectureware.type.impl.java.JavaMetaModel"> <typeStrategy class="org.openarchitectureware.type.impl.oawclassic.OAWClassicStrategy" convertPropertiesToLowerCase="false"/> </metaModel> <fileEncoding value="ISO-8859-1"/> <expand value="Root::Root FOREACH me.getElements('Model')"/> <genPath value="${srcGenPath}/"/> <srcPath value="${srcGenPath}/"/> <beautifier class="org.openarchitectureware.xpand2.output.JavaBeautifier"/> <beautifier class="org.openarchitectureware.xpand2.output.XmlBeautifier"/> </component> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicfinish.oaw"> <instantiatorEnvironmentSlot value="ie"/> <dumpfile value="${dumpfile}"/> </cartridge> </workflow> 23 Definition des Workflows WIRTSCHAFTS INFORMATIK Workflow.oaw <?xml version="1.0" encoding="UTF-8"?> <workflow> <property file="workflow.properties"/> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicstart.oaw"> <metaEnvironmentSlot value="me"/> <instantiatorEnvironmentSlot value="ie"/> </cartridge> <component class="org.openarchitectureware.core.frontends.xmi.workflow.XMIInstantiator"> <instantiatorEnvironmentSlot value="ie"/> <modelFile value="${model.xmi}"/> <xmlMapFile value="${toolMappingFile}"/> <metaMapFile value="${metaMapFile}"/> <toolAdapterClassname value="${toolAdapterClassname}"/> <moduleFile value="${moduleFile}"/> <outputSlot value ="model" /> </component> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicinit.oaw"> <metaEnvironmentSlot value="me"/> </cartridge> <component class="org.openarchitectureware.check.CheckComponent"> <metaModel class="org.openarchitectureware.type.impl.java.JavaMetaModel"> <typeStrategy class="org.openarchitectureware.type.impl.oawclassic.OAWClassicStrategy" convertPropertiesToLowerCase="false"/> </metaModel> <checkFile value="java::AssociationChecks"/> <expression value="me.getElements('ModelElement')"/> <abortOnError value="true"/> </component> <component id="dirCleaner“ class="org.openarchitectureware.workflow.common.DirectoryCleaner" skipOnErrors="true"> <directories value="${srcGenPath}"/> </component> <component id="generator" class="org.openarchitectureware.xpand2.Generator" skipOnErrors="true"> <metaModel class="org.openarchitectureware.type.impl.java.JavaMetaModel"> <typeStrategy class="org.openarchitectureware.type.impl.oawclassic.OAWClassicStrategy" convertPropertiesToLowerCase="false"/> </metaModel> <fileEncoding value="ISO-8859-1"/> <expand value="Root::Root FOREACH me.getElements('Model')"/> <genPath value="${srcGenPath}/"/> <srcPath value="${srcGenPath}/"/> <beautifier class="org.openarchitectureware.xpand2.output.JavaBeautifier"/> <beautifier class="org.openarchitectureware.xpand2.output.XmlBeautifier"/> </component> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicfinish.oaw"> <instantiatorEnvironmentSlot value="ie"/> <dumpfile value="${dumpfile}"/> </cartridge> </workflow> 24 Definition des Workflows WIRTSCHAFTS INFORMATIK Workflow.properties # Note: all paths must be found in the classpath! # the metamappings file metaMapFile = metamappings.xml # model.xmi: name of the XMI export # toolMappingFile: tool mapping file to use # toolAdapterClassname: tool adapter implementation # moduleFile: profile files model.xmi = Bibliothek.mdzip toolMappingFile = magicdraw_xmi21_all.xml toolAdapterClassname = org.openarchitectureware.core.frontends.xmi.toolsupport.uml.magicdraw.MagicDrawAdapter21 moduleFile = magicdraw/md11/UML_Standard_Profile.xml # path to create the generated output to srcGenPath = src-gen # path where the dump file is created dumpfile = bin/dump 25 Definition des Workflows WIRTSCHAFTS INFORMATIK Workflow.oaw <?xml version="1.0" encoding="UTF-8"?> <workflow> <property file="workflow.properties"/> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicstart.oaw"> <metaEnvironmentSlot value="me"/> <instantiatorEnvironmentSlot value="ie"/> </cartridge> <component class="org.openarchitectureware.core.frontends.xmi.workflow.XMIInstantiator"> <instantiatorEnvironmentSlot value="ie"/> <modelFile value="${model.xmi}"/> <xmlMapFile value="${toolMappingFile}"/> <metaMapFile value="${metaMapFile}"/> <toolAdapterClassname value="${toolAdapterClassname}"/> <moduleFile value="${moduleFile}"/> <outputSlot value ="model" /> </component> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicinit.oaw"> <metaEnvironmentSlot value="me"/> </cartridge> <component class="org.openarchitectureware.check.CheckComponent"> <metaModel class="org.openarchitectureware.type.impl.java.JavaMetaModel"> <typeStrategy class="org.openarchitectureware.type.impl.oawclassic.OAWClassicStrategy" convertPropertiesToLowerCase="false"/> </metaModel> <checkFile value="java::AssociationChecks"/> <expression value="me.getElements('ModelElement')"/> <abortOnError value="true"/> </component> <component id="dirCleaner“ class="org.openarchitectureware.workflow.common.DirectoryCleaner" skipOnErrors="true"> <directories value="${srcGenPath}"/> </component> <component id="generator" class="org.openarchitectureware.xpand2.Generator" skipOnErrors="true"> <metaModel class="org.openarchitectureware.type.impl.java.JavaMetaModel"> <typeStrategy class="org.openarchitectureware.type.impl.oawclassic.OAWClassicStrategy" convertPropertiesToLowerCase="false"/> </metaModel> <fileEncoding value="ISO-8859-1"/> <expand value="Root::Root FOREACH me.getElements('Model')"/> <genPath value="${srcGenPath}/"/> <srcPath value="${srcGenPath}/"/> <beautifier class="org.openarchitectureware.xpand2.output.JavaBeautifier"/> <beautifier class="org.openarchitectureware.xpand2.output.XmlBeautifier"/> </component> <cartridge file="org/openarchitectureware/workflow/oawclassic/classicfinish.oaw"> <instantiatorEnvironmentSlot value="ie"/> <dumpfile value="${dumpfile}"/> </cartridge> </workflow> 26 Definition der Templates WIRTSCHAFTS INFORMATIK Root.xpt «IMPORT org::openarchitectureware::core::meta::core» «IMPORT org::openarchitectureware::meta::uml::classifier» «IMPORT oaw4::demo::classic::uml::meta» «DEFINE Root FOR Model» «EXPAND Root FOREACH OwnedElement» «ENDDEFINE» «DEFINE Root FOR Package» «EXPAND Root FOREACH OwnedElement» «ENDDEFINE» «DEFINE Root FOR Entity» «EXPAND java::JavaBean::BeanClass» «ENDDEFINE» «DEFINE Root FOR Object»«ENDDEFINE» 27 Definition der Templates WIRTSCHAFTS INFORMATIK JavaBean.xpt «IMPORT org::openarchitectureware::meta::uml::classifier» «EXTENSION java::NamingConventions» «DEFINE BeanClass FOR Class» «FILE packagePath()+"/"+NameS+".java"» package «packageName()»; public class «Name» «IF hasSuperClass» extends «SuperClass.fqn()» «ENDIF» implements java.io.Serializable { «EXPAND Attribute::PropertyDeclaration FOREACH Attribute» «EXPAND Attribute::Getter FOREACH Attribute» «EXPAND Attribute::Setter FOREACH Attribute» «EXPAND Association::ReferenceVariables» «EXPAND Association::AccessorMethods» } «ENDFILE» «ENDDEFINE» 28 Definition der Templates WIRTSCHAFTS INFORMATIK Attribute.xpt «IMPORT org::openarchitectureware::meta::uml::classifier» «EXTENSION java::NamingConventions» «DEFINE PropertyDeclaration FOR Attribute» private «Type.NameS» «asInstanceVar()»; «ENDDEFINE» «DEFINE Getter FOR Attribute» public «Type.NameS» «asGetter()» () { return this.«asInstanceVar()»; } «ENDDEFINE» «DEFINE Setter FOR Attribute» public void «asSetter()» («Type.NameS» «asParameter()») { this.«asInstanceVar()» = «asParameter()»; } «ENDDEFINE» 29 Definition von Extensions WIRTSCHAFTS INFORMATIK NamingConventions.ext import org::openarchitectureware::meta::uml; import org::openarchitectureware::meta::uml::classifier; String asParameter (ModelElement elem) : "p"+elem.NameS.toFirstUpper(); String asSetter (ModelElement elem) : "set"+elem.NameS.toFirstUpper(); String asGetter (ModelElement elem) : "get"+elem.NameS.toFirstUpper(); String asInstanceVar (ModelElement elem) : elem.NameS.toFirstLower(); String packageName (Class cls) : JAVA oaw4.demo.classic.uml.extend.ClassUtil .getPackageName(org.openarchitectureware.meta.uml.classifier.Class); String packagePath (Class cls) : packageName(cls).replaceAll("\\.", "/"); String fqn (Class cls) : packageName(cls).length>0 ? packageName(cls)+"."+cls.NameS : cls.NameS; 30 Definition von Extensions WIRTSCHAFTS INFORMATIK ClassUtil.java package oaw4.demo.classic.uml.extend; import org.openarchitectureware.meta.uml.classifier.Class; import org.openarchitectureware.meta.uml.classifier.Package; public class ClassUtil { public static String getPackageName (Class cls) { string result = ""; for (Package pck=cls.Package(); pck!=null; pck=pck.SuperPackage()) { result = pck.NameS() + (result.length()>0 ? "."+result : ""); } return result; } } 31 Generierter Quellcode WIRTSCHAFTS INFORMATIK Autor.java package oaw4.demo.classic.uml.entity; public class Autor implements java.io.Serializable { private int id; private String name; public int getId() { return this.id; } public String getName() { return this.name; } public void setId(int pId) { this.id = pId; } public void setName(String pName) { this.name = pName; } private java.util.Collection<oaw4.demo.classic.uml.entity.Buch> verfasstesBuch; public void addVerfasstesBuch( oaw4.demo.classic.uml.entity.Buch pVerfasstesBuch) { this.verfasstesBuch.add(pVerfasstesBuch); } public void removeVerfasstesBuch( oaw4.demo.classic.uml.entity.Buch pVerfasstesBuch) { this.verfasstesBuch.remove(pVerfasstesBuch); } public java.util.Iterator<oaw4.demo.classic.uml.entity.Buch> return this.verfasstesBuch.iterator(); } getVerfasstesBuch() { } 32 Generierter Quellcode WIRTSCHAFTS INFORMATIK Bibliothek.java package oaw4.demo.classic.uml.entity; public class Bibliothek implements java.io.Serializable { private int id; private String name; public int getId() { return this.id; } public String getName() { return this.name; } public void setId(int pId) { this.id = pId; } public void setName(String pName) { this.name = pName; } private java.util.Collection<oaw4.demo.classic.uml.entity.Exemplar> eigenesBuch; public void addEigenesBuch( oaw4.demo.classic.uml.entity.Exemplar pEigenesBuch) { this.eigenesBuch.add(pEigenesBuch); } public void removeEigenesBuch( oaw4.demo.classic.uml.entity.Exemplar pEigenesBuch) { this.eigenesBuch.remove(pEigenesBuch); } public java.util.Iterator<oaw4.demo.classic.uml.entity.Exemplar> getEigenesBuch() { return this.eigenesBuch.iterator(); } } 33 Generierter Quellcode WIRTSCHAFTS INFORMATIK Buch.java package oaw4.demo.classic.uml.entity; public class Buch implements java.io.Serializable { private int id; private String titel; public int getId() { return this.id; } public String getTitel() { return this.titel; } public void setId(int pId) { this.id = pId; } public void setTitel(String pTitel) { this.titel = pTitel; } private java.util.Collection<oaw4.demo.classic.uml.entity.Autor> autor; public void addAutor(oaw4.demo.classic.uml.entity.Autor pAutor) { this.autor.add(pAutor); } public void removeAutor(oaw4.demo.classic.uml.entity.Autor pAutor) { this.autor.remove(pAutor); } public java.util.Iterator<oaw4.demo.classic.uml.entity.Autor> getAutor() { return this.autor.iterator(); } } 34 Generierter Quellcode WIRTSCHAFTS INFORMATIK Exemplar.java package oaw4.demo.classic.uml.entity; public class Buch implements java.io.Serializable { private int id; private String titel; public int getId() { return this.id; } public String getTitel() { return this.titel; } public void setId(int pId) { this.id = pId; } public void setTitel(String pTitel) { this.titel = pTitel; } private java.util.Collection<oaw4.demo.classic.uml.entity.Autor> autor; public void addAutor(oaw4.demo.classic.uml.entity.Autor pAutor) { this.autor.add(pAutor); } public void removeAutor(oaw4.demo.classic.uml.entity.Autor pAutor) { this.autor.remove(pAutor); } public java.util.Iterator<oaw4.demo.classic.uml.entity.Autor> getAutor() { return this.autor.iterator(); } } 35 Generierter Quellcode WIRTSCHAFTS INFORMATIK Exemplar.java package oaw4.demo.classic.uml.entity; public class Exemplar implements java.io.Serializable { private int inventarNr; private String standort; public int getInventarNr() { return this.inventarNr; } public String getStandort() { return this.standort; } public void setInventarNr(int pInventarNr) { this.inventarNr = pInventarNr; } public void setStandort(String pStandort) { this.standort = pStandort; } private oaw4.demo.classic.uml.entity.Bibliothek eigentuemer; private oaw4.demo.classic.uml.entity.Buch buch; public void setEigentuemer( oaw4.demo.classic.uml.entity.Bibliothek pEigentuemer) { this.eigentuemer = pEigentuemer; } public oaw4.demo.classic.uml.entity.Bibliothek getEigentuemer() { return this.eigentuemer; } public void setBuch(oaw4.demo.classic.uml.entity.Buch pBuch) { this.buch = pBuch; } public oaw4.demo.classic.uml.entity.Buch getBuch() { return this.buch; } } 36 Evaluation WIRTSCHAFTS INFORMATIK Vorteile: - gute Dokumentation - Einbettung in Eclipse - Verwendung beliebiger Metamodelle - hohe Individualisierbarkeit Nachteile: - umständliche Bedienbarkeit - unausgreifte Fehlertoleranz 37 Fazit WIRTSCHAFTS INFORMATIK Aufgrund der offenen Struktur gut geeignet für die Entwicklung von MDSD/MDA-Projekten Insbesondere bei großen Projekten leistungsstark Zu empfehlen bei Lösungen mit hohem Anspruch an Individualität 38 Berücksichtigung von Assoziationen WIRTSCHAFTS INFORMATIK Association.xpt «IMPORT org::openarchitectureware::meta::uml::classifier» «EXTENSION java::NamingConventions» «EXTENSION java::Associations» «DEFINE ReferenceVariables FOR Class» «FOREACH AssociationEnd.Opposite.select(ae|ae.isNavigable) AS ae» private «ae.fqn()» «ae.asInstanceVar()»; «ENDFOREACH» «ENDDEFINE» «DEFINE AccessorMethods FOR Class» «EXPAND ToOneAccessorMethods FOREACH AssociationEnd.Opposite.select(ae|!ae.isMultiple && ae.isNavigable)» «EXPAND ToManyAccessorMethods FOREACH AssociationEnd.Opposite.select(ae|ae.isMultiple && ae.isNavigable)» «ENDDEFINE» «DEFINE ToOneAccessorMethods FOR AssociationEnd» public void «asSetter()» («Class.fqn()» «asParameter()») { this.«asInstanceVar()» = «asParameter()»; } public «Class.fqn()» «asGetter()» () { return this.«asInstanceVar()»; } «ENDDEFINE» «DEFINE ToManyAccessorMethods FOR AssociationEnd» public void add«NameS.toFirstUpper()» («Class.fqn()» «asParameter()») { this.«asInstanceVar()».add(«asParameter()»); } public void remove«NameS.toFirstUpper()» («Class.fqn()» «asParameter()») { this.«asInstanceVar()».remove(«asParameter()»); } public «iterator()» «asGetter()» () { return this.«asInstanceVar()».iterator(); } «ENDDEFINE» 39 Berücksichtigung von Assoziationen WIRTSCHAFTS INFORMATIK Association.xpt «IMPORT org::openarchitectureware::meta::uml::classifier» «EXTENSION java::NamingConventions» «EXTENSION java::Associations» «DEFINE ReferenceVariables FOR Class» «FOREACH AssociationEnd.Opposite.select(ae|ae.isNavigable) AS ae» private «ae.fqn()» «ae.asInstanceVar()»; «ENDFOREACH» «ENDDEFINE» «DEFINE AccessorMethods FOR Class» «EXPAND ToOneAccessorMethods FOREACH AssociationEnd.Opposite.select(ae|!ae.isMultiple && ae.isNavigable)» «EXPAND ToManyAccessorMethods FOREACH AssociationEnd.Opposite.select(ae|ae.isMultiple && ae.isNavigable)» «ENDDEFINE» «DEFINE ToOneAccessorMethods FOR AssociationEnd» public void «asSetter()» («Class.fqn()» «asParameter()») { this.«asInstanceVar()» = «asParameter()»; } public «Class.fqn()» «asGetter()» () { return this.«asInstanceVar()»; } «ENDDEFINE» «DEFINE ToManyAccessorMethods FOR AssociationEnd» public void add«NameS.toFirstUpper()» («Class.fqn()» «asParameter()») { this.«asInstanceVar()».add(«asParameter()»); } public void remove«NameS.toFirstUpper()» («Class.fqn()» «asParameter()») { this.«asInstanceVar()».remove(«asParameter()»); } public «iterator()» «asGetter()» () { return this.«asInstanceVar()».iterator(); } «ENDDEFINE» 40 Berücksichtigung von Assoziationen WIRTSCHAFTS INFORMATIK Association.ext import org::openarchitectureware::meta::uml::classifier; extension java::NamingConventions; String fqn (AssociationEnd ae) : !ae.isMultiple ? ae.Class.fqn() : "java.util.Collection<"+ae.Class.fqn()+">"; String iterator (AssociationEnd ae) : "java.util.Iterator<"+ae.Class.fqn()+">"; 41 Berücksichtigung von Assoziationen WIRTSCHAFTS INFORMATIK Association.xpt «IMPORT org::openarchitectureware::meta::uml::classifier» «EXTENSION java::NamingConventions» «EXTENSION java::Associations» «DEFINE ReferenceVariables FOR Class» «FOREACH AssociationEnd.Opposite.select(ae|ae.isNavigable) AS ae» private «ae.fqn()» «ae.asInstanceVar()»; «ENDFOREACH» «ENDDEFINE» «DEFINE AccessorMethods FOR Class» «EXPAND ToOneAccessorMethods FOREACH AssociationEnd.Opposite.select(ae|!ae.isMultiple && ae.isNavigable)» «EXPAND ToManyAccessorMethods FOREACH AssociationEnd.Opposite.select(ae|ae.isMultiple && ae.isNavigable)» «ENDDEFINE» «DEFINE ToOneAccessorMethods FOR AssociationEnd» public void «asSetter()» («Class.fqn()» «asParameter()») { this.«asInstanceVar()» = «asParameter()»; } public «Class.fqn()» «asGetter()» () { return this.«asInstanceVar()»; } «ENDDEFINE» «DEFINE ToManyAccessorMethods FOR AssociationEnd» public void add«NameS.toFirstUpper()» («Class.fqn()» «asParameter()») { this.«asInstanceVar()».add(«asParameter()»); } public void remove«NameS.toFirstUpper()» («Class.fqn()» «asParameter()») { this.«asInstanceVar()».remove(«asParameter()»); } public «iterator()» «asGetter()» () { return this.«asInstanceVar()».iterator(); } «ENDDEFINE» 42