<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xml:base="http://www.eiffelroom.org" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
 <title>eiffelroom - Creating a web application with Goanna - Comments</title>
 <link>http://www.eiffelroom.org/article/creating_a_web_application_with_goanna</link>
 <description>Comments for &quot;Creating a web application with Goanna&quot;</description>
 <language>en</language>
<item>
 <title>Will update tutorial</title>
 <link>http://www.eiffelroom.org/article/creating_a_web_application_with_goanna#comment-374</link>
 <description>&lt;p&gt;Thanks Neal,&lt;/p&gt;

&lt;p&gt;I will integrate this info in the tutorial on Goanna&#039;s Origo page too.&lt;/p&gt;

</description>
 <pubDate>Sun, 04 Nov 2007 09:26:40 -0800</pubDate>
 <dc:creator>bayt</dc:creator>
 <guid isPermaLink="false">comment 374 at http://www.eiffelroom.org</guid>
</item>
<item>
 <title>Great Tutorial</title>
 <link>http://www.eiffelroom.org/article/creating_a_web_application_with_goanna#comment-373</link>
 <description>&lt;p&gt;Thank you for doing this, Till. One thing I&#039;d like to add is that the parameter collections are for validating the semantics of a submitted form, not for validating user input.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mandatory Parameter Collection&lt;/strong&gt; - These are mandatory at the form processing level, not required fields in the form the user sees.  Typically, these are a html hidden elements used to verify that some system state is the same at form processing time as it was at form generation time.  For example, it might contain the user name of a logged in user to prevent them from submitting a form, logging out, logging in as a new user, and then using the back button to resubmit the previously generated form for the previous user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required Parameter Collection&lt;/strong&gt; - These are html elements which must be present in the form for correct processing to occur or whose absence indicates a serious bug in the form generation routine or an attack on the web site. This doesn&#039;t necessarily mean that the user must provide a value for the element. &amp;quot;address_line_2&amp;quot; on a registration page might be an example of a required parameter for which no user input would be required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optional Parameter Collection&lt;/strong&gt; - These are elements whose absence from a submitted form is expected sometimes. No processing for this parameter will occur if they are not present in the form.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add If Absent Parameter Collection&lt;/strong&gt; - These are elements whose absence from a form has meaning.  html checkbox elements provide a typical example. If they are not present in the form submittal, a PARAMETER_PROCESSING_RESULT for them is added so that the appropriate processing for their unchecked state will occur.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validating User Input&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each GOA_REQUEST_PARAMETER is responsible for validating the input it receives from the user.  Since receiving invalid input is expected, this does not interrupt request processing. Typically, invalid user input produces&lt;/p&gt;

&lt;p&gt;&amp;quot;not PARAMETER_PROCESSING_RESULT.is_value_valid&amp;quot;&lt;/p&gt;

&lt;p&gt;which in turn triggers the redisplay of the form with an error message.  Several GOA_REQUEST_PARAMETER descendents implement this behavior for common data types.&lt;/p&gt;

</description>
 <pubDate>Sun, 04 Nov 2007 09:19:52 -0800</pubDate>
 <dc:creator>neallester</dc:creator>
 <guid isPermaLink="false">comment 373 at http://www.eiffelroom.org</guid>
</item>
<item>
 <title>Creating a web application with Goanna</title>
 <link>http://www.eiffelroom.org/article/creating_a_web_application_with_goanna</link>
 <description>
&lt;h2 id=&quot;toc0&quot;&gt;This is a short tutorial for building web applications with Goanna&lt;/h2&gt;
&lt;p&gt;It covers the following topics&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt; Installing all the software you need&lt;/li&gt;
    &lt;li&gt; Getting to know Goanna&lt;/li&gt;
    &lt;li&gt; A short description on how to develop a web application with Goanna&lt;/li&gt;
&lt;/ul&gt;


&lt;h2 id=&quot;toc1&quot;&gt;How it all works&lt;/h2&gt;
&lt;p&gt;Goanna offers many different services and layers of abstraction.&lt;/p&gt;

&lt;p&gt;For this tutorial we will use the Goanna web application library. The Goanna web application library is a framework which allows to build web applications. The framework itself builds upon the Goanna fast cgi interface. And on the base of it all is an eposix server. In order to scale up with the traffic and to be able to host other sites than only the ones created with Goanna we will use an Apache web server.&lt;/p&gt;

&lt;p&gt;The Apache web server interacts with our web application via the fast cgi interface.&lt;/p&gt;


&lt;h2 id=&quot;toc2&quot;&gt;Installation&lt;/h2&gt;
&lt;p&gt;These installation instructions are meant for a (k)ubuntu system. At the time of writing ubuntu Feisty Fawn (7.04) was the current stable version.&lt;/p&gt;

&lt;p&gt;First thing first, get a version of EiffelStudio. At the time of writing EiffelStudio 5 (5.7.64493 GPL Edition) was the current stable version. You can find EiffelStudio at &lt;a href=&quot;http://eiffelstudio.origo.ethz.ch/downloads&quot;&gt;http://eiffelstudio.origo.ethz.ch/downloads&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After installing EiffelStudio according to the instructions make sure that the following  environment variables are set:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export ISE_EIFFEL={location of EiffelStudio in file system}&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export ISE_PLATFORM=linux-x86&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export PATH=$PATH:$ISE_EIFFEL/studio/spec/$ISE_PLATFORM/bin&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export ISE_C_Compiler=gcc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next thing you need to get is a few Eiffel libraries&lt;/p&gt;


&lt;h3 id=&quot;toc3&quot;&gt;Gobo&lt;/h3&gt;
 &lt;ul&gt;
    &lt;li&gt; GOBO: get the latest version from &lt;a href=&quot;http://www.gobosoft.com&quot;&gt;http://www.gobosoft.com&lt;/a&gt;&lt;br /&gt;
