<!DOCTYPE html>
<html>

  <head>
	<meta charset="UTF-8">
	<title>Xtext - Five simple steps to your JVM language</title>
	
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="description"
		content="The website of Eclipse Xtext, an open-source framework for development of programming languages and domain-specific languages">
	<meta name="author" content="Sven Efftinge">
	<meta name="author" content="Miro Spoenemann">
	<!--  styles -->
	<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
	<!--[if lt IE 9]>
	  <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
	<![endif]-->
	
	<!-- Le fav and touch icons -->
	<link rel="shortcut icon" href="/Xtext/images/favicon.png">
	
	<link href="/Xtext/css/bootstrap.css" rel="stylesheet" type='text/css'>
	<link href="/Xtext/css/bootstrap-responsive.css" rel="stylesheet" type='text/css'>
	<link href="/Xtext/css/shield-responsive.css" rel="stylesheet" type='text/css'>
	<link href='/Xtext/css/fonts.css' rel='stylesheet' type='text/css'>
	<link href="/Xtext/css/prettyPhoto.css" rel="stylesheet" media="screen" type='text/css'>
	<link href="/Xtext/css/prettify.css" type="text/css" rel="stylesheet"/>
	<link href="/Xtext/css/style.css" rel="stylesheet" type='text/css'>
	<!-- cover flow -->
	<link href="/Xtext/css/coverflow.css" rel="stylesheet" type='text/css'>
	<!--[if lt IE 9]>
	  <link href="/css/iebugs.css" rel="stylesheet" type='text/css'>
	<![endif]-->

	<!-- BEGIN Cookie Consent
	<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.css" />
	<script src="//cdnjs.cloudflare.com/ajax/libs/cookieconsent2/3.0.3/cookieconsent.min.js"></script>
	<script>
	window.addEventListener("load", function(){
	window.cookieconsent.initialise({
		"palette": {
		"popup": {
		  "background": "#000"
		},
		"button": {
		  "background": "#f1d600"
		}
		},
		"theme": "edgeless",
		"type": "opt-in",
		onInitialise: function (status) {
		  var type = this.options.type;
		  var didConsent = this.hasConsented();
		  if (type == 'opt-in' && didConsent) {
		    // TODO: enable cookies
		  }
		  if (type == 'opt-out' && !didConsent) {
		    // TODO: disable cookies
		  }
		},
		onStatusChange: function(status, chosenBefore) {
		  var type = this.options.type;
		  var didConsent = this.hasConsented();
		  if (type == 'opt-in' && didConsent) {
		    // TODO: enable cookies
		  }
		  if (type == 'opt-out' && !didConsent) {
		    // TODO: disable cookies
		  }
		}, 
		onRevokeChoice: function() {
		  var type = this.options.type;
		  if (type == 'opt-in') {
		    // TODO: disable cookies
		  }
		  if (type == 'opt-out') {
		    // TODO: enable cookies
		  }
		},
		"content": {
		"href": "http://www.eclipse.org/legal/privacy.php"
		}
	})});
	</script>
	END Cookie Consent -->
</head>


  <body>
  
    <header class="site-header">

  <!-- Navbar -->
  <div class="navbar navbar-fixed-top">
    <div class="navbar-inner">
      <div class="container">
        <a class="btn btn-navbar" data-toggle="collapse"
          data-target=".nav-collapse"> <span class="icon-bar"></span> <span
          class="icon-bar"></span> <span class="icon-bar"></span>
        </a> <a class="brand" href="/Xtext/index.html"></a>
        <div class="nav-collapse collapse" style="height: 0px;">
          <ul class="nav">
            <!--li ><a href="/Xtext/news.html">News</a></li-->
            <li ><a href="/Xtext/download.html">Download</a></li>
            <li ><a href="/Xtext/documentation/index.html">Documentation</a></li>
            <li ><a href="/Xtext/community.html">Community</a></li>
            <li class="dropdown">
              <a class="dropdown-toggle" data-toggle="dropdown" href="#">Support &amp; Trainings<span class="caret"></span></a>
              <ul class="dropdown-menu">
                <li><a href="https://www.itemis.com/en/xtext/support-and-team/" target="_blank">itemis</a></li>
                <li><a href="https://typefox.io/trainings-2" target="_blank">TypeFox</a></li>
              </ul>
            </li>
            <li ><a href="http://xtend-lang.org">Xtend</a></li>
          </ul>
          <!--div class="nav pull-right">
            <li ><a><iframe src="https://ghbtns.com/github-btn.html?user=eclipse&repo=xtext&type=star&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe></a></li>
          </div-->
        </div>
        <!--/.nav-collapse -->
      </div>
    </div>
  </div>
  <!-- Navbar End -->

