• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
On the Use of an Internal DSL for Enriching EMF Models
 

On the Use of an Internal DSL for Enriching EMF Models

on

  • 444 views

 

Statistics

Views

Total Views
444
Views on SlideShare
442
Embed Views
2

Actions

Likes
0
Downloads
3
Comments
0

1 Embed 2

http://www.linkedin.com 2

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • By design, it can only express a limited range of structural constraints, mainly with respect to containment and type conformance. \n\nFor more complex structural constraints usually the Object Constraint Language (OCL) is used that expresses these constraints as state invariants attached to meta-model classifiers\n\n- structural constrains in form of state invariants\n- per/post condition\n
  • By design, it can only express a limited range of structural constraints, mainly with respect to containment and type conformance. \n\nFor more complex structural constraints usually the Object Constraint Language (OCL) is used that expresses these constraints as state invariants attached to meta-model classifiers\n\n- structural constrains in form of state invariants\n- per/post condition\n
  • By design, it can only express a limited range of structural constraints, mainly with respect to containment and type conformance. \n\nFor more complex structural constraints usually the Object Constraint Language (OCL) is used that expresses these constraints as state invariants attached to meta-model classifiers\n\n- structural constrains in form of state invariants\n- per/post condition\n
  • By design, it can only express a limited range of structural constraints, mainly with respect to containment and type conformance. \n\nFor more complex structural constraints usually the Object Constraint Language (OCL) is used that expresses these constraints as state invariants attached to meta-model classifiers\n\n- structural constrains in form of state invariants\n- per/post condition\n
  • By design, it can only express a limited range of structural constraints, mainly with respect to containment and type conformance. \n\nFor more complex structural constraints usually the Object Constraint Language (OCL) is used that expresses these constraints as state invariants attached to meta-model classifiers\n\n- structural constrains in form of state invariants\n- per/post condition\n
  • - Some shortcomings we came across while using OCL in an EMF based MDE toolchain -> Motivation\n\n
  • - Concerned by practical side of OCL rather than formal one\n\n- Most of the issues are well known -> no direct applicable solution to Eclipse EMF\n\n\n
  • - propagation of runtime exceptions, NPE - difficult to trace\n- difficult to narrow bugs in incorrect OCL expressions\n- OCL console can help, problem with complex expressions that invole derive features, ...\n- Despite the fact that many of these issues have already been identified or addressed, the lack of an overall integration is a crucial issue, which, according to us, influences the slow adoption of OCL in the industry.\n
  • - complex expressions that goes beyond simple object navigation\n
  • - with the lack of first-order logic collection operation the expressed concern would be quickly lost among java commands\n- result far from clean\n\n- the no really any highlight\n- emf codegen translates the model concepts into java concepts\n- optional parenthesis, lambda expressions, collection operation, ... \n
  • - with the lack of first-order logic collection operation the expressed concern would be quickly lost among java commands\n- result far from clean\n\n- the no really any highlight\n- emf codegen translates the model concepts into java concepts\n- optional parenthesis, lambda expressions, collection operation, ... \n
  • - with the lack of first-order logic collection operation the expressed concern would be quickly lost among java commands\n- result far from clean\n\n- the no really any highlight\n- emf codegen translates the model concepts into java concepts\n- optional parenthesis, lambda expressions, collection operation, ... \n
  • - with the lack of first-order logic collection operation the expressed concern would be quickly lost among java commands\n- result far from clean\n\n- the no really any highlight\n- emf codegen translates the model concepts into java concepts\n- optional parenthesis, lambda expressions, collection operation, ... \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • - there is also a warning\n
  • \n
  • \n
  • \n
  • - besides the fact that we can use both java and scala libraries \n - it is a matter of adding a new dependency to the project\n\n- we could simply define a function that takes two booleans\n- the real power is that it will feel like a language feature\n\n- b will not get evaluated => advanced example\n
  • - besides the fact that we can use both java and scala libraries \n - it is a matter of adding a new dependency to the project\n\n- we could simply define a function that takes two booleans\n- the real power is that it will feel like a language feature\n\n- b will not get evaluated => advanced example\n
  • - besides the fact that we can use both java and scala libraries \n - it is a matter of adding a new dependency to the project\n\n- we could simply define a function that takes two booleans\n- the real power is that it will feel like a language feature\n\n- b will not get evaluated => advanced example\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • the different semantics between OCL and Scala, \nunlimited numerals, \n\nFinally, carrying out more case studies should help us further assess the practicality of the proposed solution and explore what other advantages of a DSL approach, beyond the traditional usage of OCL, may benefit users.\n
  • \n
  • Soon to be fully open sourced\n
  • 1. promising, but we believe that our approach is more pragmatic at least until all the extensions and production ready tools are implemented\n\n2. itself positioned as not a rival to OMG standards but as a prototype to experiment with novel approaches\n\n3. simply snippets of JS - our case represents model extensions as functions - first class citizens at code level\n\n4. external xtext based DSL, does not support constraints, prototype\n\n5. Do modern programming languages make OCL redundant?\n - we try to go beyond OCL-like expressions, advanced constructs, improved invariant support\n
  • \n
  • \n
  • External DSL can choose syntax freely\n Internal DSL has to operate in boundaries of its host language\n Multiple model packages at the same time - classes from different packages\n
  • External DSL can choose syntax freely\n Internal DSL has to operate in boundaries of its host language\n Multiple model packages at the same time - classes from different packages\n
  • External DSL can choose syntax freely\n Internal DSL has to operate in boundaries of its host language\n Multiple model packages at the same time - classes from different packages\n
  • - OCL extension is tool specific\n- selective immutability\n
  • - it is not criticism of Eclipse OCL\n- files over 800 lines (MacBook Pro, 8GB RAM)\n\n- propagation of runtime exceptions, NPE - difficult to trace\n- difficult to narrow bugs in incorrect OCL expressions\n- OCL console can help, problem with complex expressions that invole derive features, ...\n\n- OCL is either interpreted or translated to some other language\n- Xtext includes Java’s debugging support for other languages JSR-045 \n
  • \n
  • ...that are difficult to understand and maintain.\n\nA constraint related to the collaboration element defined in the UML meta-model adopted from Correa et al\n\n\n
  • ...that are difficult to understand and maintain.\n\nA constraint related to the collaboration element defined in the UML meta-model adopted from Correa et al\n\n\n
  • ...that are difficult to understand and maintain.\n\nA constraint related to the collaboration element defined in the UML meta-model adopted from Correa et al\n\nlack of debugging support\n\n

