Textual Modeling Framework Xtext

Post on 06-May-2015

5.114 views 1 download

Tags:

description

A short presentation on Xtext and the pragmatic adoption of internal and external DSLs in a real world project.

Transcript of Textual Modeling Framework Xtext

Textual Modeling Framework

Sven Efftinge, Sebastian Zarnekow itemis

Donnerstag, 16. Juli 2009

Domain-Specific Language (DSL)

Donnerstag, 16. Juli 2009

Domain-Specific Language (DSL)

A DSL is a formal, processable language targeting at a specific viewpoint or

aspect of a software system.

Donnerstag, 16. Juli 2009

Domain-Specific Language (DSL)

A DSL is a formal, processable language targeting at a specific viewpoint or

aspect of a software system.

It’s semantics, flexibility and notation is designed in order to support working

with that viewpoint as good as possible.

Donnerstag, 16. Juli 2009

Why DSLs?

Donnerstag, 16. Juli 2009

Why DSLs?• higher abstractions

Donnerstag, 16. Juli 2009

Why DSLs?• higher abstractions • avoid redundancy

Donnerstag, 16. Juli 2009

Why DSLs?• higher abstractions • avoid redundancy• separation of concerns

Donnerstag, 16. Juli 2009

Why DSLs?• higher abstractions • avoid redundancy• separation of concerns• use domain concepts (Ubiquitous Language)

Donnerstag, 16. Juli 2009

The challenge

Donnerstag, 16. Juli 2009

ComplicatedDonnerstag, 16. Juli 2009

Complicated & Expensive ?Donnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

Donnerstag, 16. Juli 2009

How we address this with

Donnerstag, 16. Juli 2009

ConvenienceDonnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Grammardefinition

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Grammardefinition

Grammar reuse

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Derivedmetamodel

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Parserrules

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Parserrules

Keywords

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Multivalue assignment

Simple assigment

Boolean assigment

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Cardinality (one or more)

Optional Element

Cardinality (zero or more)

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Alternative

Cardinality (one or more)

Optional Element

Cardinality (zero or more)

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Assignment with rulecall

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Unassigned rulecall

Assignment with rulecall

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Unassigned rulecall

Assignment with rulecall

Containment

Donnerstag, 16. Juli 2009

9

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel "http://www.xtext.org/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Unassigned rulecall

Assignment with rulecall

Cross referenceContainment

Donnerstag, 16. Juli 2009

Metamodel Inference

10

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel"http://www.xtext.org/workshop/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Donnerstag, 16. Juli 2009

Metamodel Inference

10

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel"http://www.xtext.org/workshop/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Donnerstag, 16. Juli 2009

Metamodel Inference

10

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel"http://www.xtext.org/workshop/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Donnerstag, 16. Juli 2009

Metamodel Inference

10

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel"http://www.xtext.org/workshop/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Donnerstag, 16. Juli 2009

Metamodel Inference

10

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel"http://www.xtext.org/workshop/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Donnerstag, 16. Juli 2009

Metamodel Inference

10

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel"http://www.xtext.org/workshop/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Donnerstag, 16. Juli 2009

Metamodel Inference

10

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel"http://www.xtext.org/workshop/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Donnerstag, 16. Juli 2009

Metamodel Inference

10

grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals

generate domainModel"http://www.xtext.org/workshop/DomainModel"

Model : (types+=Type)+;Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType];

Donnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

Donnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

Based on the grammar and Ecore models,Xtext provides you with sensible

default implementations.

Donnerstag, 16. Juli 2009

FlexibilityDonnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

Donnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

Dependency management

Donnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

Dependency management

Donnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

Dependency management

Donnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

Dependency management

Donnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

Dependency management

Donnerstag, 16. Juli 2009

licensed by http://www.wordle.net/

MyCustomLabelProvider

Donnerstag, 16. Juli 2009

Dependency Injection with Google fGuice

Donnerstag, 16. Juli 2009

Dependency Injection with Google fGuice

Donnerstag, 16. Juli 2009

Dependency Injection with Google fGuice

‣No dependency to concrete implementation

Donnerstag, 16. Juli 2009

Dependency Injection with Google fGuice

‣No dependency to concrete implementation‣No explicit construction

Donnerstag, 16. Juli 2009

Dependency Injection with Google fGuice