set the following environment variables&lt;ul&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export GOBO=location of gobo in file system&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export GOBO_EIFFEL=ise&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export GOBO_CC=gcc&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export GOBO_OS=unix&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;
    &lt;li&gt; for further installation notes read the readme.txt&lt;/li&gt;
    &lt;li&gt; add the folder &lt;code class=&quot;geshifilter&quot;&gt;&#039;$GOBO/bin&#039;&lt;/code&gt; to your path.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3 id=&quot;toc4&quot;&gt;Eposix&lt;/h3&gt;
 &lt;ul&gt;
    &lt;li&gt; eposix: &lt;a href=&quot;http://www.berenddeboer.net/eposix/&quot;&gt;http://www.berenddeboer.net/eposix/&lt;/a&gt;&lt;br /&gt;
set the following environment variables&lt;ul&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export EPOSIX={location of eposix in file system}&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;export EPOSIX_LIB=$EPOSIX/lib&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;
    &lt;li&gt; for further installation notes read the file &lt;code class=&quot;geshifilter&quot;&gt;$EPOSIX/INSTALL&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3 id=&quot;toc5&quot;&gt;Log4e&lt;/h3&gt;
 &lt;ul&gt;
    &lt;li&gt; log4e: &lt;code class=&quot;geshifilter&quot;&gt;svn co https://svn.origo.ethz.ch/goanna/trunk/log4e log4e&lt;/code&gt;&lt;ul&gt;
        &lt;li&gt; set the environment variable &lt;code class=&quot;geshifilter&quot;&gt;$LOG4E&lt;/code&gt; to the location of log4e in you file system&lt;/li&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;cd $LOG4E&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;geant install&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3 id=&quot;toc6&quot;&gt;Goanna&lt;/h3&gt;
 &lt;ul&gt;
    &lt;li&gt; Goanna: &lt;code class=&quot;geshifilter&quot;&gt;svn co https://svn.origo.ethz.ch/goanna/trunk/goanna goanna&lt;/code&gt;&lt;ul&gt;
        &lt;li&gt; set the environment variable &lt;code class=&quot;geshifilter&quot;&gt;$GOANNA&lt;/code&gt; to the location of Goanna in you file system&lt;/li&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;cd $Goanna/library/utility&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt; &lt;code class=&quot;geshifilter&quot;&gt;geant install&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3 id=&quot;toc7&quot;&gt;We are still not done&lt;/h3&gt;
 Install the following packages with your favorite package manager or with aptitude.&lt;ul&gt;
    &lt;li&gt; Apache2 &lt;/li&gt;
    &lt;li&gt; mod_fastcgi&lt;/li&gt;
&lt;/ul&gt;


&lt;h3 id=&quot;toc8&quot;&gt;And finally you need to get your fingers dirty&lt;/h3&gt;
 Download DevKit &lt;a href=&quot;http://www.fastcgi.com/dist/fcgi.tar.gz&quot;&gt;http://www.fastcgi.com/dist/fcgi.tar.gz&lt;/a&gt; A how-to-install-source-balls-under-linux can be found here: &lt;a href=&quot;http://www.tuxfiles.org/linuxhelp/softinstall.html&quot;&gt;http://www.tuxfiles.org/linuxhelp/softinstall.html&lt;/a&gt; .
&lt;h2 id=&quot;toc9&quot;&gt;The first steps&lt;/h2&gt;
&lt;p&gt;After you have installed everything open a browser and type &lt;code class=&quot;geshifilter&quot;&gt;localhost&lt;/code&gt; onto the  location bar. The Apache place holder page should show up. If this is not the case try a good  old windows trick, even if we are running (k)ubuntu. Restart. If this doesn&#039;t help, you will find  a lot of help out in the wild of the WWW.&lt;/p&gt;

&lt;p&gt;Now that we have our primary server up and running it is time to get in touch with Goanna.&lt;/p&gt;

&lt;p&gt;Create a new directory for the web application. Create an environment variable which points to  this directory. For the rest of this tutorial we will refer to this directory as &lt;code class=&quot;geshifilter&quot;&gt;$WEB_APP&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Goanna comes with a template for building web applications. Therefore we don&#039;t have to write  the whole application form scratch but can start right away with the interesting part. The  template can be found at &lt;code class=&quot;geshifilter&quot;&gt;$Goanna/example/application&lt;/code&gt;. So copy the content of  &lt;code class=&quot;geshifilter&quot;&gt;$Goanna/example/application&lt;/code&gt; into your &lt;code class=&quot;geshifilter&quot;&gt;$WEB_APP&lt;/code&gt; folder. If you have  an SVN version of Goanna remove any &lt;code class=&quot;geshifilter&quot;&gt;.svn&lt;/code&gt; directory from the copied template.&lt;/p&gt;

&lt;p&gt;If you like you can change the name of the application in the &lt;code class=&quot;geshifilter&quot;&gt;system.xace&lt;/code&gt; and  the &lt;code class=&quot;geshifilter&quot;&gt;build.gant&lt;/code&gt; file. Once you have done this open a console, navigate to  &lt;code class=&quot;geshifilter&quot;&gt;$Goanna&lt;/code&gt; and then run the command &lt;code class=&quot;geshifilter&quot;&gt;geant build&lt;/code&gt;. This will take some  time (around 5 minutes). But once it is done, we have a ready to run web application. If you want to work with EiffelStudio you can find a &lt;code class=&quot;geshifilter&quot;&gt;*.ecf&lt;/code&gt; file in the &lt;code class=&quot;geshifilter&quot;&gt;$WEB_APP&lt;/code&gt;  folder. Open the project in EiffelStudio and compile it. It is necessary to compile the project  even though we just compiled it with the geant build tool. This is because EiffelStudio will  generate a set of meta data about the project during compilation.&lt;/p&gt;

&lt;p&gt;Now its time to start the web application. Either you can start it from within EiffelStudio or  you can use the binary file which was generated by the geant build tool. It is located in the  &lt;code class=&quot;geshifilter&quot;&gt;$WEB_APP&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Go back to your browser and type &lt;pre class=&quot;geshifilter&quot;&gt;localhost/fastcgi/demo/go_to.htm?question&lt;code&gt; in you 
browser. If you get an error saying that the URL is not valid everything is ok. Remember, the 
Apache web server communicates with our web application via the fast-cgi interface. But it won&#039;t 
do this on its own, we first need to configure it to do so.

