The Open For Business Controller is a group of
classes use to manage the
presentation of a web application designed around the Open For Business
framework. The Controller is designed to work along with the Entity
Engine
by keeping a constant state with the Entity Delegator, as well as the
Services
Framework by keeping a state with the Local Service Dispatcher. The
goal
of the Controller is to provide a clean mechanism of separating
presentation
logic from the actual display.
This Controller makes use of several J2EE Presentation Tier design
patterns. The Context Security Filter is modeled after the
Decorating Filter
pattern. The CSF runs at the context root and is able to restrict
direct access to JSP templates as well as open doors for future
services such as debugging, logging and compression. The Control
Servlet is modeled after the
Front Controller
pattern. This Servlet is where the web application's request
processing
begins. It makes use of helper classes which process security and
events,
then dispatches to a defined view. The Views are JSP templates which
are
very similar to those described in the
Composite View pattern. These templates use helper files to
limit the amount of logic found
in the actual display page. These helper files are Java classes which
perform the logic for a specific group of views. This process is based
on the
View Helper pattern.
Note: Links above are to the
Sun Developer Network at http://developer.java.sun.com. If you're a
registered member, log in; you should be automatically logged in from
previous visits..
As stated above, the main purpose of the Controller is to separate
logic
from display. This is accomplished by:
<filter>
<filter-name>ContextSecurityFilter</filter-name>
<display-name>ContextSecurityFilter</display-name>
<filter-class>org.ofbiz.webapp.control.ContextSecurityFilter</filter-class>
<init-param>
<param-name>allowedPaths</param-name>
<param-value>/control:/index.html:/index.jsp:/default.html:/default.jsp:/images</param-value>
</init-param>
<init-param>
<param-name>errorCode</param-name>
<param-value>403</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>ContextSecurityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
The Control Servlet is at the heart of all
request processing. Valid requests which pass through the Context Security Filter begin
processing here. When a request is received, the Control Servlet first
sets up an environment for the helper classes. This environment
includes (but is not limited to) setting up an initial session object
and storing useful information about the initial request and setting a
reference to the Entity Delegator, Service Dispatcher, and Security
Handler for use by the helper classes. The request is then passed to
the Request Handler for processing. The
Request Handler processes the request
and returns to the ControlServlet
when finished.
When the Control Servlet is first loaded it will
create objects used by the web application and store them in the
application context (ServletContext). These objects can be found by
accessing the property in the context or via a JSP <useBean> tag.
These objects include: Entity Delegator, Security object, Service
Dispatcher, and the Request Handler.
The Request Handler makes use of a RequestManager
helper class to gather
a list of request mappings defined in an XML configuration file. The
configuration file lives in /WEB-INF/controller.xml
for
the appropriate context. The mapping consists
of a request URI and an optional VIEW name. View names are mapped to in
the configuration file as well. A request URI can also be associated
with an Event. Events are used to process web related logic by
either working directly with the Entity Engine through the Entity
Delegator or invoking service(s) to handle the logic through the
Service Dispatcher.
When a request is received through the Request
Handler it is first looked up in the request mappings; if no mapping is
found an 'unknown request error' is returned. Upon a successful lookup,
the Security Handler is called to verify if the current request
requires authentication and the user making the request is properly
authenticated. If the current user is not authenticated the Request
Handler redirects the request to a proper login form. After successful
authentication or if no authentication is required the Request Handler
then looks up a defined event for the request. If an event is found,
the request is passed to the EventHandler
for processing. After event processing is complete, the default view is
looked up for this request, unless the EventHandler
requests a specific view instead. The view is then checked in the view
mappings and the value is passed to the defined ViewHandler
for dispatching. If the view type is none
it is expected
that the event handles the response itself; if the view type is url
the RequestHandler then redirects to the specified URL and no ViewHandler
is called.
The Request Handler looks up request mappings in an XML file which is setup like this:
<request-map uri="checkLogin" edit="false">
<description>Verify a user is logged in.</description>
<security https="false" auth="false"/>
<event type="java" path="org.ofbiz.commonapp.security.login.LoginEvents" invoke="checkLogin" />
<response name="success" type="view" value="name" />
<response name="error" type="view" value="login" />
</request-map>
In the above mapping, the event return code success will load the view named main. If success was defined with the type request it would then [***] instead of displaying a view, it in turn calls another request. This is known as request chaining.
The view mappings are defined as follows:
<view-map name="login" page="/login.jsp"/>
A view is looked up by name and mapped to a JSP template (page).
request-map
tag:
Attribute Name | Required? | Description |
uri | Y | The name of this request. This will be the name used to access the request. |
edit | N | Reserved for future use. |
The request-map
element contains 0
or 1 security
tag, 0 or 1 event
tag and 1 or more response
tag(s).
security
tag:
Attribute Name | Required? | Description |
https | N | Does this request require being called secure (default false. |
auth | N | Does this request require the caller to be authenticated (default false. |
external-view | N | Does this request allow passing a view through the URL. (default true). |
direct-request | N | Does this request allow being called directly through a URL, if false can only be used in a chain (default true). |
event
tag:
Attribute Name | Required? | Description |
type | Y | Mapped to the event handler definitions to determine which EventHander will be used to run the event. |
path | N | The path to the class or XML file containing this event, leave empty for services. |
invoke | Y | The name of the method or service to be run. |
response
tag:
Attribute Name | Required? | Description |
name | Y | The name of the response, will also match the string returned by the event. |
type | Y | The type of response will follow: none, request, view, url. |
value | N | The name of the method or service to be run. |
The ViewHandler
is called on view
type responses. Using the above example,
the view handler default
will be used, since no type
is defined. This handler will dispatch to a JSP/Servlet. All
ViewHandlers will receive the name
and page
values from the view-map
definition.
view-map
tag:
Attribute Name | Required? | Description |
name | Y | The name of this view mapping, matches the value
of the response element. |
page | N | The page mapped to this view. |
type | N | The type of view this is, maps to a ViewHandler. An empty type will assume JSP type view. |
info | N | Extended information passed to the view handler. |
Event Handlers are defined in the XML config file such as:
<handler name="java" type="request" class="org.ofbiz.webapp.event.JavaEventHandler"/>
As in the above request mapping the login event
is defined with a type
of java
. The event type is mapped to an Event Handler
using the handler
definitions. Custom Event Handlers can be designed and would be
implemented
like the above example.
Java events are processed by locating the path
of the event (package
and classname); then, by using the Reflection API, the Event Handler
invokes
the method defined. A String object is returned to the Request Handler which is mapped to the
response element of the request definition.
[???] A document on writing Open For Business Events and Services
is forthcoming.
View Handlers are defined just like Event
Handlers, except the type is view
:
<handler name="region" type="view" class="org.ofbiz.webapp.view.RegionViewHandler"/>
The view handler handles rendering the next page
the user will see. The default
view handler supports
standard html/jsp pages by dispatching to the page defined in the view
definition. Other
view handlers like region
and velocity
use
special logic to render the page to the user.
Custom view handlers can be created easily by
implementing the ViewHandler
interface and setting a
definition
in the controller.xml
file like the above example.