com.primix.tapestry.engine
Class AbstractEngine

java.lang.Object
  |
  +--com.primix.tapestry.engine.AbstractEngine
All Implemented Interfaces:
java.util.EventListener, java.io.Externalizable, HttpSessionBindingListener, IEngine, java.io.Serializable
Direct Known Subclasses:
SimpleEngine

public abstract class AbstractEngine
extends java.lang.Object
implements IEngine, java.io.Externalizable, HttpSessionBindingListener

Basis for building real Tapestry applications. Immediate subclasses provide different strategies for managing page state and other resources between request cycles. Uses a shared instance of ITemplateSource and ISpecificationSource stored as attributes of the ServletContext (they will be shared by all sessions).

An application is designed to be very lightweight. Particularily, it should never hold references to any IPage or IComponent objects. The entire system is based upon being able to quickly rebuild the state of any page(s).

Where possible, instance variables should be transient. They can be restored inside setupForRequest(RequestContext).

In practice, a subclass (usually SimpleEngine) is used without subclassing. Instead, a visit object is specified. To facilitate this, the application specification may include a property, com.primix.tapestry.visit-class which is the class name to instantiate when a visit object is first needed. See createVisit(IRequestCycle) for more details.

Some of the classes' behavior is controlled by JVM system parameters (typically only used during development):
Parameter Description
com.primix.tapestry.enable-reset-service If true, enabled an additional service, reset, that allow page, specification and template caches to be cleared on demand. See isResetServiceEnabled().
com.primix.tapestry.disable-caching If true, then the page, specification, template and script caches will be cleared after each request. This slows things down, but ensures that the latest versions of such files are used. Care should be taken that the source directories for the files preceeds any versions of the files available in JARs or WARs.

Version:
$Id: AbstractEngine.java,v 1.37 2001/09/28 19:42:02 hship Exp $
Author:
Howard Ship
See Also:
Serialized Form

Field Summary
protected static java.lang.String HELPER_BEAN_POOL_NAME
          Servlet context attribute name for the Pool used to obtain helper beans.
protected static java.lang.String PAGE_SOURCE_NAME
          Servlet context attribute name for the IPageSource instance.
protected  PageSource pageSource
          The source for pages, which acts as a pool, but is capable of creating pages as needed.
protected static java.lang.String SCRIPT_SOURCE_NAME
          The name of the context attribute for the IScriptSource instance.
protected  ApplicationSpecification specification
          The specification for the application, which lives in the ServletContext.
protected static java.lang.String SPECIFICATION_SOURCE_NAME
          Servlet context attribute name for the default ISpecificationSource instance.
protected  ISpecificationSource specificationSource
          The source for component specifications, stored in the ServletContext (like templateSource).
protected static java.lang.String TEMPLATE_SOURCE_NAME
          Servlet context attribute name for the default ITemplateSource instance.
protected  ITemplateSource templateSource
          The source for template data.
static java.lang.String VISIT_CLASS_PROPERTY_NAME
          The name of the application specification property used to specify the class of the visit object.
 
Fields inherited from interface com.primix.tapestry.IEngine
EXCEPTION_PAGE, HOME_PAGE, STALE_LINK_PAGE, STALE_SESSION_PAGE
 
Constructor Summary
AbstractEngine()
           
 
Method Summary
protected  void activateExceptionPage(IRequestCycle cycle, ResponseOutputStream output, java.lang.Throwable cause)
          Sets the Exception page's exception property, then renders the Exception page.
protected abstract  void cleanupAfterRequest(IRequestCycle cycle)
          Invoked at the end of the request cycle to release any resources specific to the request cycle.
protected  void cleanupEngine()
          Invoked when the engine is removed from the HttpSession i.e., because the sesssion timed out or was explicitly invalidated.
protected  void clearCachedData()
          Discards all cached pages, component specifications and templates.
protected  IEngineService constructService(java.lang.String name)
          Invoked by getService(String) to construct a named service.
protected  java.lang.Object createVisit(IRequestCycle cycle)
          Invoked to lazily create a new visit object when it is first referenced (by getVisit(IRequestCycle)).
 void extendDescription(java.lang.StringBuffer buffer)
          Extends the description of the class generated by toString().
