<!DOCTYPE html>
<html>

  <head>
	<meta charset="UTF-8">
	<title>Xtext - 15 Minutes Tutorial - Extended</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/103_domainmodelnextsteps.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="340_lsp_support.html">LSP Support</a></li>
	<li><a href="350_continuous_integration.html">Continuous Integration</a></li>
</ul>
          </div>
          <div class="span8 doc-contents">
            <h1 id="domainmodel-next-steps">15 Minutes Tutorial - Extended</h1>

<p>After you have developed your first own DSL, the question arises how the behavior and the semantics of the language can be customized. Here you find a few mini-tutorials that illustrate common use cases when crafting your own DSL. These lessons are independent from each other. Each of them will be based on the language that was built in the previous <a href="102_domainmodelwalkthrough.html">domainmodel tutorial</a>.</p>

<h2 id="tutorial-code-generation">Writing a Code Generator With Xtend</h2>

<p>As soon as you generate the Xtext artifacts from the grammar, a code generator stub is put into the runtime project of your language. Let’s dive into <a href="https://www.eclipse.org/xtend/">Xtend</a> and see how you can integrate your own code generator with Eclipse.</p>

<p>In this lesson you will generate Java Beans for entities that are defined in the domainmodel DSL. For each <em>Entity</em>, a Java class is generated and each <em>Feature</em> will lead to a private field in that class including public getters and setters. For the sake of simplicity, we will use fully qualified names all over the generated code.</p>

<pre><code class="language-java">package my.company.blog;

public class HasAuthor {
    private java.lang.String author;

    public java.lang.String getAuthor() {
        return author;
    }

    public void setAuthor(java.lang.String author) {
        this.author = author;
    }
}
</code></pre>

<p>First of all, locate the file <em>DomainmodelGenerator.xtend</em> in the package <em>org.example.domainmodel.generator</em>. This Xtend class is used to generate code for your models in the standalone scenario and in the interactive Eclipse environment. Let’s make the implementation more meaningful and start writing the code generator. The strategy is to find all entities within a resource and trigger code generation for each one.</p>

<ol>
  <li>
    <p>First of all, you will have to filter the contents of the resource down to the defined entities. Therefore we need to iterate a resource with all its deeply nested elements. This can be achieved with the method <code>getAllContents()</code>. To use the resulting <a href="https://github.com/eclipse/emf/blob/R2_9_0/plugins/org.eclipse.emf.common/src/org/eclipse/emf/common/util/TreeIterator.java">TreeIterator</a> in a <code>for</code> loop, we use the extension method <code>toIterable()</code> from the built-in library class <a href="https://github.com/eclipse/xtext-lib/blob/master/org.eclipse.xtext.xbase.lib/src/org/eclipse/xtext/xbase/lib/IteratorExtensions.java">IteratorExtensions</a>.</p>

    <pre><code class="language-xtend">class DomainmodelGenerator extends AbstractGenerator {

    override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
        for (e : resource.allContents.toIterable.filter(Entity)) {
                
        }
    }
}
</code></pre>
  </li>
  <li>
    <p>Now let’s answer the question how we determine the file name of the Java class that each <em>Entity</em> should yield. This information should be derived from the qualified name of the <em>Entity</em> since Java enforces this pattern. The qualified name itself has to be obtained from a special service that is available for each language. Fortunately, Xtend allows to reuse that one easily. We simply inject the <a href="https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext/src/org/eclipse/xtext/naming/IQualifiedNameProvider.java">IQualifiedNameProvider</a> into the generator.</p>

    <pre><code class="language-xtend">  @Inject extension IQualifiedNameProvider