‣No dependency to concrete implementation‣No explicit construction‣Easy testing

Donnerstag, 16. Juli 2009

Dependency Injection with Google fGuice

‣No dependency to concrete implementation‣No explicit construction‣Easy testing‣Easy composition

Donnerstag, 16. Juli 2009

Configuration of Components in Xtext

/** * used to register components to be used within the IDE. */public class DomainmodelUiModule extends GeneratedDomainmodelUiModule { @Override public Class<? extends ILabelProvider> bindILabelProvider() { return MySpecialLabelProvider.class; }}

Donnerstag, 16. Juli 2009

Composable Code Generator

‣ Generator is composed of “fragments”

Donnerstag, 16. Juli 2009

Composable Code Generator

‣ Generator is composed of “fragments”

‣ Fragments can contribute to:

Donnerstag, 16. Juli 2009

Composable Code Generator

‣ Generator is composed of “fragments”

‣ Fragments can contribute to:

‣ Manifest.MF

Donnerstag, 16. Juli 2009

Composable Code Generator

‣ Generator is composed of “fragments”

‣ Fragments can contribute to:

‣ Manifest.MF

‣ plugin.xml

Donnerstag, 16. Juli 2009

Composable Code Generator

‣ Generator is composed of “fragments”

‣ Fragments can contribute to:

‣ Manifest.MF

‣ plugin.xml

‣ Guice modules

Donnerstag, 16. Juli 2009

Composable Code Generator

‣ Generator is composed of “fragments”

‣ Fragments can contribute to:

‣ Manifest.MF

‣ plugin.xml

‣ Guice modules

‣ Add your own fragments

Donnerstag, 16. Juli 2009

UseCase Migrating existing Apps

Donnerstag, 16. Juli 2009

• DB-Application

• Oracle DB

• OracleForms

Starting point

Donnerstag, 16. Juli 2009

• Oracle DB

• Java Rich Client

• JPA

• Spring

• Swing / JGoodies Forms

Target

Donnerstag, 16. Juli 2009

Quantities

Donnerstag, 16. Juli 2009

Quantities• 1700++ Tables

Donnerstag, 16. Juli 2009

Quantities• 1700++ Tables

• 19500++ Columns

Donnerstag, 16. Juli 2009

Quantities• 1700++ Tables

• 19500++ Columns

• 300++ Forms

Donnerstag, 16. Juli 2009

Quantities• 1700++ Tables

• 19500++ Columns

• 300++ Forms

Task

Donnerstag, 16. Juli 2009

Quantities• 1700++ Tables

• 19500++ Columns

• 300++ Forms

Task• Find abstractions

Donnerstag, 16. Juli 2009

Quantities• 1700++ Tables

• 19500++ Columns

• 300++ Forms

Task• Find abstractions

• Simplify code

Donnerstag, 16. Juli 2009

@SuppressWarnings("serial")@Entity@Table(name = "BUCHUNGSKREISE_F")public class BuchungskreiseF extends AbstractEntity implements Serializable {

@SuppressWarnings("unused") @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "bkrIdSeq") @SequenceGenerator(name = "bkrIdSeq", sequenceName = "BKR_SEQ", allocationSize = 1) @Column(name = "BKR_ID", nullable = false) private Long bkrId;

public Long getBkrId() { return bkrId; }

public void setBkrId(final Long bkrId) { this.bkrId = bkrId; }

@Column(name = "KONTO_NR", nullable = false, length = 45) private String kontoNr;

public String getKontoNr() { return kontoNr; }

public void setKontoNr(final String kontoNr) { String oldValue = this.kontoNr; this.kontoNr = kontoNr; firePropertyChangeEvent("kontoNr", oldValue, this.kontoNr); }

@Column(name = "RG_NR_BKR_IDENTIFIKATOR", nullable = false, length = 1) private Long rgNrBkrIdentifikator;

public Long getRgNrBkrIdentifikator() { return rgNrBkrIdentifikator; }

public void setRgNrBkrIdentifikator(final Long rgNrBkrIdentifikator) { Long oldValue = this.rgNrBkrIdentifikator; this.rgNrBkrIdentifikator = rgNrBkrIdentifikator; firePropertyChangeEvent("rgNrBkrIdentifikator", oldValue, this.rgNrBkrIdentifikator); }

