SlideShare una empresa de Scribd logo
1 de 121
Converging Textual
      and
Graphical Editors

                     Moritz Eysholdt
Modeling?
Modeling?
Should we model or code?
Modeling?
Should we model or code?
     Real programmers write code!
Modeling?
  Should we model or code?
       Real programmers write code!
Modeling is something the architect does.
Modeling?
  Should we model or code?
       Real programmers write code!
Modeling is something the architect does.

     Models are graphical!
Modeling?
  Should we model or code?
       Real programmers write code!
Modeling is something the architect does.

     Models are graphical!
     I model on my whiteboard.
Modeling?
  Should we model or code?
       Real programmers write code!
Modeling is something the architect does.

     Models are graphical!
     I model on my whiteboard.

              This doesn’t lead us anywhere!
Let’s take a step back
Let’s take a step back


It’s about having the right notation for the job.
Let’s take a step back


It’s about having the right notation for the job.


 It would be nice if we could just run it.
Let’s take a step back
                sounds like a
                  language




It’s about having the right notation for the job.


 It would be nice if we could just run it.
Let’s take a step back
                sounds like a      sounds like it is specific to
                  language             the job’s domain




It’s about having the right notation for the job.


 It would be nice if we could just run it.
Let’s take a step back
                sounds like a      sounds like it is specific to
                  language             the job’s domain




It’s about having the right notation for the job.


 It would be nice if we could just run it.

                                          it needs to be
                                              formal!
The Right Notation
    The Right Notation
The Right Notation
                 The Right Notation


•   Whether we call it a model or not doesn’t matter
The Right Notation
                  The Right Notation


•   Whether we call it a model or not doesn’t matter

    •   However, tools from Eclipse Modeling help to build
        tooling for this notation
The Right Notation
                  The Right Notation


•   Whether we call it a model or not doesn’t matter

    •   However, tools from Eclipse Modeling help to build
        tooling for this notation

•   Instances of this notation are a primary artifact of your
    software
The Right Notation
                  The Right Notation


•   Whether we call it a model or not doesn’t matter

    •   However, tools from Eclipse Modeling help to build
        tooling for this notation

•   Instances of this notation are a primary artifact of your
    software

•   If it has syntax and semantics, it is a language
The Right Notation
                  The Right Notation


•   Whether we call it a model or not doesn’t matter

    •   However, tools from Eclipse Modeling help to build
        tooling for this notation

•   Instances of this notation are a primary artifact of your
    software

•   If it has syntax and semantics, it is a language

•   The focus on a certain kind of tasks makes it domain
    specific. It becomes a DSL or DSML
Qualities for an effective development process
           and a high-quality product

                         Language                 Tooling

                 • Support for a few,       • Content Assist
     Writable
                   orthogonal concepts      • Quickfixes
                 • Appropriate, concise
                   syntax                   • Navigation
   Readable      • Hide technical details   • Syntax highlighting
                                            • Outline
             • Reuse established
Communicable
               syntax/semantics

                                            • Instant feedback
Error-preventing • Statically typed
                                            • Short roundtrips
Qualities for an effective development process
           and a high-quality product

                         Language                 Tooling

                 • Support for a few,       • Content Assist
     Writable
                   orthogonal concepts      • Quickfixes
                 • Appropriate, concise
                   syntax                   • Navigation
   Readable      • Hide technical details   • Syntax highlighting
                                            • Outline
             • Reuse established
Communicable
               syntax/semantics

                                            • Instant feedback
Error-preventing • Statically typed
                                            • Short roundtrips
Qualities for an effective development process
           and a high-quality product

                         Language                 Tooling

                 • Support for a few,       • Content Assist
     Writable
                   orthogonal concepts      • Quickfixes
                 • Appropriate, concise
                   syntax                   • Navigation
   Readable      • Hide technical details   • Syntax highlighting
                                            • Outline
             • Reuse established
Communicable
               syntax/semantics

                                            • Instant feedback
Error-preventing • Statically typed
                                            • Short roundtrips
Qualities for an effective development process
           and a high-quality product       Where?

                         Language                 Tooling

                 • Support for a few,       • Content Assist
     Writable
                   orthogonal concepts      • Quickfixes
                 • Appropriate, concise
                   syntax                   • Navigation
   Readable      • Hide technical details   • Syntax highlighting
                                            • Outline
             • Reuse established
Communicable
               syntax/semantics

                                            • Instant feedback
Error-preventing • Statically typed
                                            • Short roundtrips
Qualities for an effective development process
           and a high-quality product

                         Language                 Tooling

                 • Support for a few,       • Content Assist
     Writable
                   orthogonal concepts      • Quickfixes
                 • Appropriate, concise
                   syntax                   • Navigation
   Readable      • Hide technical details   • Syntax highlighting
                                            • Outline
             • Reuse established
Communicable
               syntax/semantics

                                            • Instant feedback
Error-preventing • Statically typed
                                            • Short roundtrips
Examples?
textual   Examples?
textual    Examples?
          graphical
textual    Examples?
          graphical

              forms/tables
textual    Examples?
          graphical

              forms/tables


                      mathematical
textual    Examples?
                                    graphical

                                        forms/tables


     You name it!                               mathematical
  The limit to design
 notations is available
tooling and creativity.
textual    Examples?
                                    graphical

                                        forms/tables


     You name it!                               mathematical
  The limit to design
 notations is available
tooling and creativity.
                     Multiple notations can be combined.
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




            Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




              Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
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;
}
                Information that is not in the text,
