Top Banner
Model Driven Architecture Code Generation Prof. Dr. Peter Thiemann Universität Freiburg 05.07.2006
45

Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Jul 17, 2020

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Model Driven ArchitectureCode Generation

Prof. Dr. Peter Thiemann

Universität Freiburg

05.07.2006

Page 2: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Contents

1 Code GenerationCode Generation Techniques

2 Pragmatics of Code GenerationInterfacing Generated with Non-Generated CodeSplitting in Technical SubdomainsMetaobjects

Page 3: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code GenerationReasons

Performance

Code size

Analyzability

Early detection of errors

Portability

Restrictions in the programming language

Aspects

Introspection/Reflection

Page 4: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code GenerationInstance of Metaprogramming

Programs that generate programs (base programs)Staging of metaprograms

Independent of base programs (usually earlier)base program and metaprogram are kept separateExamples: MDE generatorsDuring compilation of the base programstatic metaprogramming: generated program is unaware ofthe generation processExamples: C++ preprocessor, C++ templatesAt run-time of the base programdynamic metaprogramming: base program can beextended and modified at run timeExamples: metaobject protocol of CommonLisp

Homogeneous vs heterogeneous metaprogramming

Page 5: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesTemplates and Filtering

Specification

Filter

apply toSpecification

Subset of apply toTemplates

generatedcode

Page 6: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesTemplates and Filtering/Example

Code to be generated from templates

Template variables may be bound to model values

Example: generate JavaBean from XML specification

Page 7: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesTemplates and Filtering/Example

Bean specification

<class name="Person" package="de.unifrei"><attribute name="name" type="String"/><attribute name="age" type="int"/>

</class>

expected generated code

package de.unifrei;public class Person {

private String name;public String getName () {return name;}public void setName (String name) {this.name=name;}private int age;public int getAge () {return age;}public void setAge (int age) {this.age=age;}

}

Page 8: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesTemplates and Filtering/Example using XSLT

<xsl:template match="/class">package <xsl:value-of select="@package"/>;public class <xsl:value-of select="@name"/>{ <xsl:apply-templates select="attribute"/> }

</xsl:template>

<xsl:template match="attribute"><xsl:variable name="capname"

select="concat( translate(substring( @name, 1, 1),’abcdefghijklmnopqrstuvwxyz’,’ABCDEFGHIJKLMNOPQRSTUVWXYZ’ ),

substring(@name, 2))" />private <xsl:value-of select="@type"/>

<xsl:value-of select="@name"/>;public <xsl:value-of select="@type"/>

get<xsl:value-of select="$capname" /> (){return <xsl:value-of select="@name"/>;}

public void set<xsl:value-of select="$capname" />(<xsl:value-of select="@type"/> <xsl:value-of select="@name"/>){this.<xsl:value-of select="@name"/>=<xsl:value-of select="@name"/>;}

</xsl:template>

Page 9: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesTemplates and Metamodel

generatedcode

parse

is based on

Metamodel

InstanceMetamodel− Templates

apply to

creates

instance of

Specification

parse XML and map to user-defined metamodel

generate code from template and metamodel

Page 10: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesFrame Processors

and setparameters

2) instance

Generator

inst

ance

and

set p

aram

eter

s

{repeat}

Code−Frame

FrameSpecification−

1) create &

instance

3) generate

4)generated

code

A frame is an object consisting of slots and a codetemplate

Control iterates over frame instantiation

Exporting of the final frame structure generates the code

Page 11: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesFrame Processors/Example Frame Hierarchy

Parent

value3: FRAMEvalue2: FRAMEvalue1: int

value1: string

AChild2

value1: string

AnotherOne

value1: string

value2: FRAME

AChild

Page 12: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesFrame Processors/Example

Frame specification

.Frame GenNumberElement (Name, MaxValue).Dim vIntQual = (MaxValue > 32767) ? "long" : "short".Dim sNumbersInitVal<!vIntQual!> int <!Name!> <?= <!sNumbersInitVal!>?>;

.End Frame

Frame instantiation

.myNumberElem = CreateFrame ("GenNumberElement", "aShortNumber", 100)

Code generation

.Export myNumberElem

Page 13: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesAPI-based Generators

ProgramClient− applies

APImodifies

creates orCode

instanceof, corresponds

expressed bythe base of

AST/CST

Grammar

Page 14: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesInline Generation

contains the version−Source−Code

specification

Configuration

preprocess Source−Code

resolvedsome versions

[all resolved]

Source−Codeall versions

resolved

compilationBytecode

Machine− or

{opt

iona

l} preprocess

[else]

Integrated Compiler

Page 15: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesCode Attributes

Annotate code with active comments

Examples: JavaDoc, XDoclet (supported by Eclipse)

/*** @ejb:bean type="Stateless"* name="vvm/VVMQuery"* local-jndi-name="/ejb/vvm/VVMQueryLocal"* jndi-name="/ejb/vvm/VVMQueryRemote"* view-type="both"*/

public abstract class VVMQueryBean/**

* @ejb:interface-method view-type="both"*/

public List getPartsForVehicle ( VIN theVehicle ) {return super.getPartsForVehicle ( theVehicle );

}}