</code></pre>

    <p>This allows to ask for the name of an entity. It is straightforward to convert the name into a file name:</p>

    <pre><code class="language-xtend">override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
    for (e : resource.allContents.toIterable.filter(Entity)) {
        fsa.generateFile(
            e.fullyQualifiedName.toString("/") + ".java",
            e.compile)
    }
}
</code></pre>
  </li>
  <li>
    <p>The next step is to write the actual template code for an entity. For now, the function <code>Entity.compile</code> does not exist, but it is easy to create it:</p>

    <pre><code class="language-xtend">private def compile(Entity e) '''
    package «e.eContainer.fullyQualifiedName»;
        
    public class «e.name» {
    }
'''
</code></pre>
  </li>
  <li>
    <p>This small template is basically the first shot at a Java-Beans generator. However, it is currently rather incomplete and will fail if the <em>Entity</em> is not contained in a package. A small modification fixes this. The <code>package</code> declaration has to be wrapped in an <code>IF</code> expression:</p>

    <pre><code class="language-xtend">private def compile(Entity e) '''
    «IF e.eContainer.fullyQualifiedName !== null»
        package «e.eContainer.fullyQualifiedName»;
    «ENDIF»
        
    public class «e.name» {
    }
'''
</code></pre>

    <p>Let’s handle the <em>superType</em> of an <em>Entity</em> gracefully, too, by using another <code>IF</code> expression:</p>

    <pre><code class="language-xtend">private def compile(Entity e) '''
    «IF e.eContainer.fullyQualifiedName !== null»
        package «e.eContainer.fullyQualifiedName»;
    «ENDIF»
        
    public class «e.name» «IF e.superType !== null
            »extends «e.superType.fullyQualifiedName» «ENDIF»{
    }
'''
</code></pre>
  </li>
  <li>
    <p>Even though the template will compile the <em>Entities</em> without any complaints, it still lacks support for the Java properties that each of the declared features should yield. For that purpose, you have to create another Xtend function that compiles a single feature to the respective Java code.</p>

    <pre><code class="language-xtend">private def compile(Feature f) '''
    private «f.type.fullyQualifiedName» «f.name»;
        
    public «f.type.fullyQualifiedName» get«f.name.toFirstUpper»() {
        return «f.name»;
    }
        
    public void set«f.name.toFirstUpper»(«f.type.fullyQualifiedName» «f.name») {
        this.«f.name» = «f.name»;
    }
'''
</code></pre>

    <p>As you can see, there is nothing fancy about this one. Last but not least, we have to make sure that the function is actually used.</p>

    <pre><code class="language-xtend">private def compile(Entity e) '''
    «IF e.eContainer.fullyQualifiedName !== null»
        package «e.eContainer.fullyQualifiedName»;
    «ENDIF»
        
    public class «e.name» «IF e.superType !== null
            »extends «e.superType.fullyQualifiedName» «ENDIF»{
        «FOR f : e.features»
            «f.compile»
        «ENDFOR»
    }
'''
</code></pre>
  </li>
</ol>

<p>The final code generator is listed below. Now you can give it a try! Launch a new Eclipse Application (<em>Run As → Eclipse Application</em> on the Xtext project) and create a <em>dmodel</em> file in a Java Project. Eclipse will ask you to turn the Java project into an Xtext project then. Simply agree and create a new source folder <em>src-gen</em> in that project. Then you can see how the compiler will pick up your sample <em>Entities</em> and generate Java code for them.</p>

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

import com.google.inject.Inject
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.xtext.generator.AbstractGenerator
import org.eclipse.xtext.generator.IFileSystemAccess2
import org.eclipse.xtext.generator.IGeneratorContext
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.example.domainmodel.domainmodel.Entity
import org.example.domainmodel.domainmodel.Feature

class DomainmodelGenerator extends AbstractGenerator {

    @Inject extension IQualifiedNameProvider

    override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
        for (e : resource.allContents.toIterable.filter(Entity)) {
            fsa.generateFile(
                e.fullyQualifiedName.toString("/") + ".java",
                e.compile)
        }
    }

    private def compile(Entity e) '''
        «IF e.eContainer.fullyQualifiedName !== null»
            package «e.eContainer.fullyQualifiedName»;
        «ENDIF»
        
        public class «e.name» «IF e.superType !== null
                »extends «e.superType.fullyQualifiedName» «ENDIF»{
            «FOR f : e.features»
                «f.compile»
            «ENDFOR»
        }
    '''

    private def compile(Feature f) '''
        private «f.type.fullyQualifiedName» «f.name»;
        
        public «f.type.fullyQualifiedName» get«f.name.toFirstUpper»() {
            return «f.name»;
        }
        
        public void set«f.name.toFirstUpper»(«f.type.fullyQualifiedName» «f.name») {
            this.«f.name» = «f.name»;
        }
    '''
}
</code></pre>

<p>If you want to play around with Xtend, you can try to use the Xtend tutorial which can be materialized into your workspace. Simply choose <em>New → Example → Xtend Examples → Xtend Introductory Examples</em> and have a look at the features of Xtend. As a small exercise, you could implement support for the <em>many</em> attribute of a <em>Feature</em> or enforce naming conventions, e.g. generated field names should start with an underscore.</p>

<h2 id="tutorial-validation">Creating Custom Validation Rules</h2>