protected boolean isSameClass(EClass left, exists.
                               doesn’t 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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




             Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {
	    return errorMessage.toString();
                                                                                     •   High-level 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;
                                                                                  The diagram is the big picture, details are
}
                Information that is not in the text,                                           in property dialogs.
protected boolean isSameClass(EClass left, exists.
                               doesn’t EClass right) {                             Graphical notations are commonly used
	    return left.getName().equals(right.getName())
	    	     	    && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); at higher levels of abstractions.
}

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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




              Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •
	    return errorMessage.toString();
}
              Very formal syntax
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;
}                         Non-Formal Elements
                whitespace, line-breaks, comments
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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




              Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                           Suggests non-formalism
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;
                                                                                               Non-Formal Elements
}                         Non-Formal Elements
                                                                                   Modify: position, size, shape, color, font, icon
                whitespace, line-breaks, comments
protected boolean isSameClass(EClass left, EClass right) {
	    return left.getName().equals(right.getName())                                  Add: note-box, custom shapes, comments
	    	    	     && 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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




              Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                           Suggests non-formalism
         •    Standard text editor
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;
}
            The editor can be language-aware, but is
protected boolean isSameClass(EClass required to.
                              not 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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




              Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                           Suggests non-formalism
         •    Standard text editor                                                   •     Custom editor
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;
}
            The editor can be language-aware, but is                                       Each language requires a special