The setting for the Apache web server are stored in text files which can be found at 
&lt;code&gt;/etc/apache2&lt;/pre&gt;. You will need super user rights in order to edit the settings. For  example you could open a text editor in super user mode and edit the files from within this  editor. Open the file &lt;code class=&quot;geshifilter&quot;&gt;/etc/apache2/httpd.conf&lt;/code&gt; and add the following lines:&lt;/p&gt;

&lt;p&gt;&lt;pre class=&quot;geshifilter&quot;&gt;LoadModule fastcgi_module /usr/lib/apache2/modules/mod_fastcgi.so

FastCgiExternalServer &quot;$WEB_APP/EIFGENs/web_application/W_code/web_application&quot; -host localhost:7878&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;You need to replace &lt;code class=&quot;geshifilter&quot;&gt;web_application&lt;/code&gt; with the name of your project&lt;/p&gt;

&lt;p&gt;If you are not using EiffelStudio the fast cgi server is located at  &lt;pre class=&quot;geshifilter&quot;&gt;$WEB_APP/web_application&lt;code&gt;

And finally open the file &lt;code&gt;/etc/apache2/sites-available/default&lt;/pre&gt; and add the  following lines:&lt;/p&gt;

&lt;p&gt;&lt;pre class=&quot;geshifilter&quot;&gt;Alias /demo &quot;$WEB_APP/EIFGENs/web_application/W_code/web_application&quot;
    &amp;lt;Directory &quot;$WEB_APP/EIFGENs/web_application/W_code/&quot;&amp;gt;
    SetHandler fastcgi-script
    Options ExecCGI
    Order allow,deny
    Allow from all
    &amp;lt;/Directory&amp;gt;
    TODO&lt;/pre&gt;&lt;/p&gt;

&lt;p&gt;You need to replace &lt;code class=&quot;geshifilter&quot;&gt;web_application&lt;/code&gt; with the name of your project&lt;/p&gt;

&lt;p&gt;If you are not using EiffelStudio the fast cgi server is located at  &lt;code class=&quot;geshifilter&quot;&gt;$WEB_APP/web_application&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now everything is set up, all that is left to do is to restart the apache server so the new  settings are loaded. Go to a console and type &lt;code class=&quot;geshifilter&quot;&gt;sudo /etc/init.d/apache2 restart&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Head back to the browser and once again type &lt;code class=&quot;geshifilter&quot;&gt;localhost/fastcgi/demo/go_to.htm?question&lt;/code&gt;. This time, the page should be displayed.&lt;/p&gt;

&lt;p&gt;Congratulations you just finished your first hands on experience with Goanna. Go ahead and play a little with the web page. Try some combinations of input.&lt;/p&gt;


&lt;h2 id=&quot;toc10&quot;&gt;A tour around town&lt;/h2&gt;
&lt;p&gt;This chapter is a guided tour through the example application. The tour will not go into great  depth but still we will see many things so bear with me.&lt;/p&gt;

&lt;p&gt;Open your favorite Eiffel editor and open the example web application. The project contains quite  a lot of clusters, but all the user code resides in the root_cluster. Within the root cluster you  find two sub clusters containing the servlets and the parameters.&lt;/p&gt;

&lt;p&gt;If you are not familiar with the java servlet, let me give you a brief introduction, for the  rest of you just skip the next paragraph.&lt;/p&gt;

&lt;p&gt;The name servlets comes from a mixing of the words server and applets. So servlets are applets  which run on a server. Any servlet must implement three features, &lt;pre class=&quot;geshifilter&quot;&gt;do_get(request, response), 
do_post(request, response) and do_head(request, response)&lt;/pre&gt;. Request is an object which  holds all the data about the requests. Similarly the response is an object which will hold the  generated response which is sent back to the user once the servlet is done with its processing.  The &lt;code class=&quot;geshifilter&quot;&gt;do_get, do_post and do_head&lt;/code&gt; features should implement the handling of the HTML  requests GET, POST and HEAD.&lt;/p&gt;

&lt;p&gt;Now the servlets in Goanna do exactly the same thing as the java servlets - even the interface  is the same.&lt;/p&gt;

&lt;p&gt;We start our tour at the &lt;code class=&quot;geshifilter eiffel&quot;&gt;APPLICATION_CONFIGURATION&lt;/code&gt; class. As the name suggests this class  holds configurations about the application. Take a look at &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_APPLICATION_CONFIGURATION&lt;/code&gt;  for the documentation of the attributes. Besides the configuration this class also holds the  logic on which servlet is used to generate the response for a request. Take a short look at the  function &lt;code class=&quot;geshifilter eiffel&quot;&gt;next_page&lt;/code&gt;. The displayable servlet which is returned is used to render the  response.&lt;/p&gt;

&lt;p&gt;The different properties which are set in the &lt;code class=&quot;geshifilter eiffel&quot;&gt;APPLICATION_CONFIGURATION&lt;/code&gt; are described in  the &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_APPLICATION_CONFIGURATION&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next we take a look at the &lt;code class=&quot;geshifilter eiffel&quot;&gt;APPLICATION_SERVER&lt;/code&gt;. The name might be a bit misleading, since  the class does not represent a server but it holds an instance of a eposix server and uses this  instance to communicate with the apache server. The class implements two features  &lt;code class=&quot;geshifilter eiffel&quot;&gt;command_line_ok&lt;/code&gt; and &lt;code class=&quot;geshifilter eiffel&quot;&gt;register_servlets&lt;/code&gt;. &lt;code class=&quot;geshifilter eiffel&quot;&gt;Command_line_ok&lt;/code&gt; does many things but  it does not check if the &lt;code class=&quot;geshifilter eiffel&quot;&gt;command_line&lt;/code&gt; is correct. Just leaves it as it is, it works even  if it doesn&#039;t do what the name suggest. Much more important for you is the  &amp;lt;/e&amp;gt;register_servlet&amp;lt;/e&amp;gt; method. It is responsible for registering all the servlets to the  &lt;code class=&quot;geshifilter eiffel&quot;&gt;SERVLET_MANAGER&lt;/code&gt;. I will explain later why it is important to register your servlets.  For now just remember, that you always have to update this feature if you add a new servlet.&lt;/p&gt;

