Home

Language Workbench Challenge 2013 Xtext Submission

image

Contents

1. String 2 ES 3 var Integer stressPoints if hasTimePressureAtWork 30 else 0 http www eclipse org Xtext documentation htmlitxbaseLanguageRef Introduction P P g guag 23 O o JD c A o o 1 Oo Ct gt Ww t Rp e Rp wo N e O o oo 1 DoT A Ww N e E o 1t LWC13 Xte t Submission stressPoints stressPoints daysSleepingBadPerWeek 3 stressPoints stressPoints glassesOfAlcoholPerDay 12 stressPoints stressPoints daysWithSportPerWeek 2 if stressPoints gt 80 High else if stressPoints gt 40 Medium else Low 2 7 Including Expressions into the QL Language Recall the example of a housowning questionnaire as mentioned in the LWC13 task import types Money form Box1HouseOwning hasSoldHouse Did you sell a house in 20107 boolean hasBoughtHouse Did you by a house in 20107 boolean hasMaintLoan Did you enter a loan for maintenance reconstruction boolean if hasSoldHouse sellingPrice Price the house was sold for Money privateDebt Private debts for the sold house Money valueResidue Value residue Money sellingPrice privateDebt Compared to the language developed in section 2 2 we need to add 1 a condition statement to express optional questions see line 8 and 2 the capability for automatically deriving a question s answer from previously answered questions see line 11 As explained in section 2 2 our grammar inherits from
2. 2 import types Money We will use them to import types used as a question s answer type The operator means that a to many containment reference with name imports is added as EReference to the Questionnaire EClass The means that this rule can be repeated zero to many times After the import statements the QL model can contain multiple form declarations Import import importedNamespace QualifiedName The Import rule is defined to start with the keyword import followed by a QualifiedName The QualifiedName rule is not defined in the Q1Ds1 xtext grammar itself it is inherited from the Xbase grammar This rule defines a so called Datatype Rule which maps to datatype in this case EString 1 Import 2 import importedNamespace QualifiedName After the imports section QL forms are defined Form form name ID element FormElement DU e N e l6http www eclipse org Xtext documentation html grammarMixins 17To enforce at least one rule call the operator would be used instead 16 e Ww N Hn it LWC13 Xte t Submission Forms have an attribute called name ID is a terminal rule which is defined in Xtext s root grammar Terminals It allows typical Java style identifiers beginning with a word character followed by arbitrary many characters numbers or underscores The next step is to define the rule FormElement It is an abstract rule which will
3. which is a framework that is intended to define processes for code generation This file defines the process to generate code for the DSL implementation Q1Dsl xtext This is the file that contains the DSL language definition itself It is called the Grammar of the language 12More about MWE2 see http www eclipse org Xtext documentation htmlitMWE2 13 oo IO Ct A wow N Hm D DD N N NY NM M LB Be Ro Roo un Q oa F Ww N e O JO 0 A WwW NBEO 27 28 29 30 31 1t LWC13 Xtes lt t Submission 2 3 Defining the Grammar Open the Grammar file Q1Ds1 xtext In a first step we will leave out the expression part in the syntax for simplicity Enter the following text into the Grammar file grammar org eclipse xtext example ql Q1Dsl with org eclipse xtext xbase Xbase generate qlDsl http www eclipse org xtext example q1 Q1Ds1 The top most container of QL files is a Questionnaire Questionnaire imports Import forms Form Allows importing of qualified names of types Import import importedNamespace QualifiedName QL consists of questions grouped in a top level form construct Form form name ID 4 element FormElement pig Abstract rule for elements contained in a Form FormElement Question Each question identified by a name that at the same time represents the result of the question A question has a label that contains the actual ques
4. Price the house was sold for 172000 Private debts for the sold house 42000 Value residue 130000 Did you sell a car in 2010 Price the car was sold for 0 Did you buy a car in 2010 S Next pages 68 o o 1 Oo Ct FF wo hM m Rp N e oc it LWC13 Xte t Submission 5 Additional Concepts 5 1 Validation As an optional task the LWC13 task requires the implementation of analysis rules Xtext provides a validation framework which integrates into the EMF Validation framework The Xtext User Manual contains a Validation chapter that is worth reading additionally We will show in this section how the constraints defined in the task description can be realized with Xtext 5 1 1 Extending the Java Validator class With the first translation of the Xtext grammar the generator has already created the necessa ry infrastructure to implement custom validation rules Look into the package org eclipse xtext example ql validation you will find a Java class Q1Ds1JavaValidator The class extends the AbstractQ1DslJavaValidator class which is regenerated each time the grammar is translated Thus the generation gap pattern is applied here again It is safe to extend the Q1Ds1JavaValidator class manually But instead of implementing the constraints in Java we will use Xtend again For easier inte gration our Xtend based validator class will be inserted into the class hierarchy of Q1DslJavaValidator Create an Xtend
5. resources link to the first actual page to be presented The page HouseOwningPage contains two sections Y amp default v amp css using the forms HouseOwning and GarageOwning thus Y amp generated E CarOwningPage css the generated file pages HouseOwningPage xhtml wi T erm res the two base files forms HouseOwningBase xhtml gt amp templates and forms GarageOwningBase xhtml together 63 o oo Oo Ct FF Ww m ee Be HH HH an oo F C N e e O oo JO Ct A wo N Hm E o 1t LWC13 Xte t Submission lt html xmlns http www w3 org 1999 xhtm1 xmlns ui http java sun com jsf facelets xmlns h http java sun com jsf html xmlns f http java sun com jsf core gt lt h head gt lt h head gt lt ui composition template index xhtml gt lt ui define name content gt lt h outputStylesheet library default css generated name HouseQwningPage css gt lt div gt lt ui include src generated forms HouseOwningBase xhtml gt lt div gt lt p gt lt div gt lt ui include src generated forms GarageOwningBase xhtml gt lt div gt lt div gt lt h outputLink value CarOwningPage jsf gt CarOwningPage lt h outputLink gt lt div gt lt ui define gt lt ui composition gt lt html gt The two pages are referenced in lines 9 and 10 Line 12 defines the link to the next page as defined in the navigation section of the QLS model Line 8 specifies which CSS file is to be used to
6. N Q C a ao FF Ww N it LWC13 Xte t Submission label class ym g33 ym gl Did you sell a house in 2010 lt label gt The JSF html selectBooleanCheckbox will be translated in a more complex HTML input tag The most interesting thing is the action definition onclick which lets JSF do some magic via AJAX to trigger partial page reloads The base functionality is provided by the JSF framework and some JavaScript libraries lt input id houseOwningForm chkHasSoldHouse class ym g50 ym gl type checkbox onclick mojarra ab this event valueChange houseOwningForm chkHasSoldHouse houseOwningForm grp hasSoldHouse hasBoughtHouse pu checked checked name houseOwningForm chkHasSoldHouse gt lt input gt On client side the browser renders the question well grouped by use of some CSS framework classes already mentioned in section 3 1 3 Did you sell a house in 2010 El The following CSS classes out of WebContent resources default css base css are respon sible for the shown layout e ym grid defines that childs should be grouped in a table e ym g number defines the width of an element e ym gl defines that the element should float to the left of its container Other question types are following the same pattern of a label and a proper input element to interact with the application div class ym grid gt lt h outputLabel styleClass ym g60 ym gl value Pri
7. Privacy Policy Terms of Service 86 it LWC13 Xtes lt t Submission This build could be reproduced on any Jenkins server with the following configuration settings e Create a job of style Maven2 3 e Git repository URL https code google com a eclipselabs org p lwci3 xtext e Build trigger poll repository every 30 minutes 1 30 e n the Maven build section choose a Maven 3 installation e Configure POM projects pom xml Goals and options clean install e Alternative settings file Advanced options devenv lwc13 devenv settings xml e Add post build action archive artifacts projects target repository 6 Closing Words Thank you for reading this document We have been writing it with the intention that it should provide easy access for first time users of Xtext to this powerful Language Workbench This explains also the size of the document We could have written it shorter if we assumed more background knowledge of the potential readers or if we left many things with just short comments Xtext has grown over years gaining more and more experience from real life projects that want to leverage the power of DSLs in integrated environments We could only touch the surface of Xtext and Xtend here and tried to choose the most simple solution The QL assignment did fit quite well into what Xtext can provide mostly out of the box but its real power is unvealed when DSLs have non standard requireme
8. Since condition expressions for groups are optional the method body has to return simply true in the case that no expression is assigned When groups have a condition the condition expression is assigned as the method body 33 it LWC13 Xte t Submission 2 9 Scoping Scoping is roughly said the computation of referrable names in a given context It is a quite complex topic and we won t cover it here into deep The topic itself is heavily documented by the Xtext user manual several articles and implementation examples The Xtext framework already provides default implementations to solve scoping and linking In the case of Xbase based languages the XbaseBatchScopeProvider is configured by default as implementation of the IScopeProvider interface For our use case the default behavior is already sufficient Through the JVM model inference the implicit this variable is already bound to the class representing the form and thus the fields representing the question elements are known as callable features 30 X text manual Scoping 3le g http blogs itemis de stundzig archives 776 32e g https github com LorenzoBettini xtext scoping 34 it LWC13 Xtes lt t Submission 3 Developing the Code Generator 3 1 Reference Implementation Before implementing a code generator one has to know what the target code is Therefo re a reference implementation has been developed which was coded to large degree manu a
9. Tycho introduces some Eclipse specific packaging types which trigger the module to be built by Tycho plugins build resources resource lt directory gt project build directory xtext lt directory gt lt resource gt lt resources gt lt plugins gt lt Copy all Xtext related sources to seperate folder that is registered as resource si uliclewe gt lt plugin gt lt artifactId gt maven resources plugin lt artifactId gt lt executions gt lt execution gt lt id gt copy resources lt id gt lt phase gt initialize lt phase gt lt goals gt lt goal gt copy resources lt goal gt lt goals gt lt configuration gt lt outputDirectory gt project build directory xtext lt outputDirectory gt lt resources gt lt resource gt lt directory gt src lt directory gt lt includes gt lt include gt xtext lt include gt lt include gt mwe2 lt include gt lt includes gt lt resource gt lt resources gt lt configuration gt lt execution gt lt executions gt lt plugin gt Next we do something special for MWE2 In order to execute an MWE2 workflow this workflow file must be loadable from the project s classpath But the MWE2 file is contained in the source path of a project Therefore an additionaly directory target xtext is added as resource folder to the project resource folders are added to the classpath and copy Xtext related resources from the source direc
10. WEB CONTENT contentIndex For the new artifact add a new extension called def generate FormIndex It receives a list of Form elements In a short loop it generates a html outputlink node for each element in the given list of forms Because doGenerate is called for each QL resource the generator currently has the limitation that all QL model elements have to be defined within the same QL resource to ensure generation of a correct form index page def generate FormIndex List lt Form gt forms 2 2359 lt ui composition template index xhtml gt lt ui define name content gt FOR elem forms SEPARATOR lt br gt gt lt h outputLink value elem name gt jsf gt lt elem name gt lt h outputLink gt ENDFOR lt ui define gt lt ui composition gt By using the attribute template of a composition tag as already described in 3 1 3 the structure and styles of index xhtml will be derived in our form index page Our generated form index needs a index xhtml in the applications root folder which itself or one of its parent templates defines a facelet insert section with name content like described in section 3 1 3 To get the possibility to change the template for all generated files in a single file easily later we will use the generated form index as template for generated form pages in a later step The generated form index looks similar to the one described in section 3 1 4 93 o o Oo
11. chapter we will describe how the optional task to define a language for styling and layout information can be accomplished in our language workbench The language QLS should allow for defining the following information e Grouping of question forms into pages sections and subsections e Navigation links between pages Styling of question texts by defining font style font weight font family and color e Defining the appearance of a question by specifying the widget type to render The following shows an example model that we want to be able to define with QLS page HouseOwningPage 1 section house uses Box1HouseOwning question hasBoughtHouse font style italic question valueResidue font weight bold font color 2233FF font family Arial section garage uses Garagelwning question hasBoughtGarage widget Radio Yepp Nope navigation CarOwningPage J page CarOwningPage uses Car wning HE oe This example model defines two pages The first page consists of two sections one for the question form Box1HouseOwning which was defined in chapter 2 and one for a further form called GarageOwning The form to be rendered inside a page or a section is specified by the uses keyword This definition must be unambiguously e g if there is a form included by a page 58 o o Jl Oo Ct A UO Ne w won N N N N PN PM NY NM DN Be e e e e Be pa pa pap Qj N e O DAN O C FPF CQ N FPF O 4o DAN TD
12. class Q1Ds1XtendValidator and extend it from AbstractQ1DslJavaValidator package org eclipse xtext example ql validation import javax inject Inject import org eclipse xtext validation Check import org eclipse xtext xbase XFeatureCall import org eclipse xtext xbase XbasePackage import org eclipse xtext xbase jvmmodel I JvmModelAssociations import static extension org eclipse xtext nodemodel util NodeModelUtils class Q1DslXtendValidator extends AbstractQlDslJavaValidator Inject extension IJvmModelAssociations 5 40nttp www eclipse org modeling emf project validation 4lsee http www eclipse org Xtext documentation html validation 69 it LWC13 Xte t Submission Derive QlDslJavaValidator from the the Xtend validator public class QlDslJavaValidator extends Q1DslXtendValidator do nothing here rules are implemented in Xtend 5 1 2 Constraint Ensure order of questions The first constraint in the LWC13 task is defined so Test for cyclic dependencies For instance the following snippet should be rejected 1 BH Ge Eh we E vogllesa y 2 if y x X boolean The reason is that y will only be asked for when x is true but x will only get a value when y is true Of course such cyclic dependencies could occur transitively and nested in expressions Another way of stating this check is the ordering of questions should be consistent with how the question variables are u
13. classes to create the artifacts Usually one template per artifact is created Create the class Root java in package org eclipse xtext example ql generator package org eclipse xtext example ql generator import javax inject Inject import org eclipse emf ecore resource Resource import org eclipse xtext generator IFileSystemAccess import org eclipse xtext generator IGenerator import org eclipse xtext xbase compiler JvmModelGenerator SuppressWarnings restriction public class Root implements IGenerator Inject 47 13 14 15 16 17 18 19 A WwW N e P N it LWC13 Xtes lt t Submission JvmModelGenerator jvmModelGenerator public void doGenerate Resource input IFileSystemAccess fsa dispatch to other generators jvmModelGenerator doGenerate input fsa 5 As a first generator to which is dispatched we inject an instance of JvmModelGenerator This is a standard generator shipped with Xtext which translates types inferred by the Jvm Model Inferrer to Java classes In our case the Java class for Forms are generated by the JvmModelGenerator In JSF terms we speek of the Backing Bean Next Xtext has to know that Root is the template that has to be invoked as generator imple mentation Whenever a default implementation must be exchanged by a custom one this has to be added or overridden in the respective Guice module In the case of the custom IGenerator implementation thi
14. collect the different alternatives of elements that can be contained in a form In our first step the rule Question will be the only alternative We will introduce a second alternative later in the grammar and in order to reduce the refactoring effort we are introducing the FormElement already now FormElement Question Finally the Question rule is defined In a first step Questions are identified by a name followed by a label string and a reference to a type Later we will add expressions to compute the value Question name ID label STRING type JvmTypeReference A Question s type is a reference to a JVM Type Think of this for now that we refer to Java types The JvmTypeReference rule is also inherited through Xbase actually Xbase derives itself from another grammar Xtype which declares these rules 2 4 Generate Language Implementation Now that the initial grammar of the language has been defined it is time to test the language Xtext ships with a code generator which generates all the glue code needed for the language implementation To generate the code we need to execute the generator workflow GenerateQ1Dsl mwe2 For this select the workflow file open the context menu and select Run As MWE2 Workflow The generator will print some information to the Console and finally it should print Done O main INFO lipse emf mwe utils StandaloneSetup Registering platform Uri e 13727 mai
15. eclipse xtext example ql sdkversion 1 00 quallitient gt category name DSL gt lt feature gt lt category def name DSL label DSL gt lt site gt The POM for this project has the packaging type eclipse repository besides that it is as simple as the previous POM lt xml version 1 0 encoding UTF 8 gt lt project xsi schemaLocation http maven apache org P0M 4 0 0 http maven apache org xsd maven 4 0 0 xsd xmlns http maven apache org P0M 4 0 0 xmlns xsi http www w3 org 2001 XMLSchema instance gt lt modelVersion gt 4 0 0 lt modelVersion gt A http tinyurl com cho280x 85 O 0 N Oo Ct 10 11 12 13 14 LWC13 Xtes lt t Submission lt parent gt lt groupId gt org eclipse xtext example ql lt groupId gt lt artifactId gt parent lt artifactId gt lt version gt 1 0 0 SNAPSHOT lt version gt lt X gt lt relativePath gt pom xml lt relativePath gt lt parent gt lt artifactId gt org eclipse xtext example ql repository lt artifactId gt lt packaging gt eclipse repository lt packaging gt lt project gt The resulting repository is then available in the target repository folder 5 2 8 Continuous Integration For continuous integration we use the build infrastructure from Cloudbees which is free for open source software Cloudbees offers Jenkins as CI server and we have set up a build job for the DSL projects https kthoms ci cloud
16. element final true static true setInitializer it append 1L 1 We want to make the resulting Java class serializable This is optional but better style The refore the class has to implement the java io Serializable interface whose JVM Model representative is retrieved from the TypeReferences instance and added to the superTypes collection The identifier it denotes the implicit variable of type Form of the closure It is not necessary to qualify it here it could be left out The closure passed to the setInitializer method initializes the field with the value 1 of type long val allQuestions form eAllContents filter typeof Question toList for question allQuestions members question toField question name question type 5 3l o o 1 Oo Ct FF WwW N Rp hop Rh O oo nn nw A A OO N e it LWC13 Xte t Submission E All Question instances from the resource are bound to the final variable allQuestions Since Questions can be nested into groups the content has to be searched recursively eA11Contents will traverse over all elements Next for each Question a JvmField instance is inferred Here the JvmTypesBuilder is helping us with the method toField which gets the name and type of the derived field Here we see the effect of the extension keyword It seems that toField is actually a method of type Question but it is a method of the JvmTypesBuilder class for question all
17. grammar The metamodel will represent the language s Abstract Syntax Tree AST Xtext creates the following structure in the Ecore metamodel e an EPackage for each generate statement The name of the EPackage is the first argu ment q1Ds1 the package s nsURI is the second argument http www eclipse org xtext example ql Q1Ds1 e an EClass for each return type of a parser rule If a parser rule does not define a return type an implicit one with the same name as the rule itself is assumed You can specify multiple rules that return the same type but only one EClass will be generated for each type defined in an action or a cross reference e an EEnum M That s what has been entered in the project wizard Phttp www eclipse org Xtext documentation htmlimetamodelInference 15 it LWC13 Xtes lt t Submission for each return type of an enum rule e an EData Type for each return type of a terminal rule or a data type rule Alternatively an Xtext grammar could be mapped to an existing Ecore metamodel 1 Questionnaire 2 imports Import 3 forms Form The top most container rule is Questionnaire Per model resource exactly one instance of this type will be contained in the root content of the resource Any other element will be contained directly or indirectly within this instance Each QL model will contain zero to many import statements e g 1 import java math BigDecimal
18. index xhtml lt ui composition template resources default templates defaultLayout xhtml gt The reference application is shipped with a default template placed in WebContent resources default It is a very simple one providing only a skeleton templates defaultLayout xhtml with basically 3 sections header content footer where clients can add custom content The current web application expects a defined facelets insert section with name content 38 o ON Dot gt WwW Ne NOM N N NY YN Ro Re Be Be Be Be Be Be Be mu Q Ot F Ww N e O oo DT FPF WwW N FF O it LWC13 Xtes lt t Submission within the template or one of its parents for proper composition In our reference implementa tion it is declared in resources default templates defaultLayout xhtml lt DOCTYPE html PUBLIC W3C DTD XHTML 1 0 Transitional EN http www w3 org TR xhtmli DTD xhtmli transitional dtd lt html xmlns http www w3 org 1999 xhtm1 xmlns h http java sun com jsf html xmlns ui http java sun com jsf facelets gt lt h head gt lt title gt lt ui insert name title gt LWC 2013 Xtext lt ui insert gt lt title gt lt h head gt lt body gt lt div id header gt lt ui insert name header gt lt ui include src resources default templates header xhtml lt ui insert gt lt div gt lt div id content gt lt ui insert name content gt Content area Compose by use of tag facelet defi
19. lt workflowDescriptor gt lt timestampFileName gt xtext generator timestamp lt timestampFileName gt lt jvmSettings gt lt fork gt true lt fork gt lt jvmArgs gt lt jvmArg gt Xms100m lt jvmArg gt lt jvmArg gt Xmx700m lt jvmArg gt lt jvmArg gt XX MaxPermSize 128m lt jvmArg gt lt jvmArg gt Dlog4j configuration file basedir META INF log4j properties lt jvmArg gt lt jvmArgs gt lt jvmSettings gt lt configuration gt lt execution gt lt executions gt lt plugin gt The fornax oaw m2 plugin plugin is responsible to invoke the MWE2 workflow GenerateQ1Ds1 mwe2 The module value in this workflow is configured as parameter workflowDescriptor to this plu gin The plugin is executed in the generate sources lifecycle phase which is processed before com pilation You will see this output when it is executed INFO fornax oaw m2 plugin 3 4 0 run workflow xtext org eclipse xtext example ql INFO Fornax Model Workflow Maven2 Plugin V3 4 0 INFO Executing workflow in forked mode INFO Workflow org eclipse xtext example qls GenerateQlsDsl finished 83 A WwW N e o o JO Ct me C 10 11 12 13 14 it LWC13 Xte t Submission Last but not least the xtend maven plugin is configured plugin lt groupId gt org eclipse xtend lt groupId gt lt artifactId gt xtend maven plugin lt artifactId gt lt plugin gt This plugin compiles the Xten
20. see now that the editor has recognized our DSL The language s keywords are highlighted Xtext offers far more than just syntax coloring for the language it created a fully integrated editor You may explore some of the features now e If you make errors error markers are created and resolved while you type e Content assist is offered with CTRL SPACE e The Outline view 4 presents the structure of the document and allows quick navigation e F3 allows jumping to the definition of an element which is defined somewhere else You could try this by selecting Money and press F3 At the moment only the type infor mation of questions is cross referenced From now on we will extend the DSL a bit further This usually requires to restart the test environment So close it and proceed reading 2 6 Xbase The language developed in section 2 2 does not yet meet all demands on the LWC2013 task Two core features are missing First a question s answer can be computed i e its answer can be derived from an expression referring to previous questions answers Second questions can be optional depending on the previous answers For this also the possibility to define expressions is needed This is where Xbase comes into play Xbase is an expression language which can be reused in your own Xtext DSL Its language concepts are similar to Java but with some syntactical derivations improving readability The Xbase grammar is defined in Xte
21. this There is POM that only contains module entries in the projects folder modules lt module gt org eclipse xtext example ql lt module gt lt module gt org eclipse xtext example ql ui lt module gt lt module gt org eclipse xtext example qls lt module gt lt module gt org eclipse xtext example qls ui lt module gt lt module gt org eclipse xtext example ql sdk lt module gt lt module gt org eclipse xtext example ql repository lt module gt lt modules gt http code google com a eclipselabs org p lwci3 xtext source browse projects pom xml 79 it LWC13 Xtes lt t Submission When building the DSL projects this POM has to be executed Assuming the build is executed from the repository root the typical build command would be 1 mvn s devenv lwc13 devenv settings xml f projects pom xml clean install o ON Det A WwW 10 11 12 5 2 4 QL Runtime Project POM Let s look a bit at the POM of the QL Runtime Project org eclipse xtext example ql lt xml version 1 0 encoding UTF 8 gt lt project xsi schemaLocation http maven apache org POM 4 0 0 http maven apache org xsd maven 4 0 0 xsd xmlns http maven apache org P0M 4 0 0 xmlns xsi http www w3 org 2001 XMLSchema instance gt lt modelVersion gt 4 0 0 lt modelVersion gt lt parent gt lt groupId gt org eclipse xtext example ql lt groupId gt lt artifactId gt parent lt artifactId gt lt v
22. to Java polymorphic dispatching is internally realized by a dispatcher method using a cascade of instanceof constructs def dispatch doSomething SubTypeA input 1 do something SubTypeA specific def dispatch doSomething SubTypeB input do something SubTypeB specific def useDispatching val SuperType a new SubTypeA val SuperType b new SubTypeB a doSomething b doSomething In this example the types SubTypeA and SubTypeA are sub types of SuperType The method doSomething is declared for each of the two sub types as input parameter with accordingly different body here only indicated by comments In line 12 these methods are called on the objects aand b which have SuperType as static type and one of the sub types as compile time type Xtend invokes the correct method here i e for a the method in lines 1 3 and for b the one in lines 5 7 is called Xtend offers the possibility to define Rich Strings also called templates which is especially useful when writing code generators Rich Strings allow for writing complex Strings with line breaks and indentations without the need for concatenating special characters like n or t A Rich String construct starts and ends with triple single quotes Within such a Rich String code pieces which themself return a String can be inserted surrounded by guillemots If you wonder where you can find these guillemot brackets on your keyboard the
23. 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 IF page form null lt div class highlight_section gt lt ui include src generated forms lt page form name gt Base xhtml gt lt div gt ELSE FOR section page eAllContents toList filter typeof Section toList SEPARATOR lt p gt gt lt div class highlight_section gt lt ui include src generated forms lt section form name gt Base xhtml gt lt div gt ENDFOR ENDIF IF page navigation null form lt div class highlight section ym grid gt lt h outputLabel styleClass 1v11Lb1 ym gl id lblNavigation value Next pages gt FOR nextPage page navigation nextPage gt lt h outputLink styleClass lvliLbl ym gl value nextPage name gt jsf gt nextPage name lt h outputLink gt ENDFOR lt div gt lt form gt ENDIF lt ui define gt lt ui composition gt lt html gt QJ def generateIndexPage Page page lt xml version 1 0 encoding UTF 8 gt SIL EOscnerdbteda gt lt DOCTYPE html PUBLIC W3C DTD XHTML 1 0 Transitional EN http www w3 org TR xhtm11 DTD xhtml1 transitional dtd gt lt html xmlns http www w3 0rg 1999 xhtml xmlns h http java sun com jsf html xmlns ui http java sun com jsf facelets gt lt ui composition template index xhtml gt lt ui define name content gt lt h outputLink value p
24. A RA Ww NRO it LWC13 Xtes lt t Submission it is not allowed to refer to another form in one of its containing sections This restriction is ensured by implementing a corresponding validation How this can be done is covered in section 5 1 In a section or page the styling information for the questions of the included form can be defined as in lines 3 9 and 11 The navigation keyword allows to define the order in which the pages are to be displayed by specifying which page should appear next Before we can write the corresponding Xtext grammar we need to create the DSL projects for QLS as we have done for the Questionnaire language For this refer again to chapter 2 2 and replace all occurences of ql with qls The project org eclipse xtext example qls should then contain the grammar file QlsDsl xtext We define the content of this file as the following grammar org eclipse xtext example qls QlsDsl with org eclipse xtext common Terminals generate qlsDsl http www eclipse org xtext example qls QlsDs1 import http www eclipse org xtext example q1 Q1Ds1 as ql QuestionnaireStyleModel pages t Page Page page name ID uses form ql Form ID 4 element PageElement navigation Navigation CURE PageElement QuestionStyling Section QuestionStyling question question ql Question styling StyleInformation StyleInformation StyleInformation M font style fontStyle STRING amp font w
25. Atest Language Workbench Challenge 2013 Xtext Submission Version 1 0 April O8th 2013 Karsten Thoms Johannes Dicks Thomas Kutz itemis it LWC13 Xtes lt t Submission Abstract The Language Workbench Challenge 2013 LWC13 is an initiative created by a group of experts at the CodeGeneration 2010 conference The aim is to set a common task for Language Workbenches which is implemented with the different existing alternatives in a comparable way This document describes in detail how the task is solved with Xtext Xtext is one of the most well known Language Workbenches and part of the Eclipse Modeling Project Testimonial We would like to thank 1 Angelo Hulshout for initiating and organizing the Language Workbench Challenge It is his work that allows the Language Workbench Challenge to continue now in its 3rd year 2 The Xtext Team is doing a great job on developing a robust flexible and easy to use Language Workbench 3 Gregor Kurpiel is a Web and Mobile Developer at itemis AG and supported us on creating a basic web application style l http www codegeneration net cg2010 see http www languageworkbenches net for the detailed description of the LWC11 competition and other submissions http martinfowler com articles languageWorkbench html http blog efftinge de 2007 11 definition of term language workbench html http www xtext org http www eclipse org modeling it LWC13 Xtes
26. Call exp as XFeatureCall feature simpleName field simpleName else a complex expression e g XFeatureCalli XFeatureCall2 val xfeaturecalls exp eAllContents filter typeof XFeatureCall xfeaturecalls exists feature simpleName field simpleName return result 54 it LWC13 Xte t Submission 36 37 Creates an id for the given domain object 38 7 39 def String getId EObject o 40 switch o 41 ConditionalQuestionGroup group allConditionalGroups o index0f o 42 Question o name 43 Form o name toLowerCase 44 45 46 47 48 Get all ConditionalGroups underneath the given context 49 50 def private allConditionalGroups EObject ctx 51 ctx form eAllContents filter typeof ConditionalQuestionGroup toList 52 53 54 55 Get the parent formis name 56 57 def getFormName FormElement elem 58 elem form name toFirstLower 59 60 61 62 Get the Form container of the given question 63 64 def getForm EObject question 65 EcoreUtil2 getContainerOfType question typeof Form as Form 66 67 os 69 Returns the expression assigned to a FormElement dependent on subtype for FormElement 70 71 def getExpression FormElement elem 72 switch elem 73 Question elem expression 74 ConditionalQuestionGroup elem condition 95 it LWC13 Xtes lt t Submission Besides several small helper f
27. Ct A wo Ne e e e rne a nme n rn o Jl O a 4 OO N F O 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 it LWC13 Xte t Submission QIDsIExtensions When implementing a generator often some basic logic concerning the information extraction from the model needs to be implemented We extracted this functionality into an own Xtend class for modularity and reuse purposes All of these functions are used in the JSF Generator and some of them are even called in the QLS generator which will be described in chapter 4 2 later on The created Xtend class is called Q1Ds1Extension xtend class QlDslExtensions Inject extension IJvmModelAssociations TEE Computes the FormElements which are accessed by the expression of a Question def Iterable lt FormElement gt getDependentElementsWithExpression Question q if q expression null return emptyList The JvmField which is inferred from a Question val JvmField field q jvmElements filter typeof JvmField head Get all FormElements which have an expression val Iterable lt FormElement gt allFormElementsWithExpression q form eAllContents filter typeof FormElement filter it expression null toSet search the expressions of the form elements which call the JvmField field in a feature call val result allFormElementsWithExpression filter val exp it expression if exp instanceof XFeatureCall a simple expression e g XFeature
28. Float default Ttessasomesotherenumbernsbypest Now as you know the basic concepts of Xtend let s finally start writing the code generator 46 o oo Oo Ct A C Ne oo 1 Oo Ct A wo N e e r N e oO it LWC13 Xte t Submission 3 3 Code Generator In this section you will learn how to implement the code generator for the target application For simplicity the code generator templates are placed in the org eclipse xtext example ql project in a sub package generator Usually it would be better to create a separate project which contains the generator since the language is independent from a single target platform It would be possible to create different code generators for different target platforms and it would be better to implement each of them as separate projects Generator templates in Xtend are implementations of the IGenerator interface package org eclipse xtext generator public interface IGenerator Oparam input the input for which to generate resources Oparam fsa file system access to be used to generate files public void doGenerate Resource input IFileSystemAccess fsa 3 3 1 Dispatcher template The code generator is invoked with a Resource instance which holds a Questionnaire instan ce We have to generate multiple artifacts for each resource so it is a common pattern to create a template class which serves as entry point and dispatches to other template
29. InjectWith import org eclipse xtext junit4 XtextRunner import org eclipse xtext junit4 util ParseHelper import org eclipse xtext junit4 validation ValidationTestHelper import org eclipse xtext xbase XbasePackage import org junit Before import org junit Test import org junit runner RunWith RunWith typeof XtextRunner InjectWith typeof Q1Ds1InjectorProvider class Q1DslValidationTest Inject extension ParseHelper lt Questionnaire gt parseHelper Inject extension ValidationTestHelper Before def void setUp O parseHelper fileExtension ql 72 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 it LWC13 Xtes lt t Submission QTest def void testValidation CallBeforeDeclaration expectError 4 form Foo 4 aug 69 a ys WEY booleanm if y x X boolean parse assertError XbasePackage eINSTANCE XFeatureCall ERR FEATURE CALL BEFORE DECLARATION must be declared before Test def void testValidation CallBeforeDeclaration expectSuccess Y form Foo x foo boolean nae G2 xL ome Oe boglesa y parse assertNoErrors Type check conditions and variables the expressions in conditions should be type correct and should ultimately be booleans The assigned variables should be assigned consistently each assignment should use the same ty
30. Questions if question expression null members question toGetter question name question type members question toSetter question name question type else val getter question toGetter question name question type getter body question expression members getter The next loop creates the accessor methods for the fields We could have done this in the previous loop also but it is better style to declare the fields first and methods next in the class The inferred JvmDeclaredType will be translated to Java later so it is better to have that clean from the beginning Within the loop we decide if the question has a computation expression or not If it hasn t one it is a simple field with getter and setter where we call the toGetter toSetter builder functions If the question value is computed by an expression it does not make sense to offer a setter method The field needs to be read only The getter method does not simply return the value of a field Instead the method has to evaluate the expression Thus we assign the expression as body of the method for question allQuestions members question createlsEnabledMethod def Jvm peration createlsEnabledMethod Question question question toMethod is question name toFirstUpper Enabled 32 it LWC13 Xte t Submission 9 typeReferences getTypeForName boolean question null body it append re
31. Window Preferences 100n Windows do not unpack it into a deep directory since this might cause troubles with long path names it LWC13 Xte t Submission e Mac Eclipse Preferences Workspace Encoding File encoding is important to some type of files It is better that the workspace is set to a common encoding to avoid any platform specific encoding By default the workspace is using platform encoding which is Cp1252 on Windows and MacRoman on Mac We will use ISO 8859 1 as a common encoding here Open Eclipse Preferences and go to General Workspace e Change setting Text file encoding to Other ISO 8859 1 Launch Operation e Open Run Debug Launching e Change Launch Operation to Always launch the previously launched application This will allow you re running the previous launched application by just pressing the Run or Debug button in the Eclipse toolbar or using keyboard shortcuts The default settings does not always do what you want 2 Developing the Questionnaire Language 2 1 Xtext Overview This overview will give you a rough idea about what Xtext is all about We will then dive into the details and work on a small project In a nutshell Xtext is a workbench to create and work with textual domain specific languages DSLs It comes as a feature set of plugins to the popular Eclipse IDE The first thing you will want to do is to create your own domain specific language DSL and s
32. Xbase making its rules reusable in the questionnaire language To fulfill the missing requirements our grammar needs to be extended to the following 7 grammar org eclipse xtext example ql Q1Dsl with org eclipse xtext xbase Xbase generate qlDsl http www eclipse org xtext example q1 Q1Ds1 The top most container of QL files is a Questionnaire Questionnaire imports Import forms Form Allows importing of qualified names of types https gist github com kthoms 5114439 24 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 HG it LWC13 Xtes lt t Submission Import import importedNamespace QualifiedName QL consists of questions grouped in a top level form construct Form form name ID element FormElement Upar Abstract rule for elements contained in a Form FormElement Question ConditionalQuestionGroup Each question identified by a name that at the same time represents the result of the question A question has a label that contains the actual question text presented to the user Every question has a type A question can optionally be associated to an expression this makes the question computed El Question name ID label STRING type JvmTypeReference expression XParenthesizedExpression Wee Groups questions within a block optional
33. age name gt jsf gt lt page name gt lt h outputLink gt lt ui define gt lt ui composition gt lt html gt PAP ER 66 LWC13 Xtes lt t Submission 86 87 88 89 90 1t LWC13 Xtes lt t Submission def getId StyleInformation styleInfo val question styleInfo eContainer as QuestionStyling question question form id 1bl question id toFirstUpper y The doGenerate method is similar to the one of the JSFGenerator from section 3 3 3 It basi cally defines file names and delegates to other methods for defining the generated files contents generateCssFile generateXhtmlFile generateIndexPage We won t go into details here Instead let s test the generated application For this you can basically follow the instructions given in section 3 4 To see some genrated pa ges you first need to define a QLS model To start the application you can use the index xhtml file in folder WebContent generated pages Right click on this file and press Run As Run On Server Finish Using the example models in this chapter a web application similar to the one on the following screenshot will be generated You can change the style model and refresh the browser page to see the result immediately 67 LWC13 Xte t Submission Language Workbench Challenge 2013 Xtext Submission Did you sell a house in 2010 Did you buy a house in 2010 Did you enter a loan for maintenance reconstruction
34. ained in a profile We define a profile external repositories which is activated by default in the activeProfiles section lt settings gt lt activeProfiles gt lt activeProfile gt external repositories lt activeProfile gt lt activeProfiles gt lt profiles gt lt profile gt lt id gt external repositories lt id gt lt repositories gt lt repository gt lt id gt Eclipse Juno lt id gt lt layout gt p2 lt layout gt lt url gt http download eclipse org releases juno lt url gt lt repository gt lt repository gt lt id gt Eclipse Orbit lt id gt lt layout gt p2 lt layout gt lt url gt http download eclipse org tools orbit downloads drops R20120526062928 repository url lt repository gt lt repository gt lt id gt Eclipse Xtext id lt layout gt p2 lt layout gt lt url gt http download eclipse org modeling tmf xtext updates composite releases lt url gt lt repository gt lt repositories gt lt pluginRepositories gt lt pluginRepository gt lt id gt fornax releases lt id gt lt name gt Fornax Release Repository lt name gt lt url gt http www fornax platform org nexus content repositories releases lt url gt lt pluginRepository gt 76 34 35 36 37 38 39 40 41 it LWC13 Xte t Submission lt pluginRepository gt lt id gt xtend lt id gt lt url gt http build eclipse org common xtend maven lt url gt lt pluginRepository
35. bees com job 1wc13 ds1 https kthoms ci cloudbees com job Iwc13 dsl ClickStart Apps DBs Builds Repositories Services Support as Jenkins Iwc13 dsl Zur ck zur bersicht z A Zur ck zur bersic Projekt Iwc13 dsl a Status nderungen Arbeitsbereich 3 Jetzt bauen Arbeitsbereich G Projekt L schen E artifacts jar 776 00 B amp E content jar E org eclipse xtext example al sdk_1 0 0 201304050942 jar a Groups E org eclipse xtext example gl ui 1 0 0 201304050942 jar E org eclipse xtext example ql_1 0 0 201304050942 jar Letzte erfolgreiche Artefakte 7 Konfiqurieren Module Roles E E org eclipse xtext example gls ui 1 0 0 201304050942 jar Move E ora eclipse xtext example gls 1 0 0 201304050942 jar 114 65 KB amp DO Forge Hook Log Letzte nderungen E Git Abfrage Protokoll 5 Build Verlauf Trend Permalinks 9 8 05 04 2013 11 32 39 Letzter Build 48 vor 3 Stunden 40 Minuten 7 04 04 2013 15 02 40 Letzter stabiler Build 8 vor 3 Stunden 40 Minuten e Letzter erfolgreicher Build 48 vor 3 Stunden 40 Minuten 0 6 04 04 2013 14 05 28 e Letzter fehlgeschlagener Build 2 vor 2 Tage 22 Stunden Oo 5 04 04 2013 12 59 52 e Letzter erfolgloser Build 2 vor 2 Tage 22 Stunden 0 4 03 04 2013 16 02 36 3 02 04 2013 16 54 23 Q 2 02 04 2013 16 50 51 1 02 04 2013 16 43 48 RSS aller Builds EJ RSS der Fehlschl ge Contact Us
36. ce the house was sold for lt h inputText styleClass ym g33 ym gl id inSellingPrice 42 10 11 12 HG CU F w N c o 1 o it LWC13 Xte t Submission value houseOwning sellingPrice amount gt lt f ajax event keyup execute inSellingPrice render grp ValueReside gt lt h inputText gt lt div gt As you can see in the figure above the definition of an JSF html inputText tag is also very easy With it is possible to access a bean and its values In our sample we access a property amount of a property sellingPrice of a bean with name houseOwning lt input id houseOwningForm inSellingPrice class ym g33 ym gl type text onkeyup mojarra ab this event keyup houseOwningForm inSellingPrice houseOwningForm grp ValueReside 2 pu value 0 name houseOwningForm inSellingPrice lt input gt Price the house was sold for 0 3 2 Xtend Since we will use Xtend to write the code generator this chapter describes some basic concepts of the Xtend language However we will not cover all aspects of Xtend in this section for more information see also the official documentation Xtend is a statically typed general purpose language similar to Java Xtend uses Xbase as core language which was already roughly explained in section 2 6 Hence the presented concepts of Xbase are also valid for Xtend The main focus of Xtend lies in providing a language that
37. d files to Java files It does some fancy stuff since Xtend files might have references to Java classes which are not compiled or might even be not compilable before Xtend classes are compiled The plugin therefore scans Xtend files for Java type references and precompiles stub classes These stubs are not complete but enough for Xtend to enable cross referencing these classes Later when Xtend has created the Java sources they are compiled together with the other Java sources by the compiler plugin 5 2 5 QL UI Project POM The POM for the UI project is surprisingly simply Nothing special has to be configured lt xml version 1 0 encoding UTF 8 gt lt project xsi schemaLocation http maven apache org P0M 4 0 0 http maven apache org xsd maven 4 0 0 xsd xmlns http maven apache org P0M 4 0 0 xmlns xsi http www w3 org 2001 XMLSchema instance gt lt modelVersion gt 4 0 0 lt modelVersion gt lt parent gt lt groupId gt org eclipse xtext example ql lt groupId gt lt artifactId gt parent lt artifactId gt lt version gt 1 0 0 SNAPSHOT lt version gt lt relativePath gt pom xml lt relativePath gt lt parent gt lt artifactId gt org eclipse xtext example ql ui lt artifactId gt lt packaging gt eclipse plugin lt packaging gt lt project gt 5 2 6 SDK Feature POM Not mentioned yet but we have prepared also a feature project that bundles the QL and QLS plugins into one feature The feature p
38. e UI module and the UI module is cleaned after the runtime module was build the code is removed again and compilation would fail Further if we clean the project we also want that the generated code in the UI project is removed To solve this build issue the runtime project has to configure the maven clean plugin to clean up sources also from the dependend projects Normally we would need to configure the UI and Tests project to skip cleaning but the code is generated to the src gen folder which is not recognized as an output folder By default the clean plugin just removes the target folder Often project structures are mavenized to follow a standard layout Then the sources would be in src main java 82 oo JO Ct FF wo N Hm No Be LB Be hp RR RA Be RR Rp e O O ON O C FF CQ Nme O 22 23 24 25 26 27 it LWC13 Xtes lt t Submission and generated sources below target e g target generated java And then we would the mentioned issue that cleaning must be skipped for the dependend projects plugin groupId org fornax toolsupport groupId artifactId fornax oaw m2 plugin artifactId lt executions gt lt execution gt lt id gt xtext lt id gt lt phase gt generate sources lt phase gt lt goals gt lt goal gt run workflow lt goal gt lt goals gt lt configuration gt lt workflowEngine gt mwe2 lt workflowEngine gt lt workflowDescriptor gt org eclipse xtext example ql GenerateQl1Ds1
39. eds to be handled in the scope provider of the QLS language We already learned about scoping in section 2 9 The scope provider for the QLS language looks like the following class QlsDslScopeProvider extends AbstractDeclarativeScopeProvider 1 Inject extension QlsDslExtensions def IScope scope QuestionStyling question EObject context EReference ref Scopes scopeFor EcoreUtil2 getAllContentsOfType context form typeof Question The method scope QuestionStyling question is always invoked whenever the visible ele ments for the attribute question in the grammar rule QuestionStyling need to be computed This is for example the case when the content assist needs to compute the elements to be pro posed The method s implementation is quite simple The static method scopeFor expects a list of elements which are in scope visible in the current context For computing the visible elements we use a recursive algorithm to get the form declaration of the parent section or page which is mandatory This algorithm is defined in the Xtend class QlsDslExtensions which is 61 oo 1 oO Ct A wo N R RR Be Be Rp o gt CQ N e O 1t LWC13 Xtes lt t Submission imported in line 3 Note that the expression context form in line 7 will call the correspon ding extension method in Q1sDslExtensions There we use Xtend s polymorphic dispatching feature see also section 3 2 class QlsDslExtensions 4 def dispatc
40. eight fontWeight STRING amp font color fontColor STRING amp font family fontFamily STRING amp widget widget Widget DES 99 it LWC13 Xte t Submission 34 Widget Widget 35 widgetType Radio DropDown CheckBox Text Slider labels STRING labels STRING 36 37 38 Section 39 section name ID uses form ql Form ID 40 element PageElement 41 B 42 43 44 Navigation Navigation 45 navigation nextPage Page ID After reading chapter 2 2 you should be familiar with the concepts of Xtext grammar definitions and understand most parts of the QLS grammar One new concept represented in the QLS grammar is the one of unordered lists HG StyleInformation StyleInformation pee font style fontStyle STRING amp font weight fontWeight STRING amp font color fontColor STRING amp font family fontFamily STRING amp widget widget Widget Je os o 1 QA Ct g uN The styling information can be defined in an arbitrary order in which each kind of element font style font color and so on may only occur at most once The arbitrariness of the order is expressed by the amp between the style elements The optionality of each style information is again declared by the question mark A further noteworthy aspect is the handling of references In Xtext references to language
41. elements are expressed by using squared brackets An example for this are the references to existing pages in the navigation section Navigation Navigation navigation nextPage Pagel ID 60 o o Oo Ct FF C Ne E o 1t LWC13 Xtes lt t Submission Here nextPage is a reference to an existing page description which may even be defined in a different file ID defines which attribute should be used for the reference s name Xtext auto matically creates hyperlinks to the referenced elements which can be enabled by holding Ctrl and moving the curser over the reference or by pressing F3 To define references to elements defined in other langauges than the own the reference needs to be qualified An example in QLS is the reference to questions or forms defined in a QL model To express this on the grammar level the QL DSL needs first to be imported import http www eclipse org xtext example q1 Q1Ds1 as ql Since the QL DSL is imported under the name ql references can now be qualified by using a double colon QuestionStyling question question ql Question styling StyleInformation This grammar rule allows for refering all question elements defined in any QL model in our test project However since there is always an unambiguous form specified for a page or a section only the questions defined within this form should be referable This is a typical scoping issue which ne
42. enerated Run the GenerateQlDsl mwe2 workflow again Then restart the runtime workbench Xbase comes out of the box with the support for standard Java types like Strings or Integers inside expressions However in the questionnaire language own data types like the Money type from the example need also to be integrated Such data types will be typically defined in a Java class When importing such a type via the import statement it will be available in the questionnaire definition Xbase needs to know how to handle these types when they are used and The logic for these operators need to in expressions with operators like be implemented in special methods in the data type itself As example let s see how this is achieved for the Money type package types import java math BigDecimal public class Money private BigDecimal amount public Money BigDecimal amount this amount amount Select it from the Run Run Configurations dialog or from the drop down menu next to the green play button in the tool bar 5http code google com a eclipselabs org p lwci3 xtext source browse examples QLTest src types Money java 26 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 it LWC13 Xte t Submission Y public BigDecimal getAmount return amount Implement operators public Money operator_minus Money other return new Mon
43. eption and add the following lines as first statements to prevent execution of the generator if the file extension does not fit if input URI fileExtension q1 return After this pre condition is passed we want to execute the generator logic for our model so it is a good idea to save the models root node in a variable 1 val questionnaire input contents head as Questionnaire Because we want to generate JSF artifacts into the WebContent folder in the following steps we let Guice add a JSFOutputConfigurationProvider extension to our JSFGenerator 51 e N RA P N RA O o N Oo Ct 10 cU F cC N it LWC13 Xte t Submission class JSFGenerator implements IGenerator Inject extension JSFOutputConfigurationProvider After this we have the possibility to use the WEB_CONTENT outlet constant as described in section dO The following section 3 3 3 will describe the different extensions of the JSFGenerator which are responsible to generate the JSF artifacts described in 3 1 In a real world project it can be a good decision to seperate different artifacts in different Xtend files Our sample is a very simple one so we will add a new extension definition derived from the sample below to the JSFGenerator xtend class which encapsulates the logic to generate a single artifact def generate Artifact EObject modelInfo lt xml version 1 0 encoding UTF 8 7 lt genera
44. erate for you 3 projects into your workspace 12 it LWC13 Xtes lt t Submission Y 4 2 org eclipse xtext example ql v GS src v t amp org eclipse xtext example ql EF GenerateQIDsl mwe2 A QIDsI xtext G9 src gen 9 xtend gen gt BAJRE System Library J2SE 1 5 gt BA Plug in Dependencies gt 2 META INF Ex build properties 5 i org eclipse xtext example ql tests gt 2 org eclipse xtext example ql ui org eclipse xtext example ql This is the Runtime Project which holds the language definition and any implementation which is not UI dependent Most of the implementation details of this tutorial will be done in this project org eclipse xtext example ql tests This project is intended to hold test code for the language Tests are implemented with JUnit Xtext will generate some infrastructure code required for tests into here We will deal testing of DSLs at the end of this tutorial For now you can close this project if you want org eclipse xtext example ql ui Xtext produces a language specific text editor The editor is an Eclipse plugin While the runtime part of the language could be used in any UI or even from command line the Editor is dependent on the Eclipse platform All projects are almost empty right now Only the Runtime Project contains two important files in the src folder e GenerateQlDsl mwe2 This is a so called MWE2 Workflow MWE is short for Modeling Workflow Engine
45. erator import org eclipse emf ecore resource Resource import org eclipse xtext generator IFileSystemAccess class JSFGenerator implements IGenerator override doGenerate Resource input IFileSystemAccess fsa throw new Unsupported perationException TOD0 auto generated method stub 50 11 12 oo Oo Ct A C Ne NOR HH Ra Be Be RA Rp O O Ct A C N e O it LWC13 Xtes lt t Submission To get the created JSFGenarator executed we have to inject and dispatch to it in our dispatcher template Root java which was created in section 3 3 1 earlier package org eclipse xtext example ql generator import javax inject Inject import org eclipse emf ecore resource Resource import org eclipse xtext generator IFileSystemAccess import org eclipse xtext generator IGenerator import org eclipse xtext xbase compiler JvmModelGenerator public class Root implements IGenerator Inject JvmModelGenerator jvmModelGenerator Inject JSFGenerator jsfGenerator public void doGenerate Resource input IFileSystemAccess fsa dispatch to other generators jvmModelGenerator doGenerate input fsa jsfGenerator doGenerate input fsa Now it is time to add some functionality to the JSFGenarator Open the file JSFGenarator xtend and go to the doGenerate extension which is responsible to generate artifacts Delete the auto generated body of the extension initially it just throws an UnsupportedOperationExc
46. ersion gt 1 0 0 SNAPSHOT lt version gt lt relativePath gt pom xml lt relativePath gt lt parent gt lt artifactId gt org eclipse xtext example ql lt artifactId gt At the beginning we have the typical Maven coordinates and parent dependency The Parent POM is at the root of the repository which is 2 directories up The POM one directory up is the Reactor POM Note that it is important to mention here the exact same version as declared in the Parent POM This module inherits the parent s version and groupld coordinates only the artifactId changes Maven Tycho enforces that the POM version matches Bundle Version and the artifactId must be equal to the Bundle SymbolicName of the manifest A bit special are SNAPSHOT versions which is a special Maven concept for intermediate development versions of artifacts When the project version is a snapshot version the bundle version must have an additional qualifier In our case here the project version is 1 0 0 SNAPSHOT which means the bundle version must be 1 0 0 qualifier The qualifier gets replaced at build time by a timestamp Bundle Name org eclipse xtext example ql Bundle Version 1 0 0 qualifier The next entry packaging is especially important 1 lt packaging gt eclipse plugin lt packaging gt 80 HG ory nwa A A Ww N 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 it LWC13 Xte t Submission
47. es lt t Submission 11 lt plugin gt o o 1 Oo Ct FF Ww NR D DD N NN NM ON Ro Be Be Ro Be Be pop ao Ov F Ww N e O 0 0 Io ro Nme O oo Jl aw A A O N rn Supported Target Environments Eclipse is partially OS dependent Which platforms should be considered in the target platform configuration is configured with the target platform configuration plugin plugin lt groupId gt org eclipse tycho lt groupId gt lt artifactId gt target platform configuration lt artifactId gt lt version gt tycho version lt version gt lt configuration gt lt resolver gt p2 lt resolver gt lt pomDependencies gt consider lt pomDependencies gt lt environments gt lt environment gt lt os gt win32 lt os gt lt ws gt win32 lt ws gt lt arch gt x86 lt arch gt lt environment gt lt environment gt lt os gt win32 lt os gt lt ws gt win32 lt ws gt lt arch gt x86_64 lt arch gt lt environment gt lt environment gt lt os gt macosx lt os gt lt ws gt cocoa lt ws gt lt arch gt x86_64 lt arch gt lt environment gt lt environments gt lt configuration gt lt plugin gt Java Source Code version The produced code requires Java 1 6 for compilation This needs to be configured at the tycho compiler plugin lt plugin gt lt groupId gt org eclipse tycho lt groupId gt lt artifactId gt tycho compiler plugin lt artifactId gt lt version gt tycho version lt version g
48. example if you are at some point where a reference to another entity must be inserted your DSL editor shows you all the references that would be valid here according to your language rules and lets you choose among them All in all using the DSL editor generated by Xtext it is quite easy to establish a text file that adhers to your DSL Depending on your language s type you could call this text file e g a model a document a program or whatever We will refer to DSL files here as models files Consider now that you have created a model What can you do with it A typical requirement is to generate an implementation of it in a language like Java C or XML Or a graphical representation Or something quite different This is where code generation comes in Xtext creates a skeleton code generator for you Typically you use that code generator as a starting point to produce e g Java source code documentation in say DocBook or Wiki format over view graphics using GraphViz or any other stuff you need Xtext offers special support for textual output formats but it is also possible to generate binaries This was only a short outline of some prominent Xtext aspects It is by far not everything Xtext can do for you but it should suffice for now The next chapters will show you in more detail how to work with Xtext 2 2 Create the DSL Projects Let s start creating the projects for the Questionnaire DSL Open the New Project W
49. ey this amount subtract other amount public Money operator_plus Money other return new Money this amount add other amount public Money operator_multiply Money other return new Money this amount multiply other amount public Money operator_divide Money other return new Money this amount divide other amount The data type Money simply holds the amount as a value of type BigDecimal For each operator a special method e g operator_minus Money other defines how to procede when this ope rator is used two values of type Money In this simple example a new Money object is created and its value is computed corresponding to the operator type When evaluating an expression Xbase searches for these methods inside the used types to compute the result In order to test the new version of the questionnaire language the MWE workflow needs to be executed again Right click on GenerateQlDsl mwe2 Run As MWE2 Workflow The questionnaire language now supports expressions but there is still one point missing Questions cannot be referenced within an expression For this we need to derive a JVM model from the questionnaire model which we will discuss in the next section 2 8 JVM Model Inference For languages using Xbase it is necessary to tell Xtext how to map concepts of a language to a Java model In our example a Form could be mapped to the Type concept while Questions are the fields of a class By d
50. file 62 HG it LWC13 Xtes lt t Submission e Generate one XHTML file wiring all form XHTMLs together and reference CSS file Let s take the following QLS model as a reference example page HouseOwningPage 1 section house uses HouseOwning question hasBoughtHouse font style italic question valueResidue font weight bold 42233FF font family Verdana font color os o JJ Det g C2 Ww Nl ND Be rne Be Be RR RA a RR Rp O vo ON Oot FF CQ NR O 3 section garage uses Garagelwning question hasBoughtGarage widget Radio Yepp Nope navigation CarOwningPage page CarOwningPage uses Car wning question hasSoldCar font color green question hasBoughtCar font color red 5 The intended generated file structure is visualized Y amp WebContent in the screenshot on the left The files in the fol v amp generated v forms der forms are generated by the QL model to code 2 CarOwning xhtml E CarOwningBase xhtml GarageOwning xhtml iit generator as described in chapter 3 The code ge nerator for the QLS model needs to generate the B GarageOwningBase xhtml E HouseOwning xhtml XHTML files under the folder pages and the CSS BH OwningBase xhtml SL n Mm files in resources default css generated The file vip pages pages index xhtml serves as root page containing the CarOwningPage xhtml E HouseOwningPage xhtml El index xhtml Y
51. gt lt pluginRepositories gt lt profile gt lt profiles gt lt settings gt The settings file is placed in the repository under devenv lwc13 devenv settings xml In order to use this settings file it has to be put to HOME m2 or passed with the s option to the mvn command 5 2 2 Parent POM Since Maven supports a simple POM inheritance it is common to extract common settings for a set of project modules into a so called Parent POM This pom xml fil is placed in the root of the repository The Parent POM is responsible for different things e Definition of the common group identifier and version 1 lt groupId gt org eclipse xtext example ql lt groupId gt 2 lt version gt 1 0 0 SNAPSHOT lt version gt e Tycho Plugin configuration Note the lt extensions gt true lt extensions gt entry To make the Tycho version that is used easier configurable a property tycho version is defined which is used for all Tycho plugin configurations 1 lt properties gt 2 lt tycho version gt 0 17 0 lt tycho version gt 3 lt properties gt 4 lt build gt 5 lt plugins gt 6 lt plugin gt 7 lt groupld gt org eclipse tycho lt groupId gt 8 lt artifactId gt tycho maven plugin lt artifactId gt 9 lt version gt tycho version lt version gt 10 lt extensions gt true lt extensions gt C http code google com a eclipselabs org p lwci3 xtext source browse pom xml TT LWC13 Xt
52. h Form getForm Section section 1 if section form null section form Y else section eContainer form Jr def dispatch getForm Page page page form 5 Note that for the first method the return type Form needs to be declared explicitly since it is recursively calling itself in line 8 and thus its return type cannot be derived automa tically The calculated form is used in the scope provider as input for the helper method getAllContentsOfType which is used to collect all questions defined in the given form Now it s time to play around with the QLS language and to test its features For this switch to the test project in the runtime environment see also section 2 5 and create a file with the file extension qls 4 2 QLS Code Generator So far our QLS models have no effect on the generated output The first step is to think about which artifacts are to be generated from a QLS model The QLS model contains two kinds of information The first is layout information A page consists of one or more forms Recall that for each form two XHTML files are already generated one for the base content of the form site and a wrapper referencing this base XHTML Hence a page maps to an XHTML file which is composed of all specified forms The second information in QLS is styling information As usual in web development styling is expressed in the CSS format in our tool To sum up the actions for each page e Generate one CSS
53. ication Right click on the index file and press Run As Run On Server In the next dialog choose the Tomcat server which you should have configured in section 3 1 1 if not then now is the time to do it and press Nezt If your test project is not already in the Configured area then it needs to be moved there by using the Add gt button Finally press F inish to start the application in the integrated browser within eclipse You can also copy the link and paste it in a web browser of your choice The result should be similar to the one on the next screenshot 56 itemis LWC13 Xte zt Submission a amp _http localhost 8080 org eclipse xtext example base jsf generated forms HouseOwning jsf gt gt E Language Workbench Challenge 2013 Xtext Submission HouseOwning Form Did you sell a house in 2010 Did you buy a house in 2010 Did you enter a loan for maintenance reconstruction Price the house was sold for 172000 Private debts for the sold house 42000 Value residue 130000 Now it s show time You can modify your QL model and save it The XHTML files will be regenerated on the fly The server needs some seconds to reload the backing beans Afterwards you can press the Refresh button and see the result immediately 97 o o 1 Oo Ct gt WwW Ne NV Rh LB LB RR RR RR Rp O d ON Oo oa A CQ N e O it LWC13 Xtes lt t Submission 4 Layout and Styling Language QLS 4 1 The Language QLS In this
54. ileName resources default css generated page name css fsa generateFile cssFileName WEB CONTENT cssContent val xhtmlContent generateXhtmlFile page val xhtmlFileName generated pages page name xhtml fsa generateFile xhtmlFileName WEB CONTENT xhtmlContent val contentIndex generateIndexPage styleModel pages get 0 fsa generateFile generated pages index xhtml WEB CONTENT contentIndex def generateCssFile Page page lt Ogenerated gt FOR styleInfo page eAllContents filter typeof StyleInformation toList styleInfo id IF styleInfo fontColor null color styleInfo fontColor ENDIF IF styleInfo fontFamily null gt font family styleInfo fontFamily ENDIF IF styleInfo fontStyle null font style styleInfo fontStyle ENDIF IF styleInfo fontWeight null font weight styleInfo fontWeight ENDIF Jr ENDFOR 22 19 def generateXhtmlFile Page page SL NEOsenendtedE gt lt html xmlns http www w3 org 1999 xhtm1 xmlns ui http java sun com jsf facelets xmlns h http java sun com jsf html xmlns f http java sun com jsf core gt lt h head gt lt h head gt lt ui composition template index xhtml gt lt ui define name content gt lt h outputStylesheet library default css generated name page name css gt 65 45 46 4T 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
55. ined in class JsfOutputConfigurationProvider 49 o o 1 Oo Ct FF C t m E o 1t LWC13 Xte t Submission 3 3 3 JSF Generator After creation of the class Root in section 3 3 1 where we easily can add new Generators and the defintion of the JsfOutputConfigurationProvider in section 3 3 2 which prvides an output folder for JSF artifacts we use the New Xtend Class Wizard to create a new Xtend class called JSFGenerator xtend in package org eclipse xtext example ql generator This class will be our entry point to generate JSF related artifacts The New Xtend Class Wizard provides the possibility to bind interfaces to the new class by use of the Add button near the interface section 8 Xtend Class e e te Xtend Class NY 4 Create a new Xtend class S Source folder org eclipse xtext example ql src Browse Package org eclipsextext example ql generato Browse Name JSFGenerator Superclass java lang Object Browse Interfaces e org eclipsextext generator IGenerator Add Remove As we want to create a new generator we add the interface org eclipse xtext generator IGenerator to our new Xtend class After typing in the package the name and the interface of our new Xtend class as shown in the figure above we can finish the wizard so that the class shown in the following listing will be created in our project package org eclipse xtext example ql generator import org eclipse xtext generator IGen
56. input input input def useExtension 16 square returns 256 y What Xtend basically does is changing the syntax of how methods are called Instead of writing toLastUpper Hello Xtend always offers the alternative to use the first input parameter as receiver of the method call Hello toLastUpper This results in the syntax being more chained than nested which improves readability To use methods from another class as extension methods in your class the field defining an object of the other class needs to be marked with the extension keyword In our scenario we will use dependency injection like the following class MyGenerator implements IGenerator Inject extension IJvmModelAssociations This statement simply allows to use the methods declared by the interface IJvmModelAssociations in our generator class as extension methods on our objects Which 44 oo 1 Oo Ct A wo N m e Rp wow N e Cc 1 2 it LWC13 Xtes lt t Submission concrete implementation of the interface is later actually called is configured in the Guice module A further useful feature of Xtend is polymorphic dispatching Using the dispatch keyword on multiple methods with identical signatures has the effect that the decision on which method should be called is based on the runtime type of the target object In contrast Java binds methods at compile time based on the static type of the target object Since Xtend compiles
57. is more readable than Java in certain situations In the background Xtend compiles to Java code Thus it plays perfectly together with Java e g methods declared in Java classes can be called in Xtend and vice versa Several concepts of Xtend are especially beneficial when writing code generators 38http www eclipse org xtend documentation html 43 a Ct 5 N HH ND C CQ Ne e N RP it LWC13 Xte t Submission def someMethod 4 var myQuestion where do we go myQuestion myQuestion toFirstLower val myAnswer 42 The answer for question myQuestion is myAnswer In Xtend a method is defined with the def keyword The return type is optional and will be automatically inferred Only when a method is recursively invoking itself a return type needs to be specified explicitly The keyword var defines a variable constant values are defined with val In Xtend since it is based on Xbase everything is an expression meaning that it has a return type Consequently the last expression of a method defines the return value and also the return type of the method In line 3 a so called extension method is used Recall that the String class in Java does not provide a method toFirstUpper Xtend allows for extending closed types without changing them maybe you already guess where Xtend got its name from You can easily write your own extensions e g for the Integer type def square Integer
58. ission Model types The additional keyword extension has the effect that the methods of the JvmTypesBuilder become so called extension methods This means the functions become implicitly available as additional methods on the first argument of the function We will see extensive use of this nice feature of Xtend in the implementation of the Xtend based code generator in the next chapter TypeReferences is used to retrieve the respective JVM Model instances for given qualified Java class names through its getTypeForName methods for form element forms 1 acceptor accept form toClass forms form name initializeLater Let s take a deeper look on the infer method The outer loop simply iterates over the Form instances of the Questionnaire element Inside the loop we first derive a Class instance for each Questionnaire element in package forms JVM Model Inference is executed in two phases In the first phase all types are derived without any content In the second phase the content of the types is derived This is done by the closure passed to initializeLater The reason why this has to happen this way is that during inference of type members they could refer again to types that are derived by the inferrer The two phases prevent circular calls it superTypes typeReferences getTypeForName typeof Serializable element null members toField serialVersionUID typeReferences getTypeForName long
59. izard with File New Project Choose Xtext Project and press Next 11 it LWC13 Xtes lt t Submission eoo New Xtext Project New Xtext Project gt This wizard creates a couple of projects for Xtext DSL Project name org eclipse xtext example ql M Use default location Location Users thoms Development workspaces runtime lwc13 org eclipse xtext example Browse Language Name org eclipse xtext example ql QIDs Extensions ql Layout A Generator Configuration Use Provisional API Compare Refactoring and new Serializer gt _ Create SDK feature project Working sets _ Add project to working sets Working sets gt Select Back Next gt Cancel Finish On the project wizard page enter 1 Project name org eclipse xtext example ql Xtext will create multiple projects which share this prefix It is a convention to use a lowercase dot separated name 2 Language name org eclipse xtext example ql Q1Dsl This is an identifier for the language which must be unique and follows a Java full qualified identifier name pattern 3 Language Extensions ql This will be the file extension for DSL files 4 Uncheck the option Create SDK feature project It would not harm to have that checked it would just create an additional Feature Project which we do not handle in this tutorial any further Now press Finish Xtext will gen
60. ll members toField serialVersionUID typeReferences getTypeForName long element final true static true setInitializer it append 1L 1 val allQuestions form eAllContents filter typeof Question toList for question allQuestions 1 members question toField question name question type for question allQuestions if question expression null members question toGetter question name question type members question toSetter question name question type else val getter question toGetter question name question type getter body question expression members getter 5 members question createlsEnabledMethod val allQuestionGroups form eAllContents filter typeof ConditionalQuestionGroup toList var groupIndex 0 for questionGroup allQuestionGroups members questionGroup createIsGroupVisibleMethod groupIndex groupIndex groupIndex 1 29 60 61 62 63 64 65 66 67 68 69 70 71 72 73 P N e al 1t LWC13 Xtes lt t Submission def Jvm peration createIsEnabledMethod Question question question toMethod is question name toFirstUpper Enabled typeReferences getTypeForName boolean question null body it append return question expression null Create a method lt code gt public boolean isGroup groupIndex Visible lt code gt def Jvm peration createIsGroupVisibleMethod C
61. lly From this reference code the templates can be derived Also this is a manual step We use a Java Server Faces JSF see 1 2 based 4 e org eclipse xtext example gl referenceimpl a Deployment Descriptor org eclipsextext example ql referencei a 8 Java Resources 4 src EH default package 4 EN converter J MoneyConverter java 4 iH forms J HouseOwning java a iB types J Money java J TypeFactory java gt BA Libraries El JavaScript Resources gt metadata amp settings build 4 2 WebContent 4 amp forms HouseOwning xhtml index xhtml a 2 META INF E MANIFEST MF 4 gt resources 4 3 default 4 gt img E jsfjpg tomcat v7 jpg Ba WebToolsPlatform png Ma xtext logo color 800 small png 4 2 templates defaultLayout xhtml footer xhtml header xhtml 4 WEB INF 4 gt lib javax faces jar a javax servlet jsp jstl 1 2 2 jar 4 javax servlet jsp jstl api 1 2 1 jar TH faces config xml Xj web xml index xhtml X classpath _ gitignore X project v pom xml application which can be deployed on any Java Web container also known as a Servlet contai ner like Glassfish JBoss and Apache Tomcat The screenshot shows the structure of the web application project The application is available for download from the project homepage JSF QL 1 0 zip Large parts of the application are not derivable from the model they build the skeleton of the project This is C
62. load Xtext separately and install it in your Eclipse instance e You can download a specially crafted complete Eclipse distribution which has Xtext pre packaged already We will take the latter approach here and describe the individual steps 1 Go to the Xtext download page Here you can get Eclipse 4 2 x Juno including Xtext 2 3 1 along with some tools Xtext depends on The latter are subsumed here under Xtext for simplicity If you want you can download also a distribution which is already bundled with Eclipse 4 3 0 Kepler but be aware that this is not finalized until end of June 2013 2 The Eclipse Xtext distribution is available for multiple platforms a Linux GTK x86 64 bit b Linux GTK x86 32 bit c Mac OSX x86 64 bit d Windows 64 bit e Windows 32 bit 3 Unpack the downloaded archive file in a directory of your choice Example Linux 1 cd opt local 2 gzip dc download eclipse SDK 4 2 Xtext 2 3 1 linux gtk x86 64 tar gz tar 3 xvfp The archive will be extracted to a new directory named eclipse Before unpacking the ar chive please ensure that there is no subdirectory named eclipse yet Different operating systems may require different unpacking methods 4 Start Eclipse by running the eclipse executable in the newly created eclipse directory 1 4 Workspace Setup Before we begin start Eclipse and set up a fresh workspace Some settings should be done Open the workspace settings e Windows
63. lt t Submission Document History Version 0 1 2013 01 28 Initial creation Version 1 0 2013 04 08 e Final version for the Language Workbench Challenge workshop in Cambridge it LWC13 Xtes lt t Submission Table Of Contents 1 Introduction 6 Ll Task Description sa siese rd ase e e taa EOS 6 12 Techiologey e seoseta aar da aa A 6 13 Installing Eclipse and Xtext s sc ice a 2 bee a han eben RR 8 l4 Workspace DOMED oia E 493 4 he webb RUROX A 8 Workspace Encoding o sec sca 44 zu a hoo ERD as aaa 9 Launch per ar arterielle ee MRS SERS CEES 9 Developing the Questionnaire Language 9 B DIOR UNETE ec eee ae ow ee ee eee are 9 22 Create the DSL Projects lt e ka scs 24 22 Ha qeges e wa we Tw ana an 11 2 3 Defining the Grammar 224 oce ox 44444 aan Een nee 14 2 4 Generate Language Implementation o 17 R ntime Project folder SFO s c 2k ca 4 1 204 ar aa EE RES 18 Runtime Project folder SEc gen 22 225299 EY Rs 18 2 5 Testing the Questionnaire Language HE Emmen 19 2 5 1 Creating a Launch Configuration s ss e se sect eh eee RR 19 2 5 Create Test Pre S uuu iots ee ab O ore ec a en 20 ZB JOB oer aa a uem deo RO ea AER Ee de OA EHS Oe ED 22 2 7 Including Expressions into the QL Language o nn nn 24 2 8 JVM Medel Inference o ki ged pep Roy Go Red AA A 27 29 SCOPS PIC 34 Developing the Code Generator 35 3 1 Reference Implementation m mm m nn 30 olr A
64. ly made conditional with an if condition ConditionalQuestionGroup ConditionalQuestionGroup if condition XParenthesizedExpression element FormElement DE Compared to the grammar defined in section 2 2 the follwoing points have changed FormElement Question ConditionalQuestionGroup A FormElement is now either a normal question or a ConditionalQuestionGroup Conditional question groups are groups of form elements embraced by an optional if condition ConditionalQuestionGroup ConditionalQuestionGroup 25 pp w N HG os ON Oo u FF uN it LWC13 Xte t Submission if condition XParenthesizedExpression element FormElement sat For the condition of the if statement the grammar rule XParenthesizedExpression inherited from Xbase is used An XParenthesizedExpression is simply an expression in parenthesis The if statement is optional as defined by the question mark symbol which allows for just grouping questions without the necessarity for a condition The inner elements are again FormElements making it possible to nest groups within groups and so on The last part that has changed is the Question rule Here again the rule XParenthesizedExpression is used to optionally embed Xbase expressions Question name ID label STRING type JvmTypeReference expression XParenthesizedExpression After changing the grammar the implementation has to be reg
65. m ide iv P Mwe workflow O Run an application org eclipse ui ide workbench Y P Mwe2 Launch BD Generate Language Infr Java Runtime Environment P Generate Language Infr 4 OSGi Framework Java executable e default java ju Task Context Plug in Test R I Jy Task Context Test Execution environment J2SE 1 5 Java SE 7 MacOS X Default Environments Q Runtime JRE Java SE 7 MacOS X Default Installed JREs Bootstrap entries Apply Revet Filter matched 20 of 21 items O close Eng Now switch to the Arguments page and enter in the VM arguments text box 1 Xms40m Xmx512m XX MaxPermSize 150m Especially important is the MaxPermSize setting since the default size of the PermGen space of the VM 64MB often is not enough Now press the Run button Another Eclipse instance will start with an empty workspace Close the Welcome window 2 5 2 Create Test Project In the Runtime Workspace create a new Plug in Project with name QLTest 2 As before uncheck the options on the second wizard page 20 oo Jl OO Ct gt Ww Ne e Be Be rne H CU F CQ N e O oo a C2 N m it LWC13 Xte t Submission The DSL has to support custom datatypes like Money which must be defined Select the src folder and create a new Java class Money in package types package types import java math BigDecimal public cla
66. multaneous Release Plan LWC13 Xte t Submission Questionnaire Application The developed code generator will generate JavaServer Faces 2 1 JSF pages in XHTML file format JSF is part of the Java Enterprise Edition Java EE It is useful to have a basic understanding of how web applications work even if JSF provides a nice level of abstraction The JSF reference implementation from Oracle Mojarra 2 1 68 is able to run within the well known Servlet container Apache Tomcat v7 0 In order to not reload the whole page whenever some content needs to be updated e g optional questions need to be displayed depending on other questions answers we will use AJAX The following screenshot shows the resulting application a WC Xtext XN A a amp http localhost 8080 org eclipse xtext example base jsf generated forms HouseOwning jsf H gt Language Workbench Challenge 2013 Xtext Submission HouseOwning Form Did you sell a house in 2010 Did you buy a house in 2010 Did you enter a loan for maintenance reconstruction Price the house was sold for 172000 Private debts for the sold house 42000 Value residue 130000 1t 2008 2013 itemis AG http www javaserverfaces org Shttp javaserverfaces java net 9http tomcat apache org it LWC13 Xtes lt t Submission 1 3 Installing Eclipse and Xtext Xtext is a SDK for the Eclipse IDE To install it you have two options e You can down
67. n INFO emf mwe2 runtime workflow Workflow Done 17 it LWC13 Xte t Submission After successful execution the projects will be filled with implementation code Code that will be regenerated each time the generator is executed will go to the source folder src gen in all three projects whereas code generated to src will be generated only once as skeleton It is safe to edit these classes Xtext follows the Generation Gap Pattern Generated code is based on the Xtext API Manual code is separated from generated code Often manual classes are derived from generated classes to allow overriding of generated code or adding functionality Investigate the generated code a bit Some pieces to mention Runtime Project folder src The class Q1Ds1RuntimeModule is a Guice configuration Guice is a famous Dependency Injection framework in Java Xtext makes heavy use of Dependency Injection which in turn allows to exchange nearly every bit of the framework for customizing or to work around limitations if necessary without the need to change the framework itself Class Q1Ds1StandaloneSetup is needed when using the language in standalone mode ie without an Eclipse environment Eclipse plugins like Xtext and the language plu gin usually need an OSGi container as execution environment Xtext is designed to be executable without the need to be deployed into an OSGi container but for this certain registrations are req
68. ne amp name content lt ui insert gt lt div gt lt div id footer gt lt ui insert name footer gt lt ui include src resources default templates footer xhtml gt lt ui insert gt lt div gt lt body gt lt html gt We added two facelets insert sections to give the possibility to replace the header and footer To simplify the concrete JSF compositions later we let JSF include default content for both by use of facelets include for a fixed source src Our structural layout definition which is composed by using resources default templates defaultLayout xhtml as template in WebContent resources default has a Cascading Style Sheet CSS where fine grained layouting can be done 35http de wikipedia org wiki Cascading_Style_Sheets 39 it LWC13 Xtes lt t Submission 4 y WebContent Ey forms Ey META INF 4 oy resources 4 oy default 4 Ey css Ej base css EJ container css Ey img m templates Ey WEB INF Ey indexxhtml The applications style sheets consist of 2 files container css defines styles for main page elements basically we took the style of http www itemis de e base css defines extended elements like grids see http www yaml de docs Because we are not focusing on layout topics we just did some small things to integrate the style with the contents like adding CSS classes to XHTML elements The CSS definitions are added to show how dividing of c
69. ner InjectWith typeof Q1DslInjectorProvider class Q1DslValidationTest Inject extension ParseHelper lt Questionnaire gt parseHelper Inject extension ValidationTestHelper Now the test methods can be implemented They are super simple QTest def void testValidation CallBeforeDeclaration expectSuccess Y form Foo 4 x foo boolean di ES Las LEY OOille ania 74 8 9 it LWC13 Xtes lt t Submission parse assertNoErrors Due to the tight Java integration the unit tests of the Xtend class can be executed by running them through the context menu Run As JUnit Test LI org eclipse xtext example gl validation test QlDslValidationTest testValidation AssignmentTyr Y a 68 2 Be Runs 6 6 El Errors 0 Failures 0 bi org eclipse xtext example ql validation test QIDs ValidationTest Ru nner JUnit 4 1 5 30 s j tEjtestValidation CallBeforeDeclaration expectError 0 662 s El testValidation_CallBeforeDeclaration_expectSuccess 0 213 s dEltestvalidation_ConditionTypeCheck_expectError 0 189 s dEltestvalidation_ConditionTypeCheck_expectSuccess 0 216 s dEltestvalidation_AssignmentTypeCheck_expectFailure 0 129 s dEltestvalidation_AssignmentTypeCheck_expectSuccess 0 121 s I Package Explorer 5 Navigator fg Type Hierarchy 5 2 Build The build of software products is usually done on build servers without manual interaction In the Eclipse ecosystem several build
70. nts Almost every peace in Xtext is highly customizable and it is one of the most flexible frameworks we know of This flexibility comes to the price of complexity Xtext is well documented by the reference manual several blogs show advanced concepts in detail and hundreds of projects solve different real world requirements Many open projects exist which are worth studying Learning Xtext does not mean following a single tutorial it needs training The sources and the debugger are valuable friends when solving issues The community around Xtext is very helpful and likely the largest of all language 87 it LWC13 Xtes lt t Submission workbenches We hope that this document was helpful for you to understand some concepts of Xtext and gave you the right level of abstraction to learn how to use this tool If we helped you to decide to use Xtext or Xtend in your project then it was worth the effort and we would be pleased to hear from you Karsten Thoms Johannes Dicks Thomas Kutz April 2013 88
71. o a ee Re Rx RE wea ee ERE Ronde nie o 85 D Continuous Ineo ss oes sa ee A EROR CR 86 6 Closing Words 87 it LWC13 Xtes lt t Submission 1 Introduction 1 1 Task Description The LWC13 task is to implement a DSL for questionnaires Questionnaire Language QL which basically allows the definition of forms with questions We assume that you have read the LWC13 assigment document carefully before continuing reading this document 1 2 Technology Stack This tutorial expects that you are somehow familiar with Java and Eclipse and have heard about EMF and how it works in general before We start almost at the beginning but not quite Grammar Definition We will use Xtext 2 4 0 which is at the moment of writing the latest official release Xtext 2 5 is in preparation and will be released with Eclipse Kepler in June 2013 The solution approach described here would work also with any version of Xtext gt 2 0 but the API might differ slightly so there is no guarantee that each codeline printed here would work exactly with all versions For better reproduction it is highly recommended to use the versions mentioned above Code Generator For Code Generation we will use the language Xtend which itself is based on Xtext Xtend makes use of a common expression language shipped with Xtext called Xbase The languages developed here will also be based on Xbase but more on this later 8http wiki eclipse org Kepler Si
72. oing this elements of the language can be made available in expressions Further it allows that model elements are linkable where Java types are expected without necessarily generate a Java class 27 o o 1 Oo Ct FF C Ne Boe e RR Be Rp N O Ct Pp CQ Ne O it LWC13 Xte t Submission The derivation of the Java model for language concepts is the responsibility of the JVM Mo del Inferrer which is a class that implements the IJvmModelInferrer interface A skeleton has already been generated into package org eclipse xtext example ql jvmmodel The file Q1DslJvmModelInferrer xtend is a class written with Xtend The mapping that has to be implemented for the Questionnaire DSL should be as follows 1 Each Form instance is mapped to a JvmDeclaredType which is the common concept for Java classes and interfaces The type s name is simply the form name and the target package is forms 2 Each Question of a Form is mapped to a JvmField which is added as member of the declared type 3 For each Question accessor methods for the field are generated The field gets only a setter if the value of the Question is not computed by an expression If the field is computed the content of the getter has to compute the result 4 For each Question a method is lt QUESTIONNAME gt Enabled is inferred Questions with computed values are not enabled 5 For each ConditionalQuestionGroup a method is produced that computes whether the grou
73. onditionalQuestionGroup group int groupIndex group toMethod isGroup groupIndex Visible typeReferences getTypeForName boolean group null if group condition null 4 body group condition else body it append return true Now lets take a deeper look at the implementation class Q1DslJvmModelInferrer extends AbstractModelInferrer Inject extension JvmTypesBuilder Inject TypeReferences typeReferences def dispatch void infer Questionnaire element IJvmDeclaredTypeAcceptor acceptor boolean isPreIndexingPhase 4 The inferrer class implements IJvmModellnferrer but for convenience we derive from its abstract implementation AbstractModelInferrer The main method to implement is infer In the case of QL models the root element of model resources is a Questionnaire The base implementation uses polymorphic dispatching on the root element of a model resource and the infer method of our implementation hooks into the dispatching by using the dispatch keyword That is also why the first argument can be of type Questionnaire and not of the base type EObject like defined in the infer method that is definied in IJvmModelInferrer The implementation uses two services which are injected as members into the class e The JvmTypesBuilder offers factory and builder functions to create instances of JVM 30 HG a u FF C N Q Ct amp Ww NR CU e C N rn it LWC13 Xte t Subm
74. ontent and styles can be done 3 1 4 Reference Forms The basic structure of our web application was described in the previous sections This was the part of the application which was very general and can be reused for any other application In the following we will describe the specific content which enables the questionnaire application specified in the LWC 2013 task description The questionnaire content basically consist of 3 main artifacts a 2 Java Resources 4 88 src e WebContent forms index xhtml a link for each form will 4 Hj converter D ren be available here it uses WebContent index xhtml as tem 4 Hj forms plate and will be the template for concrete forms in our A HouseOwning java EP a es application n Money java N TypeFactory java e WebContent forms House Owning xhtml this file will im bes Fue plement the questionnaire form it uses ava cript Resources build WebContent forms index xhtml as its template 4 y WebContent 4 i forms e src forms HouseOwning java the so called BackingBe EJ HouseOwning xhtml E index xhtml Ey META INF Sy resources 40 Ey WEB INF E index xhtml o o 1 Oo Ct A C Ne ho Rp N e Oo 1t LWC13 Xtes lt t Submission an 9 which holds the state of a questionnaire form Within the reference application there are 3 additional artifacts which can be seen as some kind of utils e Money java a custom type that can be used in a bean e MoneyConverter java a custom c
75. onverter which will be used to convert values entered in web pages to custom types used in the bean and vise Versa e TypeFactory java a Factory that creates any kind of com plex types e g instances of custom type Money Form The form of our reference application consists of different areas where each defines a single element of the questionnaire Each question has a label and an input element Whenever the user changes a value of an input element the page should reload partly by using AJAX In the following listings and screenshots you can see how the different parts of the questionnaire are defined and how they are rendered The following represents a question which can be answered by yes OR no The label and checkbox are grouped by using a so called div to create a close relation between them div class ym grid gt lt h outputLabel styleClass ym g33 ym gl value Did you sell a house in 2010 gt lt h selectBooleanCheckbox styleClass ym g50 ym gl id chkHasSoldHouse value houseOwning hasSoldHouse gt lt f ajax execute chkHasSoldHouse render grp_hasSoldHouse_hasBoughtHouse gt lt h selectBooleanCheckbox gt lt div gt The JSF html outputLabel tag is rendered to a HTML label tag on server side before the server responses on client requests 36http docs oracle com javaee 5 tutorial doc bnaqm html Thttps en wikipedia org wiki Ajax programming 41 Ae N e o
76. p is visible or not Now place the content into the inferrer class package org eclipse xtext example ql jvmmodel import com google inject Inject import java io Serializable import org eclipse xtext common types Jvm0peration import org eclipse xtext common types util TypeReferences import org eclipse xtext example qgl glDsl ConditionalQuestionGroup import org eclipse xtext example ql qlDsl Question import org eclipse xtext example ql qlDsl Questionnaire import org eclipse xtext xbase XExpression import org eclipse xtext xbase XbaseFactory import org eclipse xtext xbase jvmmodel AbstractModellnferrer import org eclipse xtext xbase jvmmodel IJvmDeclaredTypeAcceptor import org eclipse xtext xbase jvmmodel JvmTypesBuilder class Q1DslJvmModelInferrer extends AbstractModelInferrer 1 Inject extension JvmTypesBuilder Pnttps gist github com kthoms 5132153 28 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 w e gt O 0 JO Ct A C N e o 50 51 52 53 54 55 56 57 58 59 it LWC13 Xtes lt t Submission Inject TypeReferences typeReferences def dispatch void infer Questionnaire element IJvmDeclaredTypeAcceptor acceptor boolean isPreIndexingPhase for form element forms acceptor accept form toClass forms form name initializeLater implements Serializable it superTypes typeReferences getTypeForName typeof Serializable element nu
77. pe QTest def void testValidation ConditionTypeCheck expectError 222 form Foo 4 if foo length a X boolean m parse assertError XbasePackage eINSTANCE XMemberFeatureCall org eclipse xtext xbase validation IssueCodes incompatible types Type mismatch QTest def void testValidation ConditionTypeCheck expectSuccess S e d form Foo if foo length gt 1 a X boolean Y gt parse assertNoErrors 73 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 no Ct FP C N N oo Ct A CQ Ne it LWC13 Xtes lt t Submission OTest def void testValidation AssignmentTypeCheck expectFailure form Foo a X boolean foo length Y parse assertError XbasePackage eINSTANCE XMemberFeatureCall org eclipse xtext xbase validation IssueCodes incompatible types Type mismatch OTest def void testValidation AssignmentTypeCheck expectSuccess 33 form Foo a X boolean foo length gt 1 Y parse assertNoErrors Basically the class is a plain JUnit 4 class We have to use a special JUnit execution class XtextRunner and provide a language specific initializer class Q1Ds1InjectorProvider Next the class adds two extension classes ParseHelper provides a parse method for char se quences This will parse and validate the model Afterwards the observed issues can be asserted with the methods from the RunWith typeof XtextRun
78. pecify a grammar for it The grammar file is a plain text file with xtext filename extension and the grammar within is defined with a BNF like syntax While you can use any text editor to modify it Xtext gives you a specialized editor for grammar files It is aware of the Xtext language gives you syntax coloring code completion and more To get a first impression see Unttp www xtext org oo Oo Ct A Ww N e hop Rh O 1t LWC13 Xtes lt t Submission the screenshot of the Xtext grammar file opened with the Xtext grammar editor below It is not required to fully understand the content yet this will be discussed in the next chapter in detail grammar org eclipse xtext example domainmodel Domainmodel with org eclipse xtext xbase Xbase 10 generate domainmodel http www xtext org example Domainmodel 1 25 DomainModel 3 elements AbstractElement 4 155 AbstractElement 6 PackageDeclaration Entity Import 8c Import 2 import importedNamespace Quali fiedNameWi thWi ldCard 21 PackageDeclaration 22 package name QualifiedName 23 elements AbstractElement 24 pts 269 Entity 27 entity name ValidID extends superType JvmParameterizedTypeReference 28 features Feature 29 316 Feature 32 Property Operation 345 Property 35 name ValidID type JvmTypeReference 375 Operation 3 op name ValidID paramss FullJvmFormalParameter pa
79. putConfigurationProvider public final String WEB CONTENT WebContent IEE return a set of link OutputConfiguration available for the generator public Set lt OutputConfiguration gt get utputConfigurations Set lt QutputConfiguration gt outputConfigurations super getOutputConfigurations OutputConfiguration webContent new OutputConfiguration WEB_CONTENT webContent setDescription Read only Output Folder for web generated application artifacts webContent set utputDirectory WebContent webContent set verrideExistingResources true webContent setCreateOutputDirectory true webContent setCleanUpDerivedResources true webContent setSetDerivedProperty true outputConfigurations add webContent return outputConfigurations The interface OutputConfiguration provides several options to configure the behavior of the so called Outlet We use the defaults as in OutputConfigurationProvider except its name description and output Directoy Our JsfOutputConfigurationProvider can be bound in the Q1Ds1RuntimeModule by overri ding extending the method configure OOverride public void configure Binder binder super configure binder binder bind IOutputConfigurationProvider class to JSFOutputConfigurationProvider class in Singleton class After this step we can refer to the additional OutputConfiguration in generators by use of the constant WEB CONTENT def
80. r antlr internal contains an ANTLR3 grammar and the Lexer and Parser classes generated from it 2 5 Testing the Questionnaire Language 2 5 1 Creating a Launch Configuration In order to test the language and the editor we need to deploy the developed plugins within another Eclipse instance For testing the easiest way is start a so called Runtime Instance Open the dialog Run Run Configurations and select the node Eclipse Application from the left tree widget and press the icon with the sign to create a new Launch Config You could leave the defaults here or change the name and location like in the screenshot 2lnttp www antlr org 19 it LWC13 Xtes lt t Submission eoo Run Configurations Create manage and run configurations Create a configuration to launch an Eclipse application Y g x aoi Name LWC13 Runtime type filter text Main gt 09 Arguments le Plug ins 8 Configuration E Tracing BG Environment Ed Common E Apache Tomcat Workspace Data Y Eclipse Application E Location workspace_loc runtime Iwc13 gt Generic Server O Clear workspace log only Workspace File System Variables H Generic Server External Lai F5 Java Applet Y Ask for confirmation before clearing Configure defaults E Java Application gt JuJUnit Program to Run Ji JUnit Plug in Test m2 Maven Build Run a product l org eclipse platfor
81. rams FullJvmFormalParameter 39 body XBlockExpression 40 41 QualifiedNameWithWildCard 42 QualifiedName 5 The aforementioned example DSL allows you to define entities like Person Car Book and so on An entity has properties e g a Person has a name a gender and a date of birth A Book has a title one or more authors and an ISBN number A textual DSL model could look like this but you could also imagine other syntaxes entity Person name String gender m birthday Date b entity Book title String authors Person isbnNumber String 10 it LWC13 Xte t Submission Note that the Property authors is of type Person so there can be references between entities In the Xtext grammar file you specify how you want to define entities and their properties Once you have completed your language you can do that define some entities say Book and Person together with their respective properties and with proper references between them The nice thing is that Xtext not only gives you a syntax driven editor for editing grammar files Additionally it generates an editor that is specific to the language you have defined It knows about your language s keywords and where to place them it knows about all the syntactical constructs you have made up in your grammar it includes all the nice stuff like syntax coloring code completion validation and more For
82. rence mechanism The Xtend language makes heavy use of this nice feature which makes it almost unneccessary to declare types anywhere For dynamic languages Chttps gist github com kthoms 5240455 71 o oo Oo Ct FF C N m DD DD NM Ra Ro Ro RR Rp Po N e O BAN O 0 PR CQ NN KF O 1t LWC13 Xte t Submission this is natural since the actual type is known and evaluated at runtime Static typed language often lack this feature 6 form Foo2 e if Cbar lenath T Type mismatch cannot convert from int to boolean 10 form Foo3 Qi a X boolean 99 13 F Type mismatch cannot convert from String to boolean 5 1 4 Testing validation rules It is easy to test validation rules in a runtime environment However we will show how these rules can also be unit tested Also herefore the Xtext framework already contains the necessary infrastructure Remember that Xtext has already created a test plugin with the initial generator run Now it is time to make use of it Again it is easier to create the test with Xtend Xtend allows us to create simple models inline with Rich Strings pass the result to a parser and validate the result With Xtend this is a one liner package org eclipse xtext example ql validation test import javax inject Inject import org eclipse xtext example ql Q1Ds1InjectorProvider import org eclipse xtext example ql qlDsl Questionnaire import org eclipse xtext junit4
83. render the site s elements The CSS file for the house owning page contains all corresponding styling information which are linked to the corresponding label elements by their ids houseowning 1blHasBoughtHouse font style italic 5 houseowning 1blValueResidue color 2233FF font family Verdana font weight bold garageowning 1blHasBoughtGarage E When JSF converts from XHTML each element gets a unique full qualified id In our scenario this is always the id of the parent form concatenated with the id of the element itself As separator JSF uses a colon However colons are special characters in CSS hence they need to be escaped Now that the intended artifacts to be generated are clarified the code generator itself can be written Here again we use Xtend see section 3 2 64 o o 1 Oo Ct A C Ne e PF PF 4 do U Q2 yy Q2 y CQ Y N NN Lb Lb PD LP YH N NY NY Be RR BP Be BP he BF BF BB e CQ N e O AN DT RA CQ N H O ON DW Ct RA OO N ONO C A CQ NR O it LWC13 Xte t Submission class QlsDslGenerator implements IGenerator Inject extension Jsf utputConfigurationProvider Inject extension QlDslExtensions override void doGenerate Resource input IFileSystemAccess fsa if input URI fileExtension qls return val styleModel input contents head as QuestionnaireStyleModel for page styleModel pages val cssContent generateCssFile page val cssF
84. roject is org eclipse xtext example ql sdk which can be found in the projects folder of the Git repository 84 oO on Dna e CQ 10 11 12 13 14 NIN Oo c amp it LWC13 Xte t Submission For feature projects the packaging type is eclipse feature Nothing special has to be confi gured further lt xml version 1 0 encoding UTF 8 gt lt project xsi schemaLocation http maven apache org P0M 4 0 0 http maven apache org xsd maven 4 0 0 xsd xmlns http maven apache org P0M 4 0 0 xmlns xsi http www w3 org 2001 XMLSchema instance gt lt modelVersion gt 4 0 0 lt modelVersion gt lt parent gt lt groupId gt org eclipse xtext example ql lt groupId gt lt artifactId gt parent lt artifactId gt lt version gt 1 0 0 SNAPSHOT lt version gt lt X gt lt relativePath gt pom xml lt relativePath gt lt parent gt lt artifactId gt org eclipse xtext example ql sdk lt artifactId gt lt packaging gt eclipse feature lt packaging gt lt project gt 5 2 7 p2 Repository The result of the build should be a p2 repository which the user can configure as update site The repository project org eclipse xtext example ql repository contains a category xml file which references the feature that should be available on this repository lt xml version 1 0 encoding UTF 8 gt lt site gt lt feature url features org eclipse xtext example ql sdk 1 0 0 qualifier jar id org
85. rst letter s case which might come in handy in some situations Large numbers can be written more readable by using underscores to separate digits 1 a day has toFirstUpper 86 400 000 milliseconds 2 results in A day has 86400000 milliseconds As in Java Xbase provides if else expressions for defining conditions Since each expression has a return type it is valid to use if else blocks similar to the ternary operator in Java 1 var x if condition 42 else 43 There are further concepts in Xbase which we will not cover here in more detail since they have not much relevance for the Questionnaire language So e g it is possible to use loops for iterating over a collection of element there is a switch case expression with type guards allowing for defining behavior depending on the type of a parameter and last but not least Xbase allows the definition of closures For more details please look up the reference documentation or the Xbase tutorials directly in Eclipse File New Other Xbase Tutorial With these capabilities integrated in the Questionnaire language it is feasible to define complex domain logic e g for the result of a questionnaire directly in its definition For example when designing a questionnaire for a test let s say to define a person s stress level you can write some Xbase code as expression for the last result question 1 stressLevelResult Your Stress Level
86. run reference Checkout from git OR download from project home page code google com Import project from git Checkout instructions S http www eclipse org webtools 36 oo 1 Oo Ct FF C N eae Rh e Ra a e Ne Oo it LWC13 Xtes lt t Submission https code google com a eclipselabs org p 1lwc13 xtext source checkout Download zip from project homepage Download zip from http code google com a eclipselabs org p 1wc13 xtext Run as MWE2 Workflow 1 org eclipse xtext example ql src org eclipse xtext example ql GenerateQIDsl mwe2 2 org eclipse xtext example qls src org eclipse xtext example qls GenerateQlsDsl mwe2 Run configuration LWC13 Runtime import existing project Iwc13 xtext examples QLTest 3 1 3 Main Layout The logical entry to the web application is the welcome file WebContent index xhtml decla red in WebContent WEB INF web xml The index xhtml composes the main layout with page contents and will later be helpful to integrate the generated artifacts with the web application s layout by using JSF s XHTML templating lt xml version 1 0 encoding UTF 8 gt lt DOCTYPE html PUBLIC W3C DTD XHTML 1 0 Transitional EN http www w3 org TR xhtmli DTD xhtmli transitional dtd lt html xmlns http www w3 0rg 1999 xhtml xmlns h http java sun com jsf html xmlns ui http java sun com jsf facelets gt lt body gt lt ui composition template resources defaul
87. s has to be added to the Q1Ds1RuntimeModule class Open this class and add a configuration that binds the IGenerator interface to the Root class Override public Class lt extends IGenerator gt bindIGenerator return Root class Now we are ready to add additional templates and register them in the Root class 3 3 2 Output Configuration Provider In JSF applications all the web related content is normally placed under WebContent instead of src gen which is mostly used as output for generated java artifacts We want to adapt to the web applications structure and seperate generated java classes and JSF artifacts from each other For that purposes add a class called JsfOutputConfigurationProvider java deri ved from org eclipse xtext generator utputConfigurationProvider within package org eclipse xtext example ql generator The new provider adds an additional OutputConfiguration for the ouput directory WebContent as shown in the listing below package org eclipse xtext example ql generator import java util Set 3 http xtextcasts org episodes 15 output configurations 48 O o N Oo C 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 CU FF C N rn it LWC13 Xte t Submission import org eclipse xtext generator DutputConfiguration import org eclipse xtext generator DutputConfigurationProvider public class JSF utputConfigurationProvider extends Out
88. sed in conditions and computed values The task allows two approaches to achieve the goal We will choose the second approach Check that elements referred in expressions have been declared before their usage Xtext does not enforce that elements are declared before they are used somewhere The referred names simply must be in the scope of the context which the current scope implementation already accomplishes We could implement this constraint also in the scope provider of the language by restricting the scope to elements that have been declared before However we will implement this as a semantic constraint in the validator class To implement the constraint we need to know the location in the model where a Question element is declared and where it is called in an expression Besides the Abstract Syntax Tree Xtext maintains a second model which represents the document This is the so called Node Model and the class NodeModelUtils provides some utility functions to navigate from an AST element to the node model Since Questions that are referred in expressions are local to the Form we can simply compare the offset in the document of the declared Question and the feature call in an expression Xtext validation rules are implemented as methods which are annotated with Check The method name does not matter Check methods are expected to have exactly one parameter 70 e Ww N O 0 N Q C 10 11 12 it LWC13 Xtes lt t Submi
89. ss Money private BigDecimal amount public Money BigDecimal amount this amount amount public BigDecimal getAmount return amount Select the src folder and create a new file housepurchase ql Once you have created the file a popup dialog will appear to ask if you would like to add the Xtext nature on this project Answer with Yes 600 Add Xtext Nature 1 Do you want to add the Xtext nature to the project QLTest From now on your project will be considered to contain files that Xtext should recognize q1 files Projects having the Xtext nature will be processed by the Xtext Builder when building projects other projects are ignored The Xtext Builder indexes the Xtext based resources links the cross references in the editor and validates the model files On errors resource markers are created which can be seen in the editor and the Problems View Enter the content for housepurchase q1 import types Money form BoxiHouseOwning hasSoldHouse Did you sell a house in 2010 boolean hasBoughtHouse Did you by a house in 2010 boolean hasMaintLoan Did you enter a loan for maintenance reconstruction boolean Phttps gist github com kthoms 5036304 21 10 11 it LWC13 Xte t Submission sellingPrice Price the house was sold for Money privateDebt Private debts for the sold house Money valueResidue Value residue Money You
90. ssion which is of the type of element that has to be checked The base class provides methods to create error messages For the case of this constraint the necessary context object type is XFeatureCall Now open the Q1Ds1XtendValidator class again and add this method QCheck def void check featureDeclaredBeforeCall XFeatureCall featureCall 1 val featureSource featureCall feature sourceElements head val nodeFeature if featureSource null featureSource node else featureCall feature node val nodeCall featureCall node if nodeFeature null if nodeFeature offset gt nodeCall offset error featureCall feature simpleName must be declared before featureCall XbasePackage eINSTANCE XAbstractFeatureCall Feature ERR FEATURE CALL BEFORE DECLARATION null After restarting the workbench the situation will be recognized as an error te validation ql X 1o form Foo Q2 if QO C y Y boolean ub Ok must be declared before 5 1 3 Constraint Type conformance check Next the LWC13 task requires checking the type conformance in expressions Type check conditions and variables the expressions in conditions should be type correct and should ultimately be booleans The assigned variables should be assigned consistently each assignment should use the same type Here we have to do nothing since this constraint is already implemented in Xbase This works thanks to Xbase s type infe
91. systems are available The one gaining most attention nowadays is Maven Tycho which is a set of plugins for the well known Maven build framework In Maven the build descriptors are so called POM files usually pom xml For the LWC example we have added such POM files to enable a headless build 5 2 1 settings xml Maven needs to know about repositories from where it can download artifacts By default Maven only knows about Maven Central which is the repository hosted by Apache For our build we need to consume some artifacts that are not available at Maven Central e The Fornax Workflow plugin is used to execute MWE workflows to generate code from the Xtext grammar e The Xtend plugin compiles Xtend classes to Java code All plugin dependencies must be resolvable through Eclipse p2 repositories The layout p2 is a special layout contributed by Tycho The plugins consume dependencies from 75 o oo Oo Ct A wo Ne bb e e RR Rp N oo on FP WwW NY Ra O 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 LWC13 Xtes lt t Submission Eclipse Juno Composite repository of the Eclipse Juno simultaneous release Most plugins are resolved through this repository Eclipse Orbit Orbit contains OSGi bundles of 3rd party components like logj javax faces javax inject Google Guava etc Eclipse Xtext The release repository for Xtext Xtend MWE2 In settings xml repository configurations must be cont
92. t lt configuration gt lt encoding gt UTF 8 lt encoding gt lt meminitial gt 128m lt meminitial gt lt maxmem gt 1024m lt maxmem gt 78 0 So oa A A Ww N rn LWC13 Xtes lt t Submission o o 1 Oo Ct gt C tn Hm hop mM O lt source gt 6 0 lt source gt lt target gt 6 0 lt target gt lt verbose gt true lt verbose gt lt configuration gt lt plugin gt Maven Plugin Management In the pluginManagement section the plugins that potentially participate in the build are configured with their versions This is because Maven would select the latest available version of a plugin instead and prints warnings during the build It is better to fix the versions of plugins that are used to those with which the build has been tested Also basic plugin configurations can be added here lt plugin gt lt groupId gt org eclipse tycho lt groupId gt lt artifactId gt tycho p2 repository plugin lt artifactId gt lt version gt tycho version lt version gt lt plugin gt lt plugin gt lt groupId gt org apache maven plugins lt groupId gt lt artifactId gt maven clean plugin lt artifactId gt lt version gt 2 4 1 lt version gt lt plugin gt 5 2 3 Reactor POM The project consists of several modules which is called a Multi Module Project in Maven terms The modules of a project are listed in a modules section Often the modules are enlisted in the Parent POM but we splitted
93. t templates defaultLayout xhtml gt lt ui define name content gt Hello World lt ui define gt lt ui composition gt 34http docs oracle com javaee 6 javaserverfaces 2 1 docs vdldocs facelets 37 HG CU F w N HG e WwW N it LWC13 Xtes lt t Submission lt body gt lt html gt Subpages of the application should use the index xhtml placed in WebContent itself as their template and overwrite the content section with custom output via the same pattern lt ui composition template index xhtml gt lt ui define name content gt my xhtml content lt ui define gt lt ui composition gt Everything between the opening and closing facelet define tag within the subpage will be passed into a corresponding facelet insert section name attribute is set to content defined in the template here defaultLayout xhtml or one of its parent templates when the HTML output is rendered by the JSF framework Default template We keep the main layout definition and the page contents separated from each other The WebContent index xhtml defines the main composition of the application s structural layout and content of pages as described in section 3 1 3 Layout template defintions should be placed in a folder WebContent resources templateName in our web application To change the main layout it is just necessary to change the template reference of the facelets composite in WebContent
94. ted gt lt DOCTYPE html PUBLIC W3C DTD XHTML 1 0 Transitional EN http www w3 org TR xhtm11 DTD xhtml1 transitional dtd gt lt html xmlns http www w3 org 1999 xhtml xmlns h http java sun com jsf htm1 xmlns ui http java sun com jsf facelets gt artifact content lt html gt To get a valid XHTML page we have to generate the DOCTYPE and HTML tag into each XHTML file It was replaced in the listings of the following sections to focus on what matters JSF Form index To get simple access to all generated forms in the application we want to generate an index page where a link is included for each form which is defined in our model The generated index page should be saved in a file called index xhtml within a subfolder generated forms of the WEB_CONTENT outlet created in section 3 3 2 class JSFGenerator implements IGenerator Inject extension JSF utputConfigurationProvider Inject extension QlDslExtensions override doGenerate Resource input IFileSystemAccess fsa 52 oe o NI o 10 11 12 13 oO On Dot FF WwW Ne e Rp wo N e O it LWC13 Xtes lt t Submission if input URI fileExtension q1 return model root val questionnaire input contents head as Questionnaire generate index page with links to generated forms val contentIndex generate FormIndex questionnaire forms val fileNameIndex generated forms index xhtml fsa generateFile fileNameIndex
95. tion text presented to the user Every question has a type oy Question name ID label STRING type JvmTypeReference With the grammar above the QL language won t fulfill all requirements of the LWC2013 task We will extend the grammar later to meet all requirements With this grammar a valid model file would look like this Shttps gist github com kthoms 4758255 14 it LWC13 Xtes lt t Submission 1 import types Money 2 3 form BoxiHouseOwning 4 hasSoldHouse Did you sell a house in 2010 boolean 5 hasBoughtHouse Did you by a house in 2010 boolean 6 hasMaintLoan Did you enter a loan for maintenance reconstruction boolean 7 8 sellingPrice Price the house was sold for Money 9 privateDebt Private debts for the sold house Money 10 valueResidue Value residue Money 11 Now let us explain the grammar in more detail 1 grammar org eclipse xtext example ql Q1Dsl with org eclipse xtext xbase Xbase The grammar has a unique identifier named org eclipse xtext example ql Q1Ds1 It is derived from another grammar org eclipse xtext xbase Xbase Xbase defines a grammar for expressions but more on this later Xtext supports single inheritance for grammars 1 generate qlDsl http www eclipse org xtext example ql Q1Ds1 This is an instruction for the metamodel used for the language The generate statement means that Xtext generates an Ecore metamodel for this
96. tory to this directory by use of the maven resource plugin plugin lt artifactId gt maven clean plugin lt artifactId gt 8l O 0 1 0 Ct B CQ 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 it LWC13 Xte t Submission configuration lt filesets gt lt fileset gt lt directory gt src gen lt directory gt lt excludes gt lt exclude gt gitignore lt exclude gt lt excludes gt lt fileset gt lt fileset gt lt directory gt xtend gen lt directory gt lt excludes gt lt exclude gt gitignore lt exclude gt lt excludes gt lt fileset gt lt fileset gt lt directory gt project artifactId ui src gen lt directory gt lt excludes gt lt exclude gt gitignore lt exclude gt lt excludes gt lt fileset gt lt fileset gt lt directory gt tests project artifactId tests src gen lt directory gt lt excludes gt lt exclude gt gitignore lt exclude gt lt excludes gt lt fileset gt lt filesets gt lt configuration gt lt plugin gt When the workflow for an Xtext project is executed Xtext generates code not only into the runtime project but also into the UI and Tests project When these projects are build in a multi module build each project is built one after the other and all required lifecycle phases are executed per project This has a special consequence for the clean phase When Xtext is generating code into th
97. turn question expression null For each Question a method boolean is lt QUESTIONNAME gt Enabled is inferred The body of the method does simply return true if the Question does not have an computation expression assigned or false otherwise In this case we assign to the body a closure that computes the method implementation text This is the first example where we make use of Xtend s Rich String feature the text between the three single quotes which is later heavily used in the code generator templates val allQuestionGroups form eAllContents filter typeof ConditionalQuestionGroup toList var groupIndex 0 for questionGroup allQuestionGroups members questionGroup createIsGroupVisibleMethod groupIndex groupIndex groupIndex 1 0 Jl awa A A Ww N Hm def Jvm peration createIsGroupVisibleMethod ConditionalQuestionGroup group int groupIndex 1 9 group toMethod isGroup groupIndex Visible typeReferences getTypeForName boolean group null 10 if group condition null 11 body group condition 12 7 else q 13 body it append return true We now filter all ConditionalQuestionGroup instances from the Questionnaire and loop over them For each of them a method is lt QUESTIONGROUPINDEX gt Visible is produced Unfor tunately question groups are anonymous thus we maintain an index counter and name the methods isGroup lt IDX gt Visible
98. ue a v n 36 b 00 ECC 36 Tomcat Tata db es a a 36 44 2 Impert and rum reference 2 lt o 22 4 a2 Gona eg ka nina 36 Import project Ton ge eu a ten ox m ER ox RO xc RR m de 36 Download zip from project homepage nenn 37 odo Main LOU ee ee 37 gd Ib ame aussah 40 ll dee a a a ee era i 41 ico ccr 43 LWC13 Xtes lt t Submission e ATTI 43 C Code CEET a dee aa Aa a a a a a A 47 3 3 1 Dispatcher template lt cos soa oko ko o XS ria ehe ee 47 32 Output Configuration Provider sos amp 2 aspe ee doe eee EXC 48 e en ee AS a Be a RSE Ee Ge 50 JOE Borm indek e sd oe Kr ER Fee MAE ee a S 52 3 4 Testing the Questionnaire Application lll 56 4 Layout and Styling Language QLS 58 41 The Lancia QLS a2 2o weh Gen ea Rok CSG Re CR Ree ee 58 42 QLS Code Generator 2 uud ux kdo RR eR REOR S x8 REOR 3 OE EES EH 62 5 Additional Concepts 69 d A 69 5 1 1 Extending the Java Validator class e s s sati ae ee hae 240 ea ws 69 5 1 2 Constraint Ensure order of questions 2 222 70 5 1 3 Constraint Type conformance check lll 71 5 14 Testing validation rules oo run 12 22 cp T 75 GL settings Xml IEA T9 Dax Parent POM sra t a aoia 4333 AE AR 77 Dr Ti cs oe oe son a ee doe de ey ee 79 5 24 QL R ntime Project POM 2 zu 42 aore eh e e BS 80 ig QOL ULProject POM 2 3 dox ES ee ana ae a 84 acp SDK Feature POM ea so za Rhode eod OARS Beale WS 84 DALY
99. uired which an OSGi container would usually provide automatically This is especially useful when Xtext based languages are used in build environments or other IDEs e Class Q1DslFormatter allows the implementation of a declarative code formatter for the DSL e File Q1Ds1JvmModel Inferrer xtend is a class implemented with the Xtend language The JVM Model Inferrer will play an important role later when we introduce expressions and code generation e Class QlDslJavaValidation allows the implementation of validation rules for the DSL Runtime Project folder src gen IShttp heikobehrens net 2009 04 23 generation gap pattern http code google com p google guice 20nttp en wikipedia org wiki Dependency_injection 18 it LWC13 Xtes lt t Submission e The Ecore metamodel is generated to file Q1Ds1 ecore v platform resource org eclipse xtext example ql src gen org eclipse xtext example ql QIDsl ecore Vv 8 qlDsl Y E Questionnare x imports Import X forms Form Y E Import c3 importedNamespace EString Y E Form name EString E element FormElement H FormElement Y E Question gt FormElement c3 name EString c3 label EString type JumTypeReference platform resource org eclipse xtext common types model JavaVMTypes ecore The Java implementation code for the metamodel can be found in the package org eclipse xtext example ql qlDsl e The package org eclipse xtext example ql parse
100. unctions which can be basically read by themselves the method getDependentElementsWithExpression needs some more explanation For a given question this method return all other form elements questions or conditional groups which use the question in their expression This method is used to define which parts of the web page need to be updated when a particular question is answered by the user For this first the JVM field in the backing bean associated with the input question is fetched line 11 Afterwards all form elements which contain an expression line 13 16 are filtered in a way that only the ones remain whose expression contains the JVM fields name 19 32 The result of this filtering is the method s return value line 33 3 4 Testing the Questionnaire Application It s time to test the application we have developed so far If your runtime environment is still open you need to restart it Just switch to the runtime instance and press File Restart See also section 2 5 for more information on how to start your runtime evironment for testing Once the runtime environement is running you can test the code generator in the QLText project created in section 2 5 Code generation process is triggered automatically on the fly when the QL model gets modified The generated artifacts are located in folder WebContent generated forms Into this folder also an index xhtml file is placed which you can use as starting point for the questionnaire appl
101. ustom types src types Custom type converter src converter Libraries WebContent WEB INF lib Web Application Descriptor WebContent WEB INF web xml Faces configuration WebContent WEB INF faces config xml Images WebContent resources default img Page Templates WebContent resources default templates After describing some necessary configuration 35 it LWC13 Xte t Submission of the IDE we will focus on the parts which are dependent on the QL model and thus subject of code generation in sub sesction 3 1 4 These artifacts are e Java Bean classes representing the state of a Form src forms e JSF enabled XHTML pages representing the presentation of a Form WebContent forms 3 1 1 IDE Configuration Webtools To get a nicely integrated developement environment we will install some com ponents of the Web Tools Platform WTP into an existing Eclipse installation install new software http download eclipse org releases juno Web XML Java EE and OSGi Enterprise Development e Eclipse Java EE Developer Tools 3 4 0 v201107072300 e JavaServer Faces Tools JSF Project 3 4 1 v201208241503 e JST Server Adapters 3 2 200 v20120517 1442 e JST Server UI 3 4 0 v20120503 1042 e JST Server Adapters Extensions 3 3 101 v20120821 1416 e Eclipse Web Developer Tools 3 4 1 v201208170345 e Eclipse Java Web Developer Tools 3 4 1 v201208231800 Tomcat installation add new server tomcat v7 3 1 2 Import and
102. xt thus its elements can be used in any other Xtext grammar by importing or directly extending Xbase via Xtext s possibility for grammar inheritance In addition to the grammar Xbase ships with further infrastructural parts like a compiler inter preter linker or static analyzer which all can be adapted to your own needs In the background Xbase produces plain Java code which is run on the JVM Like other DSLs defined with Xtext 7f not present open with Window Show View Outline 22 it LWC13 Xte t Submission Xbase provides also editor features like syntax highlighting content assistance and navigation via hyperlinks In the following we will first introduce some language concepts of Xbase and afterwards we will describe how to integrate Xbase into the Questionnaire DSL In Xbase everything is an expression which always has a return type which might be null for some expressions Variables are defined with the var keyword whereas for constant values the val keyword is used Types are derived automatically so they don t need to be defined explicitly 1 var myVariable some modifiable value 2 val Integer myConstant 42 Xbase ships with a library extending existing Java types like String or Integer with further functionality So besides the already known String operations from Java like toUpperCase or toLowerCase in Xbase expressions you can also use toFirstUpper and toFirstLower changing only the fi
103. y are bound to CTRL lt and CTRL gt in the Xtend editor There are also logical structures like for loops or if else statements supported def htmlContent List lt String gt contents lt html gt 45 0 nu O oa FF C N rn N ODO Ct A C N it LWC13 Xte t Submission lt body gt FOR content contents BEFORE p SEPARATOR br AFTER lt p gt gt IF content length gt 10 Large Content content toFirstUpper ELSE Small Content content toFirstUpper ENDIF ENDFOR gt lt body gt lt html gt Note the special keywords in the FOR loop declaration BEFORE and AFTER will be called once before and after the iteration but only if the loop will be iterated at least once With the SEPARATOR keyword a string which will be inserted between two iteratins can be specified Calling the example method with hello Some more text results in html lt body gt lt p gt Small Content Hello lt br gt Large Content Some more text lt p gt lt body gt lt html gt Last but not least Xtend offers a more sophisticated switch case statement than Java does The break statement as known from Java is implicit in Xtend Furthermore switching based on Strings and even based on the type of the switch argument is possible like in the following example def getTypeName Number input switch input megas M se en Intel Float It is a

Download Pdf Manuals

image

Related Search

Related Contents

Bedienungsanleitung  fulltext - DiVA Portal  MODE D`EMPLOI - Focale22.com  Samsung T23A750 Uporabniški priročnik  XERO XBS-08 Intelligence Bluetooth Stereo Headset  DeLOCK 5m mini DP/DVI  Smart SV&T - User Manual  per  8-channel thermocouple input module now available! New Product  

Copyright © All rights reserved.
Failed to retrieve file