Page 16: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesCode Attributes/Language Support

.NET supports attributes that can be attached to parts ofC#programs

[AttributeUsage(AttributeTargets.All,Inherited=true,AllowMultiple=true)]

public class MyCustomAttribute: System.Attribute{

private string desc;private string name;

}

Similar feature: Metadata (aka Annotations) in Java5

Page 17: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesExcursion: Metadata in Java5

Many APIs require extra data that must be kept in syncwith the codeJava 5 defines a general purpose annotation facility thatpermits the definition and use of customized annotationtypes (generalizing javadoc, @deprecated, transient, etc)Java 5 annotations consist of

syntax for declaring annotation types,a syntax for annotating declarations,APIs for reading annotations,a class file representation for annotations,an annotation processing tool (apt)

Annotations do not affect semantics directly, but mayinfluence the execution contextAnnotations can be read from source files, class files, orreflectively at run time(Used in EJB 3.0)

Page 18: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesExcursion: an annotation type declaration

/*** Describes the Request-For-Enhancement(RFE) that led* to the presence of the annotated API element.*/

public @interface RequestForEnhancement {int id();String synopsis();String engineer() default "[unassigned]";String date() default "[unimplemented]";

}

Page 19: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesExcursion: an annotation type use

@RequestForEnhancement(id = 2868724,synopsis = "Enable time-travel",engineer = "Mr. Peabody",date = "4/1/3007"

)public static voidtravelThroughTime(Date destination) { ... }

annotation is special kind of modifier

precedes all other modifiers

Page 20: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code Generation TechniquesSummary

Staging program/ generated/metaprogram manual

Templatesand Filtering

before separate separate

Template andMetamodel

before separate separate

Frame Pro-cessors

before separate separate

API-basedGenerators

before/during/after separate separate

Inline Gener-ation

before/during mixed integrated

Code At-tributes

before/during (mixed) separate

Page 21: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Pragmatics of Code Generation

Which functionality to generatenot provided by the platformdescribable with a DSL

Generating the final applicationone build process which regenerates all generated andtransformed artifactswithout manual intervention or fixing

Exploiting the model beyond generated codeComponent testsSimple GUIsDatabase generation scriptsComponent configurations

Page 22: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code GenerationExamples for Configurations

SoftwareEJB deployment descriptorsBehavior for web frameworks like StrutsHibernate configurationsCORBA IDL

Hardware (from deployment diagrams)Installation of components on particular machinesGeneration of database tablesInfrastructure like load balancers

Page 23: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code GenerationPretty Code

People look at generated codeThey do not trust the generator (initially)DebuggingChecking the configuration of the generator

How to improve acceptanceGenerate comments with information from the modelsPretty printer for code formattingUse “location strings”[2006-07-02 10:58:36]GENERATED FROM TEMPLATE MdsdBookMODEL ELEMENT aChapter::aSection::generate()

Exception: portions optimized for performance

Page 24: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Code GenerationInterfacing Generated with Non-Generated Code

Keep generated and hand-written code separate as muchas possibleUse a suitable software architecture for this task

what is generatedwhat is written manuallyhow the two are combinedtools: interfaces, abstract classes, delegation, designpatterns (Factory, Strategy, Bridge, Template Method)

Generated code should be a throw-away product!

Page 25: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedStandard Solution: Protected Regions

accelerate(dv:int)

speed: int

stop()

Auto

}

//protected area end − 0002

//protected area begin − 0002

//insert your code here

public void stop(){}//protected area end −0001//insert your code here

//protected area begin − 0001

public void accelerate (int dv){

int speed = 0;

public class Auto{

}

complex generation

not always possible to preserve contents

weak separation between generated and non-generatedcode

Page 26: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedAlternative Solution: Layered Implementation

Platform Layer

Model Layer

Application Logic Layer

Base class(part of platform)

Manually programmed, abstract

generated, abstract

"Middle" − class

concrete class

manually implemented

Three layers of functionalityidentical for all components of a certain kinddifferent for each component, but can be generated fromthe modelmanual implementation

Page 27: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedCombination a

non−generated codegenerated code

Generated code calls non-generated code

Advice: only generate a small portion of code at a time andintegrate with existing, tested code

Page 28: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedCombination b

generated

non−generated code

Manual code calls generated code

Requires knowledge of generated code

May generate dependencies in the build process

Page 29: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedCombination c

generated

non−generated

Generated codeinherits from manual code orimplements a manual interface

Manual codehas some interface to program againstcan instantiate generated code via Factory pattern

Page 30: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedCombination d

generated

non−generated

Manual code inherits from generated code

Implementation may override generated, generic behavior

Factory

Page 31: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedCombination e

generated

non−generated

Generated code inherits from manual code

Invokes operations in manual code

Page 32: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedCombination f

generated

non−

generated

Manual class invokes operations of generated subclass

Template Method pattern

Superclass defines abstract operations

Generated subclass implements these operations

Page 33: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedConsequences for Methodology

Multi-layer generation may be necessary because ofdependenciesFirst generation step:

generates set of base classes from certain model elementsyields “API” for the manual part

Second generation step:generation involves all model elementsreferences (potentially) manually written parts

Page 34: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedConstraints

post: balance > balance@pre + amountpre: amount > 0

context Account.increase (int amount)Account

balnace: int

increase (int amount): void

The programmer shoud not be able to subvert the modelconstraints.

Page 35: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedConstraints and Protected Regions

// generatedclass Account {

int balance;public void increase ( int amount ) {

assert (amount > 0);// check preconditionint balance_atPre = balance;// saved for postcondition// --- protected region begin ---

// --- protected region end ---assert (balance = balance_atPre + amount);// check postcondition

}}