</header>


    <div class="page-content">
  <script>
    function startSearch(event) {
        if (event.keyCode == 13) {
            var q = 'site:eclipse.org/Xtext/documentation+' + event.target.value;
            window.open('https://www.google.com/search?q=' + q, "_self");
        }
    }
  </script>
  <div class="wrapper">
  	<div id="page">  
      <div class="inner">
        <div id="maincontainer" class="container">
          <span class="edit-on-github pull-right">
            <a href="https://github.com/eclipse/xtext/edit/website-published/xtext-website/documentation/104_jvmdomainmodel.md">Edit on Github</a>
          </span>
          <div class="span3" style="margin-left: 0px;">
            <div class="search-bar">
              <img src="/Xtext/images/search-gray.png"/>
              <input type="search" id="google-search" onkeyup="startSearch(event);"/>
            </div>
            <ul id="nav-outline" style="margin-left: 0px;">
	<li class="nav-part">Getting Started</li>
	<li><a href="102_domainmodelwalkthrough.html">15 Minutes Tutorial</a></li>
	<li><a href="103_domainmodelnextsteps.html">15 Minutes Tutorial - Extended</a></li>
	<li><a href="104_jvmdomainmodel.html">Five simple steps to your JVM language</a></li>
		
	<li class="nav-part">Reference Documentation</li>
	<li><a href="301_grammarlanguage.html">The Grammar Language</a></li>
	<li><a href="302_configuration.html">Configuration</a></li>
	<li><a href="303_runtime_concepts.html">Language Implementation</a></li>
	<li><a href="305_xbase.html">Integration with Java</a></li>
	<li><a href="307_special_languages.html">Typical Language Configurations</a></li>
	<li><a href="308_emf_integration.html">Integration with EMF</a></li>
	<li><a href="310_eclipse_support.html">Eclipse Support</a></li>
	<li><a href="330_web_support.html">Web Editor Support</a></li>
	<li><a href="350_continuous_integration.html">Continuous Integration</a></li>
</ul>
          </div>
          <div class="span8 doc-contents">
            <h1 id="jvm-domain-model">Five simple steps to your JVM language</h1>

<p>In this tutorial we will basically implement the <a href="https://www.eclipse.org/Xtext/documentation/103_domainmodelnextsteps.html">domain model language</a> again, but this time we will make use of the special JVM support shipped with Xtext. This kind of language is really a sweet spot for DSLs, so feel free to use this as a blueprint and add your project specific features later on.</p>

<p>The revised domain model language supports expressions and cross-links to Java types. It is directly translated to Java source code. The syntax should look very familiar. Here is an example:</p>

<pre><code class="language-domainexample">import java.util.List

package my.model {

    entity Person {
        name: String
        firstName: String
        friends: List&lt;Person&gt;
        address : Address
        op getFullName() : String {
            return firstName + " " + name;
        }
        
        op getFriendsSortedByFullName() : List&lt;Person&gt; {
            return friends.sortBy[ f | f.fullName ]
        }
    }
    
    entity Address {
        street: String
        zip: String
        city: String
    }
}
</code></pre>

<p>As you can see, it supports all kinds of advanced features such as Java generics and full expressions, even including lambda expressions. Don’t panic, you will not have to implement these concepts on your own but will reuse a lot of helpful infrastructure to build the language.</p>

