I did some work on some docs. Here's the beginnings... Please feel free
to add :-)
Title: Xwork Documentation

XWork

Introduction

What is Xwork?


Xwork is a generic command pattern framework.


Xwork 1.0 Mission Statement:

The Purpose: To create a generic, reusable, and extensible command pattern framework not tied to any particular usage.

Features:
* Flexible and customizable configuration based on a simple Configuration interface
* Core command pattern framework which can be customized and extended through the use of interceptors to fit any request / response environment
* Built in type conversion and action property validation using Ognl
* Powerful validation framework based on runtime attributes and a validation interceptor

How does Xwork relate to Webwork?

Webwork 2.0 is built on top of Xwork.

Webwork 2.0 Mission Statement:

The Purpose: To create the best Model-2 MVC web application framework supporting advanced web application development paradigms such as component based development and code reuse.

Features:
* Built on XWork, but customized to be specifically tailored for web application development
* Custom web-specific Xwork interceptors
* Flexible configuration extended from Xwork with web-specific configuration parameters
* Multiple web-based views, including custom JSP taglibs, Velocity support with pre-built macros, XSLT views, and JasperReport

The Basics

Actions

Actions are the basic unit of execution...

The Action Interface

ActionSupport

ActionContext

Lifecycle

No FormBeans?

Xwork / Webwork does not require the use of FormBeans
like Struts...

Configuration - Xwork.xml

Xwork is configured through the use of a file named xwork.xml in the root of the classpath. This file defines the action and interceptor configurations and mappings.

Packages

The primary unit of configuration in XWork is a package. Packages define a context for configuring and referencing actions and interceptors. All action and interceptor references are scoped inside a package. Here's an example package definition:

<package name="foo" extends="default" namespace="/foo">
<result-types>
<result-type name="chain" class="com.opensymphony.xwork.ActionChainResult"/>
</result-types>

<interceptors>
<interceptor name="timer" class="com.opensymphony.xwork.interceptor.TimerInterceptor"/>
<interceptor name="logger" class="com.opensymphony.xwork.interceptor.LoggingInterceptor"/>
<interceptor name="chain" class="com.opensymphony.xwork.interceptor.ChainingInterceptor"/>
<interceptor name="params" class="com.opensymphony.xwork.interceptor.ParametersInterceptor"/>
<interceptor name="static-params" class="com.opensymphony.xwork.interceptor.StaticParametersInterceptor"/>
<interceptor name="component" class="com.opensymphony.xwork.interceptor.component.ComponentInterceptor"/>
<interceptor name="result" class="com.opensymphony.xwork.interceptor.ResultInterceptor"/>
<interceptor name="stack" class="com.opensymphony.xwork.interceptor.StackInterceptor"/>

<interceptor-stack name="defaultStack">
<interceptor-ref name="result"/>
<interceptor-ref name="static-params"/>
<interceptor-ref name="params"/>
<interceptor-ref name="stack"/>
</interceptor-stack>

<interceptor-stack name="debugStack">
<interceptor-ref name="timer"/>
<interceptor-ref name="logger"/>
</interceptor-stack>
</interceptors>

<global-results>
<result name="login" type="chain">
<param name="actionName">login</param>
</result>
</global-results>

<action name="Foo" class="com.opensymphony.xwork.SimpleAction">
<param name="foo">17</param>
<param name="bar">23</param>
<result name="success" type="chain">
<param name="actionName">Bar</param>
</result>
<interceptor-ref name="debugStack"/>
<interceptor-ref name="defaultStack"/>
</action>
</package>

We'll take the components of this package declaration one-by-one to understand what this file is doing.

Package

The package element has one required attribute, "name", which acts as the key for later reference to this package. The "extends" attribute is optional and allows one package to inherit the configuration of a previous package including all interceptor, interceptor-stack, and action configurations. Note that the configuration file is processed sequentially down the document, so the package referenced by an "extends" should be defined above the package which extends it.

Namespace

The optional namespace attribute warrants its own discussion section. The namespace attribute allows you to segregate action configurations into namespaces, so that you may use the same action alias in more than one namespace with different classes, parameters, etc. This is in contrast to Webwork 1.x, where all action names and aliases were global and could not be re-used in an application. The default namespace, which is "" (an empty string) is used as a "catch-all" namespace, so if an action configuration is not found in a specified namespace, the default namespace will also be searched. This allows you to have global action configurations outside of the "extends" hierarchy, as well as to allow the previous Webwork 1.x behavior by not specifying namespaces. It is also intended that the namespace functionality can be used for security, for instance by having the path before the action name be used as the namespace by the Webwork 2.0 ServletDispatcher, thus allowing the use of J2EE declarative security on paths to be easily implemented and maintained.