&lt;p&gt;A few classes remain in the &lt;code class=&quot;geshifilter&quot;&gt;root_cluster&lt;/code&gt;. There is the &lt;code class=&quot;geshifilter eiffel&quot;&gt;MESSAGE_CATALOG&lt;/code&gt;.  It is used as a &lt;code class=&quot;geshifilter eiffel&quot;&gt;&lt;a href=&quot;http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+STRING&amp;btnI=I%27m+Feeling+Lucky&quot;&gt;&lt;span style=&quot;color: #800000&quot;&gt;STRING&lt;/span&gt;&lt;/a&gt;&lt;/code&gt; repository which allows to use a string in several different  places and only define it once. This also makes it easy to localize your web application by  simply adding another &lt;code class=&quot;geshifilter eiffel&quot;&gt;MESSAGE_CATALOG&lt;/code&gt; for another language.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;geshifilter eiffel&quot;&gt;SESSION_STATUS&lt;/code&gt; is used to hold informations during a session. Information stored  in an instance of this class will be available to every request during a session. The  &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt; is used to hold informations on the processing of this request.  It can also be used to hold informations which are only valid during the processing of this  request and not during the entire session. The purpose of the &lt;code class=&quot;geshifilter eiffel&quot;&gt;PARAMETER_PROCESSING_RESULT&lt;/code&gt;  is very similar to the purpose of the &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt; except that it holds  information about a parameter rather than about a request. Especially  &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt; is used heavily in the Goanna application framework. It is  passed as an argument to a lot of functions which makes it very interesting to use as a  container in order to pass information from one parts of the applications to an other during  the processing of a request.&lt;/p&gt;

&lt;p&gt;The last class in the root folder is &lt;code class=&quot;geshifilter eiffel&quot;&gt;PROGRAMMING_LANGUAGE_SELECTION&lt;/code&gt;. It is part of the  example application and not of the Goanna framework.&lt;/p&gt;

&lt;p&gt;Now that we came by all the classes in the &lt;code class=&quot;geshifilter&quot;&gt;root_cluster&lt;/code&gt; it is time to head into  the parts where the action happens.&lt;/p&gt;

&lt;p&gt;Let&#039;s first have a look at the servlets. You find three classes in the servlet cluster. Two of  them should remind you of the pages which you have seen while taking a look at the web page.  The third is &lt;code class=&quot;geshifilter eiffel&quot;&gt;SHARED_SERVLETS&lt;/code&gt; we will come back to this class in a moment. So lets start  with the &lt;code class=&quot;geshifilter eiffel&quot;&gt;ANSWER_SERVLET&lt;/code&gt;. It inherits from &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_DISPLAYABLE_SERVLET&lt;/code&gt; which means it  must implement the following four methods: &lt;code class=&quot;geshifilter eiffel&quot;&gt;ok_to_display&lt;/code&gt;, &lt;code class=&quot;geshifilter eiffel&quot;&gt;new_xml_document&lt;/code&gt;,  &lt;code class=&quot;geshifilter eiffel&quot;&gt;add_body&lt;/code&gt;, &lt;code class=&quot;geshifilter eiffel&quot;&gt;add_footer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;geshifilter eiffel&quot;&gt;Ok_to_display&lt;/code&gt; should be called by the &lt;code class=&quot;geshifilter eiffel&quot;&gt;next_page&lt;/code&gt; method of the  &lt;code class=&quot;geshifilter eiffel&quot;&gt;APPLICATION_CONFIGURATION&lt;/code&gt; class. It is there to make sure, that it is ok to display the  servlet to the user. This could for example be used to prevent the displaying of a servlet if a  user is not logged in.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;geshifilter eiffel&quot;&gt;new_xml_document&lt;/code&gt; will return a newly created instance of &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_XML_DOCUMENT&lt;/code&gt;. If you  take a closer look at the implementation of &lt;code class=&quot;geshifilter eiffel&quot;&gt;ANSWER_SERVLET&lt;/code&gt; you notice that  &lt;code class=&quot;geshifilter eiffel&quot;&gt;new_xml_document&lt;/code&gt; actually returns an instance of &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_PAGE_XML_DOCUMENT&lt;/code&gt;. This is  legal since &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_PAGE_XML_DOCUMENT&lt;/code&gt; is a subclass of &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_XML_DOCUMENT&lt;/code&gt;. Besides just  creating a new instance of &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_XML_DOCUMENT&lt;/code&gt; this feature already adds some elements to  the xml document. In this example only the &amp;amp;lt;html&amp;amp;gt;, &amp;amp;lt;head&amp;amp;gt;...&amp;amp;lt;/head&amp;amp;gt; and  &amp;amp;lt;body&amp;amp;gt; tags, but this can extended to add lets say a menu or a logo. So the  &lt;code class=&quot;geshifilter eiffel&quot;&gt;new_xml_document&lt;/code&gt; does also an implicit &lt;code class=&quot;geshifilter eiffel&quot;&gt;add_header&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;geshifilter eiffel&quot;&gt;add_body&lt;/code&gt; and &lt;code class=&quot;geshifilter eiffel&quot;&gt;add_footer&lt;/code&gt; do just what they promise by their names. They are used to add the content of the page.&lt;/p&gt;

&lt;p&gt;By now you may be wondering why we are creating xml documents if we want to return html as a  response to the request. Well the xml documents which are created will be transformed to html  after the servlet has processed the request. This allows to use the same output of the servlet  for different purposes, all that is needed is a rule to transform the xml into the requested  format.&lt;/p&gt;