<p>We will now walk through the five little steps needed to get this language fully working including its compiler. The first three steps are very similar to those in the <a href="102_domainmodelwalkthrough.html">15 Minutes Tutorial</a>.</p>

<p>After you have installed Xtext on your machine, start Eclipse and set up a fresh workspace.</p>

<h2 id="domain-model-step1">Step One: Create A New Xtext Project</h2>

<p>In order to get started we first need to create some Eclipse projects. Use the Eclipse wizard to do so:</p>

<p><em>File → New → Project… → Xtext → Xtext Project</em></p>

<p>Choose a meaningful project name, language name and file extension, e.g.</p>

<table>
  <tbody>
    <tr>
      <td><strong>Project name:</strong></td>
      <td>org.example.domainmodel</td>
    </tr>
    <tr>
      <td><strong>Language name:</strong></td>
      <td>org.example.domainmodel.Domainmodel</td>
    </tr>
    <tr>
      <td><strong>File extension:</strong></td>
      <td>dmodel</td>
    </tr>
  </tbody>
</table>

<p>Click on <em>Finish</em> to create the projects</p>

<p><img src="images/30min_wizard.png" alt="" /></p>

<p>After you have successfully finished the wizard, you will find five new projects in your workspace.</p>

<table>
  <tbody>
    <tr>
      <td>org.example.domainmodel</td>
      <td>The grammar definition and all language-specific components (parser, lexer, linker, validation, etc.)</td>
    </tr>
    <tr>
      <td>org.example.domainmodel.tests</td>
      <td>Unit tests for the language</td>
    </tr>
    <tr>
      <td>org.example.domainmodel.ide</td>
      <td>Platform-independent IDE functionality (e.g. services for content assist)</td>
    </tr>
    <tr>
      <td>org.example.domainmodel.ui</td>
      <td>The Eclipse editor and other workbench related functionality</td>
    </tr>
    <tr>
      <td>org.example.domainmodel.ui.tests</td>
      <td>Unit tests for the Eclipse editor</td>
    </tr>
  </tbody>
</table>

<p><img src="images/30min_initialprojectlayout.png" alt="" /></p>

<h2 id="domain-model-step2">Step Two: Write the Grammar</h2>

<p>The wizard will automatically open the grammar file <em>Domainmodel.xtext</em> in the editor. As you can see it already contains a simple <em>Hello World</em> grammar. Replace that grammar definition with the one for our language:</p>

<pre><code class="language-xtext">grammar org.example.domainmodel.Domainmodel with
                                      org.eclipse.xtext.xbase.Xbase

generate domainmodel "http://www.example.org/domainmodel/Domainmodel"

Domainmodel:
    importSection=XImportSection?
    elements+=AbstractElement*;

AbstractElement:
    PackageDeclaration | Entity;

PackageDeclaration:
    'package' name=QualifiedName '{'
        elements+=AbstractElement*
    '}';

Entity:
    'entity' name=ValidID ('extends' superType=JvmTypeReference)? '{'
        features+=Feature*
    '}';

Feature:
    Property | Operation;

Property:
    name=ValidID ':' type=JvmTypeReference;

Operation:
    'op' name=ValidID 
        '('(params+=FullJvmFormalParameter 
        (',' params+=FullJvmFormalParameter)*)?')'
        ':' type=JvmTypeReference 
    body=XBlockExpression;

</code></pre>

<p>Some parts of this grammar are equal to the one in the <a href="102_domainmodelwalkthrough.html">15 Minutes Tutorial</a>, but other parts are different.</p>

<ol>
  <li>

    <pre><code class="language-xtext">grammar org.example.domainmodel.Domainmodel with
              org.eclipse.xtext.xbase.Xbase
</code></pre>

    <p>The first thing to note is that instead of inheriting from the usual <em>org.eclipse.xtext.common.Terminals</em> grammar, we make use of <em>org.eclipse.xtext.xbase.Xbase</em>. Xbase allows us to easily reuse and embed modern, statically typed expressions as well as Java type signatures in our language.</p>
  </li>
  <li>

    <pre><code class="language-xtext">Domainmodel:
    importSection=XImportSection?
    elements+=AbstractElement*;