<p>One of the main advantages of DSLs is the possibility to statically validate domain-specific constraints. Because this is a common use case, Xtext provides a dedicated hook for this kind of validation rules. In this lesson, we want to ensure that the name of an <em>Entity</em> starts with an upper-case letter and that all features have distinct names across the inheritance relationship of an <em>Entity</em>.</p>

<p>Locate the class <em>DomainmodelValidator</em> in the package <em>org.example.domainmodel.validation</em> of the language project. Defining the constraint itself is only a matter of a few lines of code:</p>

<pre><code class="language-java">public static final String INVALID_NAME = "invalidName";

@Check
public void checkNameStartsWithCapital(Entity entity) {
    if (!Character.isUpperCase(entity.getName().charAt(0))) {
        warning("Name should start with a capital",
            DomainmodelPackage.Literals.TYPE__NAME,
            INVALID_NAME);
    }
}
</code></pre>

<p>Any name for the method will do. The important thing is the <a href="https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext/src/org/eclipse/xtext/validation/Check.java">Check</a> annotation that advises the Xtext framework to use the method as a validation rule. If the name starts with a lower case letter, a warning will be attached to the name of the <em>Entity</em>.</p>

<p>The second validation rule is straight-forward, too. We traverse the inheritance hierarchy of the <em>Entity</em> and look for features with equal names.</p>

<pre><code class="language-java">@Check
public void checkFeatureNameIsUnique(Feature feature) {
    Entity superEntity = ((Entity) feature.eContainer()).getSuperType();
    while (superEntity != null) {
        for (Feature other : superEntity.getFeatures()) {
            if (Objects.equal(feature.getName(), other.getName())) {
                error("Feature names have to be unique", DomainmodelPackage.Literals.FEATURE__NAME);
                return;
            }
        }
        superEntity = superEntity.getSuperType();
    }
}
</code></pre>

<p>The sibling features that are defined in the same entity are automatically validated by the Xtext framework, thus they do not have to be checked twice. Note that this implementation is not optimal in terms of execution time because the iteration over the features is done for all features of each entity.</p>

<p>You can determine when the <code>@Check</code>-annotated methods will be executed with the help of the <a href="https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext/src/org/eclipse/xtext/validation/CheckType.java">CheckType</a> enum. The default value is <code>FAST</code>, i.e. the checks will be executed on editing, saving/building or on request; also available are <code>NORMAL</code> (executed on build/save or on request) and <code>EXPENSIVE</code> (executed only on request).</p>

<pre><code class="language-java">@Check(CheckType.NORMAL)
public void checkFeatureNameIsUnique(Feature feature) {
    ...
}
</code></pre>

<h2 id="tutorial-unit-tests">Unit Testing the Language</h2>

<p>Automated tests are crucial for the maintainability and the quality of a software product. That is why it is strongly recommended to write unit tests for your language. The Xtext project wizard creates two test projects for that purpose. These simplify the setup procedure for testing the basic language features and the Eclipse UI integration.</p>

<p>This tutorial is about testing the parser, the linker, the validator and the generator of the <em>Domainmodel</em> language. It leverages Xtend to write the test cases.</p>

<ol>
  <li>
    <p>The core of the test infrastructure is the <a href="https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/XtextRunner.java">XtextRunner</a> (for JUnit 4) and the language-specific <a href="https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/IInjectorProvider.java">IInjectorProvider</a>. Both have to be provided by means of class annotations. An example test class should have already been generated by the Xtext code generator, named <em>org.example.domainmodel.tests.DomainmodelParsingTest</em>:</p>

    <pre><code class="language-xtend"> @RunWith(XtextRunner)
 @InjectWith(DomainmodelInjectorProvider)
 class DomainmodelParsingTest {
    
     @Inject
     ParseHelper&lt;Domainmodel&gt; parseHelper
    
     @Test 
     def void loadModel() {
         val result = parseHelper.parse('''
             Hello Xtext!
         ''')
         Assert.assertNotNull(result)
         val errors = result.eResource.errors
         Assert.assertTrue('''Unexpected errors: «errors.join(", ")»''', errors.isEmpty)
     }
    
 }
