<?xml version="1.0"?>
<!-- 
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 -->

<document>

 <properties>
  <title>Turbine Services - RunData Service</title>
 </properties>

<body>

<section name="RunData Service">

<p>
RunData is an interface that is passed around within Turbine. RunData
provides the threading mechanism, as there is one RunData object per
HTTP request. The RunData service manages the isues surrounding multiple
requests being accepted. TurbineRunData is the interface that is
specific to the Turbine RunData service, and via the recyclable
interface can be sent back to the Factory for recycling.
</p>

<p>
RunData objects should never be held on to across requests. They are
considered one time only objects.
</p>

<p>
All this higher level processing by the service means that for each HTTP
request there is an interface that is castable to, or available, that
can be used to access all information to do with that request. As an
example, information such as the content type of the request and the
response can be queried or sent, as well as other information
surrounding servlet HTTP management, such as Sessions, PrintWriters as
well as Turbine specific information such as Users, AccessControlLists,
Templating, Error Handling and Contexts.
</p>

</section>

<section name="Configuration">

<p>
In the TurbineResources.properties the service needs to be defined for
Turbine to initialize with.
</p>


<source><![CDATA[
# -------------------------------------------------------------------
# 
#  S E R V I C E S
#
# -------------------------------------------------------------------
# Classes for Turbine Services should be defined here.
# Format: services.[name].classname=[implementing class]
#
# To specify properties of a service use the following syntax:
# service.[name].[property]=[value]

services.TurbineRunDataService.classname=org.apache.turbine.services.rundata.TurbineRunDataService
.
.
.
# -------------------------------------------------------------------
#
#  R U N   D A T A   S E R V I C E
#
# -------------------------------------------------------------------
# Default implementations of base interfaces for request processing.
# Additional configurations can be defined by using other keys
# in the place of the <default> key.  
# -------------------------------------------------------------------

services.RunDataService.default.run.data=org.apache.turbine.services.rundata.DefaultTurbineRunData
services.RunDataService.default.parameter.parser=org.apache.turbine.util.parser.DefaultParameterParser
services.RunDataService.default.cookie.parser=org.apache.turbine.util.parser.DefaultCookieParser
]]></source>

</section>

<section name="Using RunData">

<p>
As RunData encapsulates all aspects of Turbine's gathering the
HttpRequest and sending the HttpResponse, any status to do with the
Request can be queried and any manipulation of the final response can be
carried out through the RunData Object.
</p>

<p>
Turbine is a servlet and the functionality equated with the
javax.servlet and javax.servlet.http can be manipulated through the
RunData interface. One of the most useful components of the Servlet
libraries was Sessions. These are accessed through RunData; it also
provides direct access to the PrintWriter, Server details, Content
Types, ContextPath, Redirections, Client details, etc. Some of the
functions which equate with the servlet libraries are:
</p>

<source><![CDATA[
getLocale()
setLocale(Locale locale)
getCharSet()
setCharSet(String charset)
getContentType()
setContentType(String mimetype)
getOut()  //get PrintWriter Object
getRedirectURI()
getRemoteAddr()
getRemoteHost()
getRequest()
getResponse()
getServletContext()
getSession()
getStatusCode()  
]]></source>

<p>
The get/setLocale(), get/setCharSet() and get/setContentType() methods
are used for specifying the locale, character encoding and content type
of the body of the servlet response.
</p>

<p>
The method setLocale() is called to specify explicitly the locale 
of the response. If setLocale() is not called, the "locale.default.language"
and "locale.default.country" properties from Turbine Resources are used to
determine the locale. If these properties are not set, the JVM's default
locale determines the locale.
</p>

<p>
If the locale is set to something else than the default locale or Locale.US,
an explicit encoding is not specified with the setCharSet() method or the
"locale.default.charset" property, and the main MIME type of the content is
"text", the getContentType() method adds a locale specific encoding (charset) 
to the content type automatically.
</p>

