Introduction
 | IMPORTANT: sunShine (= session framework) is part of the scratchpad area
of the current Cocoon
release. This means it is not officially released yet. The API and functionality might change
before it is moved into the official release. Using this is at your own risk!
If you want to catch the latest status of these components check out Cocoon
from CVS and have a look at this upto-date documentation.
|
A session is a data storage which resides on the server and records
information about one single user. sunShine creates a session on demand and
from that point of time the user is tracked and information can be stored
inside the session. Each following request of this user is linked to the one
specific session, so there is always only one session per user on the
server.
To avoid a fast growing amount of sessions on the server and the
overcome potential security problems, a session has usually a valid period of
time. If during this period no new request comes in from the user, the session
object on the server will be destroyed by the server (this time period is
called session timeout). The web application often allows a user to explictly
destroy a session.
The usual web applications create sessions during login of a user and
destroy them when the user logs out.
This document describes the basic sunShine session management using
the sunShine Transformer.
The chapter "Special Contexts" explains some special sunShine
contexts which do not require a session. They are available everytime. These
special contexts are the request context, the response context and the
temporary context.
Sessions
The sunShine-session actions is responsible for creating and
terminating a session. It is controlled by a sitemap parameter named "action".
This parameter can have the values "create" and "terminate". If no parameter is
set, it defaults to "create".
The action either creates a new session immediately (if not already
available), or terminates it (if available).
Contexts
sunShine Transformer
The sunShine transformer is responsible for interpreting the tags
and performing the actions required. The sunShine transformer is configured
into the sitemap and can be used inside a document. All tags must be prefixed
with the sunShine namespace. So the actual tag used in the document will read
<sunshine:xxxx>. The current namespace URI for sunShine is
"http://cocoon.apache.org/sunshine/1.0".
Context-Tags
A context is basically an application specific block of XML data in
the users session. Each context has a unique name.
The command createcontext is used to create a new context.
A name attribute must be given to the context in order to identify it.
The following names may not be used: sunShine, request, response, session,
context, temp, sunSpot or sunRise. If a context of the same name already exists
then this command will have no effect.
<createcontext name="mycontext"/>
In order to delete a context the command deletecontext is
provided. Again a name attribute must be provided.
<deletecontext name="mycontext"/>
Once created, XML data can then be stored inside or read from a
given context.
Accessing context data
The data in a context can be dynamically accessed using the
following commands.
getxml allows data to be read out of a context. A
path attribute describes the source of the data inside the context and
consists of an XPath expression. All path values must be absolute and
only nodes and attributes can be accessed.
An optional default value can also be provided to allow for the
nonexistence of the requested data.
<getxml context="mycontext"
path="/User/Name"/>
<getxml context="mycontext"
path="/User/Name">Matthew</getxml>
Attributes can also be accessed.
<getxml context="mycontext"
path="/User/Name/@Age"/>
Data can be written into a context using the setxml
command. It is possible to set values or nodes as the following examples
show.
<setxml context="mycontext"
path="/User/Name"/>Carsten</setxml>
<setxml context="mycontext"
path="/User/"/><Name>Carsten</Name></setxml>
Using the setxml command causes all the nodes below the
target node to be deleted. If you wish to maintain the nodes and manipulate
individual branches of the XML tree - then sunShine offers the
mergexml command.
Use the removexml command to remove nodes from the
context.
<removexml context="mycontext"
path="/User/"/>
Example
The following example shows the use of several commands and in
particular how the mergexml command can be used to manipulate context
data.
 |  |  |
 |
<resource xmlns:sunshine="http://cocoon.apache.org/sunshine/1.0">
<sunshine:createcontext name="trackdemo"/>
<!-- build context data -->
<sunshine:setxml context="trackdemo" path="/">
<context>
<users>
<user id="1">
<name>Carsten</name>
</user>
</users>
</context>
</sunshine:setxml>
<sunshine:mergexml context="trackdemo" path="/context">
<users>
<user id="1">
<name>Ziegeler</name>
<developer>true</developer>
</user>
<user id="2">
<name>Walter</name>
</user>
</users>
</sunshine:mergexml>
<sunshine:getxml context="trackdemo" path="/"/>
</resource>
|  |
 |  |  |