&lt;p&gt;The last feature is called name and returns a string. This string is used by Goanna to determine  if this servlet is suited to handle a request or not. But more on this later. For now it is ok  to think of the name as being an identifier which allows it for a request to specify which  servlet should be used to handle it. Since &lt;code class=&quot;geshifilter eiffel&quot;&gt;name&lt;/code&gt; is used as an id, it must be unique within  the application.&lt;/p&gt;

&lt;p&gt;Lets move on to the &lt;code class=&quot;geshifilter eiffel&quot;&gt;QUESTION_SERVLET&lt;/code&gt;. The class looks very similar to the  &lt;code class=&quot;geshifilter eiffel&quot;&gt;ANSWER_SERVLET&lt;/code&gt;. There are two main differences, besides that the servlet generates  different xml output. The first is, that the last parameter in the call to  &lt;code class=&quot;geshifilter eiffel&quot;&gt;start_page_element&lt;/code&gt; in the feature &lt;code class=&quot;geshifilter eiffel&quot;&gt;new_xml_document&lt;/code&gt; is not &lt;code class=&quot;geshifilter&quot;&gt;Void&lt;/code&gt;.  This will start a &amp;amp;lt;form&amp;amp;gt; right after the &amp;amp;lt;body&amp;amp;gt; started. So if a page contains a  form, the last parameter in &lt;code class=&quot;geshifilter eiffel&quot;&gt;start_page_element&lt;/code&gt; must not be &lt;code class=&quot;geshifilter&quot;&gt;Void&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The other difference to the &lt;code class=&quot;geshifilter eiffel&quot;&gt;ANSWER_SERVLET&lt;/code&gt; is that the &lt;code class=&quot;geshifilter eiffel&quot;&gt;QUESTION_SERVLET&lt;/code&gt; redefines  make. This is necessary because the servlets wants to receive parameters. In Goanna each servlet  must specify which parameters it can handle and what kind of conditions are involved in  processing this parameters. This is done in the constructor. &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_APPLICATION_SERVLET&lt;/code&gt;  offers you five lists where you can add a parameter. How a parameter is handled during the  processing of the request depends on the list to which it was added. Take a look at the lists  in the &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_APPLICATION_SERVLET&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;We already reached the last class in this cluster: &lt;code class=&quot;geshifilter eiffel&quot;&gt;SHARED_SERVLETS&lt;/code&gt;. All this class does  is implementing the singleton pattern for every servlet in the application. Therefore a once  feature must be added for every servlet in the application.&lt;/p&gt;

&lt;p&gt;Last but not least we reached the parameters cluster. Similar to the servlet cluster we find a  &lt;code class=&quot;geshifilter eiffel&quot;&gt;SHARED_PARAMTERS&lt;/code&gt; class. This class does the same for the parameters what the  &lt;code class=&quot;geshifilter eiffel&quot;&gt;SHARED_SERVLETS&lt;/code&gt; does for the servlets. Now besides the &lt;code class=&quot;geshifilter eiffel&quot;&gt;SHARED_PARAMETERS&lt;/code&gt; you find  four other classes in this cluster, and if you think back at the web page you should recognize  them. Every parameter which we had on the HTML page has a corresponding Eiffel class in the  cluster parameters.&lt;/p&gt;

&lt;p&gt;Goanna provides a large set of deferred parameter base classes from which one can inherit when  implementing the parameters. When taking a look at the different parameters in the example one  can notice that even if each looks different they have several things in common. Each class  offers a method to store and to retrieve the value from the parameter into a persistent storage.  Also each parameter class has a name and a label_string. The name is used to uniquely identify  the parameter, and the label_string will be displayed besides the input field. It is possible to  use the same parameter multiple times on the same page. Goanna parameters offer a suffix  functionality. To use this functionality at least one of the following features needs to be  redefined: &lt;code class=&quot;geshifilter eiffel&quot;&gt;min_suffix&lt;/code&gt;, &lt;code class=&quot;geshifilter eiffel&quot;&gt;max_suffix&lt;/code&gt;, &lt;code class=&quot;geshifilter eiffel&quot;&gt;is_suffix_valid&lt;/code&gt;.&lt;/p&gt;


&lt;h2 id=&quot;toc11&quot;&gt;What happens behind the scenes&lt;/h2&gt;
&lt;p&gt;Now before we dive into writing our own web application let&#039;s have a look behind the scene.  Knowing how a request is processed by Goanna is essential in order to be able to write a web  application.&lt;/p&gt;

&lt;p&gt;When you send a request the apache server tries to match the requested URI to one of its Aliases. If it finds an alias, it will look what kind of reference is referred to by this alias. In the  case of a Goanna page, the alias will point to a fast-cgi server. So the apache server will  forward the request to the fast-cgi application i.e. the Goanna web application. Now the Goanna  application takes over the control.&lt;/p&gt;

&lt;p&gt;Basically the Goanna application will perform the following steps: &lt;ol&gt;
    &lt;li&gt; determine which servlet will handle the request&lt;/li&gt;
    &lt;li&gt; validate the parameters which have been submitted with the request&lt;/li&gt;
    &lt;li&gt; execute the servlets main logic&lt;/li&gt;
    &lt;li&gt; generate a response&lt;/li&gt;
    &lt;li&gt; This all sounds very easy and intuitive but there is more to it than it might appear at first.&lt;/li&gt;
&lt;/ol&gt;

&lt;/p&gt;