<p>
The locale specific charset is obtained from the MimeTypeService, which
maintains mappings between locales and charsets.
</p>

<p>
As always consult the Javadocs for more detail.
</p>

<p>
To use Turbine to only manipulate the functions that came with the Sun
Servlet libraries is to miss out on Turbine's power. Turbine is a
framework which enables manipulation of the HttpResponse and HttpRequest
above and beyond the simple Servlet libraries. Turbine has services and
layers surrounding those available with the Response and Request that
allow easier creation and management of Websites and Web-enabled
Applications. In fact you wont have to type import javax.servlet.*
again!
</p>

</section>

<section name="Session Management">
<p>
Sessions are managed in Turbine via the User interface. The User
interface allows for a blend of cookie management, memory management and
relational database to be used to manage a user's session. A user of the
site can have their Turbine session set as either temporary storage or
permanent storage. The permanent storage will survive a servlet engine
restart. How all this is managed by Turbine is transparent to the Java
Engineer. As an example assume we want to monitor how often a user
returns to the website we are developing and we want to reward them for
their returning interaction:
</p>

<source><![CDATA[
//in Login Action class
public void doPerform(RunData data, Context context) 
    throws Exception
{
    //get the Parameters, username and password
    ParameterParser params = data.getParameters();
    String loginname = params.getString("username");
    String password = params.getString("password");

    try
    {
        //cast to TurbineUser interface
        //and check if user is in system
        TurbineUser user = (TurbineUser)
                             TurbineSecurity
                              .getAuthenticatedUser(loginname, password);

        //put User into Session 
        data.setUser(user);

        //mark the User as logged in
        user.setHasLoggedIn(new Boolean(true));

        //add to the access counter
        user.incrementAccessCounter();

        //add to the access counter for the session
        user.incrementAccessCounterForSession();
 
        //check to see if user is to have
        //their status changed to valued
        if(user.getAccessCounter() > 500 )
        {
            //set into persistant storage
            //that our visitor is now a 
            //valued user
            user.setPerm("valued", new Boolean(true));
        }

        data.save();
    }
    catch (Exception e)
    {
        //error handling
    }
}
]]></source>

<p>
While skeletal this shows a good example of permanent and temporary
management of User information. The line data.setUser() puts the User
into session, the hasLoggedIn() method updates the User Object to
reflect the fact that the session has passed Authentication; however
until the RunData's save method is called both the User and hasLoggedIn
flag are only existing in Turbine's memory. Neither become a part of
RunData's HttpSession until they are saved into the session through
data.save(). The AccessCounter is persistent storage and is saved into
the database. The AccessCounter for the session counts the number of
pages that are requested throgh Turbine for the user's session. Once
their session logs out or the session times out, that information is
lost. The user.setPerm() method allows for information to be stored
persistently into the database as a HashTable entry. The example above
was intended to show that information can be handled through a
consistent interface allowing for the management at the
request/response, session and persistent levels without any direct
manipulation of the HttpRequest, HttpResponse, HttpSession or Relational
database. As always, refer to the Javadocs for more information on the
RunData, User and TurbineUser interfaces.
</p>

</section>

<section name="Parameter and Cookie Parsing">
<p>
One of the most useful parts of the RunData interface is the easy
retrieval of parameters attached to a request. The ParameterParser and
CookieParser Interfaces are available through the RunData interface and
provide convenience methods for gathering parameters from either the URI
or Session. Turbine handles parameters as name/value pairs through the
URI via the BaseValueParser object, allowing the parameters to be
requested as a Java type rather than a catch-all:
</p>

<source><![CDATA[
/** the doPerform method from Invoice.java Action class */
public void doPerform(RunData data, Context context) throws Exception
{
    //get parameters
    ParameterParser params = data.getParameters();

    /**
     * Where "units" is the HTML Input Form name
     */
    int units = params.getInt("units");  

    /**
     * Get the description, if there is no entry from the
     * HTML input form, set the default as "No Description". 
     */
    String description = params.getString("description","No Description");

    /**
     * If there is no total, set the value to 0.
     */
    BigDecimal total = params.getBigDecimal("total",new BigDecimal(0));
}
]]></source>