</code></pre>

    <p><em>Note</em>: When using JUnit 5 the <a href="https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/extensions/InjectionExtension.java">InjectionExtension</a> is used instead of the XtextRunner. The Xtext code generator generates the example slightly different, depending on which option you have chosen in the <em>New Xtext Project</em> wizard.</p>
  </li>
  <li>
    <p>The utility class <a href="https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/util/ParseHelper.java">ParseHelper</a> allows to parse an arbitrary string into a <em>Domainmodel</em>. The model itself can be traversed and checked afterwards. A static import of <a href="http://junit.sourceforge.net/javadoc/org/junit/Assert.html">Assert</a> leads to concise and readable test cases. You can rewrite the generated test case as follows:</p>

    <pre><code class="language-xtend"> import static org.junit.Assert.*

 ...

     @Test 
     def void parseDomainmodel() {
         val model = parseHelper.parse(
             "entity MyEntity {
                 parent: MyEntity
             }")
         val entity = model.elements.head as Entity
         assertSame(entity, entity.features.head.type)
     }
</code></pre>
  </li>
  <li>
    <p>In addition, the utility class <a href="https://github.com/eclipse/xtext-core/blob/master/org.eclipse.xtext.testing/src/org/eclipse/xtext/testing/validation/ValidationTestHelper.java">ValidationTestHelper</a> allows to test the custom validation rules written for the language. Both valid and invalid models can be tested.</p>

    <pre><code class="language-xtend"> @Inject ParseHelper&lt;Domainmodel&gt; parseHelper

 @Inject ValidationTestHelper validationTestHelper

 @Test
 def testValidModel() {
     val entity = parseHelper.parse(
         "entity MyEntity {
             parent: MyEntity
         }")
     validationTestHelper.assertNoIssues(entity)
 } 

 @Test
 def testNameStartsWithCapitalWarning() {
     val entity = parseHelper.parse(
         "entity myEntity {
             parent: myEntity
         }")
     validationTestHelper.assertWarning(entity,
         DomainmodelPackage.Literals.ENTITY,
         DomainmodelValidator.INVALID_NAME,
         "Name should start with a capital"
     )
 }
</code></pre>

    <p>You can further simplify the code by injecting <code>ParseHelper</code> and <code>ValidationTestHelper</code> as extensions. This feature of Xtend allows to add new methods to a given type without modifying it. You can read more about extension methods in the <a href="https://www.eclipse.org/xtend/documentation/202_xtend_classes_members.html#extension-methods">Xtend documentation</a>. You can rewrite the code as follows:</p>

    <pre><code class="language-xtend"> @Inject extension ParseHelper&lt;Domainmodel&gt;

 @Inject extension ValidationTestHelper

 @Test
 def testValidModel() {
     "entity MyEntity {
     parent: MyEntity
     }".parse.assertNoIssues
 }

 @Test
 def testNameStartsWithCapitalWarning() {
     "entity myEntity {
         parent: myEntity
     }".parse.assertWarning(
         DomainmodelPackage.Literals.ENTITY,
         DomainmodelValidator.INVALID_NAME,
         "Name should start with a capital"
     )
 }
</code></pre>
  </li>
  <li>
    <p>The <a href="https://github.com/eclipse/xtext-extras/blob/master/org.eclipse.xtext.xbase.testing/src/org/eclipse/xtext/xbase/testing/CompilationTestHelper.java">CompilationTestHelper</a> utility class comes in handy while unit testing the custom generators:</p>

    <pre><code class="language-xtend"> @Inject extension CompilationTestHelper

 @Test def test() {
     '''
         datatype String
			
         package my.company.blog {
             entity Blog {
                 title: String
             }
         }
     '''.assertCompilesTo('''
         package my.company.blog;

         public class Blog {
             private String title;
				
             public String getTitle() {
                 return title;
             }
				
             public void setTitle(String title) {
                 this.title = title;
             }
         }
     ''')
     }
</code></pre>
  </li>
  <li>
    <p>After saving the Xtend file, it is time to run the tests. Select <em>Run As → JUnit Test</em> from the editor’s context menu. All implemented test cases should succeed.</p>
  </li>
</ol>

<p>These tests serve only as a starting point and can be extended to cover the different features of the language. As a small exercise, you could implement e.g. test cases for the <code>checkFeatureNameIsUnique</code> validation rule. You can find more test cases in the example projects shipped with the Xtext Framework. Simply go to <em>File → New → Example → Xtext Examples</em> to instantiate them into your workspace.</p>

<hr />

<p><strong><a href="104_jvmdomainmodel.html">Next Chapter: Five simple steps to your JVM 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://www.planeteclipse.org/">Eclipse Planet</a></li>
              <li><a href="https://www.eclipse.org/forums/index.php/f/27/">Xtext Forum</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>