On the Use of an Internal DSL for Enriching EMF Models On the Use of an Internal DSL for Enriching EMF Models Presentation Transcript

  • On the Use of an Internal DSL for Enriching EMF Models Filip Křikava Philippe Collet Université Nice Sophia Antipolis I3S - CNRS UMR 7271 France 2012 Workshop on OCL and Textual Modeling (OCL 2012), MODELS’12 September, 30th, 2012 - Innsbruck/AUSTRIA
  • The Journey 2
  • The Journey - applying MDE into Self-Adaptive Software SystemsMeta-modeling with EMF 2
  • The Journey - applying MDE into Self-Adaptive Software SystemsMeta-modeling with EMF - limited expressiveness of structural constraintsEnriching EMF with OCL 2
  • The Journey - applying MDE into Self-Adaptive Software Systems Meta-modeling with EMF - limited expressiveness of structural constraints constraints Enriching EMF with OCLoperation contractsimplementation of operation bodiesimplementation of derived features 2
  • The Journey - applying MDE into Self-Adaptive Software Systems Meta-modeling with EMF - limited expressiveness of structural constraints constraints Enriching EMF with OCLoperation contracts - encountered number of shortcomings - since our work is based on Scalaimplementation of operation bodies Enriching EMF with Scalaimplementation of derived features 2
  • The Journey - applying MDE into Self-Adaptive Software Systems Meta-modeling with EMF - limited expressiveness of structural constraints constraints Enriching EMF with OCLoperation contracts - encountered number of shortcomings - since our work is based on Scalaimplementation of operation bodies Enriching EMF with Scalaimplementation of - internal DSL in Scala to enrich EMF derived features - similar OCL features - full advantage of the host language - state-of-the-art tool support + 2
  • Outline• Some Shortcomings of OCL• Internal DSL Approach• Implementation• Conclusion 3
  • Some Shortcomings of OCL• Based solely on our experience • different usage of OCL - different pros/cons • concerned by practicality rather than formality • not a complete study nor first one (well known issues) 4
  • Some Shortcomings of OCL Expressions Constraints Capturing OCL Expressions Tool Support Constructs • Poor support for user feedback• Complex expressions are • No support for warning / • Scalability and stability hard to write and critiques problems with larger maintain models • No support for• Limited extensibility and dependent constraints • Limited developer reuse feedback • Limited flexibility in• Side-effect free context definition • Insufficient debugging expressions capability • No support for repairing• Inconsistency/Confusing inconsistencies issues • No support for invariant reuse across different models D. Kolovos, et al. On the Evolution of OCL for Capturing Structural Constraints, In Rigorous Methods for Software Construction and Analysis, 2009. 5
  • Internal DSL Approach - Overview• The shortcomings are related to scalability • OCL language • performance, stability and features of OCL tools • when used in the large (many invariants, complex expressions) • similar problems are in other external DSLs (EOL/EVL) 6
  • Internal DSL Approach - Overview• External DSL like OCL raises the level of abstraction: 7
  • Internal DSL Approach - Overview• External DSL like OCL raises the level of abstraction: parent.types ->select(name <> ) ->forAll(e | e <> self implies e.name <> self.name) 7
  • Internal DSL Approach - Overview• External DSL like OCL raises the level of abstraction: parent.types ->select(name <> ) ->forAll(e | e <> self implies e.name <> self.name)• The same could be expressed in plain Java, but ... no 7
  • Internal DSL Approach - Overview• External DSL like OCL raises the level of abstraction: parent.types ->select(name <> ) ->forAll(e | e <> self implies e.name <> self.name)• The same could be expressed in plain Java, but ... no• Having a language that has a more powerful and flexible constructs and state-of-the-art tool support 7
  • Internal DSL Approach - Overview• External DSL like OCL raises the level of abstraction: parent.types ->select(name <> ) ->forAll(e | e <> self implies e.name <> self.name)• The same could be expressed in plain Java, but ... no• Having a language that has a more powerful and flexible constructs and state-of-the-art tool support self.parent.types .filter(name != ) .forall(e => e != self implies e.name != self.name) 7
  • Internal DSL Approach - Why Scala?• Modern general purpose language• Runs on top of JVM• Well designed for building internal DSLs• Statically typed using type inference• Well supported by major tool vendor 8
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods 9
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1] - getTransactions(until: Date, from: Date) : Transactions [0..*] 9
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1]• Derived property: - getTransactions(until: Date, from: Date) : Transactions [0..*] def getPrintedName (self: Customer): String = self.owner.title + " " + self.owner.name 9
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1]• Derived property: - getTransactions(until: Date, from: Date) : Transactions [0..*] def getPrintedName (self: Customer): String = self.owner.title + " " + self.owner.name 9
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1]• Derived property: - getTransactions(until: Date, from: Date) : Transactions [0..*] def getPrintedName (self: Customer): String = self.owner.title + " " + self.owner.name 9
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1]• Derived property: - getTransactions(until: Date, from: Date) : Transactions [0..*] def getPrintedName (self: Customer): String = self.owner.title + " " + self.owner.name 9
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1]• Derived property: - getTransactions(until: Date, from: Date) : Transactions [0..*] def getPrintedName (self: Customer): String = self.owner.title + " " + self.owner.name• Operation body: def invokeGetTransactions(self: Customer, until: Date, from: Date): Set[Transaction] = self.transactions filter ( t => t.date.isAfter(from) && t.date.isBefore(until) ) 10
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1]• Derived property: - getTransactions(until: Date, from: Date) : Transactions [0..*] def getPrintedName (self: Customer): String = self.owner.title + " " + self.owner.name• Operation body: def invokeGetTransactions(self: Customer, until: Date, from: Date): Set[Transaction] = self.transactions filter ( t => t.date.isAfter(from) && t.date.isBefore(until) ) 10
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1]• Derived property: - getTransactions(until: Date, from: Date) : Transactions [0..*] def getPrintedName (self: Customer): String = self.owner.title + " " + self.owner.name• Operation body: def invokeGetTransactions(self: Customer, until: Date, from: Date): Set[Transaction] = self.transactions filter ( t => t.date.isAfter(from) && t.date.isBefore(until) ) 10
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1]• Derived property: - getTransactions(until: Date, from: Date) : Transactions [0..*] def getPrintedName (self: Customer): String = self.owner.title + " " + self.owner.name• Operation body: def invokeGetTransactions(self: Customer, until: Date, from: Date): Set[Transaction] = self.transactions filter ( t => t.date.isAfter(from) && t.date.isBefore(until) ) 10
  • Internal DSL Approach - Basics• Enriching constructs represented as Scala object methods Customer - printedName : String [1..1]• Derived property: - getTransactions(until: Date, from: Date) : Transactions [0..*] def getPrintedName (self: Customer): String = self.owner.title + " " + self.owner.name• Operation body: def invokeGetTransactions(self: Customer, until: Date, from: Date): Set[Transaction] = self.transactions filter ( t => t.date.isAfter(from) && t.date.isBefore(until) ) 10
  • Internal DSL Approach - Basics• Constraints 11
  • Internal DSL Approach - Basics• Constraintsdef validateOfAge(self: Customer): Boolean = self.age >= 18 11
  • Internal DSL Approach - Basics• Constraintsdef validateOfAge(self: Customer): Boolean = self.age >= 18 11
  • Internal DSL Approach - Basics• Constraintsdef validateOfAge(self: Customer): Boolean = self.age >= 18 11
  • Internal DSL Approach - Basics• Constraintsdef validateOfAge(self: Customer): Boolean = self.age >= 18 11
  • Internal DSL Approach - Basics • Constraintsdef validateOfAge(self: Customer): Boolean = self.age >= 18def validateOfAge(self: Customer): Option[String] = if (self.age >= 18) { None else { Some("The person %s is under age" format self.name) } 11
  • Internal DSL Approach - Basics • Constraintsdef validateOfAge(self: Customer): Boolean = self.age >= 18def validateOfAge(self: Customer): Option[String] = if (self.age >= 18) { None else { Some("The person %s is under age" format self.name) } 11
  • Internal DSL Approach - Basics• Constraints • a constraint that check whether a UML class contains getInstance method 12
  • Internal DSL Approach - Basics• Constraints • a constraint that check whether a UML class contains getInstance method def validateDefinesGetInstance(self: UMLClazz) = { } 13
  • Internal DSL Approach - Basics• Constraints • a constraint that check whether a UML class contains getInstance method def validateDefinesGetInstance(self: UMLClazz) = { self.features.find(_.name == "getInstance") match { }} 14
  • Internal DSL Approach - Basics• Constraints • a constraint that check whether a UML class contains getInstance method def validateDefinesGetInstance(self: UMLClazz) = { self.features.find(_.name == "getInstance") match { case Some(_) => Success }} 15
  • Internal DSL Approach - Basics• Constraints • a constraint that check whether a UML class contains getInstance method def validateDefinesGetInstance(self: UMLClazz) = { self.features.find(_.name == "getInstance") match { case Some(_) => Success case None => Error("Missing getInstance" )}} 16
  • Internal DSL Approach - Basics• Constraints • a constraint that check whether a UML class contains getInstance method def validateDefinesGetInstance(self: UMLClazz) = { self.features.find(_.name == "getInstance") match { case Some(_) => Success case None => Error("Missing getInstance", QuickFix("Add a getInstance operation", { } ))}} 17
  • Internal DSL Approach - Basics• Constraints • a constraint that check whether a UML class contains getInstance method def validateDefinesGetInstance(self: UMLClazz) = { self.features.find(_.name == "getInstance") match { case Some(_) => Success case None => Error("Missing getInstance", QuickFix("Add a getInstance operation", { clazz: UMLClazz => clazz.features += create[UMLFeature] { op => op.setName("getInstance") // ... } } ))}} 18
  • Internal DSL Approach - Basics• Constraints dependencydef validateDefinesGetInstance(self: UMLClazz)@satisfies(“DefinesGetInstance”)def validateDefinesGetIsStatic(self: UMLClazz)• Using proxy to ensure each invariant is called at most once for a specific instance• Referencing by strings is not very practical • Looking into Scala 2.10 macros 19
  • Internal DSL Approach - Basics• Constraints dependencydef validateDefinesGetInstance(self: UMLClazz)@satisfies(“DefinesGetInstance”)def validateDefinesGetIsStatic(self: UMLClazz)• Using proxy to ensure each invariant is called at most once for a specific instance• Referencing by strings is not very practical • Looking into Scala 2.10 macros 19
  • Internal DSL Approach - Extensibility• Scala is extensible language• For example, there is no implies operation in Scala self.parent.types .forall(e => e != self implies e.name != self.name) 20
  • Internal DSL Approach - Extensibility• Scala is extensible language• For example, there is no implies operation in Scala self.parent.types .forall(e => e != self implies e.name != self.name)• Possibility to extend existing types class ExtBoolean(a: Boolean) { def implies(b: => Boolean) = !a || b } implicit def extBoolean(a: Boolean) = new ExtBoolean(a) 20
  • Internal DSL Approach - Extensibility• Scala is extensible language• For example, there is no implies operation in Scala self.parent.types .forall(e => e != self implies e.name != self.name)• Possibility to extend existing types class ExtBoolean(a: Boolean) { def implies(b: => Boolean) = !a || b } implicit def extBoolean(a: Boolean) = new ExtBoolean(a)• This way we can add missing OCL operations (closure) 20
  • Internal DSL Approach - Reusability• Breaking expression into smaller pieces• Organizing them as functions in objects and libraries• Shared across project 21
  • Internal DSL Approach - Reusability• Breaking expression into smaller pieces• Organizing them as functions in objects and libraries• Shared across project• Push further using structural typing - reused across modelsdef validateNonEmptyName(self: { def name: String } ) = !self.name.isEmpty 21
  • Internal DSL Approach - Undefined and Invalid Values interface Person { Person public String getFirstName();- firstName : String [0..1]- lastName : String [1..1] public String getLastName(); }• Using the NonEmptyName constraint might lead to NPE !self.firstName.isEmpty 22
  • Internal DSL Approach - Undefined and Invalid Values interface Person { Person public String getFirstName();- firstName : String [0..1]- lastName : String [1..1] public String getLastName(); }• Using the NonEmptyName constraint might lead to NPE !self.firstName.isEmpty self.firstName != null implies !self.firstName.isEmpty 22
  • Internal DSL Approach - Undefined and Invalid Values interface Person { Person public String getFirstName();- firstName : String [0..1]- lastName : String [1..1] public String getLastName(); }• Using the NonEmptyName constraint might lead to NPE !self.firstName.isEmpty self.firstName != null implies !self.firstName.isEmpty 22
  • Internal DSL Approach - Undefined and Invalid Values interface Person { Person public scala.Option<String>- firstName : String [0..1] getFirstName();- lastName : String [1..1] public String getLastName(); } Option<T> - get() : T - isDefined : Boolean … … ... Some None 23
  • Internal DSL Approach - Undefined and Invalid Values interface Person { Person public scala.Option<String>- firstName : String [0..1] getFirstName();- lastName : String [1..1] public String getLastName(); } Option<T> - get() : T - isDefined : Boolean … … ... Some None 23
  • Internal DSL Approach - Type Casts• OCLif self.oclIsKindOf(Customer) then self.oclAsType(Customer).someAction()else // something elseendif• Scalaself match { case c: Customer => c.someAction() case _ => // something else} 24
  • Internal DSL Approach - Drawbacks• Expressions can contain arbitrary code • difficult to ensure side-effect free expressions • possibility to use external checker like IGJ • @ReadOnly parameter annotation• Loss of formal reasoning and analysis• No constructs related to postconditions 25
  • Implementation - Sigma Framework • Simple API for enriching EMF models using Java class methods - delegate computation • Small layer on top of EMF and EValidator • Target language agnostic (Xtend, Kotlin, ...) • Ecore EMF • EValidator Sigma Core Sigma Scala Codegen Dynamic • generate direct calls EMF Delegates Templates • reduce the runtime overhead caused by reflection • simplifies debugging, code orientation 26
  • Conclusion• Improve the EMF integration and solid tools to the community• Specify the deviations from OCL and its consequences• Specify the trade-offs between standardized OCL and flexibility of the DSL approach• Looking beyond traditional usage of OCL 27
  • The Journey further on ... ... ... + Model to Text Model to Model Model Testingtransformation transformation 28
  • Thank you! http://nyx.unice.fr/projects/sigma Filip Křikava filip.krikava@i3s.unice.frThe work reported in this paper is partly funded by the ANR SALTY projectunder contract ANR-09-SEGI-012. 29
  • Related Work• There is a plenty of work addressing OCL shortcomings - popular research subject• OCLLib, OCLUnit, OCLDoc, ...• Epsilon project• JS4EMF• Xcore• “C# 3.0 makes OCL redundant” 30
  • Some Shortcomings of OCL Expressions• Side-effect free expressions • by default, expressions are side-effect • no assignment semantics • all data-types are immutable • useful for constraints • impossible to implement state changing operations • no support for generic class type parameters • while having generic collections 31
  • Some Shortcomings of OCL Expressions• Some inconsistency, confusions • ‘.’ and ‘->’ operators • implicit oclAsSet • implicit collection flattening in collect • logical operation with undefined values • different OCL meta-models • no support for generic class type parameters • while having generic collections 32
  • Internal DSL Approach - Principles• EMF codegen translates model concepts into Java • model classifier -> Java class • structural / behavioral feature -> method 33
  • Internal DSL Approach - Principles• EMF codegen translates model concepts into Java • model classifier -> Java class • structural / behavioral feature -> method• Scala allow to omit parenthesis in zero arg methods self.getMembership.getParticipant.getDateOfBirth 33
  • Internal DSL Approach - Principles• EMF codegen translates model concepts into Java • model classifier -> Java class • structural / behavioral feature -> method• Scala allow to omit parenthesis in zero arg methods self.getMembership.getParticipant.getDateOfBirth• Remove get noise using codegen dynamic templates self.membership.participant.dateOfBirth 33
  • Internal DSL Approach - Principles• EMF codegen translates model concepts into Java • model classifier -> Java class • structural / behavioral feature -> method• Scala allow to omit parenthesis in zero arg methods self.getMembership.getParticipant.getDateOfBirth• Remove get noise using codegen dynamic templates self.membership.participant.dateOfBirth• Scala supports lambda expressions• Large number of collection operations 33
  • Some Shortcomings of OCL Expressions• Complex expressions are hard to write and maintain • linearity of the OCL expression• Limited extensibility and reuse • difficult to add new operations (i.e. support for regular expressions)• Side-effect free expressions • by default side-effect free expressions; no instantiation• Inconsistency/Confusing issues • implicit flattening, logic with undefined values, missing generics class type parameters, etc. 34
  • Some Shortcomings of Tool Support• Impressive number of academic OCL tools • lack of commercial tools• Eclipse OCL project • Set of OCL editors (e.g. OCLInEcore) • Based on EMF delegates• Scalability and stability problems with larger models• Limited developer feedback• Insufficient debugging capability 35
  • Some Shortcomings of OCL Expressions“... Second, it is compact, yet powerful. Youcan write short and to the point expressionsthat do a lot.” - Anders Ivner, foreword to the 2nd edition of The Object Constraint Language 36
  • Some Shortcomings of OCL Expressions“... Second, it is compact, yet powerful. Youcan write short and to the point expressionsthat do a lot.” - Anders Ivner, foreword to the 2nd edition of The Object Constraint Language • true for short, straight-forward expressions • not so true for complex ones • hard for new users when they move from tutorial like expressions into real word ones 36
  • The problem with OCL expressions• OCL in form of expressions that can be chained together parent.types ->select(name <> ) ->forAll(e | e <> self implies e.name <> self.name) 37
  • The problem with OCL expressions• The linearity of the expression chaining often leads to long and complex expressionsself.allContents ->forAll (p | (p.oclIsKindOf(ClassifierRole) implies p.name = implies self.allContents ->forAll (q | q.oclIsKindOf(ClassifierRole) implies (p.oclAsType(ClassifierRole).base = q.oclAsType(ClassifierRole).base imples p = q) ) ) and (p.oclIsKindOf(AssociationRole) implies p.name = imples self.allContents ->forAll ( q | q.oclIsKindOf(AssociationRole) implies (p.oclAsType(AssociationRole).base = q.oclAsType(AssociationRole).base imples p = q) ) ) 38
  • The problem with OCL expressions• The linearity of the expression chaining often leads to long and complex expressionsself.allContents ->forAll (p | (p.oclIsKindOf(ClassifierRole) implies p.name = implies self.allContents ->forAll (q | q.oclIsKindOf(ClassifierRole) implies (p.oclAsType(ClassifierRole).base = q.oclAsType(ClassifierRole).base imples p = q) ) ) and (p.oclIsKindOf(AssociationRole) implies p.name = imples self.allContents ->forAll ( q | q.oclIsKindOf(AssociationRole) implies (p.oclAsType(AssociationRole).base = q.oclAsType(AssociationRole).base imples p = q) ) )• This combined with poor tool support 39