</code></pre>

    <p>A <em>Domainmodel</em> contains an optional import section and an arbitrary number of <em>AbstractElements</em>. The concept of <em>XImportSection</em> is part of <em>org.eclipse.xtext.xbase.Xbase</em> and comes with tool support and syntax like you know it from Java.</p>
  </li>
  <li>

    <pre><code class="language-xtext">AbstractElement:
    PackageDeclaration | Entity;
</code></pre>

    <p>The rule <em>AbstractElement</em> delegates to either the rule <em>PackageDeclaration</em> or the rule <em>Entity</em>.</p>
  </li>
  <li>

    <pre><code class="language-xtext">PackageDeclaration:
    'package' name=QualifiedName '{'
        elements+=AbstractElement*
    '}';
</code></pre>

    <p>A <em>PackageDeclaration</em> is used to declare a name space which can again contain any number of <em>AbstractElement</em>s. Xtext has built-in support for qualified names and scoping based on the hierarchy of the produced model. The default implementation will add the package names as the prefix to contained entities and nested packages. The qualified name of an <em>Entity</em> ‘Baz’ which is contained in a <em>PackageDeclaration</em> ‘foo.bar’ will be ‘foo.bar.Baz’. In case you do not like the default behavior you will need to use a different implementation of <a href="https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext/src/org/eclipse/xtext/naming/IQualifiedNameProvider.java">IQualifiedNameProvider</a>.</p>
  </li>
  <li>

    <pre><code class="language-xtext">Entity:
    'entity' name=ValidID ('extends' superType=JvmTypeReference)? '{'
        features+=Feature*
    '}';
</code></pre>

    <p>The rule <em>Entity</em> starts with the definition of a keyword followed by a name. The <em>extends</em> clause makes use of the rule <em>JvmTypeReference</em> which is defined in the super grammar. <em>JvmTypeReference</em> defines the syntax for full Java-like type names. That is everything from simple names, over fully qualified names to fully-fledged generics, including wildcards, lower bounds and upper bounds. Finally between curly braces there can be any number of <em>Features</em>, which leads us to the next rule.</p>
  </li>
  <li>

    <pre><code class="language-xtext">Feature:
    Property | Operation;
</code></pre>

    <p>The rule <em>Feature</em> delegates to either a <em>Property</em> or an <em>Operation</em>.</p>
  </li>
  <li>

    <pre><code class="language-xtext">Property:
    name=ValidID ':' type=JvmTypeReference;
</code></pre>

    <p>A <em>Property</em> has a name and makes again use of the inherited rule <em>JvmTypeReference</em>.</p>
  </li>
  <li>

    <pre><code class="language-xtext">Operation:
    'op' name=ValidID 
        '('(params+=FullJvmFormalParameter 
        (',' params+=FullJvmFormalParameter)*)?')'
        ':' type=JvmTypeReference 
    body=XBlockExpression;
</code></pre>

    <p><em>Operation</em>s also have a signature as expected. Note that also for formal parameters we can reuse a rule from the super grammar.</p>

    <p>The body of the <em>Operation</em> is the actual implementation and is defined by the rule <em>XBlockExpression</em>, which is one of the most often used entry rules from Xbase. A block consist of any number of expressions between curly braces such as:</p>

    <pre><code class="language-xbase">{
    return "Hello World" + "!"
}
</code></pre>
  </li>
</ol>

<h2 id="domain-model-step3">Step Three: Generate Language Artifacts</h2>

<p>Now that we have the grammar in place we need to execute the code generator that will derive the various language components. To do so, right-click into the grammar editor and select</p>

<p><em>Run As → Generate Xtext Artifacts</em>.</p>

<p>This action generates the parser and text editor and some additional infrastructure code. You will see its logging messages in the Console View.</p>

<p><img src="images/JvmTutorial_RunGenerator.png" alt="" /></p>