In the above example, a context for storing data is added. Using
the setxml command data is then stored into the context. The following
mergexml command then changes the name of user-1 and adds a further
tag. As there is no original user-2 the complete subtree is then added to the
context.
Reading and writing contexts
Aside from the described means of accessing data in a context,
sunShine also provides for the reading and writing of contexts. This can be
used to write an application context out to a database or to read an
application context in from a file.
sunShine offers a very flexible way of defining the source of the
context data. It is possible to specify a resource (defined in the sitemap) or
a Java class. Using a resource allows for example the context data to be read
from a database using the SQL Transformer. As this source is a sunShine
resource, the data can be generated and transformed before passing into the
context.
When a context is created, it can get additional save and load URIs
which are used for loading/saving to/from the context:
<createcontext name="mycontext" load="cocoon://load-from-db"
save="cocoon://save-to-db"/>
These URIs can then be used inside a document to load data into a
context:
<loadxml context="mycontext"/>
This example would then load the context data via the resource
load-from-db which must be defined in the sitemap.
Parameters can be passed to and interpreted by the uri or the Java
class. This allows the context data to be read dependent on say the current
user.
<loadxml
context="mycontext"><user>ben</user></loadxml>
The resource addressed by the uri will receive the parameters as
request-parameters. In addition the name of the context will always be passed
as contextname.
Writing context data works in the same manner.
<savexml context="mycontext"/>
Both commands can use the optional path attribute:
<loadxml context="mycontext" path="/user"/>
<savexml context="mycotnext" path="/user"/>
The first command will read xml from the uri and store it in the
context under the node user, the second one saves only the xml subtree
under the node user to the uri. The resource addressed by the uri will
be passed in addition to the contextname parameter the path
parameter with the corresponding value. If the path attribute is not
present the path parameter will get the value "/".
Special Contexts
sunShine creates and maintains special contexts that allow the
applications to access the environment data. This allows the read-only access
to such things as the HttpRequest or the HtppResponse using the same XPath
commands previously described. These context do not require any session, they
are everytime available.
The Request Context - Accessing the Environment, Part One
The request context is an XML description of the current
HttpRequest. This context is a special read only context which can be accessed
with the usual commands:
<getxml context="request" path="/parameter"/>
If you for example want to get the value of a parameter with the
name username you can include the following command in your XML and it
will be replaced with the value of the parameter:
<getxml context="request"
path="/parameter/username"/>
This command will be replaced with all parameters from the current
request in XML format. If you wish to obtain the complete querystring as it was
passed into sunShine - without converting the data to XML - then you can use
the "/querystring" path:
<getxml context="request"
path="/querystring"/>
The result will be a string in the format
"?param=aaa&...".
The complete context you can access via these commands has the
following XML format:
 |  |  |
 |