protected boolean isSameClass(EClass required to.
                              not left, EClass right) {                                          (or generic) editor.
	    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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




             Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                           Suggests non-formalism
         •    Standard text editor                                                   •     Custom editor
public boolean isSameStructure(EObject left, EObject right) {
	    counter = 0;
	    return internalIsSameStructure(left, right);
}
         •    Standard versioning /
public boolean internalIsSameStructure(EObject left, EObject right) {
	
	
	
              multi-user support
     ++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;
}
               SVN, CVS, GIT, GNU diff/patch, etc.
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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




             Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                           Suggests non-formalism
         •    Standard text editor                                                   •     Custom editor
public boolean isSameStructure(EObject left, EObject right) {
	    counter = 0;
	    return internalIsSameStructure(left, right);
}
         •    Standard versioning /
public boolean internalIsSameStructure(EObject left, EObject right) {
                                                                                     •     Custom versioning /
	
	
	
              multi-user support
     ++counter;
     if (!isSameClass(left.eClass(), right.eClass())) {
     	
                                                                                           multi-user support
           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;
}
                                                                                    Model repositories, diff/merge needs to
               SVN, CVS, GIT, GNU diff/patch, etc.
protected boolean isSameClass(EClass left, EClass right) {
	    return left.getName().equals(right.getName())
                                                                                             be language-aware
	    	     	    && 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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




             Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                           Suggests non-formalism
         •    Standard text editor                                                   •     Custom editor
public boolean isSameStructure(EObject left, EObject right) {
	    counter = 0;
	    return internalIsSameStructure(left, right);
}
         •    Standard versioning /
public boolean internalIsSameStructure(EObject left, EObject right) {
                                                                                     •     Custom versioning /
	
	             multi-user support
     ++counter;
     if (!isSameClass(left.eClass(), right.eClass())) {                                    multi-user support
         •
	    	     errorMessage.append("Classes are not equal: " + left + " != " + right).append('n');
	
	
     	
     }        Editing with keyboard
           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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




             Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                           Suggests non-formalism
         •    Standard text editor                                                   •     Custom editor
public boolean isSameStructure(EObject left, EObject right) {
	    counter = 0;
	    return internalIsSameStructure(left, right);
}
         •    Standard versioning /
public boolean internalIsSameStructure(EObject left, EObject right) {
                                                                                     •     Custom versioning /
	
	             multi-user support
     ++counter;
     if (!isSameClass(left.eClass(), right.eClass())) {                                    multi-user support
         •                                                                           •
	    	     errorMessage.append("Classes are not equal: " + left + " != " + right).append('n');
	
	
     	
     }        Editing with keyboard
           return false;
                                                                                           Editing with mouse
	    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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




             Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                           Suggests non-formalism
         •    Standard text editor                                                   •     Custom editor
public boolean isSameStructure(EObject left, EObject right) {
	    counter = 0;
	    return internalIsSameStructure(left, right);
}
         •    Standard versioning /
public boolean internalIsSameStructure(EObject left, EObject right) {
                                                                                     •     Custom versioning /
	
	             multi-user support
     ++counter;
     if (!isSameClass(left.eClass(), right.eClass())) {                                    multi-user support
         •                                                                           •
	    	     errorMessage.append("Classes are not equal: " + left + " != " + right).append('n');
	
	
     	
     }        Editing with keyboard
           return false;
                                                                                           Editing with mouse
         •    Expressions, Lists
	    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;
                       Mathematical Expressions,
}
                      Imperative Command Lists,
	
                             Hierarchical Data,
protected boolean isSameClass(EClass left, EClass right) {
     return left.getName().equals(right.getName())
	    	     	                           etc.
                && 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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




             Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •   High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                         Suggests non-formalism
         •    Standard text editor                                                   •   Custom editor
public boolean isSameStructure(EObject left, EObject right) {
	    counter = 0;
	    return internalIsSameStructure(left, right);
}
         •    Standard versioning /
public boolean internalIsSameStructure(EObject left, EObject right) {
                                                                                     •   Custom versioning /
	
	             multi-user support
     ++counter;
     if (!isSameClass(left.eClass(), right.eClass())) {                                  multi-user support
         •                                                                           •
	    	     errorMessage.append("Classes are not equal: " + left + " != " + right).append('n');
	
	
     	
     }        Editing with keyboard
           return false;
                                                                                         Editing with mouse
         •    Expressions, Lists                                                     •   Flow, Structure
	    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;
	    	     }
	    }
                                                                                              Visual Pattern-Matching
                       Mathematical Expressions,
	    return true;
                                                                                         Flow: Workflow, State-Machine,
}
                      Imperative Command Lists,
                                                                                                  Process Chain
                             Hierarchical Data,
protected boolean isSameClass(EClass left, EClass right) {
	    return left.getName().equals(right.getName())                                       Structure: Class Diagram, Entity
	    	     	                           etc.
                && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI());
}                                                                                             Relationship Diagram
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();
public void assertSameStructure(EObject left, EObject right) {
	    if(!isSameStructure(left, right)) {




             Text
	    	     log.error(getErrorMessage());



                                                                                      Graphics
	    	     Assert.fail(getErrorMessage());
	    }
	    //logger.debug("" + counter + " elements compared");
}

         •    Detailed views
protected String getErrorMessage() {                                                 •     High-level views
         •                                                                           •
	    return errorMessage.toString();
}
              Very formal syntax                                                           Suggests non-formalism
         •    Standard text editor                                                   •     Custom editor
public boolean isSameStructure(EObject left, EObject right) {
	    counter = 0;
	    return internalIsSameStructure(left, right);
}
         •    Standard versioning /
public boolean internalIsSameStructure(EObject left, EObject right) {
                                                                                     •     Custom versioning /
	
	             multi-user support
     ++counter;
     if (!isSameClass(left.eClass(), right.eClass())) {                                    multi-user support
         •                                                                           •
	    	     errorMessage.append("Classes are not equal: " + left + " != " + right).append('n');
	
	
     	
     }        Editing with keyboard
           return false;
                                                                                           Editing with mouse
         •    Expressions, Lists                                                     •     Flow, Structure
	    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;
	    	     }
	    }




                 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();
Xtext vs GMF

A   textual concrete syntax and a graphical concrete syntax
               on top of the same abstract syntax.
Xtext
Xtext


 G
  ra
       m
        m
            ar
Xtext


 G
  ra
       m
        m
            ar
Xtext



                                 ar
                              m
                             m
                         ra
                         G
                                       Runtime
 Superclass




 Subclass     Class




 Ecore model          LL(*) Parser    Text editor
Xtext



                                  ar
                               m
                              m
                          ra
                          G
 Semantic
Metamodel                               Runtime
  Superclass




   Subclass    Class




   Ecore model         LL(*) Parser    Text editor
Superclass




GMF   Subclass




      Ecore model
                   Class
Superclass




GMF       Subclass




          Ecore model
                       Class




  Graph
  Model
Superclass




GMF       Subclass




          Ecore model
                       Class




  Graph                         Tool
  Model                        Model
Superclass




GMF       Subclass




          Ecore model
                               Class




  Graph                 Map             Tool
  Model                Model           Model
Superclass




GMF       Subclass




          Ecore model
                               Class




  Graph                 Map             Tool
  Model                Model           Model




                   GMF
                 Generator
                  Model
Superclass




GMF       Subclass




          Ecore model
                               Class




  Graph                 Map             Tool
  Model                Model           Model




                   GMF
                 Generator
                  Model
Runtime Models
      and
Synchronization
Xtext
                    EObject         element




               eAdapters
                  NodeAdapter




                  node
          children AbstractNode
                   offset: int
                   length: int




         CompositeNode          LeafNode
                              text: String
parent
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
GMF
              ResourceSet


XMIResource                 DiagramResource




              Canonical
              EditPolicy
GMF
               ResourceSet


XMIResource                  DiagramResource




              Canonical
              Canonical
              EditPolicy
              EditPolicy
GMF
               ResourceSet


XMIResource                  DiagramResource




              Canonical
              Canonical
              EditPolicy
              EditPolicy
Xtext
Xtext

              Textual Model


        Serializer
                     Parser
                              Node Model



               Ecore Model
                Instance
Xtext
        XtextResource

                     Textual Model


               Serializer
                            Parser
                                     Node Model



                      Ecore Model
                       Instance
Xtext
        XtextResource

                     Textual Model


               Serializer
                            Parser
                                     Node Model



                      Ecore Model
                       Instance




                getContents()
Xtext                load(), save()



        XtextResource

                     Textual Model


               Serializer
                            Parser
                                      Node Model



                      Ecore Model
                       Instance




                getContents()
Xtext                load(), save()



        XtextResource

                     Textual Model


               Serializer
                            Parser
                                          Node Model



                      Ecore Model
                       Instance         FragmentProvider




                getContents()         getURIFragment()
                                      getEObject()
ResourceSet


XtextResource                 DiagramResource
diagram
                                         change

                ResourceSet


XtextResource                 DiagramResource
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                         ResourceSet


XtextResource              XtextResource    DiagramResource
Fi e l
                    od a
                 M xtu
                  le l
                    Te
 ResourceSet                         ResourceSet


XtextResource              XtextResource    DiagramResource
Fi e l
                    od a
                 M xtu
                  le l
                    Te
 ResourceSet                         ResourceSet


XtextResource              XtextResource    DiagramResource
Fi e l
                      od a
                   M xtu
                    le l
                      Te
 ResourceSet                           ResourceSet


XtextResource   save()       XtextResource    DiagramResource
Fi e l
                     od a
                  M xtu
                   le l
                     Te
 ResourceSet                          ResourceSet


XtextResource   reload()    XtextResource    DiagramResource
Fi e l
                     od a
                  M xtu
                   le l
                     Te
 ResourceSet                          ResourceSet


XtextResource   reload()    XtextResource    DiagramResource
Fi e l
                    od a
                 M xtu
                  le l
                    Te
 ResourceSet                         ResourceSet


XtextResource              XtextResource    DiagramResource
Fi e l
                    od a
                 M xtu
                  le l
                    Te
 ResourceSet                         ResourceSet


XtextResource              XtextResource    DiagramResource
Alignment
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];
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];
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];
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];
Xtext
Xtext
        Implement a
         Formatter
