Upload
sebastian-zarnekow
View
5.112
Download
1
Tags:
Embed Size (px)
DESCRIPTION
A short presentation on Xtext and the pragmatic adoption of internal and external DSLs in a real world project.
Citation preview
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