Textual Modeling Framework Xtext

7,955 views

Published on

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

Published in: Technology, Education
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
7,955
On SlideShare
0
From Embeds
0
Number of Embeds
3,559
Actions
Shares
0
Downloads
226
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Textual Modeling Framework Xtext

  1. 1. Textual Modeling Framework Sven Efftinge, Sebastian Zarnekow itemis Donnerstag, 16. Juli 2009
  2. 2. Domain-Specific Language (DSL) Donnerstag, 16. Juli 2009
  3. 3. 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
  4. 4. 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
  5. 5. Why DSLs? Donnerstag, 16. Juli 2009
  6. 6. Why DSLs? • higher abstractions Donnerstag, 16. Juli 2009
  7. 7. Why DSLs? • higher abstractions • avoid redundancy Donnerstag, 16. Juli 2009
  8. 8. Why DSLs? • higher abstractions • avoid redundancy • separation of concerns Donnerstag, 16. Juli 2009
  9. 9. Why DSLs? • higher abstractions • avoid redundancy • separation of concerns • use domain concepts (Ubiquitous Language) Donnerstag, 16. Juli 2009
  10. 10. The challenge Donnerstag, 16. Juli 2009
  11. 11. Complicated Donnerstag, 16. Juli 2009
  12. 12. Complicated & Expensive ? Donnerstag, 16. Juli 2009
  13. 13. licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  14. 14. How we address this with Donnerstag, 16. Juli 2009
  15. 15. Convenience Donnerstag, 16. Juli 2009
  16. 16. 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]; 9 Donnerstag, 16. Juli 2009
  17. 17. Grammar grammar org.xtext.workshop.DomainModel definition 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]; 9 Donnerstag, 16. Juli 2009
  18. 18. Grammar grammar org.xtext.workshop.DomainModel Grammar reuse definition 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]; 9 Donnerstag, 16. Juli 2009
  19. 19. grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals Derived generate domainModel "http://www.xtext.org/DomainModel" metamodel Model : (types+=Type)+; Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  20. 20. grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals generate domainModel "http://www.xtext.org/DomainModel" Model : (types+=Type)+; Parser rules Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  21. 21. grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals generate domainModel "http://www.xtext.org/DomainModel" Model : (types+=Type)+; Parser rules Type : Class | DataType; DataType : 'datatype' name=ID; Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* Keywords '}'; Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  22. 22. grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals generate domainModel "http://www.xtext.org/DomainModel" Multivalue assignment Model : (types+=Type)+; Type : Class | DataType; Simple assigment DataType : 'datatype' name=ID; Boolean assigment Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  23. 23. grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals generate domainModel "http://www.xtext.org/DomainModel" Model : (types+=Type)+; Cardinality (one or more) Type : Class | DataType; DataType : 'datatype' name=ID; Class : Optional Element (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* Cardinality (zero or more) '}'; Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  24. 24. grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals generate domainModel "http://www.xtext.org/DomainModel" Model : (types+=Type)+; Cardinality (one or more) Alternative Type : Class | DataType; DataType : 'datatype' name=ID; Class : Optional Element (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* Cardinality (zero or more) '}'; Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  25. 25. 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; Assignment with rulecall Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  26. 26. grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals generate domainModel "http://www.xtext.org/DomainModel" Model : (types+=Type)+; Type : Class | DataType; Unassigned rulecall DataType : 'datatype' name=ID; Assignment with rulecall Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  27. 27. grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals generate domainModel "http://www.xtext.org/DomainModel" Model : (types+=Type)+; Type : Class | DataType; Unassigned rulecall DataType : 'datatype' name=ID; Assignment with rulecall Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Containment Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  28. 28. grammar org.xtext.workshop.DomainModel with org.eclipse.xtext.common.Terminals generate domainModel "http://www.xtext.org/DomainModel" Model : (types+=Type)+; Type : Class | DataType; Unassigned rulecall DataType : 'datatype' name=ID; Assignment with rulecall Class : (abstract?='abstract')? 'class' name=ID '{' (features+=Feature)* '}'; Containment Cross reference Feature : 'attr' name=ID ':' type=[DataType]; 9 Donnerstag, 16. Juli 2009
  29. 29. Metamodel Inference 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]; 10 Donnerstag, 16. Juli 2009
  30. 30. Metamodel Inference 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]; 10 Donnerstag, 16. Juli 2009
  31. 31. Metamodel Inference 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]; 10 Donnerstag, 16. Juli 2009
  32. 32. Metamodel Inference 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]; 10 Donnerstag, 16. Juli 2009
  33. 33. Metamodel Inference 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]; 10 Donnerstag, 16. Juli 2009
  34. 34. Metamodel Inference 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]; 10 Donnerstag, 16. Juli 2009
  35. 35. Metamodel Inference 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]; 10 Donnerstag, 16. Juli 2009
  36. 36. Metamodel Inference 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]; 10 Donnerstag, 16. Juli 2009
  37. 37. licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  38. 38. Based on the grammar and Ecore models, Xtext provides you with sensible default implementations. licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  39. 39. Flexibility Donnerstag, 16. Juli 2009
  40. 40. licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  41. 41. Dependency management licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  42. 42. Dependency management licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  43. 43. Dependency management licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  44. 44. Dependency management licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  45. 45. Dependency management licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  46. 46. MyCustomLabelProvider licensed by http://www.wordle.net/ Donnerstag, 16. Juli 2009
  47. 47. Dependency Injection with Google fGuice Donnerstag, 16. Juli 2009
  48. 48. Dependency Injection with Google fGuice Donnerstag, 16. Juli 2009
  49. 49. Dependency Injection with Google fGuice ‣No dependency to concrete implementation Donnerstag, 16. Juli 2009
  50. 50. Dependency Injection with Google fGuice ‣No dependency to concrete implementation ‣No explicit construction Donnerstag, 16. Juli 2009
  51. 51. Dependency Injection with Google fGuice ‣No dependency to concrete implementation ‣No explicit construction ‣Easy testing Donnerstag, 16. Juli 2009
  52. 52. Dependency Injection with Google fGuice ‣No dependency to concrete implementation ‣No explicit construction ‣Easy testing ‣Easy composition Donnerstag, 16. Juli 2009
  53. 53. 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
  54. 54. Composable Code Generator ‣ Generator is composed of “fragments” Donnerstag, 16. Juli 2009
  55. 55. Composable Code Generator ‣ Generator is composed of “fragments” ‣ Fragments can contribute to: Donnerstag, 16. Juli 2009
  56. 56. Composable Code Generator ‣ Generator is composed of “fragments” ‣ Fragments can contribute to: ‣ Manifest.MF Donnerstag, 16. Juli 2009
  57. 57. Composable Code Generator ‣ Generator is composed of “fragments” ‣ Fragments can contribute to: ‣ Manifest.MF ‣ plugin.xml Donnerstag, 16. Juli 2009
  58. 58. Composable Code Generator ‣ Generator is composed of “fragments” ‣ Fragments can contribute to: ‣ Manifest.MF ‣ plugin.xml ‣ Guice modules Donnerstag, 16. Juli 2009
  59. 59. 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
  60. 60. UseCase Migrating existing Apps Donnerstag, 16. Juli 2009
  61. 61. Starting point • DB-Application • Oracle DB • OracleForms Donnerstag, 16. Juli 2009
  62. 62. Target • Oracle DB • Java Rich Client • JPA • Spring • Swing / JGoodies Forms Donnerstag, 16. Juli 2009
  63. 63. Quantities Donnerstag, 16. Juli 2009
  64. 64. Quantities • 1700++ Tables Donnerstag, 16. Juli 2009
  65. 65. Quantities • 1700++ Tables • 19500++ Columns Donnerstag, 16. Juli 2009
  66. 66. Quantities • 1700++ Tables • 19500++ Columns • 300++ Forms Donnerstag, 16. Juli 2009
  67. 67. Quantities • 1700++ Tables • 19500++ Columns • 300++ Forms Task Donnerstag, 16. Juli 2009
  68. 68. Quantities • 1700++ Tables • 19500++ Columns • 300++ Forms Task • Find abstractions Donnerstag, 16. Juli 2009
  69. 69. Quantities • 1700++ Tables • 19500++ Columns • 300++ Forms Task • Find abstractions • Simplify code Donnerstag, 16. Juli 2009
  70. 70. @SuppressWarnings("serial") @Entity Entity @Table(name = "BUCHUNGSKREISE_F") BUCHUNGSKREISE_F public class BuchungskreiseF extends AbstractEntity implements Serializable { @SuppressWarnings("unused") @Id Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "bkrIdSeq") @SequenceGenerator(name = "bkrIdSeq", sequenceName = "BKR_SEQ", allocationSize = 1) BKR_SEQ @Column(name = "BKR_ID", nullable = false BKR_ID false) private Long bkrId bkrId; public Long getBkrId() { return bkrId; } public void setBkrId(final Long bkrId) { this.bkrId = bkrId; } @Column(name = "KONTO_NR", nullable = false length = 45 KONTO_NR false, 45) private String kontoNr; kontoNr public String getKontoNr() { return kontoNr; } public void setKontoNr(final String kontoNr) { String oldValue = this.kontoNr; this.kontoNr = kontoNr; firePropertyChangeEvent("kontoNr", oldValue, this.kontoNr); } Donnerstag, 16. Juli 2009
  71. 71. @SuppressWarnings("serial") @Entity Entity @Table(name = "BUCHUNGSKREISE_F") BUCHUNGSKREISE_F public class BuchungskreiseF extends AbstractEntity implements Serializable { @SuppressWarnings("unused") @Id Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "bkrIdSeq") @SequenceGenerator(name = "bkrIdSeq", sequenceName = "BKR_SEQ", allocationSize = 1) BKR_SEQ @Column(name = "BKR_ID", nullable = false BKR_ID false) private Long bkrId bkrId; public Long getBkrId() { return bkrId; } public void setBkrId(final Long bkrId) { this.bkrId = bkrId; } @Column(name = "KONTO_NR", nullable = false length = 45 KONTO_NR false, 45) private String kontoNr; kontoNr public String getKontoNr() { return kontoNr; } public void setKontoNr(final String kontoNr) { String oldValue = this.kontoNr; this.kontoNr = kontoNr; firePropertyChangeEvent("kontoNr", oldValue, this.kontoNr); } Donnerstag, 16. Juli 2009
  72. 72. External DSL for Entities entity BuchungskreiseF (id=bkrId sequenceName=BKR_SEQ) { String kontoNr (notNull, length=45) Long rgNrBkrIdentifikator (notNull, length=1) String referenzcodeKontoNr (notNull, length=45) } Donnerstag, 16. Juli 2009
  73. 73. External DSL for Entities entity BuchungskreiseF (id=bkrId sequenceName=BKR_SEQ) { String kontoNr Long rgNrBkrIdentifikator String referenzcodeKontoNr } Donnerstag, 16. Juli 2009
  74. 74. External DSL for Entities BUCHUNGSKREISE_F entity BuchungskreiseF (id=bkrId sequenceName=BKR_SEQ) { String kontoNr RG_NR_BKR_IDENTIFIKATOR Long rgNrBkrIdentifikator String referenzcodeKontoNr } Donnerstag, 16. Juli 2009
  75. 75. Validation Donnerstag, 16. Juli 2009
  76. 76. Donnerstag, 16. Juli 2009
  77. 77. 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
  78. 78. Framework-Code 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
  79. 79. Framework-Code Nullpointer abfragen 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
  80. 80. Framework-Code Nullpointer abfragen Static imports 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
  81. 81. Framework-Code Nullpointer abfragen Static imports Bibliotheks Methoden definieren und benutzen 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( error("validation.esr.msg", desc.esrNr()); getResourceMap().getString("validation.esr.msg"), Severity.ERROR, getModel(Institutionen.DESC.esrNr()))); } return result; } }); Donnerstag, 16. Juli 2009
  82. 82. Internal DSL with Java @Check void checkEsrMsg() { if (!checkKontoNrPruefziffer(parseLong(_this.getEsrNr()))) error("validation.esr.msg",desc.esrNr()); } • JUnit-like • Ignore Nullpointer-Exceptions Donnerstag, 16. Juli 2009
  83. 83. Future Plans Donnerstag, 16. Juli 2009
  84. 84. Eclipse Helios Donnerstag, 16. Juli 2009
  85. 85. Eclipse Helios • Model Index Donnerstag, 16. Juli 2009
  86. 86. Eclipse Helios • Model Index • Grammar Mixins Donnerstag, 16. Juli 2009
  87. 87. Eclipse Helios • Model Index • Grammar Mixins • Base Language Donnerstag, 16. Juli 2009
  88. 88. Eclipse Helios • Model Index • Grammar Mixins • Base Language • UI Features Donnerstag, 16. Juli 2009
  89. 89. Eclipse Helios • Model Index • Grammar Mixins • Base Language • UI Features • Documentation Donnerstag, 16. Juli 2009
  90. 90. Donnerstag, 16. Juli 2009
  91. 91. Thank you very much for listening Visit the project’s web site : www.xtext.org Copyright 2009 by itemis Donnerstag, 16. Juli 2009
  92. 92. Thank you very much for listening Visit the project’sWebinar : Xtext web site www.xtext.org19:00 Tomorrow http://live.eclipse.org/node/705 Copyright 2009 by itemis Donnerstag, 16. Juli 2009

×