<parameter>
<-- All parameters: parameter names build the elements
with the values as text node childs -->
<firstparameter>value of parameter</firstparameter>
<secondparameter>value of parameter</secondparameter>
</parameter>
<-- The querystring contains only parameters send by the GET method -->
<querystring>the querystring with a leading '?' or empty<querystring>
<-- All parameters. The tags are all inside the sunshine namespace.
The generated xml can be used without modification for the
sunshine:connection command. -->
<parametervalues>
<sunshine:params>
<sunshine:param>
<sunshine:name>1st parameter name</sunshine:name>
<sunshine:value>1st parameter value</sunshine:value>
</sunshine:param>
...
<sunshine:param>
<sunshine:name>2nd parameter name</sunshine:name>
<sunshine:value>2nd parameter value</sunshine:value>
</sunshine:param>
</sunshine:params>
<!-- If a parameter has more than one value, for each value a
<sunshine:param> block is generated. -->
</parametervalues>
<!-- lists all attributes, attribute names build the elements
with the values as text node childs -->
<attributes>
</attributes>
<!-- lists all headers, header names build the elements
with the values as text node childs -->
<headers>
</headers>
<!-- lists all cookies -->
<cookies>
<cookie name="...">
<value>the cookie value</value>
<name>the name of the cookie</name>
<comment>value</comment>
<domain>value</domain>
<path>value</path>
<maxAge>value</maxAge>
<secure>value</secure>
<version>value</version>
</cookie>
</cookies>
<characterEncoding>value</characterEncoding>
<contentLength>value</contentLength>
<contentType>value</contentType>
<protocol>value</protocol>
<remoteAddress>value</remoteAddress>
<remoteHost>value</remoteHost>
<scheme>value</scheme>
<serverName>value</serverName>
<serverPort>value</serverPort>
<authType>value</authType>
<method>value</method>
<contextPath>value</contextPath>
<pathInfo>value</pathInfo>
<pathTranslated>value</pathTranslated>
<remoteUser>value</remoteUser>
<requestedSessionId>value</requestedSessionId>
<requestURI>value</requestURI>
<servletPath>value</servletPath>
<isRequestedSessionIdFromCookie>value</isRequestedSessionIdFromCookie>
<isRequestedSessionIdFromCookie>value</isRequestedSessionIdFromCookie>
<isRequestedSessionIdValid>value</isRequestedSessionIdValid>
|  |
 |  |  |
The Response Context - Accessing the Environment, Part Two
The response context is an XML description of the current
HttpResponse. This context is a special write only context which can be
accessed with the usual commands:
<sunshine:setxml context="response"
path="/header"/>
This command will be removed from the XML and the information will
be added to the response. Using the response context headers and cookies can be
added.
Adding headers
Headers can be added either by setxml or by
appendxml. If setxml is used, the header with the name gets
the given value, regardless if the header had any value beforehand or not. If
appendxml is used the value will be added.
 |  |  |
 |
<sunshine:setxml context="response"
path="/header/headername">The value</sunshine:setxml>
or
<sunshine:appendxml context="response"
path="/header/headername">The value</sunshine:appendxml>
|  |
 |  |  |
Adding cookies
Cookies can be added either by setxml or by appendxml. There is
no difference between these commands.
 |  |  |
 |
<sunshine:setxml context="response" path="/cookie">
<!-- Now follows the cookie definition -->
<name>The cookie name</name>
<value>The value of the cookie</value>
<!-- The following are optional -->
<path>value</path>
<domain>value</domain>
<secure>true or false</secure>
<comment>value</comment>
<maxAge>value</maxAge>
<version>value</version>
</sunshine:setxml>
|  |
 |  |  |
The Temporary Context
The temporary context with the name "temp" is available on
each request. It is independent from the session and has no content when a new
request starts. It can be used like any other context except that the content
is lost when the current response is finished.
Using the tempory context it is possible to use store any xml
information for processing the current request.
Form Handling
To get feedback or information from a user, forms are commonly used
to present input field in the browser. The usual approach for form handling in
web application consists of two steps. The first request presents the form to
the user. This form initiates a second request that processes the form
values.
sunShine supports this two step process, in addition sunShine offers
a single step approach.
The common approach
The common approach consists of two steps or of creating two
resources. The first resource defines the form: All input fields are declared,
each gets a unique name. This form invokes the second resource.
This resource uses the sunShine transformer to get the values
provided by the user. The values are added by the browser to the parameters of
the request. So using the request context and getxml, the values can
be fetched.
If you want to create a form with two values - forename and surname
of the user, you could generate a base xml file with the information about this
form:
 |  |  |
 |
<page>
<form>
<action>form-handling-page</action>
<input name="forename" type="text"/>
<input name="surname" type="text"/>
</form>
</page>
|  |
 |  |  |