Result-Type

Result types define classes and map them to names to be referred in the action configuration results. This serves as a shorthand name-value pair for these classes.

Interceptors

Interceptors also serve as a name-value pairing for referring to specific Interceptor classes by a shorthand name where we use interceptor-ref elements, such as in Interceptor stacks and action configurations.

Interceptor-Stack

The interceptor-stack element allows you to assign a name for later referencing via interceptor-ref to an ordered list of interceptors. This allows you to create standard groups of interceptors to be used in a certain order. The interceptor stack name/value pairs are stored in the same map as the interceptor definitions, so anywhere you use an interceptor-ref to refer to an interceptor you may also refer to an interceptor stack.

Global-results

The global results allows you to define result mappings which will be used as defaults for all action configurations and will be automatically inherited by all action configurations in this package and all packages which extend this package.

Action

The action element allows the mapping of names to action classes. These names are used, along with the namespace described above, to retrieve the action config from the configuration. The action may also be parameterized by using the param elements, as above, which will set parameters into the Action at execution (with the help of the StaticParametersInterceptor). The action may also have one or more results mapped to string return codes, such as "success", "error", or "input", which are the default 3 return states for actions, although ANY return string may be used and mapped to a result. The result, which is mapped to a result class by the "type" attribute which refers to the result-type name defined above, may also be parameterized by using the param element. The action may also define one or more interceptor refs to either interceptors or interceptor stacks to be applied before and after the action execution (see the section on Interceptors below). The ordering of these interceptor refs determines the order in which they will be applied.

Ognl

Ognl is used as both the expresion language and bean population utility for Xwork...

Interceptors

Interceptors allow you to define code to be executed before and after the execution of an action. They are defined outside the action class, yet have access to the action and the action execution environment at runtime, allowing you to encapsulate cross-cutting concerns and provide separation of concerns. Interceptors are given the ActionInvocation object at runtime, and may do whatever processing needed, then forward processing to the rest of the ActionInvocation, which will either call the next Interceptor or the Action, if there are no more Interceptors, and do whatever post-processing needed. Interceptors may also decide to short-circuit processing and return whatever result string desired WITHOUT forwarding processing, thus keeping the Action from executing. This ability should be used with caution, however, as any data loading or processing expected to be done by the Action will not happen.


Utility Interceptors

The AbstractInterceptor defines a base class for interceptor implementations. It delegates calls to subclasses, which must implement the abstract methods before() and after(). The before() call is first called, then the rest of the ActionInvocation is called and the String result is saved (and is available to the Interceptor implementation during the after() method). Finally, the after() method is called and the result is returned.

The TimerInterceptor and LoggingInterceptor are provided as simple examples and utilities. The LoggingInterceptor simply logs before and after executing the rest of the ActionInvocation. The TimerInterceptor times the execution of the remainder of the ActionInvocation by setting a java.lang.Long into the ActionContext before executing the remainder of the ActionInvocation, then it retrieves the Long from the ActionContext afterwards and uses it to compute the total execution time. The reason that the TimerInterceptor saves the Long into the ActionContext is that Interceptors must be stateless, and because the TimerInterceptor extends AbstractInterceptor, which provides callback methods for before() and after(). If TimerInterceptor directly implemented Interceptor, it could contain the before and after processing with the execution of the rest of the ActionInvocation in one method call (the call to invoke() from the Interceptor interface).


Parameter Interceptors - populating your Action

The StaticParametersInterceptor and ParametersInterceptor populate your Action fields during the ActionInvocation execution. The StaticParametersInterceptor applies the parameters defined in the Action configuration with the <param> elements. The ParametersInterceptor populates the Action with the parameters passed in as part of the request. The StaticParametersInterceptor should be applied before the ParametersInterceptor so that the static parameters may be set as the defaults and overridden by the request parameters.


ResultInterceptor, ChainingInterceptor, StackInterceptor

...Patrick please fill in here....

Validation Framework (optional)

To be filled in...

The ValidationInterceptor


Defining validation rules in a validation.xml


Building a FieldValidator


Localized and Parameterized messages



Reply via email to