HttpServletResponse res)
throws IOException,
ServletException
{
// Placeholder for the RunData object.
RunData data = null;
try
{
// Check to make sure that we started up properly.
if (initFailure != null)
{
throw initFailure;
}
// Get general RunData here...
// Perform turbine specific initialization below.
data = RunDataFactory.getRunData( req, res,
getServletConfig() );
// If this is the first invocation, perform some
// initialization. Certain services need RunData to initialize
// themselves.
init(data);
// Get the instance of the Session Validator.
SessionValidator sessionValidator = (SessionValidator)ActionLoader
.getInstance().getInstance(TurbineResources.getString(
"action.sessionvalidator"));
// if this is the redirected stage of the initial request,
// check that the session is now not new.
// If it is not, then redirect back to the
// original URL (i.e. remove the "redirected" pathinfo)
if (data.getParameters()
.getString(REDIRECTED_PATHINFO_NAME, "false").equals("true"))
{
if (data.getSession().isNew())
{
String message = "Infinite redirect detected...";
log(message);
Log.error(message);
throw new Exception(message);
}
else
{
DynamicURI duri = new DynamicURI (data, true);
// Pass on the sent data in pathinfo.
for (Enumeration e = data.getParameters().keys() ;
e.hasMoreElements() ;)
{
String key = (String) e.nextElement();
if (!key.equals(REDIRECTED_PATHINFO_NAME))
{
String value =
(String) data.getParameters().getString ( key );
duri.addPathInfo((String)key, (String)value );
}
}
data.getResponse().sendRedirect( duri.toString() );
return;
}
}
else
{
// Insist that the client starts a session before access
// to data is allowed. this is done by redirecting them to
// the "screen.homepage" page but you could have them go
// to any page as a starter (ie: the homepage)
// "data.getResponse()" represents the HTTP servlet
// response.
if ( sessionValidator.requiresNewSession(data) &&
data.getSession().isNew() )
{
DynamicURI duri = new DynamicURI (data, true);
// Pass on the sent data in pathinfo.
for (Enumeration e = data.getParameters().keys() ;
e.hasMoreElements() ;)
{
String key = (String) e.nextElement();
String value =
(String) data.getParameters().getString ( key );
duri.addPathInfo((String)key, (String)value );
}
// add a dummy bit of path info to fool browser into
// thinking this is a new URL
if (!data.getParameters()
.containsKey(REDIRECTED_PATHINFO_NAME))
{
duri.addPathInfo(REDIRECTED_PATHINFO_NAME, "true");
}
// as the session is new take this opportunity to
// set the session timeout if specified in TR.properties
int timeout =
TurbineResources.getInt("session.timeout", -1);
if (timeout != -1)
{
data.getSession().setMaxInactiveInterval(timeout);
}
data.getResponse().sendRedirect( duri.toString() );
return;
}
}
// Fill in the screen and action variables.
data.setScreen ( data.getParameters().getString("screen") );
data.setAction ( data.getParameters().getString("action") );
// Special case for login and logout, this must happen before the
// session validator is executed in order either to allow a user to
// even login, or to ensure that the session validator gets to
// mandate its page selection policy for non-logged in users
// after the logout has taken place.
if ( data.hasAction()
&& data.getAction().equalsIgnoreCase(TurbineResources
.getString("action.login"))
|| data.getAction().equalsIgnoreCase(TurbineResources
.getString("action.logout")))
{
// If a User is logging in, we should refresh the
// session here. Invalidating session and starting a
// new session would seem to be a good method, but I
// (JDM) could not get this to work well (it always
// required the user to login twice). Maybe related
// to JServ? If we do not clear out the session, it
// is possible a new User may accidently (if they
// login incorrectly) continue on with information
// associated with the previous User. Currently the
// only keys stored in the session are "turbine.user"
// and "turbine.acl".
if (data.getAction().equalsIgnoreCase(TurbineResources
.getString("action.login")))
{
String[] names = data.getSession().getValueNames();
if (names != null)
{
for (int i=0; i< names.length; i++)
{
data.getSession().removeValue(names[i]);
}
}
}
ActionLoader.getInstance().exec ( data, data.getAction() );
data.setAction(null);
}
// This is where the validation of the Session information
// is performed if the user has not logged in yet, then
// the screen is set to be Login. This also handles the
// case of not having a screen defined by also setting the
// screen to Login. If you want people to go to another
// screen other than Login, you need to change that within
// TurbineResources.properties...screen.homepage; or, you
// can specify your own SessionValidator action.
ActionLoader.getInstance().exec(
data,TurbineResources.getString("action.sessionvalidator") );
// Put the Access Control List into the RunData object, so
// it is easily available to modules. It is also placed
// into the session for serialization. Modules can null
// out the ACL to force it to be rebuilt based on more
// information.
ActionLoader.getInstance().exec(
data,TurbineResources.getString("action.accesscontroller"));
// Start the execution phase. DefaultPage will execute the
// appropriate action as well as get the Layout from the
// Screen and then execute that. The Layout is then
// responsible for executing the Navigation and Screen
// modules.
//
// Note that by default, this cannot be overridden from
// parameters passed in via post/query data. This is for
// security purposes. You should really never need more
// than just the default page. If you do, add logic to
// DefaultPage to do what you want.
String defaultPage = TurbineTemplate.getDefaultPageName(data);
if (defaultPage == null)
{
/*
* In this case none of the template services are running.
* The application may be using ECS for views, or a
* decendent of RawScreen is trying to produce output.
* If there is a 'page.default' property in the TR.props
* then use that, otherwise return DefaultPage which will
* handle ECS view scenerios and RawScreen scenerios. The
* app developer can still specify the 'page.default'
* if they wish but the DefaultPage should work in
* most cases.
*/
defaultPage = TurbineResources.getString(
"page.default", "DefaultPage");
}
PageLoader.getInstance().exec(data, defaultPage);
// If a module has set data.acl = null, remove acl from
// the session.
if ( data.getACL() == null )
{
data.getSession().removeValue(
AccessControlList.SESSION_KEY);
}
try
{
if ( data.isPageSet() == false &&
data.isOutSet() == false )
throw new Exception ( "Nothing to output" );
// We are all done! if isPageSet() output that way
// otherwise, data.getOut() has already been written
// to the data.getOut().close() happens below in the
// finally.
if ( data.isPageSet() && data.isOutSet() == false )
{
// Modules can override these.
data.getResponse()
.setLocale( data.getLocale() );
data.getResponse()
.setContentType( data.getContentType() );
// Handle the case where a module may want to send
// a redirect.
if ( ( data.getStatusCode() == 301 ||
data.getStatusCode() == 302 ) &&
data.getRedirectURI() != null )
{
data.getResponse()
.sendRedirect ( data.getRedirectURI() );
}
// Set the status code.
data.getResponse().setStatus ( data.getStatusCode() );
// Output the Page.
data.getPage().output (data.getOut());
}
}
catch ( Exception e )
{
// The output stream was probably closed by the client
// end of things ie: the client clicked the Stop
// button on the browser, so ignore any errors that
// result.
}
}
catch ( Exception e )
{
handleException(data, res, e);
}
catch (Throwable t)
{
handleException(data, res, t);
}
finally
{
// Make sure to close the outputstream when we are done.
try
{
data.getOut().close();
}
catch (Exception e)
{
// Ignore.
}