Xtext
        Implement a
         Formatter


             Implement a
          FragmentProvider
Xtext
           Implement a
            Formatter


                 Implement a
              FragmentProvider



        Implement a
        JavaValidator
GMF
GMF

 Initialize
mandatory
properties
GMF

         Initialize
        mandatory
        properties


 No Phantom
Nodes without
  container
Add a
transaction on
                                 GMF
     load



                    Initialize
                   mandatory
                   properties


            No Phantom
           Nodes without
             container
Representing (Non)-Containment References in
               Xtext and GMF
Representing (Non)-Containment References in
                 Xtext and GMF

EMF           containment             non-containment

      Rule-Call to a Parser Rule   Cross-Reference
Xtext
      Rule: value=MyRule           Rule: value=[MyRule|ID]

       Diagram’ Root-Object:
       • Node
                                   Node’s Object:
GMF    Node’s Object:              • Edge (an edge can have
       • Compartment               an object)
       • Side-Affixed nodes
       • Edges (Phantom Nodes)
Representing (Non)-Containment References in
                 Xtext and GMF

EMF           containment             non-containment

      Rule-Call to a Parser Rule   Cross-Reference
Xtext
      Rule: value=MyRule           Rule: value=[MyRule|ID]

       Diagram’ Root-Object:
       • Node
                                   Node’s Object:
GMF    Node’s Object:              • Edge (an edge can have
       • Compartment               an object)
       • Side-Affixed nodes
       • Edges (Phantom Nodes)
Representing (Non)-Containment References in
                 Xtext and GMF

EMF           containment             non-containment

      Rule-Call to a Parser Rule   Cross-Reference
Xtext
      Rule: value=MyRule           Rule: value=[MyRule|ID]

       Diagram’ Root-Object:
       • Node
                                   Node’s Object:
GMF    Node’s Object:              • Edge (an edge can have
       • Compartment               an object)
       • Side-Affixed nodes
       • Edges (Phantom Nodes)
Integration Helpers
Integration Helpers
• Prevent conflicting modifications
Integration Helpers
• Prevent conflicting modifications
• Navigate
 • Diagram ➜ Text
Integration Helpers
• Prevent conflicting modifications
• Navigate
 • Diagram ➜ Text
 • Text ➜ Diagram
    (needs Index)
Integration Helpers
• Prevent conflicting modifications
• Navigate
 • Diagram ➜ Text
 • Text ➜ Diagram
    (needs Index)
• Parser wrapper
Integration Helpers
• Prevent conflicting modifications
• Navigate
 • Diagram ➜ Text
 • Text ➜ Diagram
    (needs Index)
• Parser wrapper
• Popup editor
Demo Time
Summary
• Think about the notation, the language, that
 would be ideal to get your work done.
• Textual and graphical syntax can be combined.
• To integrate Xtext into GMF, exchange the
 XMIResource with an XtextResource -> GMF
 operates on a model persisted in textual syntax.
• Some integration code is helpful, too.
• itemis provides professional assistance.

                                                 Moritz Eysholdt

Más contenido relacionado

Similar a Converging Textual and Graphical Editors

Supporting the authoring process with linguistic software
Supporting the authoring process with linguistic softwareSupporting the authoring process with linguistic software
Supporting the authoring process with linguistic softwarevsrtwin
 
Paulking dlp
Paulking dlpPaulking dlp
Paulking dlpd0nn9n
 
Dynamic Language Practices
Dynamic Language PracticesDynamic Language Practices
Dynamic Language PracticesPaul King
 
Programming Languages #devcon2013
Programming Languages #devcon2013Programming Languages #devcon2013
Programming Languages #devcon2013Iván Montes
 
Intro to Programming Lang.pptx
Intro to Programming Lang.pptxIntro to Programming Lang.pptx
Intro to Programming Lang.pptxssuser51ead3
 
Programming Language Selection
Programming Language SelectionProgramming Language Selection
Programming Language SelectionDhananjay Nene
 
Recurrent Neural Network : Multi-Class & Multi Label Text Classification
Recurrent Neural Network : Multi-Class & Multi Label Text ClassificationRecurrent Neural Network : Multi-Class & Multi Label Text Classification
Recurrent Neural Network : Multi-Class & Multi Label Text ClassificationAmit Agarwal
 
The Spoofax Language Workbench (SPLASH 2010)
The Spoofax Language Workbench (SPLASH 2010)The Spoofax Language Workbench (SPLASH 2010)
The Spoofax Language Workbench (SPLASH 2010)lennartkats
 
Visual Ontology Modeling for Domain Experts and Business Users with metaphactory
Visual Ontology Modeling for Domain Experts and Business Users with metaphactoryVisual Ontology Modeling for Domain Experts and Business Users with metaphactory
Visual Ontology Modeling for Domain Experts and Business Users with metaphactoryPeter Haase
 
Teaching Machines to Listen: An Introduction to Automatic Speech Recognition
Teaching Machines to Listen: An Introduction to Automatic Speech RecognitionTeaching Machines to Listen: An Introduction to Automatic Speech Recognition
Teaching Machines to Listen: An Introduction to Automatic Speech RecognitionZachary S. Brown
 