@Column(name = "REFERENZCODE_KONTO_NR", nullable = false, length = 45) private String referenzcodeKontoNr;

public String getReferenzcodeKontoNr() { return referenzcodeKontoNr; }

public void setReferenzcodeKontoNr(final String referenzcodeKontoNr) { String oldValue = this.referenzcodeKontoNr; this.referenzcodeKontoNr = referenzcodeKontoNr; firePropertyChangeEvent("referenzcodeKontoNr", oldValue, this.referenzcodeKontoNr); }

@Column(name = "PC_NR_RG", nullable = false, length = 45) private String pcNrRg;

public String getPcNrRg() { return pcNrRg; }

public void setPcNrRg(final String pcNrRg) { String oldValue = this.pcNrRg; this.pcNrRg = pcNrRg; firePropertyChangeEvent("pcNrRg", oldValue, this.pcNrRg); }

@Column(name = "PC_NR_PVA", nullable = false, length = 45) private String pcNrPva;

public String getPcNrPva() { return pcNrPva; }

public void setPcNrPva(final String pcNrPva) { String oldValue = this.pcNrPva; this.pcNrPva = pcNrPva; firePropertyChangeEvent("pcNrPva", oldValue, this.pcNrPva); }

@Column(name = "MWST_NR", nullable = false, length = 10) private Long mwstNr;

public Long getMwstNr() { return mwstNr; }

public void setMwstNr(final Long mwstNr) { Long oldValue = this.mwstNr; this.mwstNr = mwstNr; firePropertyChangeEvent("mwstNr", oldValue, this.mwstNr); }

@Column(name = "J_VERSION", nullable = false, insertable = false, updatable = false, length = 22)@org.hibernate.annotations.Generated(org.hibernate.annotations.GenerationTime.ALWAYS) @Version private Long jVersion;

public Long getJVersion() { return jVersion; }

public void setJVersion(final Long jVersion) { Long oldValue = this.jVersion; this.jVersion = jVersion; firePropertyChangeEvent("jVersion", oldValue, this.jVersion); }

@Column(name = "IBAN", nullable = false, length = 34) private String iban;

public String getIban() { return iban; }

public void setIban(final String iban) { String oldValue = this.iban; this.iban = iban; firePropertyChangeEvent("iban", oldValue, this.iban); }

@Column(name = "BUCHUNGSKREIS_NR", nullable = false, length = 4) private Long buchungskreisNr;

public Long getBuchungskreisNr() { return buchungskreisNr; }

public void setBuchungskreisNr(final Long buchungskreisNr) { Long oldValue = this.buchungskreisNr; this.buchungskreisNr = buchungskreisNr; firePropertyChangeEvent("buchungskreisNr", oldValue, this.buchungskreisNr); }

}

Entity

BuchungskreiseF

Id

Long bkrId

String kontoNr

nullable = false

nullable = false 45

BUCHUNGSKREISE_F

BKR_ID

KONTO_NR

BKR_SEQ

Donnerstag, 16. Juli 2009

@SuppressWarnings("serial")@Entity@Table(name = "BUCHUNGSKREISE_F")public class BuchungskreiseF extends AbstractEntity implements Serializable {

@SuppressWarnings("unused") @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "bkrIdSeq") @SequenceGenerator(name = "bkrIdSeq", sequenceName = "BKR_SEQ", allocationSize = 1) @Column(name = "BKR_ID", nullable = false) private Long bkrId;

public Long getBkrId() { return bkrId; }

public void setBkrId(final Long bkrId) { this.bkrId = bkrId; }

@Column(name = "KONTO_NR", nullable = false, length = 45) private String kontoNr;

public String getKontoNr() { return kontoNr; }

public void setKontoNr(final String kontoNr) { String oldValue = this.kontoNr; this.kontoNr = kontoNr; firePropertyChangeEvent("kontoNr", oldValue, this.kontoNr); }

@Column(name = "RG_NR_BKR_IDENTIFIKATOR", nullable = false, length = 1) private Long rgNrBkrIdentifikator;

public Long getRgNrBkrIdentifikator() { return rgNrBkrIdentifikator; }

