Using EGL as a server-side scripting language in Tomcat

The original purpose of EGL was to enable batch generation of source code and other textual artefacts from EMF models. However, since there is no hard binding between the language and the file system, it is also possible to use EGL in other contexts.

In this article, we demonstrate using EGL as a server-side scripting language in Tomcat, to produce web pages from EMF models on the fly.

Setup

  • Download a fresh copy of Tomcat 6.0 here and extract it
  • Download egl-servlet-full.zip
  • Extract all .jar files from the zip into the lib folder of Tomcat
  • Open web.xml in the conf directory of Tomcat and add the following snippet


  • <servlet>
      <servlet-name>egl</servlet-name>
      <servlet-class>
        org.eclipse.epsilon.egl.servlet.EglServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
      <servlet-name>egl</servlet-name>
      <url-pattern>*.egl</url-pattern>
    </servlet-mapping>
    


  • Make sure that there is an environment variable called JRE_HOME and it's pointing to your JRE installation directory (the root, not the bin). In Windows, you can create this variable from System Properties→Advanced→Environment Variables→System Variables→New...


  • Create a Hello World web application

    To create a hello world web application and test your installation, you need to go through the following steps:

  • Go to the webapps folder and create a new directory named helloworld
  • Inside helloworld, create a new file called index.egl and add to it the following code
  • [%="Hello World"%]
    
  • Start Tomcat using bin/startup.bat (or startup.sh in Linux/MacOS)
  • Open your browser and go to http://localhost:8080/helloworld/index.egl
  • A web-page with the text Hello World should appear. If not, please make sure you've followed all the steps above and if it still doesn't work, please drop by the forum and we'll be happy to help.


  • Accessing parameters from the URL

    To access parameters from the URL (or fields of a submitted form) you can use the request.getParameter('parameter-name') method. For example, by modifying the source code of index.egl to the following

    [%="Hello "+request.getParameter("visitor")%]
    


    and navigating to http://localhost:8080/helloworld/index.egl?visitor=John, you should get a page reading Hello John as a result.

    Other built-in objects

    EGL provides the following built-in objects which (should) function exactly like they do in JSP
  • request
  • response
  • config
  • application
  • session


  • You may want to have a look here for a tutorial that explains their functionality.

    Caching

    EGL provides the built-in cache object to facilitate two types of caching. Page caching can be used to ensure that repeated requests to the same URL do not result in the execution of EGL templates. Fragment caching can be used to share the text generated by a template between requests for different URLs.

    For example, the following code is used to ensure that repeated requests for pages matching the regular expression index.* are served from the page cache:

    [% cache.pages("index.*"); %]
    


    The page cache can be expired programmatically, as shown below, or by restarting the Tomcat server.

    [% cache.expirePages("index.*"); %]
    


    In addition to page caching, EGL supports fragment caching which allows the contents of a sub-template to be cached. For example, the following code processes sidebar.egl only the first time that the template is executed:

    [% var sidebarTemplate = TemplateFactory.load("Sidebar.egl"); %]
    [%=cache.fragment(sidebarTemplate) %]
    
    Note that the fragment method should be used in a dynamic output section. Like pages, fragments can be expired programmatically (or by restarting the Tomcat server):
    [% cache.expireFragment(sidebarTemplate); %]
    


    A simple caching strategy is to populate the page and fragment caches from your main EGL templates, and to provide a ClearCache.egl template in a sub-directory that only administrators that can access.

    Loading EMF models in EGL pages

    The main motivation for turning EGL into a server-side scripting language is its ability to work well with EMF models. EGL provides the modelManager built-in object to let you load EMF models that reside in the web application.

    To experiment with modelManager, download the Graph.ecore and Ecore.ecore models and place them in your helloworld directory. Then, change your index.egl to look like this

    [%
    modelManager.registerMetamodel("Ecore.ecore");
    modelManager.loadModel("Sample", "Graph.ecore", "http://www.eclipse.org/emf/2002/Ecore");
    %]
    
    The metamodel has [%=EClass.all.size()%] classes
    


    Refresh the page in your browser and it should now read:

    The metamodel has 3 classes
    


    The Model Manager

    The modelManager built-in object provides the following methods:

  • registerMetamodel(file : String) : Registers the file (should be an Ecore metamodel) in EPackage.Registry.INSTANCE
  • loadModel(name : String, modelFile : String, metamodelURI : String) : Loads the model stored in modelFile using the registered metamodel metamodelURI.
  • loadModelByFile(name : String, modelFile : String, metamodelFile : String) : Loads the model stored in modelFile using the metamodel in metamodelFile.
  • loadModel(name : String, aliases : String, modelFile : String, metamodel : String, expand : Boolean, metamodelIsFilebased : Boolean) : Provides more parameters for loading models.
  • uncacheModel(modelFile : String) : Removes the modelFile from the cache (next call to loadModel() will actually reload it)
  • clear() : Clears cached models and metamodels


  • Sharing models between templates

    Currently, each model is only loaded once (the first time the loadModel() or loadModelByFile() is called). If multiple pages need to access the same model, add the model loading logic in an operation in a separate models.eol file:

    operation loadModels() {
      modelManager.registerMetamodel("Ecore.ecore");
      modelManager.loadModel("Sample", "Graph.ecore", "http://www.eclipse.org/emf/2002/Ecore");
    }
    


    and then import and call it from each one of your pages:

    [%
    import "models.eol";
    loadModels();
    %]
    
    -- Page code here
    
    


    Working with big models

    If you encounter a Java OutOfMemoryError while querying a big model you'll need to start Tomcat with more memory than the default 256 MB. To do this, go to bin/catalina.bat (on Windows -- if you're on Linux you should modify catalina.sh accordingly) and change line

    set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%
    


    to

    set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER% -Xms1024m -Xmx1024m -XX:MaxPermSize=128m
    


    If you keep getting out of memory errors, you may find Lambda Probe useful for figuring out what's going wrong.