Combining
Graphics and Text
       in
 Modeling Tools

                    Jan Köhnlein (itemis)
                    Jos W...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {
	    	     log.err...
Xtext vs GMF
Xtext
Xtext


 G
  ra
       m
        m
            ar
Xtext


 G
  ra
       m
        m
            ar
Xtext



                                 ar
                              m
                             m
              ...
Xtext



                                  ar
                               m
                              m
           ...
Superclass




GMF   Subclass




      Ecore model
                   Class
Superclass




GMF       Subclass




          Ecore model
                       Class




  Graph
  Model
Superclass




GMF       Subclass




          Ecore model
                       Class




  Graph                      ...
Superclass




GMF       Subclass




          Ecore model
                               Class




  Graph              ...
Superclass




GMF       Subclass




          Ecore model
                               Class




  Graph              ...
Superclass




GMF       Subclass




          Ecore model
                               Class




  Graph              ...
Runtime Models
      and
Synchronization
Xtext
                    EObject         element




               eAdapters
                  NodeAdapter




         ...
Xtext                                                                             GMF
                    EObject         ...
GMF
              ResourceSet


GMFResource                 DiagramResource




              Canonical
              Edit...
GMF
               ResourceSet


GMFResource                  DiagramResource




              Canonical
              Ca...
GMF
               ResourceSet


GMFResource                  DiagramResource




              Canonical
              Ca...
Xtext
Xtext

              Textual Model


        Serializer
                     Parser
                              Node Mod...
Xtext
        XtextResource

                     Textual Model


               Serializer
                            Pa...
Xtext
        XtextResource

                     Textual Model


               Serializer
                            Pa...
Xtext                load(), save()



        XtextResource

                     Textual Model


               Serializ...
Xtext                load(), save()



        XtextResource

                     Textual Model


               Serializ...
ResourceSet


XtextResource                 DiagramResource
diagram
                                         change

                ResourceSet


XtextResource                 Diagr...
ResourceSet


XtextResource                 DiagramResource
reparse()
w/ errors

                    ResourceSet


    XtextResource                 DiagramResource
ResourceSet


XtextResource                 DiagramResource
ResourceSet


XtextResource                 DiagramResource




                Canonical
                EditPolicy
ResourceSet


XtextResource                 DiagramResource




                Canonical
                EditPolicy
ResourceSet


XtextResource                 DiagramResource




                Canonical
                EditPolicy
Fi e l
                    od a
                 M xtu
                  le l
                    Te
 ResourceSet         ...
Fi e l
                    od a
                 M xtu
                  le l
                    Te
 ResourceSet         ...
Fi e l
                    od a
                 M xtu
                  le l
                    Te
 ResourceSet         ...
Fi e l
                      od a
                   M xtu
                    le l
                      Te
 ResourceSet ...
Fi e l
                     od a
                  M xtu
                   le l
                     Te
 ResourceSet     ...
Fi e l
                     od a
                  M xtu
                   le l
                     Te
 ResourceSet     ...
Fi e l
                    od a
                 M xtu
                  le l
                    Te
 ResourceSet         ...
Fi e l
                    od a
                 M xtu
                  le l
                    Te
 ResourceSet         ...
Alignment
grammar org.xtext.cg2009.Entities
  with org.eclipse.xtext.common.Terminals

generate entities "http://www.xtext.org/cg200...
grammar org.xtext.cg2009.Entities
  with org.eclipse.xtext.common.Terminals

               Avoid empty
generate entities ...
grammar org.xtext.cg2009.Entities
  with org.eclipse.xtext.common.Terminals

               Avoid empty
generate entities ...
grammar org.xtext.cg2009.Entities
  with org.eclipse.xtext.common.Terminals

               Avoid empty
generate entities ...
Xtext
Xtext
        Implement a
         Formatter
Xtext
        Implement a
         Formatter


             Implement a
          FragmentProvider
Xtext
           Implement a
            Formatter


                 Implement a
              FragmentProvider



      ...
GMF
GMF

 Initialize
mandatory
properties
GMF

         Initialize
        mandatory
        properties



Avoid Phantom
    Nodes
Add a
transaction on
                                 GMF
     load



                    Initialize
                   m...
Glue Code
Glue Code
• Prevent conflicting modifications
Glue Code
• Prevent conflicting modifications
• Navigate
 • diagram ➜ text
Glue Code
• Prevent conflicting modifications
• Navigate
 • diagram ➜ text
 • text ➜ diagram
    (needs index)
Glue Code
• Prevent conflicting modifications
• Navigate
 • diagram ➜ text
 • text ➜ diagram
    (needs index)
• Parser wrap...
Glue Code
• Prevent conflicting modifications
• Navigate
 • diagram ➜ text
 • text ➜ diagram
    (needs index)
• Parser wrap...
Demo Time
Combining Graphical and Textual
Combining Graphical and Textual
Combining Graphical and Textual
Combining Graphical and Textual
Combining Graphical and Textual
Combining Graphical and Textual
Combining Graphical and Textual
Combining Graphical and Textual
Combining Graphical and Textual
Upcoming SlideShare
Loading in …5
×

Combining Graphical and Textual

2,278 views

Published on

Combining Graphics and Text in Modeling Tools
with Jos Warmer
Talk at Eclipse Summit Europe 2009

Published in: Technology, News & Politics
2 Comments
5 Likes
Statistics
Notes
  • I agree, I would like so much to have attended this one. I suggest having a look at this post: http://koehnlein.blogspot.com/2009/06/synchronized-editors-with-tmfxtext-and.html

    maybe there are other resources for this amazing topic... in the case let me know!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • no notes to any slides :( thats a pitty!
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
2,278
On SlideShare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
130
Comments
2
Likes
5
Embeds 0
No embeds

No notes for slide
  • Combining Graphical and Textual

    1. 1. Combining Graphics and Text in Modeling Tools Jan Köhnlein (itemis) Jos Warmer (Ordina)
    2. 2. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); } public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    3. 3. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • } Detailed views public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    4. 4. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views counter = 0; return internalIsSameStructure(left, right); } public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    5. 5. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views • Very formal syntax counter = 0; return internalIsSameStructure(left, right); } public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    6. 6. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views } • Very formal syntax counter = 0; return internalIsSameStructure(left, right); • Suggests non-formalism public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    7. 7. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views } • Very formal syntax counter = 0; return internalIsSameStructure(left, right); • Suggests non-formalism • Standard text editor public boolean internalIsSameStructure(EObject left, EObject right) { ++counter; if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    8. 8. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views } • Very formal syntax counter = 0; return internalIsSameStructure(left, right); • Suggests non-formalism • ++counter; Standard text editor public boolean internalIsSameStructure(EObject left, EObject right) { • Custom editor if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    9. 9. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views } • Very formal syntax counter = 0; return internalIsSameStructure(left, right); • Suggests non-formalism • Standard text editor public boolean internalIsSameStructure(EObject left, EObject right) { • Custom editor • ++counter; Standard versioning / if (!isSameClass(left.eClass(), right.eClass())) { errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } multi-user support List<EObject> leftChildren = getRelevantChildren(left); List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    10. 10. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views } • Very formal syntax counter = 0; return internalIsSameStructure(left, right); • Suggests non-formalism • Standard text editor public boolean internalIsSameStructure(EObject left, EObject right) { • Custom editor • • ++counter; Standard versioning / if (!isSameClass(left.eClass(), right.eClass())) { Custom versioning / errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } multi-user support List<EObject> leftChildren = getRelevantChildren(left); multi-user support List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    11. 11. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views } • Very formal syntax counter = 0; return internalIsSameStructure(left, right); • Suggests non-formalism • Standard text editor public boolean internalIsSameStructure(EObject left, EObject right) { • Custom editor • • ++counter; Standard versioning / if (!isSameClass(left.eClass(), right.eClass())) { Custom versioning / errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } multi-user support List<EObject> leftChildren = getRelevantChildren(left); multi-user support • Editing with keyboard List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    12. 12. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views } • Very formal syntax counter = 0; return internalIsSameStructure(left, right); • Suggests non-formalism • Standard text editor public boolean internalIsSameStructure(EObject left, EObject right) { • Custom editor • • ++counter; Standard versioning / if (!isSameClass(left.eClass(), right.eClass())) { Custom versioning / errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } multi-user support List<EObject> leftChildren = getRelevantChildren(left); multi-user support • Editing with keyboard List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { • Editing with mouse errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    13. 13. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { log.error(getErrorMessage()); Assert.fail(getErrorMessage()); } Text Graphics //logger.debug("" + counter + " elements compared"); } protected String getErrorMessage() { return errorMessage.toString(); • • } Detailed views public boolean isSameStructure(EObject left, EObject right) { High-level views } • Very formal syntax counter = 0; return internalIsSameStructure(left, right); • Suggests non-formalism • Standard text editor public boolean internalIsSameStructure(EObject left, EObject right) { • Custom editor • • ++counter; Standard versioning / if (!isSameClass(left.eClass(), right.eClass())) { Custom versioning / errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); return false; } multi-user support List<EObject> leftChildren = getRelevantChildren(left); multi-user support • Editing with keyboard List<EObject> rightChildren = getRelevantChildren(right); if(leftChildren.size() != rightChildren.size()) { • Editing with mouse errorMessage.append("Number of children differs " + left + " " + right + " " + leftChildren.size() + " <> " + rightChildren.size()).append('n') return false; } for (int i = 0; i < leftChildren.size(); ++i) { if(!internalIsSameStructure(leftChildren.get(i), rightChildren.get(i))) { errorMessage.append("Children differ " + left + " " + right + " with children " + leftChildren.get(i) + " " + rightChildren.get(i)).append return false; } } Why not have both? return true; } protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } protected List<EObject> getRelevantChildren(EObject _this) { List<EObject> relevantChildren = new ArrayList<EObject>(_this.eContents()); for (Iterator<EObject> i = relevantChildren.iterator(); i.hasNext();) { EObject next = i.next(); if (!isRelevantChild(_this, next)) { i.remove();
    14. 14. Xtext vs GMF
    15. 15. Xtext
    16. 16. Xtext G ra m m ar
    17. 17. Xtext G ra m m ar
    18. 18. Xtext ar m m ra G Runtime Superclass Subclass Class Ecore model LL(*) Parser Text editor
    19. 19. Xtext ar m m ra G Semantic Metamodel Runtime Superclass Subclass Class Ecore model LL(*) Parser Text editor
    20. 20. Superclass GMF Subclass Ecore model Class
    21. 21. Superclass GMF Subclass Ecore model Class Graph Model
    22. 22. Superclass GMF Subclass Ecore model Class Graph Tool Model Model
    23. 23. Superclass GMF Subclass Ecore model Class Graph Map Tool Model Model Model
    24. 24. Superclass GMF Subclass Ecore model Class Graph Map Tool Model Model Model GMF Generator Model
    25. 25. Superclass GMF Subclass Ecore model Class Graph Map Tool Model Model Model GMF Generator Model
    26. 26. Runtime Models and Synchronization
    27. 27. Xtext EObject element eAdapters NodeAdapter node children AbstractNode offset: int length: int CompositeNode LeafNode text: String parent
    28. 28. Xtext GMF EObject element EObject element eAdapters NodeAdapter View node children AbstractNode Node Edge offset: int length: int layoutConstraints bendpoints CompositeNode LeafNode Bounds Bendpoints text: String x: int parent y: int width: int height: int
    29. 29. GMF ResourceSet GMFResource DiagramResource Canonical EditPolicy
    30. 30. GMF ResourceSet GMFResource DiagramResource Canonical Canonical EditPolicy EditPolicy
    31. 31. GMF ResourceSet GMFResource DiagramResource Canonical Canonical EditPolicy EditPolicy
    32. 32. Xtext
    33. 33. Xtext Textual Model Serializer Parser Node Model Ecore Model Instance
    34. 34. Xtext XtextResource Textual Model Serializer Parser Node Model Ecore Model Instance
    35. 35. Xtext XtextResource Textual Model Serializer Parser Node Model Ecore Model Instance getContents()
    36. 36. Xtext load(), save() XtextResource Textual Model Serializer Parser Node Model Ecore Model Instance getContents()
    37. 37. Xtext load(), save() XtextResource Textual Model Serializer Parser Node Model Ecore Model Instance FragmentProvider getContents() getURIFragment() getEObject()
    38. 38. ResourceSet XtextResource DiagramResource
    39. 39. diagram change ResourceSet XtextResource DiagramResource
    40. 40. ResourceSet XtextResource DiagramResource
    41. 41. reparse() w/ errors ResourceSet XtextResource DiagramResource
    42. 42. ResourceSet XtextResource DiagramResource
    43. 43. ResourceSet XtextResource DiagramResource Canonical EditPolicy
    44. 44. ResourceSet XtextResource DiagramResource Canonical EditPolicy
    45. 45. ResourceSet XtextResource DiagramResource Canonical EditPolicy
    46. 46. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
    47. 47. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
    48. 48. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
    49. 49. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource save() XtextResource DiagramResource
    50. 50. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource reload() XtextResource DiagramResource
    51. 51. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource reload() XtextResource DiagramResource
    52. 52. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
    53. 53. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
    54. 54. Alignment
    55. 55. grammar org.xtext.cg2009.Entities with org.eclipse.xtext.common.Terminals generate entities "http://www.xtext.org/cg2009/Entities" Model : {Model} (entities += Entity)*; Entity returns Entity: 'entity' (name=ID)? ('extends' superType=[Entity])? '{' (properties+=Property)* '}'; Property: SimpleProperty | ReferenceProperty; SimpleProperty: 'property' (name=ID)? ':' type=('String'|'Number'|'Bool'); ReferenceProperty : (name=ID)? 'refs' ('one' | many?='many')? type=[Entity];
    56. 56. grammar org.xtext.cg2009.Entities with org.eclipse.xtext.common.Terminals Avoid empty generate entities "http://www.xtext.org/cg2009/Entities" models Model : {Model} (entities += Entity)*; Entity returns Entity: 'entity' (name=ID)? ('extends' superType=[Entity])? '{' (properties+=Property)* '}'; Property: SimpleProperty | ReferenceProperty; SimpleProperty: 'property' (name=ID)? ':' type=('String'|'Number'|'Bool'); ReferenceProperty : (name=ID)? 'refs' ('one' | many?='many')? type=[Entity];
    57. 57. grammar org.xtext.cg2009.Entities with org.eclipse.xtext.common.Terminals Avoid empty generate entities "http://www.xtext.org/cg2009/Entities" models Model : {Model} (entities += Entity)*; Entity returns Entity: 'entity' (name=ID)? ('extends' superType=[Entity])? '{' (properties+=Property)* '}'; Property: Cover mandatory SimpleProperty | ReferenceProperty; properties in SimpleProperty: validation 'property' (name=ID)? ':' type=('String'|'Number'|'Bool'); ReferenceProperty : (name=ID)? 'refs' ('one' | many?='many')? type=[Entity];
    58. 58. grammar org.xtext.cg2009.Entities with org.eclipse.xtext.common.Terminals Avoid empty generate entities "http://www.xtext.org/cg2009/Entities" Carefully select models Model : containment or cross {Model} (entities += Entity)*; references Entity returns Entity: 'entity' (name=ID)? ('extends' superType=[Entity])? '{' (properties+=Property)* '}'; Property: Cover mandatory SimpleProperty | ReferenceProperty; properties in SimpleProperty: validation 'property' (name=ID)? ':' type=('String'|'Number'|'Bool'); ReferenceProperty : (name=ID)? 'refs' ('one' | many?='many')? type=[Entity];
    59. 59. Xtext
    60. 60. Xtext Implement a Formatter
    61. 61. Xtext Implement a Formatter Implement a FragmentProvider
    62. 62. Xtext Implement a Formatter Implement a FragmentProvider Implement a JavaValidator
    63. 63. GMF
    64. 64. GMF Initialize mandatory properties
    65. 65. GMF Initialize mandatory properties Avoid Phantom Nodes
    66. 66. Add a transaction on GMF load Initialize mandatory properties Avoid Phantom Nodes
    67. 67. Glue Code
    68. 68. Glue Code • Prevent conflicting modifications
    69. 69. Glue Code • Prevent conflicting modifications • Navigate • diagram ➜ text
    70. 70. Glue Code • Prevent conflicting modifications • Navigate • diagram ➜ text • text ➜ diagram (needs index)
    71. 71. Glue Code • Prevent conflicting modifications • Navigate • diagram ➜ text • text ➜ diagram (needs index) • Parser wrapper
    72. 72. Glue Code • Prevent conflicting modifications • Navigate • diagram ➜ text • text ➜ diagram (needs index) • Parser wrapper • Popup editor
    73. 73. Demo Time

    ×