Advertisement
Advertisement

More Related Content

Advertisement

Enriching EMF Models with Scala (quick overview)

  1. (quick overview) Enriching EMF Models with Scala Filip Krikava I3S Laboratory, CNRS, France
  2. Enriching EMF Models • Implementing • derived properties using • operations’ bodies • constrains
  3. Enriching EMF Models • Implementing • derived properties using • operations’ bodies • constrains
  4. Motivation
  5. Motivation Library + getBookByName(EString) : Book [0..1] writers books 0..* 0..* writers Writer Book - name : String [1..1] 1..* - name : String [0..1] - isbn : String [1..1] books 0..*
  6. Motivation How to make sure the books ISBN in the model are unique?
  7. Implementation (model) • Add a new operation • Add a new Ecore annotation
  8. Implementation (Java) ! * @generated ! */ ! public boolean validateBook_UniqueISBN(Book book, ! ! ! DiagnosticChain diagnostics, Map<Object, Object> context) { ! ! // TODO implement the constraint ! ! // -> specify the condition that violates the constraint ! ! // -> verify the diagnostic details, including severity, code, and ! ! // message ! ! // Ensure that you remove @generated or mark it @generated NOT ! ! if (false) { ! ! ! if (diagnostics != null) { ! ! ! ! diagnostics.add(createDiagnostic(Diagnostic.ERROR, ! ! ! ! ! ! DIAGNOSTIC_SOURCE, 0, ! ! ! ! ! ! "_UI_GenericConstraint_diagnostic", new Object[] { ! ! ! ! ! ! ! ! "UniqueISBN", getObjectLabel(book, context) }, ! ! ! ! ! ! new Object[] { book }, context)); ! ! ! } ! ! ! return false; ! ! } ! ! return true; ! }
  9. Implementation (Java) ! * @generated NOT ! */ ! public boolean validateBook_UniqueISBN(Book book, ! ! ! DiagnosticChain diagnostics, Map<Object, Object> context) { ! ! boolean violated = false; ! ! ! ! for (Book e : book.getLibrary().getBooks()) { ! ! ! if (e != book && e.getIsbn().equals(book.getIsbn())) { ! ! ! ! violated = true; ! ! ! ! break; ! ! ! } ! ! } ! ! ! ! if (violated) { ! ! ! if (diagnostics != null) { ! ! ! ! diagnostics.add(createDiagnostic(Diagnostic.ERROR, ! ! ! ! ! ! DIAGNOSTIC_SOURCE, 0, ! ! ! ! ! ! "_UI_GenericConstraint_diagnostic", new Object[] { ! ! ! ! ! ! ! ! "UniqueISBN", getObjectLabel(book, context) }, ! ! ! ! ! ! new Object[] { book }, context)); ! ! ! } ! ! ! return false; ! ! } ! ! return true; ! }
  10. Implementation (Java) • Flexible, • but • violates generation gap pattern • not very expressive
  11. We could use a domain- specific language
  12. Implementation (OCL) ! context Book ! ! inv invariant_UniqueISBN: ! ! self.library.books->forAll (e | e <> self implies e.isbn <> self.isbn)
  13. Implementation (OCL) On the Use of an Internal DSL for Enriching EMF Models • Filip Kˇikava r Philippe Collet Université Nice Université Nice Higher level of abstractions, Sophia Antipolis, France Sophia Antipolis, France I3S - CNRS UMR 7271 I3S - CNRS UMR 7271 filip.krikava@i3s.unice.fr philippe.collet@unice.fr ABSTRACT The Object Constraint Language (OCL) is widely used to enrich Scala features, such as support for higher-order functions, rich col- • but modeling languages with structural constraints, side effect free query lection libraries and implicit type conversions, allow us to write operations implementation and contracts. OCL was designed to be very similar OCL-like expressions, but also leverage from the many small and compact language with appealing short “to-the-point” libraries found in the Java and Scala ecosystems. Besides Scala also expressions. When trying to apply it to larger EMF models some comes with state-of-the-art tool support. shortcomings appear in the language expressions, the invariant con- The rest of the paper is organized as follows. In Section 2 we structs as well as in the supporting tools. describe the main shortcomings of OCL based on our experience. In this paper we argue that some of these shortcomings are mainly Section 3 shows how we use Scala as an alternative approach to related to the scalability of the OCL language and its trade-offs be- enrich EMF models. It is followed by Section 4 where the im- tween domain-specificity and general-purpose. We present an al- plementation details are presented together with an evaluation. In ternative approach based on an internal DSL in Scala. By using Section 5, we discuss related work. We briefly conclude and outline this modern multi-paradigm programing language we can realize future work in Section 6. • scalability problems of an internal DSL with similar features found in OCL while taking full advantage of the host language including state-of-the-art tool 2. SOME SHORTCOMINGS OF OCL support. In particular, we discuss the mapping between the OCL and Scala concepts together with some additional constructs for In this section we present a list of shortcomings we came across better scalability in both expressiveness and reusability of the ex- while using OCL in an EMF based MDE toolchain, but various pressions. usages of OCL reveal different pros and cons. In our study we were concerned with the practical side of OCL rather than a formal one like in [14] or [4]. 1. INTRODUCTION For each of the point we also report on works in which similar OCL is used to complement the limited expressiveness of the problems were reported. Despite the fact that many of these issues structural constraints of the modeling languages like UML (Uni- have already been identified or addressed, the lack of an overall integration is a crucial issue, which, according to us, influences the • the language fied Modeling Language) or EMF (Eclipse Modeling Framework). Such model constraints are captured as state invariants using a side- slow adoption of OCL in the industry. effect free expression language that supports first order predicate logic with model querying and navigation facilities [18, 15]. More- 2.1 OCL Expressions over, these expressions can be further used to include additional One of the key points that Anders Ivner mentions in the foreword information to the model such as operation contracts in form of pre to the second edition of The Object Constraint Language [18] is and post conditions, and implementation of derived features and “Second, it is compact, yet powerful. You can write short and to- operation bodies. OCL is also embedded in context of other tools the-point expressions that do a lot”. While this is true for many such as the Object Management Group QVT model transformation. of the short and straight-forward expressions, when the complex- OCL is an appealing and expressive language, but when applied ity grows our ease of reading and writing of these expressions de- to larger EMF models using Eclipse OCL1 , we found a number of creases radically. This might be especially hard for the new users when they move from the tutorial like expressions to real world • the tooling support shortcomings in the language expressions, the invariant constructs as well as in the supporting tools. While some of these problems ones. are already well identified in the literature either as research agenda or accompanied with some solutions (c.f. Section 2), the lack of an Complex expressions are hard to write and maintain overall integration eventually led us to look for alternatives. Ac- OCL constraints and queries are defined in form of expressions that cording to us, some of these shortcomings are in general related to can be chained together. The underlying linearity of this chaining some scalability issues as a result of trade-offs between domain- often leads to long and complex expressions that are difficult to specificity and general-purpose. understand and maintain. Since the debugging support in OCL is In this paper we present an alternative approach based on an in- rather limited, mostly only simple logging or tracing is possible, ternal DSL in Scala2 , a statically typed object-oriented and func- maintaining of these expressions is particularly hard. tional programming language that runs on top of a Java Virtual In [10] Correa et al. provide some refactoring techniques to sim- Machine (JVM). Besides the seamless integration with EMF, some plify some of these complex expressions. Ackermann et al. pro- pose in [1] to utilize specification patterns for which OCL con- 1 http://goo.gl/TECuz straints can be generated automatically, together with a collection 2 http://www.scala-lang.org/ of OCL specification patterns formally defined. These techniques F. Krikava and P. Collet, On the Use of an Internal DSL for Enriching EMF Models, OCL 2012 Workshop
  14. Approaches GPL DSL • Low level • Higher level • Flexible • Scalability problems • State-of-the-art • language tooling • tools Could we combine the two?
  15. An Internal DSL in Scala ! def validateUniqueISBN(self: Book): Boolean = { ! self.library.books forall (e => e != self implies e.isbn != self.isbn) ! } Scala version
  16. An Internal DSL in Scala ! def validateUniqueISBN(self: Book): Boolean = { ! self.library.books forall (e => e != self implies e.isbn != self.isbn) ! } Scala version ! context Book ! ! inv invariant_UniqueISBN: ! ! self.library.books->forAll (e | e <> self implies e.isbn <> self.isbn) OCL version
  17. An Internal DSL in Scala • Bridging the gap between Scala and EMF Library + getBookByName(EString) : Book [0..1] ! def invokeGetBookByName(self: Library, name: String): Option [Book] = { ! self.books find (name == _.name) ! }
  18. An Internal DSL in Scala • Bridging the gap between Scala and EMF Library + getBookByName ( EString ) : Book [0..1] ! def invoke GetBookByName(self: Library, name: String): Option [Book] = { ! self.books find (name == _.name) ! }
  19. An Example Constraint: A writer’s name must be capitalized. Geral Jay Sussman geral Jay Sussman Geral jay Sussman Geral Jay sussman ... OK ERROR
  20. An Example Basics ! def validateCapitalizedName(self: Writer) = ! self.name.split(“ ”) forall (_(0).isUpper)
  21. An Example Basics ! def validateCapitalizedName(self: Writer) = ! self.name.split(“ ”) forall (_(0).isUpper) Dependencies @Satisfies(“nonEmptyName”) def validateCapitalizedName(self: Writer) = ! self.name.split(“ ”) forall (_(0).isUpper) def validateNonEmpryName(self: Writer) = ! self.name != null && !self.name.isEmpty
  22. ⌘-1 Quick Fix @Satisfies(“nonEmptyName”) def validateCapitalizedName(self: Writer) = { if (self.name.split(“ ”) forall (_(0).isUpper)) { OK() } else { Error(“Name is not capitalized“, QuickFix(“Capitalize”) { w: Writer => w.setName(self.name.split(“ ”) map (_.capitalize) mkString (” ”)) }) } }
  23. ⌘-1 Quick Fix
  24. ⌘-1 Quick Fix
  25. ⌘-1 Quick Fix
  26. ⌘-1 Quick Fix
  27. ⌘-1 Quick Fix
  28. Implemented as a layer on top of EMF • Language agnostic • special support for Scala EMF Sigma Core • Integrated with EMF models Sigma Scala Codegen Dynamic EMF Delegates Templates
  29. It’s just a beginning • Internal DSL for • M2M • M2T • programming Ecore models • Ecore model testing • ...
  30. Thank You Questions? Soon to appear at github.com/fikovnik/Sigma Filip Krikava @fikovnik
  31. Drawbacks • Expressions can contain an arbitrary code • Harder to make formal analysis • Side-effect free with external checking • No pre/post conditions at the moment
  32. Among others • Support for • generic type parameters • multiple models • inheritance • constraint reuse • better NPE handling • ...
Advertisement