&lt;h2 id=&quot;toc12&quot;&gt;Which servlet shall process the request&lt;/h2&gt;
&lt;p&gt;A web application is basically an application which uses servlets to process requests sent to it.  Now if a request reaches the web application it must decide which servlet should process the  request. In order to do this, the application must know all servlets which exist in it and it  also needs a heuristic to decide which one to choose. Every servlet which wants to process  requests must subscribe itself to the &lt;code class=&quot;geshifilter eiffel&quot;&gt;SERVLET_MANAGER&lt;/code&gt;. Along with its subscription it  must pass a string which represents a path. When receiving a request, Goanna compares the  request URI against the servlets stored in the &lt;code class=&quot;geshifilter eiffel&quot;&gt;SERVLET_MANAGER&lt;/code&gt;. It searches for the most  specific servlet which matches the URI or a substring of it. For example the request URI is  &lt;code class=&quot;geshifilter&quot;&gt;/test/web/run.htm&lt;/code&gt; and there are three servlets stored in the &lt;code class=&quot;geshifilter eiffel&quot;&gt;SERVLET_MANAGER&lt;/code&gt;  one which subscribed to &lt;code class=&quot;geshifilter&quot;&gt;/test&lt;/code&gt;, one which subscribed to &lt;code class=&quot;geshifilter&quot;&gt;/test/web&lt;/code&gt; and  one which subscribed to &lt;code class=&quot;geshifilter&quot;&gt;/test/web/walk.htm&lt;/code&gt;. In this example &lt;code class=&quot;geshifilter&quot;&gt;/test/web&lt;/code&gt;  is chosen, since the &lt;code class=&quot;geshifilter&quot;&gt;/test/web/walk.htm&lt;/code&gt; does not match and &lt;code class=&quot;geshifilter&quot;&gt;/test&lt;/code&gt; is  less specific than &lt;code class=&quot;geshifilter&quot;&gt;/test/web&lt;/code&gt;. If there is no servlet which matches the request URI  or a substring, the default servlet is chosen, and if no default servlet is specified Goanna will  log an error.&lt;/p&gt;

&lt;p&gt;When the &lt;code class=&quot;geshifilter eiffel&quot;&gt;SERVLET_MANAGER&lt;/code&gt; has chosen a suitable servlet, Goanna populates the request  object and calls the &lt;code class=&quot;geshifilter eiffel&quot;&gt;do_get&lt;/code&gt; or the &lt;code class=&quot;geshifilter eiffel&quot;&gt;do_post&lt;/code&gt; method of the chosen servlet. Actually  always the &lt;code class=&quot;geshifilter eiffel&quot;&gt;do_get&lt;/code&gt; is executed because the &lt;code class=&quot;geshifilter eiffel&quot;&gt;do_post&lt;/code&gt; calls the &lt;code class=&quot;geshifilter eiffel&quot;&gt;do_get&lt;/code&gt;.&lt;/p&gt;


&lt;h2 id=&quot;toc13&quot;&gt;What happens in the servlet&lt;/h2&gt;
&lt;p&gt;Now that the control flow reached the servlet its getting interesting. The entering point for  the control flow is the &lt;code class=&quot;geshifilter eiffel&quot;&gt;do_get&lt;/code&gt; feature. So let us take a look at this feature, since most  of the magic happens in this feature understanding it is the key to understand how Goanna can be  used to build web applications. We will not go into every detail, but try to focus on the most  important aspects.&lt;/p&gt;

&lt;p&gt;The first thing the feature does is getting the &lt;code class=&quot;geshifilter eiffel&quot;&gt;SESSION_STATUS&lt;/code&gt; object. The session is  identified by a cookie. If the browser does not yet have a cookie set or there is no session  stored for a cookie a new &lt;code class=&quot;geshifilter eiffel&quot;&gt;SESSION_STATUS&lt;/code&gt; object is created.&lt;/p&gt;

&lt;p&gt;After the &lt;code class=&quot;geshifilter eiffel&quot;&gt;session_status&lt;/code&gt; object is initialized, a &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt; is  created. Remember for each servlet there exists only one instance in your application. Therefore  it is not possible to store informations about a certain request in a servlet. Still it is  important to be able to store informations about a request. The solution to this dilemma is the  &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt;. For every request an instance of &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt;  is created and passed along until the request has been processed. Within the &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt;  many references are available which make it easy to access different informations. So if you ever  need a reference to an object the &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt; is always a good place to look  for it. Remember the &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt; resides in the &lt;code class=&quot;geshifilter&quot;&gt;root_cluster&lt;/code&gt; of  the web application. So feel free to add your own features which are helpful for your application.&lt;/p&gt;

&lt;p&gt;Before the parameters are processed the feature &lt;code class=&quot;geshifilter eiffel&quot;&gt;ok_to_process_servlet&lt;/code&gt; is evaluated. This  is the first hook where you can influence the behavior of the servlet. If the  &lt;code class=&quot;geshifilter eiffel&quot;&gt;ok_to_process_servlet&lt;/code&gt; feature returns false, the servlet is not processed and the control  flow jumps directly to the place where the displaying servlet is chosen and the answer is  generated.&lt;/p&gt;


&lt;h2 id=&quot;toc14&quot;&gt;Handling the parameters&lt;/h2&gt;
&lt;p&gt;The next step is to get the parameters from the request. This is done by iterating over all  parameters which were passed with the request. Remember, that the parameters which a servlet can  process are specified in the constructor of the servlet. The defined parameters come here into  play. Depending on which collection a parameter has been added to, it will be processed  differently.&lt;/p&gt;

&lt;p&gt;In a first step a loop iterates over all parameters and creates an instance of  &lt;code class=&quot;geshifilter eiffel&quot;&gt;PARAMETER_PROCESSING_RESULT&lt;/code&gt; for each parameter. While doing this it also checks if all  required and all mandatory parameters are present and if there is any parameter which has not  been specified. If either an unexpected parameter has been found or a mandatory or a required  parameter is missing, the processing will abort at this point and the control flow jumps  directly to the place where the displaying servlet is chosen and the answer is generated.&lt;/p&gt;

&lt;p&gt;If everything is OK until here, the parameters are split into two categories, mandatory and  non-mandatory. Note that the required parameters are part of the non-mandatory parameters. Then both the mandatory and the non-mandatory parameters are sorted according to their  processing order. The processing order is given as an integer value, default is 3. The smaller  the &lt;code class=&quot;geshifilter eiffel&quot;&gt;processing_order&lt;/code&gt;, the earlier a parameter is processed, if several parameters have the same &lt;code class=&quot;geshifilter eiffel&quot;&gt;processing_order&lt;/code&gt; the order in which they are processed is implementation  dependent.&lt;/p&gt;