insufficient protection

simple inheritance does not help, either

Page 36: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedConstraints and Template Method

// generatedclass Account {

int balance;public final void increase ( int amount ) {

assert (amount > 0); // check preconditionint balance_atPre = balance; // saved for postconditionincrease_internal (amount);assert (balance = balance_atPre + amount); // chk postcondition

}protected abstract void increase_internal (int amount);

}

no way to subvert the dynamic contract monitoring

// manually written codeclass AccountImpl extends Account {

protected void increase_internal (int amount) {balance += amount;

}}

Page 37: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedConsistency

The programmer still has to follow some conventions inmanually written code

Naming conventionsClass must inherit from a certain generated class and mustoverride certain operationsClass must implement certain interfacesClass must implement certain operations

Check these conventions by generating code that teststhem

Page 38: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedConsistency Example

// generatedpublic abstract class SomeGeneratedBaseClass

extends SomePlatFormClass {protected abstract void someOperation ();public void someOtherOp() {

someOperation();}

}

Obligations of the developermust inherit from this classmust override someOperation()must name the class ...Implmust implement IExampleInterface

Page 39: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedConsistency Example: Good Implementation

public class SomeGeneratedBaseClassImplextends SomeGeneratedBaseClassimplements IExampleInterface {

protected void someOperation () {// do something

}public void anOperationFromExampleInterface() {

// ...}

Page 40: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Generated vs Non-GeneratedConsistency Example: Enforcement by Compiler

public abstract class SomeGeneratedBaseClassextends SomePlatFormClass {

// (see above)private void dontCallMe () {

new SomeGeneratedBaseClassImpl();// checks that class is present// and not abstract

SomeGeneratedBaseClass a =new SomeGeneratedBaseClassImpl ();// checks that class is subclass

IExampleInterface x =new SomeGeneratedBaseClassImpl ();// checks that class implements

}}

Page 41: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Splitting in Technical Subdomains

Large systems have a multitude of aspectsConsequently

models become largeone single DSL not adequatesplitting of tasks for multiple teams hard

Multiple DSLs with different modeling required

Generator unifies the different models

Must communicate via gateway metaclasses

Page 42: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Splitting in Technical SubdomainsGateway Metaclasses

Technical Subdomain

(e.g. Workflow)

Technical Subdomain 2(e.g. persistence)

Technical Subdomain 3(e.g. GUI)

Metamodel1

DSL 1 2Metamodel

DSL 2Metamodel

3 DSL 3

Metamodel elements which are used in multiplemetamodels

May result in information duplication because multipledefinitions of a modeling element must be kept consistent

Solved via proxy elements that reference modelingelements in another metamodel

Page 43: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

Splitting in Technical SubdomainsProxy Elements

anotherOp():long

Model 2Model 1

SomeInterface<<interfaceref>>

SMSAppTextEditor

<<interface>>SomeInterface

anOperation(int)<<references>>

Component

UML::Class

Interface

InterfaceRefPort*

delegate

Page 44: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

MetaobjectsThe Problem

Some applications need model information at runtimefor scriptingfor debugging

How can model information be transported to runtime?

Example: Logging of generated objects should happenwith attribute names and attribute values

Reflection helps only partially, it still cannot provide infofrom the underlying model (before model transformation)

Solution: generate metaobjects that contain the desiredinformationAssociation with concrete objects

via generated getMetaObject () operationsvia central registry

Page 45: Model Driven Architecture Code Generation · Code Generation Pretty Code People look at generated code They do not trust the generator (initially) Debugging Checking the configuration

MetaobjectsExample

getLabel()setValue (Object newVal): void

getName():StringgetValue():Object

AttributeMetaObject<<interface>>

StringAttributeMetaObject<<interface>>

getRegexp():String

SomeClass

<<pk>>name:String

{label="PLZ",zip:String

min=0, max=100} {label="Alter",age:int {label="Vorname"}firstname:String {label="Nachname"}

regexp="99999"}

label: String = "PLZ"name: String = "zip"

:StringAttributeMetaObject:SomeClassMetaObject

attributeNames: String={"name", "firstname", "age", "zip"}

name:Stringfirstname:Stringage:int

SomeClass

zip:String

name: String = "age"label: String = "Alter"min: int = 0max: int = 100

:NumAttributeMetaObject

GeneratedCode

getAttribue(name:String):AttributeMetaObject

getAttributeNames():String[]

<<interface>>ClassMetaObject

NumAttributeMetaObject<<interface>>

getMax():intgetMin():int

Model

<<instanceof>> <<instanceof>><<instanceof>>