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 theconf
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 thebin
). In Windows, you can create this variable fromSystem 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 namedhelloworld
-
Inside
helloworld
, create a new file calledindex.egl
and add to it the following code
[%="Hello World"%]
- Start Tomcat using
bin/startup.bat
(orstartup.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) inEPackage.Registry.INSTANCE
loadModel(name : String, modelFile : String, metamodelURI : String)
: Loads the model stored inmodelFile
using the registered metamodelmetamodelURI
.loadModelByFile(name : String, modelFile : String, metamodelFile : String)
: Loads the model stored inmodelFile
using the metamodel inmetamodelFile
.loadModel(name : String, aliases : String, modelFile : String, metamodel : String, expand : Boolean, metamodelIsFilebased : Boolean)
: Provides more parameters for loading models.uncacheModel(modelFile : String)
: Removes themodelFile
from the cache (next call toloadModel()
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
Running EGL on Google App Engine¶
By default App Engine will treat EGL files as static content and serve their source code instead of executing them. To work around this, add the following snippet under the root element of the appengine-web.xml
configuration file of your App Engine application.
<static-files>
<exclude path="*.egl"/>
</static-files>
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 PSI Probe useful for figuring out what's going wrong.