abstract  java.util.Collection getActivePageNames()
          Implemented by subclasses to return the names of the active pages (pages for which recorders exist).
 java.lang.String getContextPath()
          Returns the context path, the prefix to apply to any URLs so that they are recognizing as belonging to the Servlet 2.2 context.
 boolean getHasVisit()
           
 Pool getHelperBeanPool()
          Returns a Pool from which helper objects may be obtained, and to which they should be returned.
 ListenerMap getListeners()
          Allows subclasses to include listener methods easily.
 java.util.Locale getLocale()
          Returns the locale for the engine.
 IMonitor getMonitor(RequestContext context)
          Overriden in subclasses that support monitoring.
 IPageSource getPageSource()
          Returns the object used to load a page from its specification.
 IResourceResolver getResourceResolver()
          Returns an object which can find resources and classes.
 IScriptSource getScriptSource()
          Returns a source for parsed IScripts.
 IEngineService getService(java.lang.String name)
          Returns a service with the given name, constructing it (via constructService(String) if necessary.
 java.lang.String getServletPath()
          Returns the URL path that corresponds to the servlet for the application.
 ApplicationSpecification getSpecification()
          Returns the specification, if available, or null otherwise.
 ISpecificationSource getSpecificationSource()
          Returns the source of all component specifications for the application.
 ITemplateSource getTemplateSource()
          Returns the source for HTML templates.
 java.lang.Object getVisit()
          Gets the visit object, if it has been created already.
 java.lang.Object getVisit(IRequestCycle cycle)
          Gets the visit object, invoking createVisit(IRequestCycle) to create it lazily if needed.
protected  void handleStaleLinkException(StaleLinkException ex, IRequestCycle cycle, ResponseOutputStream output)
          Invoked by service(RequestContext) if a StaleLinkException is thrown by the service.
protected  void handleStaleSessionException(StaleSessionException ex, IRequestCycle cycle, ResponseOutputStream output)
          Invoked by service(RequestContext) if a StaleSessionException is thrown by the service.
 boolean isResetServiceEnabled()
          Returns true if the reset service is curently enabled.
 boolean isStateful()
          Returns true if the engine has state and, therefore, should be stored in the HttpSession.
 void readExternal(java.io.ObjectInput in)
          Reads the state serialized by writeExternal(ObjectOutput).
protected  void redirect(java.lang.String pageName, IRequestCycle cycle, ResponseOutputStream out, RequestCycleException exception)
          Invoked, typically, when an exception occurs while servicing the request.
protected  void redirectOut(IRequestCycle cycle, RedirectException ex)
          Invoked when a RedirectException is thrown during the processing of a request.
protected  void render(IRequestCycle cycle, ResponseOutputStream output)
          Invoked to render an actual result page (as opposed to a rewind).
protected  void reportException(java.lang.String reportTitle, java.lang.Throwable ex)
          Writes a detailed report of the exception to System.err.
protected  void restart(IRequestCycle cycle)
          Invalidates the session, then redirects the client web browser to the servlet's prefix, starting a new visit.
 boolean service(RequestContext context)
          Delegate method for the servlet.
protected  void serviceAction(IRequestCycle cycle, java.lang.String[] serviceContext, ResponseOutputStream output)
          Processes an 'action' URL.
protected  void serviceDirect(IRequestCycle cycle, java.lang.String[] serviceContext, java.lang.String[] parameters, ResponseOutputStream output)
          Processes a 'direct' URL.
protected  void servicePage(IRequestCycle cycle, java.lang.String[] serviceContext, ResponseOutputStream output)
          Processes a 'page' URL.
protected  void serviceReset(IRequestCycle cycle, java.lang.String[] serviceContext, ResponseOutputStream output)
          Clears the cache of pages, specifications and templates.
 void setLocale(java.util.Locale value)
          Changes the locale for the engine.
protected  void setStateful()
          Invoked by subclasses to indicate that some state must now be stored in the engine (and that the engine should now be stored in the HttpSession).
protected  void setupForRequest(RequestContext context)
          Invoked from service(RequestContext) to ensure that the engine's instance variables are setup.
 void setVisit(java.lang.Object value)
          Allows the visit object to be removed; typically done when "shutting down" a user's session (by setting the visit to null).
 java.lang.String toString()
          Generates a description of the instance.
 void valueBound(HttpSessionBindingEvent event)
          Invoked when the application object is stored into the HttpSession.
 void valueUnbound(HttpSessionBindingEvent event)
          Invoked when the application object is removed from the HttpSession.
 void writeExternal(java.io.ObjectOutput out)
          Writes the following properties: locale name (Locale.toString()) visit
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface com.primix.tapestry.IEngine
createPageRecorder, forgetPage, getPageRecorder
 

Field Detail

specification

protected transient ApplicationSpecification specification
The specification for the application, which lives in the ServletContext. If the session (and application) moves to a different context (i.e., a different JVM), then we want to reconnect to the specification in the new context. A check is made on every request cycle as needed.

templateSource

protected transient ITemplateSource templateSource
The source for template data. The template source is stored in the ServletContext as a named attribute. After de-serialization, the application can re-connect to the template source (or create a new one).

specificationSource

protected transient ISpecificationSource specificationSource
The source for component specifications, stored in the ServletContext (like templateSource).

SCRIPT_SOURCE_NAME

protected static final java.lang.String SCRIPT_SOURCE_NAME
The name of the context attribute for the IScriptSource instance. The application's name is appended.
Since:
1.0.2

VISIT_CLASS_PROPERTY_NAME

public static final java.lang.String VISIT_CLASS_PROPERTY_NAME
The name of the application specification property used to specify the class of the visit object.

TEMPLATE_SOURCE_NAME

protected static final java.lang.String TEMPLATE_SOURCE_NAME
Servlet context attribute name for the default ITemplateSource instance. The application's name is appended.

SPECIFICATION_SOURCE_NAME

protected static final java.lang.String SPECIFICATION_SOURCE_NAME
Servlet context attribute name for the default ISpecificationSource instance. The application's name is appended.

HELPER_BEAN_POOL_NAME

protected static final java.lang.String HELPER_BEAN_POOL_NAME
Servlet context attribute name for the Pool used to obtain helper beans. The application's name is appended.
Since:
1.0.4

PAGE_SOURCE_NAME

protected static final java.lang.String PAGE_SOURCE_NAME
Servlet context attribute name for the IPageSource instance. The application's name is appended.

pageSource

protected transient PageSource pageSource
The source for pages, which acts as a pool, but is capable of creating pages as needed. Stored in the ServletContext, like templateSource.
Constructor Detail

AbstractEngine

public AbstractEngine()
Method Detail

activateExceptionPage

protected void activateExceptionPage(IRequestCycle cycle,
                                     ResponseOutputStream output,
                                     java.lang.Throwable cause)
                              throws ServletException
Sets the Exception page's exception property, then renders the Exception page.

If the render throws an exception, then copious output is sent to System.err and a ServletException is thrown.


reportException

protected void reportException(java.lang.String reportTitle,
                               java.lang.Throwable ex)
Writes a detailed report of the exception to System.err.

cleanupAfterRequest

protected abstract void cleanupAfterRequest(IRequestCycle cycle)
Invoked at the end of the request cycle to release any resources specific to the request cycle.

constructService

protected IEngineService constructService(java.lang.String name)
Invoked by getService(String) to construct a named service. This method should return a new instance of the named service, or null if the application doesn't implement the named service. This seems a little awkward, but the idea is to avoid creating the service object until it is needed, since once created they have the lifecycle of the application object, which can be quite long. I don't know that its worth the cycles to create a more involved solution -- for example, extend the interface so that a pooled service object could be bound temporarily to a specific instance of the engine. Best to just leave this alone.

Subclasses should overide this method, but must also invoke it to provide the services provided by AbstractEngine:


extendDescription

public void extendDescription(java.lang.StringBuffer buffer)
Extends the description of the class generated by toString(). If a subclass adds additional instance variables that should be described in the instance description, it may overide this method. Subclasses should invoke this implementation first. They should append a space before each value.
See Also:
toString()

getLocale

public java.util.Locale getLocale()
Returns the locale for the engine. This is initially set by the ApplicationServlet but may be updated by the application.
Specified by:
getLocale in interface IEngine

getMonitor

public IMonitor getMonitor(RequestContext context)
Overriden in subclasses that support monitoring. Should create and return an instance of IMonitor that is appropriate for the request cycle described by the RequestContext. May return null.

The monitor is used to create a RequestCycle.

This implementation returns null always. Subclasses may overide without invoking it.

TBD: Lifecycle of the monitor ... should there be a commit?


getPageSource

public IPageSource getPageSource()
Description copied from interface: IEngine
Returns the object used to load a page from its specification.
Specified by:
getPageSource in interface IEngine

getService

public IEngineService getService(java.lang.String name)
Returns a service with the given name, constructing it (via constructService(String) if necessary.
Specified by:
getService in interface IEngine

getServletPath

public java.lang.String getServletPath()
Description copied from interface: IEngine
Returns the URL path that corresponds to the servlet for the application. This is required by instances of IEngineService that need to construct URLs for the application. This value will include the context path.
Specified by:
getServletPath in interface IEngine

getContextPath

public java.lang.String getContextPath()
Returns the context path, the prefix to apply to any URLs so that they are recognizing as belonging to the Servlet 2.2 context.
Specified by:
getContextPath in interface IEngine
See Also:
ContextAsset

getSpecification

public ApplicationSpecification getSpecification()
Returns the specification, if available, or null otherwise.

To facilitate deployment across multiple servlet containers, the application is serializable. However, the reference to the specification is transient. When an application instance is deserialized, it reconnects with the application specification by locating it in the ServletContext or parsing it fresh.

Specified by:
getSpecification in interface IEngine

getSpecificationSource

public ISpecificationSource getSpecificationSource()
Description copied from interface: IEngine
Returns the source of all component specifications for the application. The source is shared between sessions.
Specified by:
getSpecificationSource in interface IEngine

getTemplateSource

public ITemplateSource getTemplateSource()
Description copied from interface: IEngine
Returns the source for HTML templates.
Specified by:
getTemplateSource in interface IEngine

readExternal

public void readExternal(java.io.ObjectInput in)
                  throws java.io.IOException,
                         java.lang.ClassNotFoundException
Reads the state serialized by writeExternal(ObjectOutput).

This always set the stateful flag. By default, a deserialized session is stateful (else, it would not have been serialized).

Specified by:
readExternal in interface java.io.Externalizable

writeExternal

public void writeExternal(java.io.ObjectOutput out)
                   throws java.io.IOException
Writes the following properties:
Specified by:
writeExternal in interface java.io.Externalizable

redirect

protected void redirect(java.lang.String pageName,
                        IRequestCycle cycle,
                        ResponseOutputStream out,
                        RequestCycleException exception)
                 throws java.io.IOException,
                        RequestCycleException,
                        ServletException
Invoked, typically, when an exception occurs while servicing the request. This method resets the output, sets the new page and renders it.

render

protected void render(IRequestCycle cycle,
                      ResponseOutputStream output)
               throws RequestCycleException,
                      ServletException,
                      java.io.IOException
Invoked to render an actual result page (as opposed to a rewind).

Invokes IRequestCycle.commitPageChanges() before rendering the page.


restart

protected void restart(IRequestCycle cycle)
                throws java.io.IOException
Invalidates the session, then redirects the client web browser to the servlet's prefix, starting a new visit.

Subclasses should perform their own restart (if necessary, which is rarely) before invoking this implementation.


service

public boolean service(RequestContext context)
                throws ServletException,
                       java.io.IOException
Delegate method for the servlet. Services the request.
Specified by:
service in interface IEngine

handleStaleLinkException

protected void handleStaleLinkException(StaleLinkException ex,
                                        IRequestCycle cycle,
                                        ResponseOutputStream output)
                                 throws java.io.IOException,
                                        ServletException,
                                        RequestCycleException
Invoked by service(RequestContext) if a StaleLinkException is thrown by the service. This implementation invokes redirect(String, IRequestCycle, ResponseOutputStream, RequestCycleException) to render the StaleLink page.

Subclasses may overide this method (without invoking this implementation). A common practice is to present an eror message on the application's Home page.

Since:
0.2.10

handleStaleSessionException

protected void handleStaleSessionException(StaleSessionException ex,
                                           IRequestCycle cycle,
                                           ResponseOutputStream output)
                                    throws java.io.IOException,
                                           ServletException,
                                           RequestCycleException
Invoked by service(RequestContext) if a StaleSessionException is thrown by the service. This implementation invokes redirect(String, IRequestCycle, ResponseOutputStream, RequestCycleException) to render the StaleSession page.

Subclasses may overide this method (without invoking this implementation). A common practice is to present an eror message on the application's Home page.

Since:
0.2.10

serviceAction

protected void serviceAction(IRequestCycle cycle,
                             java.lang.String[] serviceContext,
                             ResponseOutputStream output)
                      throws RequestCycleException,
                             ServletException,
                             java.io.IOException
Processes an 'action' URL.

serviceDirect

protected void serviceDirect(IRequestCycle cycle,
                             java.lang.String[] serviceContext,
                             java.lang.String[] parameters,
                             ResponseOutputStream output)
                      throws RequestCycleException,
                             ServletException,
                             java.io.IOException
Processes a 'direct' URL.

servicePage

protected void servicePage(IRequestCycle cycle,
                           java.lang.String[] serviceContext,
                           ResponseOutputStream output)
                    throws RequestCycleException,
                           ServletException,
                           java.io.IOException
Processes a 'page' URL.

serviceReset

protected void serviceReset(IRequestCycle cycle,
                            java.lang.String[] serviceContext,
                            ResponseOutputStream output)
                     throws RequestCycleException,
                            ServletException,
                            java.io.IOException

Clears the cache of pages, specifications and templates.


clearCachedData

protected void clearCachedData()
Discards all cached pages, component specifications and templates.
Since:
1.0.1

setLocale

public void setLocale(java.util.Locale value)
Changes the locale for the engine.
Specified by:
setLocale in interface IEngine

setupForRequest

protected void setupForRequest(RequestContext context)
Invoked from service(RequestContext) to ensure that the engine's instance variables are setup. This allows the application a chance to restore transient variables that will not have survived deserialization. Determines the servlet prefix: this is the base URL used by services to build URLs. It consists of two parts: the context path and the servlet path.

The servlet path is retrieved from HttpServletRequest.getServletPath().

The context path is retrieved from HttpServletRequest.getContextPath().

The final path is available via the getServletPath() method.

In addition, this method locates and/or creates the:

Subclasses should invoke this implementation first, then perform their own setup.


getHelperBeanPool

public Pool getHelperBeanPool()
Description copied from interface: IEngine
Returns a Pool from which helper objects may be obtained, and to which they should be returned. The pool is keyed on class name.
Specified by:
getHelperBeanPool in interface IEngine
Since:
1.0.4

getResourceResolver

public IResourceResolver getResourceResolver()
Returns an object which can find resources and classes.
Specified by:
getResourceResolver in interface IEngine

toString

public java.lang.String toString()
Generates a description of the instance. Invokes extendDescription(StringBuffer) to fill in details about the instance.
Overrides:
toString in class java.lang.Object
See Also:
extendDescription(StringBuffer)

valueBound

public void valueBound(HttpSessionBindingEvent event)
Invoked when the application object is stored into the HttpSession. This implementation does nothing.
Specified by:
valueBound in interface HttpSessionBindingListener

valueUnbound

public void valueUnbound(HttpSessionBindingEvent event)
Invoked when the application object is removed from the HttpSession. This occurs when the session times out or is explicitly invalidated (for example, by the reset or restart services). Invokes cleanupEngine().
Specified by:
valueUnbound in interface HttpSessionBindingListener

cleanupEngine

protected void cleanupEngine()
Invoked when the engine is removed from the HttpSession i.e., because the sesssion timed out or was explicitly invalidated.

Locates all active pages (pages which have been activated) and invokes IPage.cleanupPage() on them. This gives pages a chance to release any long held resources. This primarily exists so that pages that hold references to stateful session EJBs can remove those EJBs in a timely manner.

Subclasses may overide this method to clean up any engine-held resources, but should invoke this implementation first.


isResetServiceEnabled

public boolean isResetServiceEnabled()
Returns true if the reset service is curently enabled.
Specified by:
isResetServiceEnabled in interface IEngine

getActivePageNames

public abstract java.util.Collection getActivePageNames()
Implemented by subclasses to return the names of the active pages (pages for which recorders exist).

getVisit

public java.lang.Object getVisit()
Gets the visit object, if it has been created already.
Specified by:
getVisit in interface IEngine

getVisit

public java.lang.Object getVisit(IRequestCycle cycle)
Gets the visit object, invoking createVisit(IRequestCycle) to create it lazily if needed.
Specified by:
getVisit in interface IEngine

setVisit

public void setVisit(java.lang.Object value)
Description copied from interface: IEngine
Allows the visit object to be removed; typically done when "shutting down" a user's session (by setting the visit to null).
Specified by:
setVisit in interface IEngine

getHasVisit

public boolean getHasVisit()

createVisit

protected java.lang.Object createVisit(IRequestCycle cycle)
Invoked to lazily create a new visit object when it is first referenced (by getVisit(IRequestCycle)). This implementation works by looking up the name of the class in the application specification.

Subclasses may want to overide this method if some other means of instantiating a visit object is required.


getScriptSource

public IScriptSource getScriptSource()
Description copied from interface: IEngine
Returns a source for parsed IScripts. The source is typically shared between all sessions.
Specified by:
getScriptSource in interface IEngine

isStateful

public boolean isStateful()
Description copied from interface: IEngine
Returns true if the engine has state and, therefore, should be stored in the HttpSession. This starts as false, but becomes true when the engine requires state (such as when a visit object is created, or when a peristent page property is set).
Specified by:
isStateful in interface IEngine

setStateful

protected void setStateful()
Invoked by subclasses to indicate that some state must now be stored in the engine (and that the engine should now be stored in the HttpSession). The caller is responsible for actually creating the HttpSession (it will have access to the RequestContext).
Since:
1.0.2

getListeners

public ListenerMap getListeners()
Allows subclasses to include listener methods easily.
Since:
1.0.2

redirectOut

protected void redirectOut(IRequestCycle cycle,
                           RedirectException ex)
                    throws RequestCycleException
Invoked when a RedirectException is thrown during the processing of a request.
Throws:
RequestCycleException - if an IOException is thrown by the redirect
Since:
1.0.6