**/
protected void doService(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
RequestContext context = null;
try
{
// Create a context from the various bits and pieces.
context = createRequestContext(request, response);
// The subclass provides the engine.
IEngine engine = getEngine(context);
if (engine == null)
throw new ServletException(
Tapestry.getMessage("ApplicationServlet.could-not-locate-engine"));
boolean dirty = engine.service(context);
HttpSession session = context.getSession();
// When there's an active session, we *may* store it into
// the HttpSession and we *will not* store the engine
// back into the engine pool.
if (session != null)
{
// If the service may have changed the engine and the
// special storeEngine flag is on, then re-save the engine
// into the session. Otherwise, we only save the engine
// into the session when the session is first created (is new).
try
{
boolean forceStore =
engine.isStateful() && (session.getAttribute(_attributeName) == null);
if (forceStore || dirty)
{
if (LOG.isDebugEnabled())
LOG.debug("Storing " + engine + " into session as " + _attributeName);
session.setAttribute(_attributeName, engine);
}
}
catch (IllegalStateException ex)
{
// Ignore because the session been's invalidated.
// Allow the engine (which has state particular to the client)
// to be reclaimed by the garbage collector.
if (LOG.isDebugEnabled())
LOG.debug("Session invalidated.");
}
// The engine is stateful and stored in a session. Even if it started
// the request cycle in the pool, it doesn't go back.
return;
}
if (engine.isStateful())
{
LOG.error(
Tapestry.format(
"ApplicationServlet.engine-stateful-without-session",
engine));
return;
}
// No session; the engine contains no state particular to
// the client (except for locale). Don't throw it away,
// instead save it in a pool for later reuse (by this, or another
// client in the same locale).
if (LOG.isDebugEnabled())
LOG.debug("Returning " + engine + " to pool.");
_enginePool.store(engine.getLocale(), engine);
}
catch (ServletException ex)
{
log("ServletException", ex);
show(ex);
// Rethrow it.
throw ex;
}
catch (IOException ex)
{
log("IOException", ex);
show(ex);
// Rethrow it.
throw ex;
}
finally
{
if (context != null)
context.cleanup();
}
}