public void setRgNrBkrIdentifikator(final Long rgNrBkrIdentifikator) { Long oldValue = this.rgNrBkrIdentifikator; this.rgNrBkrIdentifikator = rgNrBkrIdentifikator; firePropertyChangeEvent("rgNrBkrIdentifikator", oldValue, this.rgNrBkrIdentifikator); }

@Column(name = "REFERENZCODE_KONTO_NR", nullable = false, length = 45) private String referenzcodeKontoNr;

public String getReferenzcodeKontoNr() { return referenzcodeKontoNr; }

public void setReferenzcodeKontoNr(final String referenzcodeKontoNr) { String oldValue = this.referenzcodeKontoNr; this.referenzcodeKontoNr = referenzcodeKontoNr; firePropertyChangeEvent("referenzcodeKontoNr", oldValue, this.referenzcodeKontoNr); }

@Column(name = "PC_NR_RG", nullable = false, length = 45) private String pcNrRg;

public String getPcNrRg() { return pcNrRg; }

public void setPcNrRg(final String pcNrRg) { String oldValue = this.pcNrRg; this.pcNrRg = pcNrRg; firePropertyChangeEvent("pcNrRg", oldValue, this.pcNrRg); }

@Column(name = "PC_NR_PVA", nullable = false, length = 45) private String pcNrPva;

public String getPcNrPva() { return pcNrPva; }

public void setPcNrPva(final String pcNrPva) { String oldValue = this.pcNrPva; this.pcNrPva = pcNrPva; firePropertyChangeEvent("pcNrPva", oldValue, this.pcNrPva); }

@Column(name = "MWST_NR", nullable = false, length = 10) private Long mwstNr;

public Long getMwstNr() { return mwstNr; }

public void setMwstNr(final Long mwstNr) { Long oldValue = this.mwstNr; this.mwstNr = mwstNr; firePropertyChangeEvent("mwstNr", oldValue, this.mwstNr); }

@Column(name = "J_VERSION", nullable = false, insertable = false, updatable = false, length = 22)@org.hibernate.annotations.Generated(org.hibernate.annotations.GenerationTime.ALWAYS) @Version private Long jVersion;

public Long getJVersion() { return jVersion; }

public void setJVersion(final Long jVersion) { Long oldValue = this.jVersion; this.jVersion = jVersion; firePropertyChangeEvent("jVersion", oldValue, this.jVersion); }

@Column(name = "IBAN", nullable = false, length = 34) private String iban;

public String getIban() { return iban; }

public void setIban(final String iban) { String oldValue = this.iban; this.iban = iban; firePropertyChangeEvent("iban", oldValue, this.iban); }

@Column(name = "BUCHUNGSKREIS_NR", nullable = false, length = 4) private Long buchungskreisNr;

public Long getBuchungskreisNr() { return buchungskreisNr; }

public void setBuchungskreisNr(final Long buchungskreisNr) { Long oldValue = this.buchungskreisNr; this.buchungskreisNr = buchungskreisNr; firePropertyChangeEvent("buchungskreisNr", oldValue, this.buchungskreisNr); }

}

Entity

BuchungskreiseF

Id

Long bkrId

String kontoNr

nullable = false

nullable = false 45

BUCHUNGSKREISE_F

BKR_ID

KONTO_NR

BKR_SEQ

Donnerstag, 16. Juli 2009

entity BuchungskreiseF (id=bkrId sequenceName=BKR_SEQ) {

String kontoNr

Long rgNrBkrIdentifikator

String referenzcodeKontoNr

}

(notNull, length=45)

(notNull, length=45)

(notNull, length=1)

External DSL for Entities

Donnerstag, 16. Juli 2009

entity BuchungskreiseF (id=bkrId sequenceName=BKR_SEQ) {

String kontoNr

Long rgNrBkrIdentifikator

String referenzcodeKontoNr

}

External DSL for Entities

Donnerstag, 16. Juli 2009

entity BuchungskreiseF (id=bkrId sequenceName=BKR_SEQ) {

String kontoNr

Long rgNrBkrIdentifikator

String referenzcodeKontoNr

}

BUCHUNGSKREISE_F

RG_NR_BKR_IDENTIFIKATOR

External DSL for Entities

Donnerstag, 16. Juli 2009

ValidationDonnerstag, 16. Juli 2009

Donnerstag, 16. Juli 2009