What if-your-application-could-speak, by Marcos Silveira
What if-your-application-could-speak, by Marcos SilveiraWhat if-your-application-could-speak, by Marcos Silveira
What if-your-application-could-speak, by Marcos SilveiraThoughtworks
 
What if-your-application-could-speak
What if-your-application-could-speakWhat if-your-application-could-speak
What if-your-application-could-speakMarcos Vinícius
 
Designing and Implementing Search Solutions
Designing and Implementing Search SolutionsDesigning and Implementing Search Solutions
Designing and Implementing Search SolutionsFindwise
 
Natural language processing and search
Natural language processing and searchNatural language processing and search
Natural language processing and searchNathan McMinn
 
Importance Of Being Driven
Importance Of Being DrivenImportance Of Being Driven
Importance Of Being DrivenAntonio Terreno
 
Generating docs from APIs
Generating docs from APIsGenerating docs from APIs
Generating docs from APIsjamiehannaford
 
DSL Construction rith Ruby
DSL Construction rith RubyDSL Construction rith Ruby
DSL Construction rith RubyThoughtWorks
 
Building a Neural Machine Translation System From Scratch
Building a Neural Machine Translation System From ScratchBuilding a Neural Machine Translation System From Scratch
Building a Neural Machine Translation System From ScratchNatasha Latysheva
 

Similar a Converging Textual and Graphical Editors (20)

Supporting the authoring process with linguistic software
Supporting the authoring process with linguistic softwareSupporting the authoring process with linguistic software
Supporting the authoring process with linguistic software
 
Paulking dlp
Paulking dlpPaulking dlp
Paulking dlp
 
Dynamic Language Practices
Dynamic Language PracticesDynamic Language Practices
Dynamic Language Practices
 
Programming Languages #devcon2013
Programming Languages #devcon2013Programming Languages #devcon2013
Programming Languages #devcon2013
 
Intro to Programming Lang.pptx
Intro to Programming Lang.pptxIntro to Programming Lang.pptx
Intro to Programming Lang.pptx
 
Programming Language Selection
Programming Language SelectionProgramming Language Selection
Programming Language Selection
 
Recurrent Neural Network : Multi-Class & Multi Label Text Classification
Recurrent Neural Network : Multi-Class & Multi Label Text ClassificationRecurrent Neural Network : Multi-Class & Multi Label Text Classification
Recurrent Neural Network : Multi-Class & Multi Label Text Classification
 
The Spoofax Language Workbench (SPLASH 2010)
The Spoofax Language Workbench (SPLASH 2010)The Spoofax Language Workbench (SPLASH 2010)
The Spoofax Language Workbench (SPLASH 2010)
 
DSL Best Practices
DSL Best PracticesDSL Best Practices
DSL Best Practices
 
Visual Ontology Modeling for Domain Experts and Business Users with metaphactory
Visual Ontology Modeling for Domain Experts and Business Users with metaphactoryVisual Ontology Modeling for Domain Experts and Business Users with metaphactory
Visual Ontology Modeling for Domain Experts and Business Users with metaphactory
 
Teaching Machines to Listen: An Introduction to Automatic Speech Recognition
Teaching Machines to Listen: An Introduction to Automatic Speech RecognitionTeaching Machines to Listen: An Introduction to Automatic Speech Recognition
Teaching Machines to Listen: An Introduction to Automatic Speech Recognition
 
What if-your-application-could-speak, by Marcos Silveira
What if-your-application-could-speak, by Marcos SilveiraWhat if-your-application-could-speak, by Marcos Silveira
What if-your-application-could-speak, by Marcos Silveira
 
What if-your-application-could-speak
What if-your-application-could-speakWhat if-your-application-could-speak
What if-your-application-could-speak
 
Designing and Implementing Search Solutions
Designing and Implementing Search SolutionsDesigning and Implementing Search Solutions
Designing and Implementing Search Solutions
 
Natural language processing and search
Natural language processing and searchNatural language processing and search
Natural language processing and search
 
Metamorphic Domain-Specific Languages
Metamorphic Domain-Specific LanguagesMetamorphic Domain-Specific Languages
Metamorphic Domain-Specific Languages
 
Importance Of Being Driven
Importance Of Being DrivenImportance Of Being Driven
Importance Of Being Driven
 
Generating docs from APIs
Generating docs from APIsGenerating docs from APIs
Generating docs from APIs
 
DSL Construction rith Ruby
DSL Construction rith RubyDSL Construction rith Ruby
DSL Construction rith Ruby
 
Building a Neural Machine Translation System From Scratch
Building a Neural Machine Translation System From ScratchBuilding a Neural Machine Translation System From Scratch
Building a Neural Machine Translation System From Scratch
 

Más de meysholdt

Xtext's new Formatter API
Xtext's new Formatter APIXtext's new Formatter API
Xtext's new Formatter APImeysholdt
 
Lightweight Xtext Editors as SWT Widgets
Lightweight Xtext Editors as SWT WidgetsLightweight Xtext Editors as SWT Widgets
Lightweight Xtext Editors as SWT Widgetsmeysholdt
 
Serializing EMF models with Xtext
Serializing EMF models with XtextSerializing EMF models with Xtext
Serializing EMF models with Xtextmeysholdt
 
Turning Ideas Into Code Faster
Turning Ideas Into Code FasterTurning Ideas Into Code Faster
Turning Ideas Into Code Fastermeysholdt
 
Executable specifications for xtext
Executable specifications for xtextExecutable specifications for xtext
Executable specifications for xtextmeysholdt
 
Xbase - Implementing Domain-Specific Languages for Java
Xbase - Implementing Domain-Specific Languages for JavaXbase - Implementing Domain-Specific Languages for Java
Xbase - Implementing Domain-Specific Languages for Javameysholdt
 