&lt;h2 id=&quot;toc15&quot;&gt;Processing the parameters&lt;/h2&gt;
&lt;p&gt;Now that the parameters are split and ordered its time to process them. First the mandatory  parameters are processed. Processing means that the feature process of the parameter is called.  After processing a mandatory parameter the application checks the value of feature  &lt;code class=&quot;geshifilter eiffel&quot;&gt;is_value_valid&lt;/code&gt;. If the value is not valid the processing of the parameters will stop  immediately and the feature &lt;code class=&quot;geshifilter eiffel&quot;&gt;perform_invalid_mandatory_parameters_processing&lt;/code&gt; is called.&lt;/p&gt;

&lt;p&gt;If all mandatory parameters contain valid values, the feature  &lt;code class=&quot;geshifilter eiffel&quot;&gt;perform_post_mandatory_parameter_processing&lt;/code&gt; is called. After that a second loop will  iterate over the none mandatory parameters. For each of the none mandatory parameters the process  feature of the parameter is executed, but the feature &lt;code class=&quot;geshifilter eiffel&quot;&gt;is_value_valid&lt;/code&gt; is not evaluated.  This means all parameters are processed even if one or more of them contain invalid values.  After all non-mandatory parameters have been processed the feature &lt;code class=&quot;geshifilter eiffel&quot;&gt;perform_final_processing&lt;/code&gt;  is called.&lt;/p&gt;


&lt;h2 id=&quot;toc16&quot;&gt;Generating the answer&lt;/h2&gt;
&lt;p&gt;In any case, if the processing was interrupted early or if all parameters contained valid values,  the servlet will call the &lt;code class=&quot;geshifilter eiffel&quot;&gt;next_page&lt;/code&gt; feature of the &lt;code class=&quot;geshifilter eiffel&quot;&gt;APPLICATION_SETTINGS&lt;/code&gt; and decide  which servlet is responsible for displaying the answer.&lt;/p&gt;

&lt;p&gt;In order to display an answer, a servlet must inherit from &lt;code class=&quot;geshifilter eiffel&quot;&gt;goa_displayable_servlet&lt;/code&gt; and  implement the deferred features.&lt;/p&gt;


&lt;h2 id=&quot;toc17&quot;&gt;Interacting with a database&lt;/h2&gt;
&lt;p&gt;What would a web application be without a database. If you only plan to do static pages then  don&#039;t use Goanna. In order to be independent of the DB a developer chooses, Goanna offers an  interface which allows to control the database accesses. The interface is rather simple and can  be implemented by the developer if he needs a special database. The class which contains the  mentioned interface is called &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_TRANSACTION_MANAGEMENT&lt;/code&gt;. This class offers a hand full of features which are called from within the Goanna web application framework and can be used as  hooks to influence the control flow.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_TRANSACTION_MANAGMENT&lt;/code&gt; allows to distinguish between a state where it is OK to  read from the DB and a state where it is OK to write to the DB. Unfortunately the naming of the  features is not always that clear. If a feature deals with &lt;code class=&quot;geshifilter eiffel&quot;&gt;version_access&lt;/code&gt; then it is  about reading data. If a feature deals with a &lt;code class=&quot;geshifilter eiffel&quot;&gt;transaction&lt;/code&gt; it is about writing data. The  feature commit is used to end a transaction.&lt;/p&gt;

&lt;p&gt;The state of the system changes in the following way:&lt;/p&gt;

&lt;p&gt;&lt;div class=&quot;geshifilter eiffel&quot; style=&quot;font-family: monospace;&quot;&gt;some state&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ok_to_start_version_access&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; start_version_access&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ok_to_read_data&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ok_to_end_version_access&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; end_version_access&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF; font-weight: bold;&quot;&gt;not&lt;/span&gt; ok_to_read&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; some state&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; some state&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ok_to_start_transaction&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; start_transaction&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ok_to_write_data&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ok_to_commit&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; commit&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #0600FF; font-weight: bold;&quot;&gt;not&lt;/span&gt; ok_write&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; some state&lt;/div&gt;&lt;/p&gt;


&lt;h2 id=&quot;toc18&quot;&gt;Creating your web application&lt;/h2&gt;
&lt;p&gt;After all this theory its time to start building your first web application with Goanna. The  following is all just advise, feel free to follow it or make it your way.&lt;/p&gt;

&lt;p&gt;My experience with browsers have shown that they are not made to ease the live of a web  application developer. So my first advise is: make a mock-up of your future web application.  This does not have to be anything fancy, just some plain old HTML and a CSS file. Once you are  happy with the design and the layout its still early enough to start messing with Goanna.&lt;/p&gt;

&lt;p&gt;I recommend that you start off with the example web application we created in the first part of  this tutorial. A good idea is to subtype the following classes for your application. This gives  you places to add common functionalities of the different servlets.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt; &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_APPLICATION_SERVLET&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt; &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_DISPLAYABLE_SERVLET&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt; &lt;e&gt; GOA_PAGE_XML_DOCUMENT (do not redefine any features)

If you take a look at &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_PAGE_XML_DOCUMENT&lt;/code&gt; you will notice that this class was generated. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the same cluster you can also find the following classes which are all generated at the same  time and are made to work together:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt; &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_PAGE_ATTRIBUTE_VALUES&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt; &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_PAGE_SCHEMA_CODES&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also in the cluster you find the &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_PAGE_XML_DOCUMENT_EXTENDED&lt;/code&gt; which is meant to contain  all the functionality which is common to all &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_PAGE_DOCUMENTS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In any case you should implement the class &lt;code class=&quot;geshifilter eiffel&quot;&gt;APPLICATION_CONFIGURATION&lt;/code&gt; early on since  without this class nothing works. The documentation of the features of  &lt;code class=&quot;geshifilter eiffel&quot;&gt;APPLICATION_CONFIGURATION&lt;/code&gt; can be found in the class &lt;code class=&quot;geshifilter eiffel&quot;&gt;GOA_APPLICATION_CONFIGURATION&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For every page in your web application repeat the following steps.&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt; As you do this you probably have to add features to other classes in order to store&lt;br /&gt;
intermediate values, or to pass values from one class to an other.&lt;/li&gt;
    &lt;li&gt; Values which should persist over several requests, but are not stored in the DB, go&lt;br /&gt;