<p>
The above example shows gathering of name/value pairs from HTML Form
Inputs and setting default values for those forms. In the case of
description, if the description is null, then the default value "No
Description" will be substituted. The Javadocs for ParameterParser show
more information on the methods available.
</p>

</section>

<section name="Security Management">

<p>
The RunData interface also exposes security management methods and
information which are encapsulated into a request. The RunData interface
exposes the AccessControlList Object, which encapsulates the Permissions
and Roles for the Groups the User is in. The getACL() method allows for
the permission of the User to be queried against their ACL.
</p>

<source><![CDATA[
/** the doPerform method from DeleteInvoice.java Action class */
public void doPerform(RunData data, Context context) throws Exception
{
    //check if the User is authorized before
    //deleting the invoice
    AccessControlList acl =  data.getACL();
    if(acl.hasPermission("deleteinvoice"))
    {
        //delete invoice logic
    }
    else
    {
        data.setMessage("You do not have permission to delete an invoice.");
        data.setTemplate(data, "UnauthorizedRequest.vm");
    }
}
]]></source>

<p>
The above example gets the AccessControlList Object for the User through
the RunData interface. The ACL is used to check against the Permissions
the User has, the PermissionSet, or a list of all permissions the User
has, most likely taken from a database. In this example, the check is
against the string "deleteinvoice". If the User has the permission, they
will be able to delete the invoice, otherwise the User will get an
unauthorized request Velocity screen.
</p>

</section>

<section name="Template Management">

<p>
The RunData also exposes methods to manipulate Screens, Actions, Pages
and Layouts. The templating service assembles the screens, actions and
layouts as well as exposing template methods. The methods for managing
screens and actions includes:
</p>

<source><![CDATA[
getAction()
getLayout()
getLayoutTemplate()
getScreen()
getTemplateInfo()  //returns TemplateInfo Object
hasAction()
hasScreen()
setAction()
setLayout()
setLayoutTemplate()
setScreen()
setScreenTemplate()    
]]></source>

<p>
For more information on how to use the RunData Interface with Velocity
templates and the Velocity context, view the Velocity Site
documentation.
</p>

</section>

<section name="Messaging">

<p>
One of the other useful wrappers the RunData interface provides access
to is messaging. The Message can be set as a String, an ECS Element or
as a FormMessages object. RunData contains access to other convenience
methods to do with Messaging such as:
</p>

<source><![CDATA[
addMessage(Element msg)
addMessage(String msg)
hasMessage()    //if the request has a message
getMessage()
getMessageAsHTML()
getMessages()   //returns a FormMessages Object
setMessage(String msg)
setMessage(Element msg)
setMessage(FormMessages msgs)  
]]></source>

<p>
An example of using messages with Velocity templates in an action is
below:
</p>

<source><![CDATA[
/** the doPerform method from Invoice.java Action class */
public void doPerform(RunData data, Context context) throws Exception
{
    data.setMessage("A message for output.");
    data.setTemplate(data, "Test.vm");
}
]]></source>

<p>
This would be accessed in the Velocity template via:
</p>

<source><![CDATA[
#*
    Velocity file, Test.vm, showing messaging example.
*#

$data.getMessage()
]]></source>

<p>
And the output would be:
</p>

<source><![CDATA[
A message for output.
]]></source>

<p>
The Javadocs for RunData show all the methods available through the
interface and is definitely the place to start when looking for more
information on what RunData exposes. The RunData interface is one of the
most important areas for a Java Engineer to understand and be familiar
within the Turbine Framework. Understanding RunData is of continual
benefit.
</p>

</section>

</body>
</document>