A stylesheet can transform this into valid html. The action tag
indicates that the "form-handling-page" should be invoked by submitting the
values.
The "form-handling-page" is a pipeline which is declared in the
sitemap and uses the sunShine transformer. It could also read the following
xml:
 |  |  |
 |
<page xmlns:sunshine="http://cocoon.apache.org/sunshine/1.0">
<forename>
<sunshine:getxml context="request" path="/parameter/forename"/>
</forename>
<surname>
<sunshine:getxml context="request" path="/parameter/surname"/>
</surname>
</page>
|  |
 |  |  |
As the form values are appended to the request, getxml
with specifying the path (which is the parameter name used for the input field)
inserts the value submitted by the user into the xml stream.
If you want to write the information in a session context, you must
wrap the whole xml inside a setxml:
 |  |  |
 |
<page xmlns:sunshine="http://cocoon.apache.org/sunshine/1.0">
<sunshine:setxml context="userdata" path="/user">
<forename>
<sunshine:getxml context="request" path="/parameter/forename"/>
</forename>
<surname>
<sunshine:getxml context="request" path="/parameter/surname"/>
</surname>
</sunshine:setxml>
</page>
|  |
 |  |  |
The user data is now stored inside the session context "userdata",
so the context has the following content:
 |  |  |
 |
<user>
<forename>Walter</forename>
<surname>Walterson</surname>
</user>
|  |
 |  |  |
The sunShine approach
The previous chapter showed the common approach for handling form
values. It forces the user to create two resources for a single form
handling.
sunShine offers an advanced approach. Only one single resource is
created. This resources contains the information about the input fields used
and in addition the information about where the submitted values should be
stored inside the session.
The example from the previous chapter could look like this:
 |  |  |
 |
<page xmlns:sunshine="http://cocoon.apache.org/sunshine/1.0">
<sunshine:form name="myform">
<sunshine:action>the-next-page</sunshine:action>
<sunshine:content>
<sunshine:inputxml name="forename" type="text"
context="userdata" path="/user/forename"/>
<sunshine:inputxml name="surname" type="text"
context="userdata" path="/user/surname"/>
</sunshine:content>
</sunshine:form>
</page>
|  |
 |  |  |
The form tag starts the form definition. The name attribute is
required to distinct between different forms on the same page. The action tag
defines the url invoked by the form and the content tag describes the content
of the form: its input fields.
The inputxml tag tells sunShine that the following request
contains form values which should be stored in the specified context under the
given path. The sunShine transformer transforms by removing the namespace and
the context attribute:
 |  |  |
 |
<page xmlns:sunshine="http://cocoon.apache.org/sunshine/1.0">
<form action="the-next-page">
<inputxml name="forename" type="text"/>
<inputxml name="surname" type="text"/>
</form>
</page>
|  |
 |  |  |
A stylesheet can now generate the appropriate html (or any other
format). The main difference is, that the resource invoked by submitting the
values has not to care about the form as sunShine maintains the form handling.
The only prerequisit is that a session for the current user and a session
context to store the information exists.
The sunShine approach allows a very easy way of form handling where
the resource which creates the form also handles the form.
For editing values - if the context already contains information
about the user - inputxml inserts the current value inside the tag. So
the xml streamed would after a second run would look like this:
 |  |  |
 |
<page xmlns:sunshine="http://cocoon.apache.org/sunshine/1.0">
<form action="the-next-page">
<inputxml name="forename" type="text">Walter</inputxml>
<inputxml name="surname" type="text">Walterson</inputxml>
</form>
</page>
|  |
 |  |  |
Like getxml it is also possible to provide default values
for the input field, if the context does not contain any information:
 |  |  |
 |
<sunshine:inputxml name="forename" context="userdata"
path="/user/forename">
Defaultname
</sunshine:xml>
|  |
 |  |  |
|