<h2 id="domain-model-step4">Step Four: Define the Mapping to JVM Concepts</h2>

<p>The syntax alone is not enough to make the language work. We need to map the domain-specific concepts to some other language in order to instruct Xtext how it is executed. Usually you define a code generator or an interpreter for that matter, but languages using Xbase can omit this step and make use of the <a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/jvmmodel/IJvmModelInferrer.java">IJvmModelInferrer</a>.</p>

<p>The idea is that you translate your language concepts to any number of Java types (<a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/JvmDeclaredType.java">JvmDeclaredType</a>). Such a type can be a Java class, Java interface, Java annotation type or a Java enum and may contain any valid members. In the end you as a language developer are responsible to create a correct model according to the Java language.</p>

<p>By mapping your language concepts to Java elements, you implicitly tell Xtext in what kind of scopes the various expressions live and what return types are expected from them. Xtext also comes with a code generator which can translate that Java model into readable Java code, including the expressions.</p>

<p>If you have already triggered the ‘Generate Xtext Artifacts’ action, you should find a stub called <em>org/example/domainmodel/jvmmodel/DomainmodelJvmModelInferrer.xtend</em> in the src folder. Please replace its contents with the following :</p>

<pre><code class="language-xtend">package org.example.domainmodel.jvmmodel

import com.google.inject.Inject
import org.example.domainmodel.domainmodel.Entity
import org.example.domainmodel.domainmodel.Operation
import org.example.domainmodel.domainmodel.Property
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder

class DomainmodelJvmModelInferrer extends AbstractModelInferrer {

  /**
   * a builder API to programmatically create Jvm elements 
   * in readable way.
   */
  @Inject extension JvmTypesBuilder

  @Inject extension IQualifiedNameProvider

  def dispatch void infer(Entity element,
                IJvmDeclaredTypeAcceptor acceptor,
                boolean isPrelinkingPhase) {
    acceptor.accept(element.toClass( element.fullyQualifiedName )) [
      documentation = element.documentation
      if (element.superType !== null)
        superTypes += element.superType.cloneWithProxies
      for (feature : element.features) {
        switch feature {

          Property : {
            members += feature.toField(feature.name, feature.type)
            members += feature.toGetter(feature.name, feature.type)
            members += feature.toSetter(feature.name, feature.type)
          }

          Operation : {
            members += feature.toMethod(feature.name, feature.type) [
              documentation = feature.documentation
              for (p : feature.params) {
                parameters += p.toParameter(p.name, p.parameterType)
              }
              body = feature.body
            ]
          }
        }
      }
    ]
  }
}
</code></pre>

<p>Let’s go through the code to get an idea of what is going on. (Please also refer to the JavaDoc of the used API for details, especially the <a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/jvmmodel/JvmTypesBuilder.java">JvmTypesBuilder</a>).</p>

<ol>
  <li>
    <pre><code class="language-xtend">def dispatch void infer(Entity element,
        IJvmDeclaredTypeAcceptor acceptor,
        boolean isPrelinkingPhase) {
</code></pre>

    <p>Using the dispatch keyword makes sure that the method is called for instances of type <em>Entity</em> only. Have a look at the Xtend documentation on <a href="http://www.eclipse.org/xtend/documentation/202_xtend_classes_members.html#polymorphic-dispatch">polymorphic dispatch</a> to understand Xtend’s dispatch functions. Extending <a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/jvmmodel/AbstractModelInferrer.java">AbstractModelInferrer</a> makes sure we don’t have to walk the syntax model on our own.</p>
  </li>
  <li>
    <pre><code class="language-xtend">acceptor.accept(element.toClass(element.fullyQualifiedName)) [
    ...
]
</code></pre>

    <p>Every <a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/JvmDeclaredType.java">JvmDeclaredType</a> you create in the model inference needs to be passed to the <em>acceptor</em> in order to get recognized. The extension method <em>toClass</em> comes from the <a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/jvmmodel/JvmTypesBuilder.java">JvmTypesBuilder</a> class. This class provides a lot of convenient extension methods, which help making the code extremely readable and concise. It is important to understand that the creation and assignment of a qualified name is done in an early phase where the compiler collects all global symbols. You cannot resolve type references at this point.</p>
  </li>
  <li>The second argument to <em>accept</em> is a lambda block that contains further initialization of the created Java type. Only in this block you are allowed to do type reference resolution. This is also the place where you add members and put the XExpressions into context. Let’s see what we do in the initialization block in detail:</li>
  <li>
    <pre><code class="language-xtend">documentation = element.documentation
</code></pre>

    <p>Here we assign some JavaDoc to the newly created element. The assignment is translated to an invocation of the method <em><a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/jvmmodel/JvmTypesBuilder.java">JvmTypesBuilder</a>.setDocumentation(<a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.common.types/emf-gen/org/eclipse/xtext/common/types/JvmIdentifiableElement.java">JvmIdentifiableElement</a>, String)</em>, and <code>element.documentation</code> is in fact calling the extension method <em><a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.xbase/src/org/eclipse/xtext/xbase/jvmmodel/JvmTypesBuilder.java">JvmTypesBuilder</a>.getDocumentation(<a href="https://github.com/eclipse/emf/blob/R2_9_0/plugins/org.eclipse.emf.ecore/src/org/eclipse/emf/ecore/EObject.java">EObject</a>)</em>. Such extension methods are explained in detail in the <a href="https://www.eclipse.org/xtend/documentation/202_xtend_classes_members.html#extension-methods">Xtend documentation</a>.</p>
  </li>
  <li>
    <pre><code class="language-xtend">if (element.superType !== null)
    superTypes += entity.superType.cloneWithProxies
</code></pre>

    <p>Set the <em>superType</em> on the inferred element. Note that we have to clone the type reference from the <em>element.superType</em>. If we did not do that, the type reference would be automatically removed from the <em>element</em>, as <em>superType</em> is an EMF containment reference.</p>
  </li>
  <li>
    <pre><code class="language-xtend">for (feature : element.features) {
    switch feature {
        Property : {
            // ...
        }
        Operation : {
            // ...
        }
    }
}
</code></pre>

    <p>When iterating over a list of heterogeneous types, the switch expression with its type guards comes in handy. If <em>feature</em> is of type <em>Property</em> the first block is executed. If it is an <em>Operation</em> the second block is executed. Note that the variable <em>feature</em> will be implicitly casted to the respective type within the blocks.</p>
  </li>
  <li>
    <pre><code class="language-xtend">Property : {
    members += feature.toField(feature.name, feature.type)
    members += feature.toSetter(feature.name, feature.type)
    members += feature.toGetter(feature.name, feature.type)
}
</code></pre>

    <p>For each <em>Property</em> we create a field as well as a corresponding getter and setter.</p>
  </li>
  <li>
    <pre><code class="language-xtend">Operation : {
    members += feature.toMethod(feature.name, feature.type) [
        documentation = feature.documentation
        for (p : feature.params) {
            parameters += p.toParameter(p.name, p.parameterType)
        }
        body = feature.body
    ]
}
</code></pre>

    <p><em>Operations</em> are mapped to a corresponding Java method. The documentation is translated and the parameters are added within the initializer. The line <code>body = feature.body</code> registers the <em>Operation</em>’s expression as the body of the newly created Java method. This defines the scope of the expression. The framework deduces the visible fields and parameters as well as the expected return type from that information.</p>
  </li>
</ol>

<h2 id="domain-model-step5">Step Five : Try the Editor!</h2>

<p>We are now able to test the IDE integration by spawning a new Eclipse using our plug-ins: right-click the project <code>org.example.domainmodel</code> in the Package Explorer and select <em>Run As → Eclipse Application</em>.</p>

<p>In the new workbench, create a Java project (<em>File → New → Project… → Java Project</em>). Xbase relies on a small runtime library on the class path. To add this, right-click on the project and go to <em>Java Build Path → Libraries → Add Library</em> and choose <em>Xtend Library</em>. Then create a new file with the file extension you chose in the beginning (<em>*.dmodel</em>) in the source folder of the Java project. This will open the generated entity editor. Try it and discover the rich editor functionality it provides. You should also have a look at the preferences of your language to find out what can be individually configured to your users needs.</p>

<p>Have fun!</p>

<p><img src="images/JvmTutorial_Editor.png" alt="" /></p>

<hr />

<p><strong><a href="301_grammarlanguage.html">Next Chapter: The Grammar Language</a></strong></p>

          </div>
        </div>
      </div>
    </div>
  </div>
</div>
    
    <footer class="site-footer">
  <div id="extra">
    <div class="inner">
      <div class="container">
        <div class="row">
          <div class="span6">
            <h3 class="footer-links-header">Quick Links</h3>
            <ul class="footer-links clearfix">
              <li><a href="http://www.eclipse.org/legal/privacy.php">Privacy Policy</a></li>
              <li><a href="http://www.eclipse.org/legal/termsofuse.php">Terms of Use</a></li>
              <li><a href="http://www.eclipse.org/legal/copyright.php">Copyright Agent</a></li>
              <li><a href="http://www.eclipse.org/legal/">Legal</a></li>
            </ul>
            <ul class="footer-links clearfix">
              <li><a href="http://www.eclipse.org">Eclipse Home</a></li>
              <li><a href="http://marketplace.eclipse.org/">Market Place</a></li>
              <li><a href="http://live.eclipse.org/">Eclipse Live</a></li>
              <li><a href="http://www.planeteclipse.org/">Eclipse Planet</a></li>
            </ul>
          </div>
          <div class="span6">
            <!-- Social Media Links -->
            <h3 class="footer-links-header"">Social Media</h3>
            <ul class="footer-links clearfix">
              <li>
                <a href="https://twitter.com/xtext"><img src="/Xtext/images/Twitter-bird-darkgray.png" class="img-responsive" style="margin-right: 5px;height: 1em;" alt="Twitter icon">@xtext on Twitter</a>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
  <a href="#" class="scrollup fadeOutRight animated" style="display: none;">ScrollUp</a>
  <!-- Le javascript
      ================================================== -->
  <!-- Placed at the end of the document so the pages load faster -->
  
  <script src="/Xtext/js/jquery-1.11.3.min.js"></script>
  <script src="/Xtext/js/bootstrap.min.js"></script>
  <script src="/Xtext/js/jquery.easing.1.3.js" type="text/javascript"></script>
  <script src="/Xtext/js/jquery.prettyPhoto.js" type="text/javascript"></script>
  <script src="/Xtext/js/prettify.js" type="text/javascript"></script>
  <script src="/Xtext/js/lang-xtend.js" type="text/javascript"></script>
  <script src="/Xtext/js/lang-common.js" type="text/javascript"></script>
  <script src="/Xtext/js/custom.js" type="text/javascript"></script>
  <!--script src="https://apis.google.com/js/platform.js" async defer></script-->
  <!--script type="text/javascript">
    var _gaq = _gaq || [];  
      _gaq.push([ '_setAccount', 'UA-2429174-3' ]);
    _gaq.push([ '_trackPageview' ]);
    (function() {
      var ga = document.createElement('script');
      ga.type = 'text/javascript';
      ga.async = true;
      ga.src = ('https:' == document.location.protocol ? 'https://ssl'
          : 'http://www')
          + '.google-analytics.com/ga.js';
      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(ga, s);
    })();
  </script-->
  <script src="/Xtext/js/coverflow.min.js" type="text/javascript"></script>
  <script>
      $(function() {
        $('#coverflow').coverflow({
          active : 1,
          visibleAside: 2,
          overlap : 0.5,
          scale : 0.9,
          angle : 20,
          trigger : {
            "itemfocus" : true,
            "swipe" : true,
            "mousewheel" : false
          }
        });
        $('#coverflow :hidden').toggle();
        $(window).resize(function() {
          $('#coverflow').coverflow();
        });
      });

  </script>
</footer>


  </body>

</html>