into the class &lt;code class=&quot;geshifilter eiffel&quot;&gt;SESSION_STATUS&lt;/code&gt;. Values which should be discarded after the request&lt;br /&gt;
has been processed go into the class &lt;code class=&quot;geshifilter eiffel&quot;&gt;REQUEST_PROCESSING_RESULT&lt;/code&gt;. Both classes are &lt;br /&gt;
available from almost all functions and are meant to be containers for such values.&lt;/li&gt;
    &lt;li&gt; Make a list of all parameters which your page should be able to handle.&lt;/li&gt;
    &lt;li&gt; Mark all parameters which are mandatory. That means that the servlet cannot process a&lt;br /&gt;
request if the parameter is missing or invalid.&lt;/li&gt;
    &lt;li&gt; Mark all parameters which are required. That means that the servlet cannot process a request&lt;br /&gt;
if the parameter is missing, but the processing of the servlet does not depend on the &lt;br /&gt;
correctness of this parameter.&lt;/li&gt;
    &lt;li&gt; Mark all parameters which are optional. That means neither the presence nor the correctness is a requirement for the processing of the servlet.&lt;/li&gt;
    &lt;li&gt; Mark all parameters which should be added if they are missing.&lt;/li&gt;
    &lt;li&gt; Sort the list of parameters in the order they should be processed. Make sure that if&lt;br /&gt;
the validation and the processing of parameter A depends on the processing of parameter &lt;br /&gt;
B parameter B is listed before parameter A.&lt;/li&gt;
    &lt;li&gt; Give each parameter a processing priority. This can be done in an iterative way. Where &lt;br /&gt;
ever parameter starts with a priority of 3. If parameters A depends on parameter B then &lt;br /&gt;
A.processing_priority = B.processing_priority+1. Repeat this until no more parameters change &lt;br /&gt;
their processing priority.&lt;/li&gt;
    &lt;li&gt; Create all parameters which you haven&#039;t created for another page. Be careful if a parameter &lt;br /&gt;
is used in more than one servlet. The processing priority is the same for all pages where a &lt;br /&gt;
parameter is used. You don&#039;t have to write your parameters from scratch but you are encouraged&lt;br /&gt;
to inherit from one of the deferred classes in the goa_parameters cluster.&lt;/li&gt;
    &lt;li&gt; The most important task a parameter has to perform is to validate the correctness of its&lt;br /&gt;
value. If you ever focused a little on security in programs you know that any input from&lt;br /&gt;
the outside has to be considered hostile until it has been validated. And since your web&lt;br /&gt;
application is going to be published on the WWW and everybody can access it you should be&lt;br /&gt;
even more concerned about validating the values of the parameters which are transmitted with&lt;br /&gt;
a request.&lt;/li&gt;
    &lt;li&gt; After all parameters are created redefine those features of the servlet which you will need &lt;br /&gt;
for your servlet to work properly. But remember, the parameters should handle themselves. In &lt;br /&gt;
Goanna it is not the responsibility of the servlet to be concerned about parameters. Still the &lt;br /&gt;
framework offers you three features to hook into the processing of the servlet and let you &lt;br /&gt;
influence its behavior. Here is the list of the features which you can use as hooks into the &lt;br /&gt;
processing of the servlet.&lt;/li&gt;
    &lt;li&gt; perform_post_mandatory_parameter_processing&lt;/li&gt;
    &lt;li&gt; perform_final_processing&lt;/li&gt;
    &lt;li&gt; perform_invalid_mandatory_parameters_processing&lt;/li&gt;
    &lt;li&gt; I recommend you to separate the logic and the displaying of a servlet. Therefore you should create a &lt;br /&gt;
&lt;code class=&quot;geshifilter eiffel&quot;&gt;DISPLAYABLE_SERVLET&lt;/code&gt; for every &lt;code class=&quot;geshifilter eiffel&quot;&gt;APPLICATION_SERVLET&lt;/code&gt; which does not make any &lt;br /&gt;
calculations but focuses solely on generating the output.&lt;/li&gt;
    &lt;li&gt; Implement the missing features of the &lt;code class=&quot;geshifilter eiffel&quot;&gt;DISPLAYABLE_SERVLET&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;h2 id=&quot;toc19&quot;&gt;A last word&lt;/h2&gt;
 This guide is only an introduction to Goanna, also is the Goanna framework at the time of  this writing still under heavy development and may change fundamentally. So there is no  guarantee that what is described in the chapters above will hold at the time of reading.&lt;p&gt;Also not all topics have been covered in depth and others have even been touched at all.  But remember code and contracts are the best documentation...&lt;/p&gt;

&lt;p&gt;Specially the following topics have not found enough space in this guide.&lt;/p&gt;

&lt;ol&gt;
    &lt;li&gt; SSL&lt;/li&gt;
    &lt;li&gt;Parameter Suffix&lt;/li&gt;
    &lt;li&gt;The different parameters classes&lt;/li&gt;
&lt;/ol&gt;

</description>
 <comments>http://www.eiffelroom.org/article/creating_a_web_application_with_goanna#comments</comments>
 <category domain="http://www.eiffelroom.org/taxonomy/term/3">Tutorial</category>
 <category domain="http://www.eiffelroom.org/taxonomy/term/9">Advanced</category>
 <category domain="http://www.eiffelroom.org/tag/goanna">goanna</category>
 <category domain="http://www.eiffelroom.org/tag/origo">origo</category>
 <category domain="http://www.eiffelroom.org/tag/till">till</category>
 <category domain="http://www.eiffelroom.org/tag/web">web</category>
 <category domain="http://www.eiffelroom.org/tag/web_applications">web applications</category>
 <pubDate>Sun, 04 Nov 2007 01:59:24 -0800</pubDate>
 <dc:creator>bayt</dc:creator>
 <guid isPermaLink="false">236 at http://www.eiffelroom.org</guid>
</item>
</channel>
</rss>