Test-Driven Development of Xtext DSLs
Test-Driven Development  of Xtext DSLsTest-Driven Development  of Xtext DSLs
Test-Driven Development of Xtext DSLsmeysholdt
 
Codegeneration Goodies
Codegeneration GoodiesCodegeneration Goodies
Codegeneration Goodiesmeysholdt
 

Más de meysholdt (8)

Xtext's new Formatter API
Xtext's new Formatter APIXtext's new Formatter API
Xtext's new Formatter API
 
Lightweight Xtext Editors as SWT Widgets
Lightweight Xtext Editors as SWT WidgetsLightweight Xtext Editors as SWT Widgets
Lightweight Xtext Editors as SWT Widgets
 
Serializing EMF models with Xtext
Serializing EMF models with XtextSerializing EMF models with Xtext
Serializing EMF models with Xtext
 
Turning Ideas Into Code Faster
Turning Ideas Into Code FasterTurning Ideas Into Code Faster
Turning Ideas Into Code Faster
 
Executable specifications for xtext
Executable specifications for xtextExecutable specifications for xtext
Executable specifications for xtext
 
Xbase - Implementing Domain-Specific Languages for Java
Xbase - Implementing Domain-Specific Languages for JavaXbase - Implementing Domain-Specific Languages for Java
Xbase - Implementing Domain-Specific Languages for Java
 
Test-Driven Development of Xtext DSLs
Test-Driven Development  of Xtext DSLsTest-Driven Development  of Xtext DSLs
Test-Driven Development of Xtext DSLs
 
Codegeneration Goodies
Codegeneration GoodiesCodegeneration Goodies
Codegeneration Goodies
 

Último

Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 

Último (20)

Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 