addValidator(new Validator<Institutionen>() { @Override public ValidationResult validate(final Institutionen institution) { final ValidationResult result = new ValidationResult(); if (institution != null && institution.getEsrNr() != null && !CheckUtils.checkPcKontoNrPruefziffer( Long.parseLong(institution.getEsrNr())) { result.add(new SimpleValidationMessage( getResourceMap().getString("validation.esr.msg"), Severity.ERROR, getModel(Institutionen.DESC.esrNr()))); } return result; } });

Donnerstag, 16. Juli 2009

addValidator(new Validator<Institutionen>() { @Override public ValidationResult validate(final Institutionen institution) { final ValidationResult result = new ValidationResult(); if (institution != null && institution.getEsrNr() != null && !CheckUtils.checkPcKontoNrPruefziffer( Long.parseLong(institution.getEsrNr())) { result.add(new SimpleValidationMessage( getResourceMap().getString("validation.esr.msg"), Severity.ERROR, getModel(Institutionen.DESC.esrNr()))); } return result; } });

Framework-Code

Donnerstag, 16. Juli 2009

addValidator(new Validator<Institutionen>() { @Override public ValidationResult validate(final Institutionen institution) { final ValidationResult result = new ValidationResult(); if (institution != null && institution.getEsrNr() != null && !CheckUtils.checkPcKontoNrPruefziffer( Long.parseLong(institution.getEsrNr())) { result.add(new SimpleValidationMessage( getResourceMap().getString("validation.esr.msg"), Severity.ERROR, getModel(Institutionen.DESC.esrNr()))); } return result; } });

Framework-CodeNullpointer abfragen

Donnerstag, 16. Juli 2009

addValidator(new Validator<Institutionen>() { @Override public ValidationResult validate(final Institutionen institution) { final ValidationResult result = new ValidationResult(); if (institution != null && institution.getEsrNr() != null && !CheckUtils.checkPcKontoNrPruefziffer( Long.parseLong(institution.getEsrNr())) { result.add(new SimpleValidationMessage( getResourceMap().getString("validation.esr.msg"), Severity.ERROR, getModel(Institutionen.DESC.esrNr()))); } return result; } });

Framework-CodeNullpointer abfragenStatic imports

Donnerstag, 16. Juli 2009

addValidator(new Validator<Institutionen>() { @Override public ValidationResult validate(final Institutionen institution) { final ValidationResult result = new ValidationResult(); if (institution != null && institution.getEsrNr() != null && !CheckUtils.checkPcKontoNrPruefziffer( Long.parseLong(institution.getEsrNr())) { result.add(new SimpleValidationMessage( getResourceMap().getString("validation.esr.msg"), Severity.ERROR, getModel(Institutionen.DESC.esrNr()))); } return result; } });

Framework-CodeNullpointer abfragenStatic importsBibliotheks Methoden definieren und benutzen

error("validation.esr.msg", desc.esrNr());

Donnerstag, 16. Juli 2009

@Check void checkEsrMsg() { if (!checkKontoNrPruefziffer(parseLong(_this.getEsrNr()))) error("validation.esr.msg",desc.esrNr()); }

Internal DSL with Java

• JUnit-like• Ignore Nullpointer-Exceptions

Donnerstag, 16. Juli 2009

Future PlansDonnerstag, 16. Juli 2009

Eclipse Helios

Donnerstag, 16. Juli 2009

Eclipse Helios•Model Index

Donnerstag, 16. Juli 2009

Eclipse Helios•Model Index

•Grammar Mixins

Donnerstag, 16. Juli 2009

Eclipse Helios•Model Index

•Grammar Mixins

•Base Language

Donnerstag, 16. Juli 2009

Eclipse Helios•Model Index

•Grammar Mixins

•Base Language

•UI Features

Donnerstag, 16. Juli 2009

Eclipse Helios•Model Index

•Grammar Mixins

•Base Language

•UI Features

•Documentation

Donnerstag, 16. Juli 2009

Donnerstag, 16. Juli 2009

Thank you very much for listening

Visit the project’s web site : www.xtext.org

Copyright 2009 by itemis

Donnerstag, 16. Juli 2009

Thank you very much for listening

Visit the project’s web site : www.xtext.org

Copyright 2009 by itemis

Xtext Webinar Tomorrow 19:00

http://live.eclipse.org/node/705

Donnerstag, 16. Juli 2009