Converging Textual and Graphical Editors

  • 1. Converging Textual and Graphical Editors Moritz Eysholdt
  • 4. Modeling? Should we model or code? Real programmers write code!
  • 5. Modeling? Should we model or code? Real programmers write code! Modeling is something the architect does.
  • 6. Modeling? Should we model or code? Real programmers write code! Modeling is something the architect does. Models are graphical!
  • 7. Modeling? Should we model or code? Real programmers write code! Modeling is something the architect does. Models are graphical! I model on my whiteboard.
  • 8. Modeling? Should we model or code? Real programmers write code! Modeling is something the architect does. Models are graphical! I model on my whiteboard. This doesn’t lead us anywhere!
  • 9. Let’s take a step back
  • 10. Let’s take a step back It’s about having the right notation for the job.
  • 11. Let’s take a step back It’s about having the right notation for the job. It would be nice if we could just run it.
  • 12. Let’s take a step back sounds like a language It’s about having the right notation for the job. It would be nice if we could just run it.
  • 13. Let’s take a step back sounds like a sounds like it is specific to language the job’s domain It’s about having the right notation for the job. It would be nice if we could just run it.
  • 14. Let’s take a step back sounds like a sounds like it is specific to language the job’s domain It’s about having the right notation for the job. It would be nice if we could just run it. it needs to be formal!
  • 15. The Right Notation The Right Notation
  • 16. The Right Notation The Right Notation • Whether we call it a model or not doesn’t matter
  • 17. The Right Notation The Right Notation • Whether we call it a model or not doesn’t matter • However, tools from Eclipse Modeling help to build tooling for this notation
  • 18. The Right Notation The Right Notation • Whether we call it a model or not doesn’t matter • However, tools from Eclipse Modeling help to build tooling for this notation • Instances of this notation are a primary artifact of your software
  • 19. The Right Notation The Right Notation • Whether we call it a model or not doesn’t matter • However, tools from Eclipse Modeling help to build tooling for this notation • Instances of this notation are a primary artifact of your software • If it has syntax and semantics, it is a language
  • 20. The Right Notation The Right Notation • Whether we call it a model or not doesn’t matter • However, tools from Eclipse Modeling help to build tooling for this notation • Instances of this notation are a primary artifact of your software • If it has syntax and semantics, it is a language • The focus on a certain kind of tasks makes it domain specific. It becomes a DSL or DSML
  • 21. Qualities for an effective development process and a high-quality product Language Tooling • Support for a few, • Content Assist Writable orthogonal concepts • Quickfixes • Appropriate, concise syntax • Navigation Readable • Hide technical details • Syntax highlighting • Outline • Reuse established Communicable syntax/semantics • Instant feedback Error-preventing • Statically typed • Short roundtrips
  • 22. Qualities for an effective development process and a high-quality product Language Tooling • Support for a few, • Content Assist Writable orthogonal concepts • Quickfixes • Appropriate, concise syntax • Navigation Readable • Hide technical details • Syntax highlighting • Outline • Reuse established Communicable syntax/semantics • Instant feedback Error-preventing • Statically typed • Short roundtrips
  • 23. Qualities for an effective development process and a high-quality product Language Tooling • Support for a few, • Content Assist Writable orthogonal concepts • Quickfixes • Appropriate, concise syntax • Navigation Readable • Hide technical details • Syntax highlighting • Outline • Reuse established Communicable syntax/semantics • Instant feedback Error-preventing • Statically typed • Short roundtrips
  • 24. Qualities for an effective development process and a high-quality product Where? Language Tooling • Support for a few, • Content Assist Writable orthogonal concepts • Quickfixes • Appropriate, concise syntax • Navigation Readable • Hide technical details • Syntax highlighting • Outline • Reuse established Communicable syntax/semantics • Instant feedback Error-preventing • Statically typed • Short roundtrips
  • 25. Qualities for an effective development process and a high-quality product Language Tooling • Support for a few, • Content Assist Writable orthogonal concepts • Quickfixes • Appropriate, concise syntax • Navigation Readable • Hide technical details • Syntax highlighting • Outline • Reuse established Communicable syntax/semantics • Instant feedback Error-preventing • Statically typed • Short roundtrips
  • 27. textual Examples?
  • 28. textual Examples? graphical
  • 29. textual Examples? graphical forms/tables
  • 30. textual Examples? graphical forms/tables mathematical
  • 31. textual Examples? graphical forms/tables You name it! mathematical The limit to design notations is available tooling and creativity.
  • 32. textual Examples? graphical forms/tables You name it! mathematical The limit to design notations is available tooling and creativity. Multiple notations can be combined.
  • 33. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //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();
  • 34. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views 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; } Information that is not in the text, protected boolean isSameClass(EClass left, exists. doesn’t 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();
  • 35. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { return errorMessage.toString(); • High-level 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; The diagram is the big picture, details are } Information that is not in the text, in property dialogs. protected boolean isSameClass(EClass left, exists. doesn’t EClass right) { Graphical notations are commonly used return left.getName().equals(right.getName()) && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); at higher levels of abstractions. } 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();
  • 36. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • return errorMessage.toString(); } Very formal syntax 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; } Non-Formal Elements whitespace, line-breaks, comments 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();
  • 37. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism 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; Non-Formal Elements } Non-Formal Elements Modify: position, size, shape, color, font, icon whitespace, line-breaks, comments protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) Add: note-box, custom shapes, comments && 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();
  • 38. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism • Standard text editor 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; } The editor can be language-aware, but is protected boolean isSameClass(EClass required to. not 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();
  • 39. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism • Standard text editor • Custom editor 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; } The editor can be language-aware, but is Each language requires a special protected boolean isSameClass(EClass required to. not left, EClass right) { (or generic) editor. 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();
  • 40. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism • Standard text editor • Custom editor public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • Standard versioning / public boolean internalIsSameStructure(EObject left, EObject right) { multi-user support ++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; } SVN, CVS, GIT, GNU diff/patch, etc. 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();
  • 41. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism • Standard text editor • Custom editor public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • Standard versioning / public boolean internalIsSameStructure(EObject left, EObject right) { • Custom versioning / multi-user support ++counter; if (!isSameClass(left.eClass(), right.eClass())) { multi-user support 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; } Model repositories, diff/merge needs to SVN, CVS, GIT, GNU diff/patch, etc. protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) be language-aware && 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();
  • 42. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism • Standard text editor • Custom editor public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • Standard versioning / public boolean internalIsSameStructure(EObject left, EObject right) { • Custom versioning / multi-user support ++counter; if (!isSameClass(left.eClass(), right.eClass())) { multi-user support • errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); } Editing with keyboard 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();
  • 43. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism • Standard text editor • Custom editor public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • Standard versioning / public boolean internalIsSameStructure(EObject left, EObject right) { • Custom versioning / multi-user support ++counter; if (!isSameClass(left.eClass(), right.eClass())) { multi-user support • • errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); } Editing with keyboard return false; Editing with mouse 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();
  • 44. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism • Standard text editor • Custom editor public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • Standard versioning / public boolean internalIsSameStructure(EObject left, EObject right) { • Custom versioning / multi-user support ++counter; if (!isSameClass(left.eClass(), right.eClass())) { multi-user support • • errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); } Editing with keyboard return false; Editing with mouse • Expressions, Lists 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; Mathematical Expressions, } Imperative Command Lists, Hierarchical Data, protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) etc. && 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();
  • 45. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism • Standard text editor • Custom editor public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • Standard versioning / public boolean internalIsSameStructure(EObject left, EObject right) { • Custom versioning / multi-user support ++counter; if (!isSameClass(left.eClass(), right.eClass())) { multi-user support • • errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); } Editing with keyboard return false; Editing with mouse • Expressions, Lists • Flow, Structure 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; } } Visual Pattern-Matching Mathematical Expressions, return true; Flow: Workflow, State-Machine, } Imperative Command Lists, Process Chain Hierarchical Data, protected boolean isSameClass(EClass left, EClass right) { return left.getName().equals(right.getName()) Structure: Class Diagram, Entity etc. && left.getEPackage().getNsURI().equals(right.getEPackage().getNsURI()); } Relationship Diagram 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();
  • 46. public void assertSameStructure(EObject left, EObject right) { if(!isSameStructure(left, right)) { Text log.error(getErrorMessage()); Graphics Assert.fail(getErrorMessage()); } //logger.debug("" + counter + " elements compared"); } • Detailed views protected String getErrorMessage() { • High-level views • • return errorMessage.toString(); } Very formal syntax Suggests non-formalism • Standard text editor • Custom editor public boolean isSameStructure(EObject left, EObject right) { counter = 0; return internalIsSameStructure(left, right); } • Standard versioning / public boolean internalIsSameStructure(EObject left, EObject right) { • Custom versioning / multi-user support ++counter; if (!isSameClass(left.eClass(), right.eClass())) { multi-user support • • errorMessage.append("Classes are not equal: " + left + " != " + right).append('n'); } Editing with keyboard return false; Editing with mouse • Expressions, Lists • Flow, Structure 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; } } 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();
  • 47. Xtext vs GMF A textual concrete syntax and a graphical concrete syntax on top of the same abstract syntax.
  • 48. Xtext
  • 49. Xtext G ra m m ar
  • 50. Xtext G ra m m ar
  • 51. Xtext ar m m ra G Runtime Superclass Subclass Class Ecore model LL(*) Parser Text editor
  • 52. Xtext ar m m ra G Semantic Metamodel Runtime Superclass Subclass Class Ecore model LL(*) Parser Text editor
  • 53. Superclass GMF Subclass Ecore model Class
  • 54. Superclass GMF Subclass Ecore model Class Graph Model
  • 55. Superclass GMF Subclass Ecore model Class Graph Tool Model Model
  • 56. Superclass GMF Subclass Ecore model Class Graph Map Tool Model Model Model
  • 57. Superclass GMF Subclass Ecore model Class Graph Map Tool Model Model Model GMF Generator Model
  • 58. Superclass GMF Subclass Ecore model Class Graph Map Tool Model Model Model GMF Generator Model
  • 59. Runtime Models and Synchronization
  • 60.
  • 61. Xtext EObject element eAdapters NodeAdapter node children AbstractNode offset: int length: int CompositeNode LeafNode text: String parent
  • 62. 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
  • 63. GMF ResourceSet XMIResource DiagramResource Canonical EditPolicy
  • 64. GMF ResourceSet XMIResource DiagramResource Canonical Canonical EditPolicy EditPolicy
  • 65. GMF ResourceSet XMIResource DiagramResource Canonical Canonical EditPolicy EditPolicy
  • 66. Xtext
  • 67. Xtext Textual Model Serializer Parser Node Model Ecore Model Instance
  • 68. Xtext XtextResource Textual Model Serializer Parser Node Model Ecore Model Instance
  • 69. Xtext XtextResource Textual Model Serializer Parser Node Model Ecore Model Instance getContents()
  • 70. Xtext load(), save() XtextResource Textual Model Serializer Parser Node Model Ecore Model Instance getContents()
  • 71. Xtext load(), save() XtextResource Textual Model Serializer Parser Node Model Ecore Model Instance FragmentProvider getContents() getURIFragment() getEObject()
  • 72. ResourceSet XtextResource DiagramResource
  • 73. diagram change ResourceSet XtextResource DiagramResource
  • 74. ResourceSet XtextResource DiagramResource
  • 75. reparse() w/ errors ResourceSet XtextResource DiagramResource
  • 76. ResourceSet XtextResource DiagramResource
  • 77. ResourceSet XtextResource DiagramResource Canonical EditPolicy
  • 78. ResourceSet XtextResource DiagramResource Canonical EditPolicy
  • 79. ResourceSet XtextResource DiagramResource Canonical EditPolicy
  • 80. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
  • 81. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
  • 82. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
  • 83. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource save() XtextResource DiagramResource
  • 84. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource reload() XtextResource DiagramResource
  • 85. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource reload() XtextResource DiagramResource
  • 86. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
  • 87. Fi e l od a M xtu le l Te ResourceSet ResourceSet XtextResource XtextResource DiagramResource
  • 89. 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];
  • 90. 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];
  • 91. 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];
  • 92. 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];
  • 93. Xtext
  • 94. Xtext Implement a Formatter
  • 95. Xtext Implement a Formatter Implement a FragmentProvider
  • 96. Xtext Implement a Formatter Implement a FragmentProvider Implement a JavaValidator
  • 97. GMF
  • 99. GMF Initialize mandatory properties No Phantom Nodes without container
  • 100. Add a transaction on GMF load Initialize mandatory properties No Phantom Nodes without container
  • 102. Representing (Non)-Containment References in Xtext and GMF EMF containment non-containment Rule-Call to a Parser Rule Cross-Reference Xtext Rule: value=MyRule Rule: value=[MyRule|ID] Diagram’ Root-Object: • Node Node’s Object: GMF Node’s Object: • Edge (an edge can have • Compartment an object) • Side-Affixed nodes • Edges (Phantom Nodes)
  • 103. Representing (Non)-Containment References in Xtext and GMF EMF containment non-containment Rule-Call to a Parser Rule Cross-Reference Xtext Rule: value=MyRule Rule: value=[MyRule|ID] Diagram’ Root-Object: • Node Node’s Object: GMF Node’s Object: • Edge (an edge can have • Compartment an object) • Side-Affixed nodes • Edges (Phantom Nodes)
  • 104. Representing (Non)-Containment References in Xtext and GMF EMF containment non-containment Rule-Call to a Parser Rule Cross-Reference Xtext Rule: value=MyRule Rule: value=[MyRule|ID] Diagram’ Root-Object: • Node Node’s Object: GMF Node’s Object: • Edge (an edge can have • Compartment an object) • Side-Affixed nodes • Edges (Phantom Nodes)
  • 106. Integration Helpers • Prevent conflicting modifications
  • 107. Integration Helpers • Prevent conflicting modifications • Navigate • Diagram ➜ Text
  • 108. Integration Helpers • Prevent conflicting modifications • Navigate • Diagram ➜ Text • Text ➜ Diagram (needs Index)
  • 109. Integration Helpers • Prevent conflicting modifications • Navigate • Diagram ➜ Text • Text ➜ Diagram (needs Index) • Parser wrapper
  • 110. Integration Helpers • Prevent conflicting modifications • Navigate • Diagram ➜ Text • Text ➜ Diagram (needs Index) • Parser wrapper • Popup editor
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121. Summary • Think about the notation, the language, that would be ideal to get your work done. • Textual and graphical syntax can be combined. • To integrate Xtext into GMF, exchange the XMIResource with an XtextResource -> GMF operates on a model persisted in textual syntax. • Some integration code is helpful, too. • itemis provides professional assistance. Moritz Eysholdt