Commits

Anonymous committed 6d9e73e

This commit was manufactured by cvs2svn to create tag 'xwork_1-0-1'.

git-svn-id: http://svn.opensymphony.com/svn/xwork/tags/xwork_1-0-1@261e221344d-f017-0410-9bd5-d282ab1896d7

Comments (0)

Files changed (26)

+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML><HEAD><TITLE>XWork Changelog</TITLE>
+<BODY bgcolor="#FFFFFF">
+<H1>XWork Changelog</H1>
+Version: <B>@version@</B> - Build Date: <B>@builddate@</B> - <A 
+href="README.html"><B>README</B></A> - <A href="http://jira.opensymphony.com/secure/BrowseProject.jspa"><B>Issue 
+Tracker</B></A> 
+<P>This is the XWork changelog. This is a high-level list of changes and bug fixes. 
+  A more exhaustive list of issues is maintained in the <A 
+href="http://jira.opensymphony.com/secure/BrowseProject.jspa">issue tracker</A>. 
+</P>
+<h3><A 
+href="http://jira.opensymphony.com/secure/IssueNavigator.jspa?reset=true&pid=10050&fixfor=21213">1.0.1</A> 
+  - Mar 21, 2004 </h3>
+<UL>
+  Key Bugfixes: 
+  <UL>
+    <LI><a href="http://jira.opensymphony.com/secure/ViewIssue.jspa?key=XW-156">XW-156</a> 
+      - Added actionMessages support 
+    <LI><a href="http://jira.opensymphony.com/secure/ViewIssue.jspa?key=XW-167">XW-167</a> 
+      - XWorkBasicConverter conversion from Date to String is not localized 
+    <LI>Exceptions occuring during OgnlValueStack.findValue() are now logged correctly 
+    <LI>Huge performance improvement when Ognl 2.6.4 is used (previous version 
+      used a modified form of 2.6.3)
+  </UL>
+  New Features: 
+  <UL>
+    <LI><a href="http://jira.opensymphony.com/secure/ViewIssue.jspa?key=XW-162">XW-162</a>, 
+      <a href="http://jira.opensymphony.com/secure/ViewIssue.jspa?key=XW-161">XW-161</a> 
+      - Replaceable ObjectFactory for creating framework objects to allow easier 
+      integration with IoC containers 
+    <LI><a href="http://jira.opensymphony.com/secure/ViewIssue.jspa?key=XW-160">XW-160</a> 
+      - Add infinite recursion detection to the ChainingInterceptor 
+    <LI>Tons of JavaDocs additions thanks to Bill Lynch
+  </UL>
+</UL>
+<h3><A 
+href="http://jira.opensymphony.com/secure/IssueNavigator.jspa?reset=true&pid=10050&fixfor=21200">1.0</A> 
+  - Feb 9, 2004 </h3>
+<UL>
+  Initial release of XWork. 
+</UL>
+<BR>
+<BR>
+</BODY></HTML>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Xwork Basics
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <h3 class="heading-1">Actions
+</h3><p class="paragraph"/>Actions are the basic unit of execution...
+<h3 class="heading-1">The Action Interface
+</h3><p class="paragraph"/>The basic interface which all XWork actions must implement. Provides several standard return values like SUCCESS and INPUT. Only contains one method, the<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> execute() <span class="java&#45;keyword">throws</span> Exception;</pre></div>
+<h3 class="heading-1">ActionSupport
+</h3>
+<h3 class="heading-1"><a href="localisation.html">Localization with XWork</a>
+</h3>
+<h3 class="heading-1">ActionContext
+</h3><p class="paragraph"/>The ActionContext provides access to the execution environment in the form of named objects during an Action invocation. A new ActionContext is created for each invocation allowing developers to access/modify these properties in a thread safe manner. The ActionContext makes a number of properties available that are typically set to appropriate values by the framework. In WebWork 2 for example, the ActionContext session map wraps an underlying HttpSession object. This allows access to environment specific properties without tying the core framework to a specific execution environment.<p class="paragraph"/>The ActionContext is acquired through the static ActionContext.getContext() method. The ActionContext is a thread local variable and thus the properties of the ActionContext will be relative to the current request thread. The ActionContext has several methods for commonly used properties as well as get() and set() methods which can be used for application specific properties. 
+<h3 class="heading-1">Lifecycle
+</h3>
+<h3 class="heading-1">No FormBeans?
+</h3><p class="paragraph"/>Xwork / Webwork does not require the use of FormBeans
+like Struts&#8230;
+  </div>
+</body>
+</html>

docs/components.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">XWork Components
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <h3 class="heading-1">Overview
+</h3><p class="paragraph"/><a href="index.html">XWork</a> provides the ComponentManager interface (and a corresponding implementation in the DefaultComponentManager class) to allow a design pattern known as <b class="bold">Inversion of Control</b> (or <b class="bold">IoC</b> for short) to be applied to your actions or other arbitrary objects. In a nutshell, the IoC pattern allows a parent object (in this case XWork's ComponentManager instance) to control a client object (usually an action, but it could be any object that implements the appropriate <b class="bold">enabler</b>).<p class="paragraph"/>You may also want to look at <a href="http://wiki.opensymphony.com/space/WebWork+2+Components">WebWork 2 Components</a> to see how WW2 uses XWork's IoC architecture.
+<h3 class="heading-1">Why IoC?
+</h3><p class="paragraph"/>So why is IoC useful? It means that you can develop components (generally services of some sort) in a top-down fashion, without the need to build a registry class that the client must then call to obtain the component instance.<p class="paragraph"/>Traditionally when implementing services you are probably used to following steps similar to these:
+<ol>
+<li>Write the component (eg an ExchangeRateService)</li>
+<li>Write the client class (eg an XWork action)</li>
+<li>Write a registry class that holds the component object (eg Registry)</li>
+<li>Write code that gives the component object to the registry (eg Registry.registerService(new MyExchangeRateService());)</li>
+<li>Use the registry to obtain the service from your client class (eg ExchangeRateService ers = Registry.getExchangeRateService();)</li>
+<li>Make calls to the component from the client class (eg String baseCurrencyCode = ers.getBaseCurrency();)</li>
+</ol><p class="paragraph"/>Using IoC, the process is reduced to the following:
+<ol>
+<li>Write the component class (eg an ExchangeRateService)</li>
+<li>Register the component class with XWork (eg componentManager.addEnabler(MyExchangeRateService, ExchangeRateAware);)</li>
+<li>Write the client class, making sure it implements the enabling interface (eg an XWork action that implements ExchangeRateAware)</li>
+<li>Access the component instance directly from your client action (eg String baseCurencyCode = ers.getBaseCurrency();)</li>
+</ol><p class="paragraph"/>XWork takes care of passing components through to enabled action classes or other components.<p class="paragraph"/>Some other benefits that IoC can provide include:
+<ul class="minus">
+<li>A component describes itself. When you instantiate a component, you can easily determine what dependencies it requires without looking at the source or using trial and error.</li>
+<li>Dependencies can be discovered easily using reflection. This has many benefits ranging from diagram generation to runtime optimization (by determining in advance which components will be needed to fufill a request and preparing them asyncronously, for example).</li>
+<li>Avoids the super-uber-mega-factory pattern where all the components of the app are held together by a single class that is directly tied back to other domain specific classes, making it hard to 'just use that one class'.</li>
+<li>Adheres to Law of Demeter. Some people think this is silly, but in practise I've found it works much better. Each class is coupled to only what it actually uses (and it should never use too much) and no more. This encourages smaller responsibility specific classes which leads to cleaner design.</li>
+<li>Allows context to be isolated and explicitly passed around. ThreadLocals may be ok in a web-app, but they aren't well suited for high concurrency async applications (such as message driven applications).</li>
+</ul>
+<h3 class="heading-1">Configuration - xwork.xml
+</h3><p class="paragraph"/>The ComponentInterceptor class is used to apply the IoC pattern to XWork actions (ie, to supply components to actions). The ComponentInterceptor should be declared in the &#60;interceptors&#62; block of xwork.xml as follows:<p class="paragraph"/><div class="code"><pre>&#60;interceptor name=<span class="xml&#45;quote">"component"</class>
+        class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.component.ComponentInterceptor"</class>/&#62;</pre></div><p class="paragraph"/>You should ensure that any actions that are to be supplied with components have this interceptor applied. (See <a href="interceptors.html">XWork Interceptors</a> for information on how to apply interceptors to actions.)<p class="paragraph"/>If you want to apply IoC to objects other than actions or other components, you will need to use the ComponentManager object directly.
+<h3 class="heading-1">Writing Component Classes
+</h3><p class="paragraph"/>The actual component class can be virtually anything you like. The only constraints on it are that it must be a concrete class with a default constructor so that XWork can create instances of it as required. Optionally, a component may implement the Initializable and/or Disposable interfaces so it will receive lifecycle events just after it is created or before it is destroyed.
+<h3 class="heading-1">Component Dependencies
+</h3><p class="paragraph"/>One feature that is not immediately obvious is that it is possible for components to depend on other components. For example if the ExchangeRateService described above depended on a Configuration component, XWork will pass the Configuration component through to the ExchangeRateService instance after ExchangeRateService is instantiated. Note that XWork automatically takes care of initializing the components in the correct order, so if A depends on B and C, and B depends on C, the ComponentManager will load C first, then B then A.
+<h3 class="heading-1">Writing Enablers
+</h3><p class="paragraph"/>An enabler should consist of just a single method that accepts a single parameter. The parameter class should either be the component class that is to be enabled, or one of the component's superclasses. XWork does not care what the name of the enabler's method is.<p class="paragraph"/>Here is an example of what the ExchangeRateAware enabler might look like:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;keyword">interface</span> ExchangeRateAware &#123;
+    <span class="java&#45;keyword">public</span> void setExchangeRateService(ExchangeRateService exchangeRateService);
+&#125;</pre></div><p class="paragraph"/>Note that typically an enabler would be an interface, however there is nothing to prevent you from using a class instead if you so choose.
+<h3 class="heading-1">Writing "Enabler-aware" Actions
+</h3><p class="paragraph"/>All an action needs to do is implement the relevant enabler interface. XWork will then call the action's enabler method just prior to the action's execution. As a simple example:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> class MyAction <span class="java&#45;keyword">extends</span> ActionSupport <span class="java&#45;keyword">implements</span> ExchangeRateAware &#123;
+    ExchangeRateService ers;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> void setExchangeRateService(ExchangeRateService exchangeRateService) &#123;
+        ers = exchangeRateService;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> execute() <span class="java&#45;keyword">throws</span> Exception &#123;
+        <span class="java&#45;object">System</span>.out.println(<span class="java&#45;quote">"The base currency is "</span> + ers.getBaseCurrency());
+    &#125;
+&#125;</pre></div><p class="paragraph"/>If you have an object that is not an action or another component, you must explictly tell XWork to supply any enabled components to your object by calling componentManager.initializeObject(enabledObject);<p class="paragraph"/>-Chris
+  </div>
+</body>
+</html>

docs/concepts.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">XWork Core Concepts
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <h3 class="heading-1">XWork Core Concepts
+</h3><p class="paragraph"/><a href="index.html">XWork</a> is based on a number of core concepts that helps to explain how the framework works. The core concepts can be broken down into two parts: Architecture Concepts and Terminology.
+<h3 class="heading-1">Architecture Concepts
+</h3>
+<ul class="star">
+<li>Explain Command Driven Architecture (in general)</li>
+<li>Explain the implementation in XWork</li>
+</ul>
+<h3 class="heading-1">Terminology
+</h3>
+<h3 class="heading-1-1">Actions
+</h3><p class="paragraph"/>Actions are classes that get invoked in response to a request, execute some code and return a Result. Actions implement at a minimum a single method, execute(), that defines the entry point called by the framework. This method allows developers to define a unit of work that will be executed each time the Action is called.
+<h3 class="heading-1-1">ActionContext
+</h3><p class="paragraph"/>The ActionContext provides access to the execution environment in the form of named objects during an Action invocation. A new ActionContext is created for each invocation allowing developers to access/modify these properties in a thread safe manner. The ActionContext makes a number of properties available that are typically set to appropriate values by the framework. In WebWork 2 for example, the ActionContext session map wraps an underlying HttpSession object. This allows access to environment specific properties without tying the core framework to a specific execution environment. For more information, see ActionContext in <a href="basics.html">XWork Basics</a>.
+<h3 class="heading-1-1">Interceptors
+</h3><p class="paragraph"/>In XWork, Interceptors are objects that dynamically intercept Action invocations. They provide the developer with the opportunity to define code that can be executed before and/or after the execution of an action. They also have the ability to prevent an action from executing. Interceptors provide developers a way to encapulate common functionality in a re-usable form that can be applied to one or more Actions. See <a href="interceptors.html">XWork Interceptors</a> for further details.
+<h3 class="heading-1-1">Stacks
+</h3><p class="paragraph"/>To handle the case where developers want to apply more than a single Interceptor to an Action, Stacks have been introduced. Stacks are an ordered list of Interceptors and/or other Stacks that get applied when an Action is invoked. Stacks centralize the declaration of Interceptors and provide a convenient way to configure mutiple actions.
+<h3 class="heading-1-1">Results
+</h3><p class="paragraph"/>Results are string constants that Actions return to indicate the status of an Action execution. A standard set of Results are defined by default: error, input, login, none and success.  Developers are, of course, free to create their own Results to indicate more application specific cases.
+<h3 class="heading-1-1">Result Types
+</h3><p class="paragraph"/>Result Types are classes that determine what happens after an Action executes and a Result is returned. Developers are free to create their own Result Types according to the needs of their application or environment. In WebWork 2 for example, Servlet and Velocity Result Types have been created to handle rendering views in web applications.
+<h3 class="heading-1-1">Packages
+</h3><p class="paragraph"/>Packages are a way to group Actions, Results, Result Types, Interceptors and Stacks into a logical unit that shares a common configuration. Packages are similiar to objects in that they can be extended and have individual parts overridden by "sub" packages.
+<h3 class="heading-1-1">ValueStack
+</h3><p class="paragraph"/>The ValueStack is a stack implementation built on top of an OGNL core. The OGNL expression language can be used to traverse the stack and retrieve the desired object. The OGNL expression language provides a number of additional features including: automatic type conversion, method invocation and object comparisons. For more information, see the <span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://ognl.org/index.html">OGNL Website</a></span>.
+<h3 class="heading-1-1">Components
+</h3><p class="paragraph"/>XWork provides the ComponentManager interface (and a corresponding implementation in the DefaultComponentManager class) to apply a design pattern known as <b class="bold">Inversion of Control</b> (or IoC for short). In a nutshell, the IoC pattern allows a parent object (in this case XWork's ComponentManager instance) to control a client object (usually an action, but it could be any object that implements the appropriate <b class="bold">enabler</b>). See <a href="components.html">XWork Components</a> for further details.
+  </div>
+</body>
+</html>

docs/configuration.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Xwork Configuration
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ Xwork is configured through the use of a file named xwork.xml in the root of the classpath which conforms to the <a href="dtd.html">Xwork 1.0 DTD</a>. This file defines the action and interceptor configurations and mappings. Here's the test xwork.xml file:<p class="paragraph"/><div class="code"><pre>&#60;!DOCTYPE xwork PUBLIC
+    <span class="xml&#45;quote">"&#45;//OpenSymphony Group//XWork 1.0//EN"</class>
+    <span class="xml&#45;quote">"http://www.opensymphony.com/xwork/xwork&#45;1.0.dtd"</class>
+ &#62;<p class="paragraph"/>&#60;xwork&#62;
+    &#60;package name=<span class="xml&#45;quote">"default"</class>&#62;
+        &#60;result&#45;types&#62;
+            &#60;result&#45;type name=<span class="xml&#45;quote">"chain"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.ActionChainResult"</class>/&#62;
+        &#60;/result&#45;types&#62;<p class="paragraph"/>        &#60;interceptors&#62;
+            &#60;interceptor name=<span class="xml&#45;quote">"timer"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.TimerInterceptor"</class>/&#62;
+            &#60;interceptor name=<span class="xml&#45;quote">"logger"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.LoggingInterceptor"</class>/&#62;
+            &#60;interceptor name=<span class="xml&#45;quote">"chain"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.ChainingInterceptor"</class>/&#62;
+            &#60;interceptor name=<span class="xml&#45;quote">"params"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.ParametersInterceptor"</class>/&#62;
+            &#60;interceptor name=<span class="xml&#45;quote">"static&#45;params"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.StaticParametersInterceptor"</class>/&#62;
+            &#60;interceptor name=<span class="xml&#45;quote">"component"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.interceptor.component.ComponentInterceptor"</class>/&#62;
+            &#60;interceptor name=<span class="xml&#45;quote">"test"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.TestInterceptor"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;expectedFoo&#60;/param&#62;
+            &#60;/interceptor&#62;<p class="paragraph"/>            &#60;interceptor&#45;stack name=<span class="xml&#45;quote">"defaultStack"</class>&#62;
+                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"static&#45;params"</class>/&#62;
+                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"params"</class>/&#62;
+            &#60;/interceptor&#45;stack&#62;<p class="paragraph"/>            &#60;interceptor&#45;stack name=<span class="xml&#45;quote">"debugStack"</class>&#62;
+                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"timer"</class>/&#62;
+                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"logger"</class>/&#62;
+            &#60;/interceptor&#45;stack&#62;
+        &#60;/interceptors&#62;<p class="paragraph"/>        &#60;global&#45;results&#62;
+            &#60;result name=<span class="xml&#45;quote">"login"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;login&#60;/param&#62;
+            &#60;/result&#62;
+        &#60;/global&#45;results&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"Foo"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;17&#60;/param&#62;
+            &#60;param name=<span class="xml&#45;quote">"bar"</class>&#62;23&#60;/param&#62;
+            &#60;result name=<span class="xml&#45;quote">"success"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;Bar&#60;/param&#62;
+            &#60;/result&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"debugStack"</class>/&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"defaultStack"</class>/&#62;
+        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"Bar"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;17&#60;/param&#62;
+            &#60;param name=<span class="xml&#45;quote">"bar"</class>&#62;23&#60;/param&#62;
+        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"TestInterceptorParam"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"test"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"expectedFoo"</class>&#62;expectedFoo&#60;/param&#62;
+            &#60;/interceptor&#45;ref&#62;
+        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"TestInterceptorParamOverride"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"test"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;foo123&#60;/param&#62;
+                &#60;param name=<span class="xml&#45;quote">"expectedFoo"</class>&#62;foo123&#60;/param&#62;
+            &#60;/interceptor&#45;ref&#62;
+        &#60;/action&#62;
+    &#60;/package&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"bar"</class> extends=<span class="xml&#45;quote">"default"</class> namespace=<span class="xml&#45;quote">"/foo/bar"</class>&#62;
+        &#60;interceptors&#62;
+            &#60;interceptor&#45;stack name=<span class="xml&#45;quote">"barDefaultStack"</class>&#62;
+                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"debugStack"</class>/&#62;
+                &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"defaultStack"</class>/&#62;
+            &#60;/interceptor&#45;stack&#62;
+        &#60;/interceptors&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"Bar"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"barDefaultStack"</class>/&#62;
+        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"TestInterceptorParamInheritance"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"test"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"expectedFoo"</class>&#62;expectedFoo&#60;/param&#62;
+            &#60;/interceptor&#45;ref&#62;
+        &#60;/action&#62;<p class="paragraph"/>        &#60;action name=<span class="xml&#45;quote">"TestInterceptorParamInehritanceOverride"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"test"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;foo123&#60;/param&#62;
+                &#60;param name=<span class="xml&#45;quote">"expectedFoo"</class>&#62;foo123&#60;/param&#62;
+            &#60;/interceptor&#45;ref&#62;
+        &#60;/action&#62;
+    &#60;/package&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"abstractPackage"</class> namespace=<span class="xml&#45;quote">"/abstract"</class> abstract=<span class="xml&#45;quote">"true"</class>&#62;
+        &#60;action name=<span class="xml&#45;quote">"test"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>/&#62;
+    &#60;/package&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"nonAbstractPackage"</class> extends=<span class="xml&#45;quote">"abstractPackage"</class> namespace=<span class="xml&#45;quote">"/nonAbstract"</class>/&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"baz"</class> extends=<span class="xml&#45;quote">"default"</class> namespace=<span class="xml&#45;quote">"baz"</class>&#62;
+        &#60;action name=<span class="xml&#45;quote">"commandTest"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"foo"</class>&#62;123&#60;/param&#62;
+            &#60;result name=<span class="xml&#45;quote">"error"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;bar&#60;/param&#62;
+            &#60;/result&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"static&#45;params"</class>/&#62;
+        &#60;/action&#62;
+        &#60;action name=<span class="xml&#45;quote">"myCommand"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class> method=<span class="xml&#45;quote">"commandMethod"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"bar"</class>&#62;456&#60;/param&#62;
+            &#60;result name=<span class="xml&#45;quote">"success"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;foo&#60;/param&#62;
+            &#60;/result&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"logger"</class>/&#62;
+        &#60;/action&#62;
+    &#60;/package&#62;<p class="paragraph"/>    &#60;package name=<span class="xml&#45;quote">"multipleInheritance"</class> extends=<span class="xml&#45;quote">"default,abstractPackage,bar"</class> namespace=<span class="xml&#45;quote">"multipleInheritance"</class>&#62;
+        &#60;action name=<span class="xml&#45;quote">"testMultipleInheritance"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.SimpleAction"</class>&#62;
+            &#60;result name=<span class="xml&#45;quote">"success"</class> type=<span class="xml&#45;quote">"chain"</class>&#62;
+                &#60;param name=<span class="xml&#45;quote">"actionName"</class>&#62;foo&#60;/param&#62;
+            &#60;/result&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"barDefaultStack"</class>/&#62;
+        &#60;/action&#62;
+    &#60;/package&#62;<p class="paragraph"/>    &#60;include file=<span class="xml&#45;quote">"includeTest.xml"</class>/&#62;
+&#60;/xwork&#62;</pre></div><p class="paragraph"/>Here you can see that I've implemented Rickard's ideas (see <a href="rickard.html">RickardXWorkThoughts</a>). 
+<ol>
+<li>Packages - All configuration settings are in a package. Result types, interceptors, and actions are all package context specific, no more global settings (unless you have a "default" package and have your other packages extend it). Result, Interceptor, and Action configurations are inherited by packages which "extend" another package, such as package "bar" above, which extends "default".</li>
+<li>Interceptor stacks - Make it easier to have sets of interceptors you apply together in a certain order. These are also inherited as part of the interceptor definition inheritance. Essentially these are just name mappings to lists of interceptors instead of one Interceptor.</li>
+<li>Namespaces - a new idea of mine, this allows actions to be aliased with the same name, providing they are in different namespaces. With the ServletDispatcher, this equates to the path before the action name, which will allow for J2EE declarative security. Namespaces are optional attributes of package definitions and, if excluded, defaults to "". If the action configuration is not found with the supplied namespace, the "" namespace is checked as the default namespace, which makes it work like we have now (any path works, you get the action aliased with the name).</li>
+</ol>
+<h3 class="heading-1">xwork.xml elements
+</h3>
+<h3 class="heading-1-1">Package
+</h3><p class="paragraph"/>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 one or more previous packages 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. The "abstract" optional attribute allows you to make a package abstract, which will allow you to extend from it without the action configurations defined in the abstract package actually being available at runtime.
+<h3 class="heading-1-1">Namespace
+</h3><p class="paragraph"/>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.
+<h3 class="heading-1-1">Result-Type
+</h3><p class="paragraph"/>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.
+<h3 class="heading-1-1">Interceptors
+</h3><p class="paragraph"/>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.
+<h3 class="heading-1-1">Interceptor-Stack
+</h3><p class="paragraph"/>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.
+<h3 class="heading-1-1">Interceptor Parameterization
+</h3><p class="paragraph"/>Interceptors are instantiated and stored at the ActionConfig level, i.e. there will be one instance per action configured in xwork.xml. These Interceptor instances may be parameterized at either the declaration level, where you map an Interceptor class to a name to be referenced later, like so:<p class="paragraph"/><div class="code"><pre>&#60;interceptor name=<span class="java&#45;quote">"test"</span> class=<span class="java&#45;quote">"com.opensymphony.xwork.TestInterceptor"</span>&#62;
+    &#60;param name=<span class="java&#45;quote">"foo"</span>&#62;expectedFoo&#60;/param&#62;
+&#60;/interceptor&#62;</pre></div><p class="paragraph"/>or at the interceptor-ref level, either inside an interceptor-stack or in an action declaration, like so:<p class="paragraph"/><div class="code"><pre>&#60;interceptor&#45;ref name=<span class="java&#45;quote">"test"</span>&#62;
+    &#60;param name=<span class="java&#45;quote">"expectedFoo"</span>&#62;expectedFoo&#60;/param&#62;
+&#60;/interceptor&#45;ref&#62;</pre></div><p class="paragraph"/>Although it is allowed by the DTD, parameters applied to interceptor-refs which refer to interceptor-stack elements will NOT be applied, and will cause a warning message.
+<h3 class="heading-1-1">Global-results
+</h3><p class="paragraph"/>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.
+<h3 class="heading-1-1">Action
+</h3><p class="paragraph"/>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).<p class="paragraph"/>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.<p class="paragraph"/>There is one shortcut when defining results, as a lot of the time a result will have only one parameter (which is often a location to redirect to (when using XWork in the web sense)).<p class="paragraph"/>Here is the long form of a result with a single location parameter:<p class="paragraph"/><div class="code"><pre>&#60;result name=<span class="java&#45;quote">"test"</span>&#62;
+    &#60;param name=<span class="java&#45;quote">"location"</span>&#62;foo.jsp&#60;/param&#62;
+&#60;/result&#62;</pre></div><p class="paragraph"/>and this is the 'shortcut' form:<p class="paragraph"/><div class="code"><pre>&#60;result name=<span class="java&#45;quote">"test"</span>&#62;foo.jsp&#60;/result&#62;</pre></div><p class="paragraph"/>Note that this shortcut <b class="bold">only</b> works when there is a single parameter for the result and the result has defined what its default parameter is.<p class="paragraph"/>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.
+<h3 class="heading-1-1">Includes - using multiple configuration files
+</h3><p class="paragraph"/>The xwork.xml configuration file may be broken up into several files, each with its own set of package declarations, by using the &#60;include&#62; element zero or more times at the bottom of your xwork.xml file, like so:<p class="paragraph"/><div class="code"><pre>&#60;include file=<span class="java&#45;quote">"includeTest.xml"</span>/&#62;</pre></div><p class="paragraph"/>These files will be processed, in order, in the same manner as the main xwork.xml, thus may have all of the same structures, including the &#60;include&#62; element. Although it is, therefore, possible to have packages in configuration files listed later in an include element extend packages defined in an earlier included file, it is not recommended. It should be considered best practice, in the case of using multiple configuration files, to declare default packages meant to be extended in the xwork.xml and to have no dependencies between sub-configuration files.
+<h3 class="heading-1">Configuration Providers
+</h3><p class="paragraph"/>XWork configuration is handled through classes which implement the ConfigurationProvider interface.  The default implementation is the XmlConfigurationProvider class.  You can either create a new provider by implementing the ConfigurationProvider interface or you can extend the XmlConfigurationProvider class.  The XmlConfigurationProvider class includes a protected method called getInputStream() which is called to acquire the configuration InputStream which is expected to be an XML data stream.  The default implementation looks for a file called xwork.xml in the class path but by overriding the getInputStream() method you can pull configuration data from any source.<p class="paragraph"/>Custom configuration providers must be registered with the ConfigurationManager before they will be used to load configuration data.  If no custom configuration providers are registered then the default configuration provider is used.  If any custom configuration providers are registered then the default configuration provider will no longer be used (although you could add a new instance of it yourself to include it in the list of providers which is searched).  To add a configuration provider just call the ConfigurationManager.addConfigurationProvider() method with the custom configuration provider as the argument.
+  </div>
+</body>
+</html>

docs/conversion.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Type Conversion
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ Type conversion allows you to easily convert objects between on class to another.  As most of the conversion is for the web, this is usually to and from String classes.  The most common example is the conversion of date.  Let's suppose we have the following classs:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> class Foo <span class="java&#45;keyword">implements</span> Action &#123;
+  <span class="java&#45;keyword">private</span> Date date;
+  <span class="java&#45;keyword">public</span> void setDate(Date date) &#123; <span class="java&#45;keyword">this</span>.date = date ; &#125;
+  <span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> execute() &#123;
+    // <span class="java&#45;keyword">do</span> work here
+  &#125;
+&#125;</pre></div><p class="paragraph"/>XWork's type converter would allow us to pass in the String 07/08/2003 and have it be automatically converted to a Date object that's been set to July 8, 2003.<p class="paragraph"/>To define your own type converter, you'll need to perform the following steps:
+<ul class="star">
+<li>create your custom type converter object by extending DefaultTypeConverter</li>
+<li>map your type converter to your Action or model using a *-conversion.properties file</li>
+</ul><p class="paragraph"/>To use the Contact example (where Contact is a persistence object), let's say we have the following Action:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> class AddContactAction <span class="java&#45;keyword">implements</span> Action &#123;
+  <span class="java&#45;keyword">private</span> Contact contact1;
+  <span class="java&#45;keyword">private</span> Contact contact2;
+  <span class="java&#45;keyword">public</span> void setContact1(Contact contact) &#123; <span class="java&#45;keyword">this</span>.contact1 = contact; &#125;
+  <span class="java&#45;keyword">public</span> void setContact2(Contact contact) &#123; <span class="java&#45;keyword">this</span>.contact2 = contact; &#125;<p class="paragraph"/>  <span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> execute() &#123; &#8230; &#125;
+&#125;</pre></div><p class="paragraph"/>What we're expecting from the UI is for contact to be "1", the primary key of the contact.  We want the type converter to convert the string "1" to the Contact with a contactId of 1.  Likewise, we'd like the converter to be able to reverse the operation.  When displayed, a Contact object should print out its contactId as a String.<p class="paragraph"/>The first step is to create our custom TypeConverter:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> class ContactConverter <span class="java&#45;keyword">extends</span> DefaultTypeConverter &#123;
+  <span class="java&#45;keyword">public</span> <span class="java&#45;object">Object</span> convertValue(Map ognlContext, <span class="java&#45;object">Object</span> value, <span class="java&#45;object">Class</span> toType) &#123;
+    <span class="java&#45;keyword">if</span>( toType == <span class="java&#45;object">String</span>.class ) &#123;
+      Contact contact = (Contact)value;
+      <span class="java&#45;keyword">return</span> <span class="java&#45;keyword">new</span> <span class="java&#45;object">String</span>(contact.getContactId());
+    &#125; <span class="java&#45;keyword">else</span> <span class="java&#45;keyword">if</span>( toType == Contact.class ) &#123;
+      <span class="java&#45;object">Integer</span> id = <span class="java&#45;keyword">new</span> <span class="java&#45;object">Integer</span>((<span class="java&#45;object">String</span>)value);
+      Session session = &#8230; // get a Hibernate Session
+      Contact contact = (Contact)session.load(Contact.class, id);
+      <span class="java&#45;keyword">return</span> contact;
+    &#125;
+  &#125;
+&#125;</pre></div><p class="paragraph"/>The next part is to bind our ContactConverter to the previous AddContactAction.  I'll bind the ContactConverter to the AddContactAction by creating a file called AddContactAction-conversion.properties that's in the same directory as the AddContactAction class.<p class="paragraph"/>I would then populate the properties file as follows:<p class="paragraph"/><div class="code"><pre>contact1 = com.acme.ContactConverter
+contact2 = com.acme.ContactConverter</pre></div><p class="paragraph"/>Now, when XWork attempts to populate your object from parameters, you'll be given the actual instances of Contact from your database.<p class="paragraph"/>Having said all that, I can't really recommend doing database lookups here as a best practice.  In fact, I'd say it's not such a good idea, but it does illustrate type converters well :)  Any exception thrown here will be handled as described in <a href="conversionerrorhandling.html">Type Conversion Error Handling</a><p class="paragraph"/>
+  </div>
+</body>
+</html>

docs/conversionerrorhandling.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Type Conversion Error Handling
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ Type conversion errors are handled by the XWorkConverter whenever any Exception is thrown by a converter during converting a value. Type conversion errors are added to a Map stored in the ActionContext which is available via ActionContext.getContext().getConversionErrors(). This map is a map of field name to values which will allow you to access the original value which failed conversion.<p class="paragraph"/>There are 2 ways of automatically populating field errors with the type conversion errors into the field errors of the Action. The first will populate all of the field errors from the conversion errors and is implemented as an Interceptor. There are actually 2 Interceptors, one in XWork and one in WebWork which extends the one in XWork. They differ in the implementation of the method<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">protected</span> <span class="java&#45;object">boolean</span> shouldAddError(<span class="java&#45;object">String</span> propertyName, <span class="java&#45;object">Object</span> value)</pre></div><p class="paragraph"/>The XWork version always returns true, whereas the WebWork Interceptor returns false for values of null, "", and {""}, preventing type conversion exceptions for these common empty values from propogating to the field errors of the Action. The WebWork version of this Interceptor has been added to the webwork-defaults.xml and to the defaultStack defined therein.<p class="paragraph"/>If you choose not to use this Interceptor, you can choose to enable this on a per-field basis by using the Validation framework with the new field validator added for this, defined in the validators.xml file like this:<p class="paragraph"/><div class="code"><pre>&#60;validator name=<span class="java&#45;quote">"conversion"</span> class=<span class="java&#45;quote">"com.opensymphony.xwork.validator.validators.ConversionErrorFieldValidator"</span>/&#62;</pre></div><p class="paragraph"/>This validator will look up the conversion errors and, if it finds a conversion error for the field it is applied to, it will add the appropriate error message to the Action.<p class="paragraph"/>Both of these methods use the<p class="paragraph"/><div class="code"><pre>XWorkConverter.getConversionErrorMessage(propertyName, stack)</pre></div><p class="paragraph"/>which looks up the type conversion error message for the property name as was done previously, by looking for a message keyed by "invalid.fieldvalue.propertyName" and using a default value if it is not found.
+
+  </div>
+</body>
+</html>

docs/dependencies.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">XWork dependencies
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ Dependencies are always an important issue for me. I like to know <i class="italic">exactly</i> what dependencies any module has.<p class="paragraph"/>Here are the dependencies for <a href="index.html">XWork</a>, split into runtime and compile time dependencies. You may also want to look at the <a href="http://wiki.opensymphony.com/space/WebWork+2+Dependencies">WebWork 2 Dependencies</a>.
+<h3 class="heading-1-1">Runtime Dependencies
+</h3>
+These are stored in CVS in the <b class="bold">lib/core</b> directory.<p class="paragraph"/><table class="wiki-table" cellpadding="0" cellspacing="0" border="0"><tr><th>JAR</th><th>Version</th><th>Link</th></tr><tr class="table-odd"><td>commons-logging.jar</td><td>1.0</td><td><span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://jakarta.apache.org/commons/logging.html">Jakarta Commons Project</a></span></td></tr><tr class="table-even"><td>mail.jar</td><td>??</td><td>??</td></tr><tr class="table-odd"><td>ognl-2.5.1.jar</td><td>2.5.1</td><td><span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://www.ognl.org">ONGL Technology</a></span></td></tr><tr class="table-even"><td>oscore-2.1.0.jar</td><td>2.1.0</td><td><a href="http://wiki.opensymphony.com/space/OSCore">OSCore</a></td></tr></table>
+<h3 class="heading-1-1">Compile time dependencies
+</h3>
+These are stored in CVS in the <b class="bold">lib/build</b> directory.<p class="paragraph"/><table class="wiki-table" cellpadding="0" cellspacing="0" border="0"><tr><th>JAR</th><th>Version</th><th>Link</th></tr><tr class="table-odd"><td>clover-1.0.jar</td><td>1.0</td><td><span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://www.thecortex.net/clover">homepage</a></span></td></tr><tr class="table-even"><td>junit-3.8.1.jar</td><td>3.8.1</td><td><span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://www.junit.org">homepage</a></span></td></tr><tr class="table-odd"><td>mockobjects-12-7-2002.jar</td><td>12-7-2002 snapshot</td><td><span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://www.mockobjects.com">homepage</a></span></td></tr><tr class="table-even"><td>velocity.jar</td><td>??</td><td><span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://jakarta.apache.org/velocity">homepage</a></span></td></tr></table>
+
+  </div>
+</body>
+</html>

docs/documentation.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Xwork Documentation
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <h3 class="heading-1"><a href="intro.html">Xwork Introduction</a>
+</h3>
+<ul class="star">
+<li>What is Xwork?</li>
+<li>How does Webwork 2.0 relate to Xwork?</li>
+</ul>
+<h3 class="heading-1"><a href="concepts.html">XWork Core Concepts</a>
+</h3>
+<ul class="star">
+<li>Terminonlogy</li>
+</ul>
+<h3 class="heading-1"><a href="basics.html">Xwork Basics</a>
+</h3>
+<ul class="star">
+<li>Actions</li>
+<li>The Action Interface</li>
+<li>ActionSupport</li>
+<li>ActionContext</li>
+<li>Lifecycle</li>
+<li>No Formbeans?</li>
+</ul>
+<h3 class="heading-1"><a href="configuration.html">Xwork Configuration</a>
+</h3>
+<ul class="star">
+<li>Xwork.xml</li>
+<li>Xwork.xml elements</li>
+</ul>
+<h3 class="heading-1"><a href="ognl.html">Ognl</a>
+</h3>
+<h3 class="heading-1"><a href="conversion.html">Type Conversion</a>
+</h3>
+<h3 class="heading-1"><a href="conversionerrorhandling.html">Type Conversion Error Handling</a>
+</h3>
+<h3 class="heading-1"><a href="interceptors.html">Xwork Interceptors</a>
+</h3>
+<ul class="star">
+<li>Utility Interceptors</li>
+<li>Parameter Interceptors</li>
+<li>ResultInterceptor, StackInterceptor, ChainingInterceptor</li>
+</ul>
+<h3 class="heading-1"><a href="validation.html">Xwork Validation Framework</a>
+</h3>
+<ul class="star">
+<li>Turning on Validation</li>
+<li>The ValidationInterceptor</li>
+<li>Defining validation rules in a validation.xml</li>
+<li>Building a FieldValidator</li>
+<li>Localized and Parameterized messages</li>
+<li>Using the ExpressionValidator</li>
+<li><a href="fieldvalidator.html">Using the VisitorFieldValidator</a></li>
+<li><a href="validationexample.html">A WebWork2 Example of Xwork Validation</a></li>
+</ul>
+<h3 class="heading-1"><a href="components.html">XWork Components</a>
+</h3>
+<ul class="star">
+<li>Overview</li>
+<li>Why IoC?</li>
+<li>Writing Component Classes</li>
+<li>Component Dependencies</li>
+<li>Writing Enablers</li>
+<li>Writing "Enabler-aware" Actions</li>
+</ul>
+  </div>
+</body>
+</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Xwork 1.0 DTD
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <div class="code"><pre>&#60;?xml version=<span class="xml&#45;quote">"1.0"</class> encoding=<span class="xml&#45;quote">"UTF&#45;8"</class>?&#62;
+&#60;!ELEMENT xwork (package|include)+&#62;<p class="paragraph"/>&#60;!ELEMENT package (result&#45;types?, interceptors?, default&#45;interceptor&#45;ref?, global&#45;results?, action&#42;)&#62;
+&#60;!ATTLIST package
+    name CDATA #REQUIRED
+    extends CDATA #IMPLIED
+    namespace CDATA #IMPLIED
+    abstract CDATA #IMPLIED
+&#62;<p class="paragraph"/>&#60;!ELEMENT result&#45;types (result&#45;type+)&#62;<p class="paragraph"/>&#60;!ELEMENT result&#45;type (param&#42;)&#62;
+&#60;!ATTLIST result&#45;type
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    default (true|false) <span class="xml&#45;quote">"false"</class>
+&#62;<p class="paragraph"/>&#60;!ELEMENT interceptors (interceptor|interceptor&#45;stack)+&#62;<p class="paragraph"/>&#60;!ELEMENT interceptor (param&#42;)&#62;
+&#60;!ATTLIST interceptor
+    name CDATA #REQUIRED
+    class CDATA #REQUIRED
+&#62;<p class="paragraph"/>&#60;!ELEMENT interceptor&#45;stack (interceptor&#45;ref+)&#62;
+&#60;!ATTLIST interceptor&#45;stack
+    name CDATA #REQUIRED
+&#62;<p class="paragraph"/>&#60;!ELEMENT interceptor&#45;ref (param&#42;)&#62;
+&#60;!ATTLIST interceptor&#45;ref
+    name CDATA #REQUIRED
+&#62;<p class="paragraph"/>&#60;!ELEMENT default&#45;interceptor&#45;ref (param&#42;)&#62;
+&#60;!ATTLIST default&#45;interceptor&#45;ref
+    name CDATA #REQUIRED
+&#62;<p class="paragraph"/>&#60;!ELEMENT global&#45;results (result+)&#62;<p class="paragraph"/>&#60;!ELEMENT action (param|result|interceptor&#45;ref)&#42;&#62;
+&#60;!ATTLIST action
+name CDATA #REQUIRED
+    class CDATA #REQUIRED
+    method CDATA #IMPLIED
+    converter CDATA #IMPLIED
+&#62;<p class="paragraph"/>&#60;!ELEMENT param (#PCDATA)&#62;
+&#60;!ATTLIST param
+    name CDATA #REQUIRED
+&#62;<p class="paragraph"/>&#60;!ELEMENT result (#PCDATA|param)&#42;&#62;
+&#60;!ATTLIST result
+    name CDATA #REQUIRED
+    type CDATA #IMPLIED
+&#62;<p class="paragraph"/>&#60;!ELEMENT include (#PCDATA)&#62;
+&#60;!ATTLIST include
+    file CDATA #REQUIRED
+&#62;</pre></div>
+  </div>
+</body>
+</html>
Added
New image

docs/featurecomparison.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Feature comparison matrix with other MVC frameworks
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://www.waferproject.org/feature-matrix.html">&#104;ttp://www.waferproject.org/feature-matrix.html</a></span>
+  </div>
+</body>
+</html>

docs/fieldvalidator.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Using the VisitorFieldValidator
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ see the <a href="validation.html">Xwork Validation Framework</a>
+<h3 class="heading-1">What is the VisitorFieldValidator
+</h3><p class="paragraph"/>The VisitorFieldValidator allows you to forward validation to object properties of your action using the objects own validation files. This allows you to use the ModelDriven development pattern and manage your validations for your models in one place, where they belong, next to your model classes. The VisitorFieldValidator can handle either simple Object properties, Collections of Objects, or Arrays.
+<h3 class="heading-1">Applying the VisitorFieldValidator
+</h3><p class="paragraph"/>The VisitorFieldValidator is applied like any other field validator in a validation.xml file (see <a href="validation.html">Xwork Validation Framework</a>).<p class="paragraph"/><div class="code"><pre>&#60;field name=<span class="java&#45;quote">"bean"</span>&#62;
+    &#60;field&#45;validator type=<span class="java&#45;quote">"visitor"</span>&#62;
+        &#60;param name=<span class="java&#45;quote">"context"</span>&#62;anotherContext&#60;/param&#62;
+        &#60;message&#62;bean: &#60;/message&#62;
+    &#60;/field&#45;validator&#62;
+&#60;/field&#62;</pre></div><p class="paragraph"/><b class="bold">context</b> is the single parameter available to be set on the VisitorFieldValidator. If set, this sets the context to use for validating the Object property. If not set, the context of the Action validation is propogated to the Object property validation. In the case of Action validation, this context is the Action alias. Here we see the context being overridden in the validator mapping, so the action alias context will not be propogated.<p class="paragraph"/>The <b class="bold">message</b> for the VisitorFieldValidator gives a String which will be appended in front of validation messages added by the validations for the Object message.<p class="paragraph"/>
+  </div>
+</body>
+</html>

docs/interceptors.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Xwork Interceptors
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <h3 class="heading-1">Overview
+</h3><p class="paragraph"/>Interceptors allow you to define code to be executed before and/or 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 code and provide separation of concerns.<p class="paragraph"/>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.<p class="paragraph"/>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.<p class="paragraph"/>Here is the invoke() method from ActionInvocation, which calls the Interceptors and the Action:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> invoke() <span class="java&#45;keyword">throws</span> Exception &#123;
+        <span class="java&#45;keyword">if</span> (executed) &#123;
+            <span class="java&#45;keyword">throw</span> <span class="java&#45;keyword">new</span> IllegalStateException(<span class="java&#45;quote">"Action has already executed"</span>);
+        &#125;<p class="paragraph"/>        <span class="java&#45;keyword">if</span> (interceptors.hasNext()) &#123;
+            Interceptor interceptor = (Interceptor) interceptors.next();
+            result = interceptor.intercept(<span class="java&#45;keyword">this</span>);
+        &#125; <span class="java&#45;keyword">else</span> &#123;
+            result = action.execute();
+            executed = <span class="java&#45;keyword">true</span>;
+        &#125;<p class="paragraph"/>        <span class="java&#45;keyword">return</span> result;
+    &#125;</pre></div><p class="paragraph"/>It may not be immediately apparent how the rest of the Interceptors and the Action come to be called from the code snippet. For this we need to look at the Interceptor implementation in <b class="bold">AroundInterceptor</b>:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> intercept(ActionInvocation invocation) <span class="java&#45;keyword">throws</span> Exception &#123;
+        before(invocation);<p class="paragraph"/>        result = invocation.invoke();
+        after(invocation);<p class="paragraph"/>        <span class="java&#45;keyword">return</span> result;
+    &#125;</pre></div><p class="paragraph"/>Here we can see that the Interceptor calls back into the ActionInvocation.invoke() to tell the ActionInvocation to continue down the chain and eventually executes the Action. It is here that the Interceptor can decide not to forward to the rest of the Interceptors and the Action, and choose instead to return a return code.<p class="paragraph"/>It is also important to know what the AroundInterceptor is doing when you extend it to implement your own Interceptors.<p class="paragraph"/>The AroundInterceptor 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. 
+<h3 class="heading-1"><a name="Utility"/><a href="interceptors.html#Utility" title="Permalink to Utility"><img src="http://wiki.opensymphony.com/images/permalink.png" alt="" border="0"/></a> Utility Interceptors
+</h3><p class="paragraph"/>The TimerInterceptor and LoggingInterceptor are provided as simple examples and utilities. 
+<ul class="star">
+<li>The <b class="bold">LoggingInterceptor</b> simply logs before and after executing the rest of the ActionInvocation.</li>
+<li>The <b class="bold">TimerInterceptor</b> times the execution of the remainder of the ActionInvocation.</li>
+</ul>
+The TimerInterceptor does not extend AroundInterceptor because it needs to keep some state (the start time) from before the rest of the execution. Interceptors must be stateless, so it is impossible to save this in an instance field. It is a good rule of thumb to say that if your interceptor needs to maintain information from the beginning to the end of the interceptor call, it should implement Interceptor directly, not subclass AroundInterceptor. Here is the code for <b class="bold">intercept()</b> in TimerInterceptor:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> intercept(ActionInvocation dispatcher) <span class="java&#45;keyword">throws</span> Exception &#123;
+        <span class="java&#45;object">long</span> startTime = <span class="java&#45;object">System</span>.currentTimeMillis();
+        <span class="java&#45;object">String</span> result = dispatcher.invoke();
+        <span class="java&#45;object">long</span> executionTime = <span class="java&#45;object">System</span>.currentTimeMillis() &#45; startTime;
+        log.info(<span class="java&#45;quote">"Processed action "</span> + dispatcher.getProxy().getActionName() + <span class="java&#45;quote">" in "</span> + executionTime + <span class="java&#45;quote">"ms."</span>);<p class="paragraph"/>        <span class="java&#45;keyword">return</span> result;
+    &#125;</pre></div><p class="paragraph"/>It is important to remember to call <b class="bold">invoke()</b> on the ActionInvocation if you directly implement Interceptor, otherwise the rest of the Interceptors and the Action will not be executed.
+<h3 class="heading-1"><a name="Parameter"/><a href="interceptors.html#Parameter" title="Permalink to Parameter"><img src="http://wiki.opensymphony.com/images/permalink.png" alt="" border="0"/></a> Parameter Interceptors - populating your Action
+</h3><p class="paragraph"/>The StaticParametersInterceptor and ParametersInterceptor populate your Action fields during the ActionInvocation execution. 
+<ul class="star">
+<li>The <b class="bold">StaticParametersInterceptor</b> applies the parameters defined in the Action configuration with the &#60;param&#62; elements.</li>
+<li>The <b class="bold">ParametersInterceptor</b> populates the Action with the parameters passed in as part of the request.</li>
+</ul><p class="paragraph"/>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.
+<h3 class="heading-1"><a name="ModelDriven"/><a href="interceptors.html#ModelDriven" title="Permalink to ModelDriven"><img src="http://wiki.opensymphony.com/images/permalink.png" alt="" border="0"/></a> ModelDrivenInterceptor - choosing your model
+</h3><p class="paragraph"/>Normally, the <b class="bold">StaticParameterInterceptor</b> and the <b class="bold">ParametersInterceptor</b> apply themselves directly to the Action.  Using the ModelDrivenInterceptor, you can specify an alternate object to have the parameters applied to instead.<p class="paragraph"/>Consider the following Action:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> class AddContactAction <span class="java&#45;keyword">implements</span> Action &#123;
+  <span class="java&#45;keyword">private</span> <span class="java&#45;object">String</span> name;
+  <span class="java&#45;keyword">private</span> <span class="java&#45;object">String</span> addr;
+  <span class="java&#45;keyword">private</span> <span class="java&#45;object">String</span> city;<p class="paragraph"/>  <span class="java&#45;keyword">public</span> void setName(<span class="java&#45;object">String</span> name) &#123; <span class="java&#45;keyword">this</span>.name = name ; &#125;
+  <span class="java&#45;keyword">public</span> void setAddr(<span class="java&#45;object">String</span> addr) &#123; <span class="java&#45;keyword">this</span>.addr = addr ; &#125;
+  <span class="java&#45;keyword">public</span> void setCity(<span class="java&#45;object">String</span> city) &#123; <span class="java&#45;keyword">this</span>.city = city ; &#125;<p class="paragraph"/>  <span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> execute() &#123;
+     Contact contact = <span class="java&#45;keyword">new</span> Contact();
+     contact.setName(name);
+     contact.setAddr(addr);
+     contact.setCity(city);<p class="paragraph"/>     // save contact information here
+  &#125;
+&#125;</pre></div><p class="paragraph"/>We can see that our action will be populated with name, addr, and city parameters if they are passed in.  In the execute we copy these values to a contact object and save the contact.<p class="paragraph"/>Here's the ModelDriven interface:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;keyword">interface</span> ModelDriven &#123;
+  <span class="java&#45;keyword">public</span> <span class="java&#45;object">Object</span> getModel();
+&#125;</pre></div><p class="paragraph"/>Let's apply the ModelDriven interface to Action above:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> class AddContactAction <span class="java&#45;keyword">implements</span> Action, ModelDriven &#123;
+  <span class="java&#45;keyword">private</span> Contact contact = <span class="java&#45;keyword">new</span> Contact();<p class="paragraph"/>  <span class="java&#45;keyword">public</span> <span class="java&#45;object">Object</span> getModel() &#123; <span class="java&#45;keyword">return</span> <span class="java&#45;keyword">this</span>.contact ; &#125;<p class="paragraph"/>  <span class="java&#45;keyword">public</span> void execute() &#123;
+    // save the contact information
+  &#125;
+&#125;</pre></div><p class="paragraph"/>Now the ParametersInterceptor and the StaticParametersInterceptor will be applied directly to our Contact so when execute gets called, this.contact will already be populated with all the information we need.  Neat, huh?<p class="paragraph"/>Behavior similar to model driven can be achieved just using the parameter interceptor.  For example, rather than implementing ModelDriven, we could have written:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> class AddContactAction <span class="java&#45;keyword">implements</span> Action &#123;
+  <span class="java&#45;keyword">private</span> Contact contact = <span class="java&#45;keyword">new</span> Contact();<p class="paragraph"/>  <span class="java&#45;keyword">public</span> Contact getContact &#123; <span class="java&#45;keyword">return</span> <span class="java&#45;keyword">this</span>.contact ; &#125;<p class="paragraph"/>  <span class="java&#45;keyword">public</span> void execute() &#123;
+    // save the contact information
+  &#125;
+&#125;</pre></div><p class="paragraph"/>The difference between this Action and the previous ModelDriven action is twofold:
+<ul class="star">
+<li>Using the ModelDriven action, we can reference our parameters name, addr, and city.  Also, the Model (Contact) will be pushed onto the ValueStack so we'll have Contact and AddContactAction on the value stack</li>
+<li>In the more recent example, we need to reference our parameters as contact.name, contact.addr, and contact.city.</li>
+</ul>
+<h3 class="heading-1"><a name="Chaining"/><a href="interceptors.html#Chaining" title="Permalink to Chaining"><img src="http://wiki.opensymphony.com/images/permalink.png" alt="" border="0"/></a> ChainingInterceptor
+</h3><p class="paragraph"/>The <b class="bold">ChainingInterceptor</b> populates the Action it is being applied to with the results of the previous action. When actions are chained together, the action being chained FROM is on the ValueStack when the next action is called. This means that when the next ActionProxy is executed, the action that is being chained TO will be placed onto the valuestack, but the old action will also be there, just down one level. This interceptor works by traversing the ValueStack to find the parameters of any objects there and sets them onto the final action.
+<h3 class="heading-1"><a name="DefaultWorkflow"/><a href="interceptors.html#DefaultWorkflow" title="Permalink to DefaultWorkflow"><img src="http://wiki.opensymphony.com/images/permalink.png" alt="" border="0"/></a> DefaultWorkflowInterceptor
+</h3><p class="paragraph"/>The <b class="bold">DefaultWorkflowInterceptor</b> implements the workflow that was found in ActionSupport in WebWork 1.x. These workflow steps are applied before the rest of the Interceptors and the Action are executed, and may short-circuit their execution:
+<ol>
+<li>If the Action implements <b class="bold">com.opensymphony.xwork.Validateable</b>, the <b class="bold">validate()</b> method is called on it, to allow the Action to execute any validation logic coded into it.</li>
+<li>If the Action implements <b class="bold">com.opensymphony.xwork.ValidationAware</b> the <b class="bold">hasErrors()</b> method is called to check if the Action has any registered error messages (either Action-level or field-level). If the ValidationAware Action has any errors, <b class="bold">Action.INPUT</b> ("input") is returned without executing the rest of the Interceptors or the Action.</li>
+<li>If the execution did not short-circuit in step 2 above, the rest of the Interceptors and the Action are executed by calling <b class="bold">invocation.invoke()</b></li>
+</ol>
+  </div>
+</body>
+</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Xwork Introduction
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <h3 class="heading-1">What is Xwork?</h3><p class="paragraph"/>Xwork is a generic command pattern framework.<p class="paragraph"/><a href="statement.html">Xwork 1.0 Mission Statement</a>
+<h3 class="heading-1">How does Xwork relate to Webwork?</h3><p class="paragraph"/>Webwork 2.0 is built on top of Xwork.<p class="paragraph"/><a href="http://wiki.opensymphony.com/space/Webwork+2.0+Mission+Statement">Webwork 2.0 Mission Statement</a>
+  </div>
+</body>
+</html>

docs/localisation.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Localization with XWork
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <h3 class="heading-1">ActionSupport.getText() and LocalizedTextUtil
+</h3><p class="paragraph"/>The implementation of com.opensymphony.xwork.LocaleAware in com.opensymphony.xwork.ActionSupport uses com.opensymphony.xwork.util.LocalizedTextUtil to find localized message texts for message keys. LocalizedTextUtil uses a system of defaults for finding resource bundle property files for searching for the message text. If LocalizedTextUtil.findText(Class aClass, String aTextName, Locale locale) is called (or LocalizedTextUtil.findText(Class aClass, String aTextName), which just uses the Locale from ActionContext.getContext.getLocale()), the following search order is used:
+<ol>
+<li>The class name is used with the call <div class="code"><pre>ResourceBundle.getBundle(aBundleName, locale, <span class="java&#45;object">Thread</span>.currentThread().getContextClassLoader())</pre></div></li>
+<li>If the message text is not found, each parent class of the action is used as above until java.lang.Object is found</li>
+<li>If the message text has still not been found, findDefaultText(aTextName, locale) is called to search the default message bundles</li>
+</ol><p class="paragraph"/>The findDefaultText(aTextName, locale) method searches named resource bundles which have been registered with LocalzedTextUtil in reverse order of their registration (i.e. the first resource bundle name registered is the last to be searched). By default, one default resource bundle name is registered with LocalizedTextUtil for search, "com/opensymphony/xwork/xwork-messages", which is bundled with the jar file to provide system-level message texts.
+
+  </div>
+</body>
+</html>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Ognl
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ OGNL is the Object Graph Navigation Language - see <span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://www.ognl.org">&#104;ttp://www.ognl.org</a></span> for the full documentation of OGNL. In this document we will only show the additional language features that are provided on top of the base OGNL EL. 
+<h3 class="heading-1">XWork-specific language features
+</h3>
+The biggest addition that XWork provides on top of OGNL is the support for the ValueStack. While OGNL operates under the assumption there is only one "root", XWork's ValueStack concept requires there be many "roots".<p class="paragraph"/>For example, suppose we are using standard OGNL (not using XWork) and there are two objects in the OgnlContext map: "foo" -&#62; foo and "bar" -&#62; bar and that the foo object is also configured to be the single *root* object. The following code illustrates how OGNL deals with these three situations:<p class="paragraph"/><div class="code"><pre>#foo.blah // returns foo.getBlah()
+#bar.blah // returns bar.getBlah()
+blah      // returns foo.getBlah() because foo is the root</pre></div><p class="paragraph"/>What this means is that OGNL allows many objects in the context, but unless the object you are trying to access is the root, it must be prepended with a namespaces such as @bar. Now let's talk about how XWork is a little different...<p class="paragraph"/>In XWork, the entire ValueStack is the root object in the context. But rather than having your expressions get the object you want from the stack and then get properties from that (ie: peek().blah), XWork has a special OGNL PropertyAccessor that will automatically look at the all entries in the stack (from the top down) until it finds an object with the property you are looking for.<p class="paragraph"/>For example, suppose the stack contains two objects: Animal and Person. Both objects have a "name" property, Animal has a "species" property, and Person has a "salary" property. Animal is on the top of the stack, and Person is below it. The follow code fragments help you get an idea of what is going on here:<p class="paragraph"/><div class="code"><pre>species    // call to animal.getSpecies()
+salary     // call to person.getSalary()
+name       // call to animal.getName() because animal is on the top</pre></div><p class="paragraph"/>In the last example, there was a tie and so the animal's name was returned. Usually this is the desired effect, but sometimes you want the property of a lower-level object. To do this, XWork has added support for indexes on the ValueStack. All you have to do is:<p class="paragraph"/><div class="code"><pre>&#91;0&#93;.name   // call to animal.getName()
+&#91;1&#93;.name   // call to person.getName()</pre></div>
+<h3 class="heading-1">Accessing static properties
+</h3><p class="paragraph"/>OGNL supports accessing static properties as well as static methods. As the OGNL docs point out, you can explicetly call statics by doing the following:<p class="paragraph"/><div class="code"><pre>@some.package.ClassName@FOO_PROPERTY
+@some.package.ClassName@someMethod()</pre></div><p class="paragraph"/>However, XWork allows you to avoid having to specify the full package name and call static properties and methods of your action classes using the "vs" prefix:<p class="paragraph"/><div class="code"><pre>@vs@FOO_PROPERTY
+@vs@someMethod()<p class="paragraph"/>@vs1@FOO_PROPERTY
+@vs1@someMethod()<p class="paragraph"/>@vs2@BAR_PROPERTY
+@vs2@someOtherMethod()</pre></div><p class="paragraph"/>The important thing to note here is that if the class name you specify is just "vs", the class for the object on the top of the stack is used. If you specify a number after the "vs" string, an object's class deeper in the stack is used instead.
+<h3 class="heading-1">Differences from the WebWork 1.x EL
+</h3>
+Besides the examples and descriptions given above, there are a few major changes in the EL since WebWork 1.x. The biggest one is that properties are no longer accessed with a forward slash (/) but with a dot (.). Also, rather than using ".." to traverse down the stack, we now use "&#91;n&#93;" where n is some positive number. Lastly, in WebWork 1.x one could access special named objects (the request scope attributes to be exact) by using "@foo", but now special variables are accessed using "#foo". However, it is important to note that "#foo" does NOT access the request attributes. Because XWork is not built only for the web, there is no concept of "request attributes", and thus "#foo" is merely a request to another object in the OgnlContext other than the root.<p class="paragraph"/><table class="wiki-table" cellpadding="0" cellspacing="0" border="0"><tr><th>Old Expression</th><th>New Expression</th></tr><tr class="table-odd"><td>foo/blah</td><td>foo.blah</td></tr><tr class="table-even"><td>foo/someMethod()</td><td>foo.someMethod()</td></tr><tr class="table-odd"><td>../bar/blah</td><td>&#91;1&#93;.bar.blah</td></tr><tr class="table-even"><td>@baz</td><td>not directly supported, but #baz is similar</td></tr><tr class="table-odd"><td>.</td><td>top or &#91;0&#93;</td></tr></table>
+<h3 class="heading-1">WebWork-specific named objects
+</h3>
+<table class="wiki-table" cellpadding="0" cellspacing="0" border="0"><tr><th>name</th><th>value</th></tr><tr class="table-odd"><td>parameters&#91;'foo']</td><td>request attribute 'foo'</td></tr><tr class="table-even"><td>request&#91;'foo']</td><td>same as parameters&#91;'foo']</td></tr><tr class="table-odd"><td>session&#91;'foo']</td><td>session attribute 'foo'</td></tr><tr class="table-even"><td>application&#91;'foo']</td><td>ServletContext attributes 'foo'</td></tr></table>
+
+  </div>
+</body>
+</html>
Added
New image

docs/rickard.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">RickardXWorkThoughts
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ <ul class="star">
+<li>Actions. These are the application implementations (generic or specific) that together define the behaviour of the application. No news here.</li>
+<li>Interceptors. These are cross-cutting concerns that apply to several actions, and which may modify the behaviour of it, produce some side-effect to the execution of the Action, or modify the input or output of the Action.</li>
+<li>Components. This is a new concept for WebWork. Instead of just having a bunch of non-related Action's, one would bundle some of them together into a Component. An Action may be part of several Components though. The main feature of a Component is to function as a state machine which determine what Action to execute during a page rendering.</li>
+<li>Packages. Also a new concept. There are usually two approaches to configuration: coarse-grained or fine-grained. In the coarse-grained style a setting applies to EVERYTHING in the app. In the fine-grained style each part needs to be individually configured. The first focus on ease-of-use and the latter on flexibility. Packages allow for something in between. An Action, Interceptor or Component can be defined in a Package and can easily refer to one another within that package. By having hierarchical packages can easily refer to definitions in other Packages. For example, we would most likely define a number of Actions, Interceptors and possible Components that are in a "default" Package, which user Packages would then depend on. However, user Packages could then override any such definition made higher up. This gives the  ease-of-use of a coarse-grained configuration together with the total control and flexibility of a fine-grained configuration, while still providing reasonably clear semantics.</li>
+</ul><p class="paragraph"/>These are the core concepts that I can think of. Now, for my own 
+portlet-ish needs (which I hope will be more common for others too in 
+the future) the following applies:
+<ul class="star">
+<li>Actions and Components, and their resulting views, are ALWAYS called through a servlet include. This means that the URL in a browser NEVER reveals that XWork is used. For example, an admin app would consist of an admin.jsp which includes the Actions/Components needed for that app. Not only does that make it easy to extend the admin app later on with more "portlets", it also makes it possible (for those who are so inclined) to use J2EE declarative security very easily. Plus bookmarks are human-friendly. This means that the dispatcher would explicitly disallow Action invocation that are NOT a result of an include. This too adds some extra security, since only actions that YOU decide should be called are actually callable. Plus, your actions can decide much better in what order they are called, depending on your app requirements. The actual include would still be using the ".action" extension though.</li>
+<li>For many simple portlets an include of a .action is fine. For complex portlets that require a state machine this is not ok. Instead, what one usually wants is to include a "component" that then delegates to some action depending on the *state* of some automata. This is similar to how the CardPane works in WebWork. Essentially, XWork would include this kind of state machine as a built-in concept instead of as an "add-on" like CardPane, since this is such an important and common case. It needs to be as simple and flexible as is possible. When a component renders its view it also creates URL's that define what the possible next states are. This means that the URL's in the generated HTML are shortlived (i.e. after one of the URL's have been clicked they are all invalid), which also means that it will be impossible to have a double form submit. After the first submit the URL will be invalid, so clicking again will not lead to a re-execution of the action. This also gives some extra security.</li>
+<li>The execution of a Component (and maybe Action's too) needs to be split into two phases. The actual execution of an action is done at the _beginning_ of a page render, and the rendering is done at the time of the include. Why? Because the action may influence what is shown on the page, and may also result in a redirect to another page. If the action execution is done at the point of the include it's too late to do a redirect, and other portlets may have rendered state that is then changed by the action execution. (This thinking, by coincidence, mirrors well how the portlet API will work)</li>
+<li>When rendering URL's, the parameters need to be namespace'd in order to allow several portlets to happily live together on a page. I.e. instead of having ?foo=bar one could have ?1.foo=bar&2.foo=bar. The XWork servlet dispatcher would then at execution filter out those parameters which does not apply to the action/component/portlet being executed, and only the remaining parameters are applied using the setX() initialization code. This requires the rendering code to use either a taglib (in JSP) or some JavaBean (in Velocity) which can do this encoding. I know that for *some* applications this will be overkill, but for those of use who are going beyond very simple web apps it is a definitive must.</li>
+</ul>
+
+  </div>
+</body>
+</html>

docs/roadmap.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">XWork Roadmap
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ Here is an overview of the general goals of the next generation <a href="http://wiki.opensymphony.com/space/WebWork">WebWork</a>, called <a href="index.html">XWork</a>. Suggestions and feature requests are encouraged to be directed to the <span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://lists.sourceforge.net/lists/listinfo/opensymphony-webwork">WebWork mailing list</a></span>, not here. Please feel free to fill this in as much as possible.
+<h3 class="heading-1-1">Core:
+</h3>
+<ul class="star">
+<li>Completely divorce from dependence on J2EE - <b class="bold">done</b></li>
+<li>Provide additional Dispatchers: e.g. JMSDispatcher and MailDispatcher - <b class="bold">Out of Scope</b></li>
+<li>Replace the ActionFactory proxy idea with Interception support - <b class="bold">done</b></li>
+<li>Overhaul configuration system - <b class="bold">done</b></li>
+<li>Provide more view systems (xml/soap/swing/awt/tea/cf/php/flash/?) - <b class="bold">Out of Scope</b></li>
+<li>Break current taglib into two taglibs (core and ui) - <b class="bold">Out of Scope - See Webwork 2.0</b></li>
+<li>Abstract current taglib code out of taglibs to make available to other view systems - <b class="bold">Out of Scope - See Webwork 2.0</b></li>
+<li>Distribute core and view systems in different jars - <b class="bold">done - Xwork is the core</b></li>
+<li>Move to <span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://www.ognl.org">OGNL</a></span> - <b class="bold">done</b></li>
+<li><span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://jira.opensymphony.com/index.html">JIRA</a></span> issues/features</li>
+<li>Fix/standardize logging - <b class="bold">done</b> I think</li>
+<li>Self-reloading config system, detects changes in config files and reloads accordingly - <b class="bold">done</b></li>
+</ul>
+<h3 class="heading-1-1">Documentation:
+</h3>
+<ul class="star">
+<li><a href="documentation.html">XWork Documentation</a></li>
+<li>Jira Xwork Roadmap: <span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://jira.opensymphony.com/secure/BrowseProject.jspa?id=10050&amp;report=roadmap">&#104;ttp://jira.opensymphony.com/secure/BrowseProject.jspa?id=10050&amp;report=roadmap</a></span></li>
+<li>Quickstart guide</li>
+<li>Examples</li>
+<li>Tutorials</li>
+<li>Better javadocs</li>
+<li><a href="featurecomparison.html">Feature comparison matrix with other MVC frameworks</a></li>
+<li>Implementation of the <span class="nobr"><img src="http://wiki.opensymphony.com/images/external-link.png" alt="&gt;&gt;" border="0"/><a href="http://www.waferproject.org/index.html">wafer project</a></span> and/or larger example application</li>
+<li>FAQ</li>
+<li>Best practices guide</li>
+</ul><p class="paragraph"/><a href="rickard.html">RickardXWorkThoughts</a>
+  </div>
+</body>
+</html>

docs/statement.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">XWork 1.0 Mission Statement
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ The Purpose:
+*To create a generic, reusable, and extensible command pattern framework not tied to any particular usage.<p class="paragraph"/>Features:
+<ul class="star">
+<li>Flexible and customizable configuration based on a simple Configuration interface</li>
+<li>Core command pattern framework which can be customized and extended through the use of interceptors to fit any request / response environment</li>
+<li>Built in type conversion and action property validation using Ognl</li>
+<li>Powerful validation framework based on runtime attributes and a validation interceptor</li>
+</ul>
+  </div>
+</body>
+</html>

docs/validation.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">Xwork Validation Framework
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ The validation framework in XWork is designed to help you apply simple validation rules to your Actions before they are executed. 
+<h3 class="heading-1">Core Concepts
+</h3><p class="paragraph"/>The Validator framework, at its core, takes just an object and a String context name for which to validate that object. This allows you to have different validations for the same class in different contexts. You can define default validations in the class-level validation file (<b class="bold">ClassName-validation.xml</b>), and then define validations which are added on top of these for a specific context (<b class="bold">ClassName-contextName-validation.xml</b>). In the case of Action validation, this context is the Action alias. The validators are applied in the order they are listed in the validation files and error messages are saved into the Object (if it implements ValidationAware).
+<h3 class="heading-1">The ValidationInterceptor
+</h3><p class="paragraph"/>The ValidationInterceptor is an Xwork Interceptor which handles the process of applying validators to an Action before it is executed and allows the Validators to apply any messages to the Action that are required. Bear in mind that even if errors are added due to failed validation, the action will still be executed.
+<h3 class="heading-1">Registering Validators
+</h3><p class="paragraph"/>Validators must be registered with the ValidatorFactory. This may either be done programmatically, using the registerValidator(String name, Class clazz) static method of the ValidatorFactory, or by putting a file name validators.xml in the root of the classpath with a structure like this:<p class="paragraph"/><div class="code"><pre>&#60;validators&#62;
+    &#60;validator name=<span class="xml&#45;quote">"required"</class>
+        class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.RequiredFieldValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"requiredstring"</class>
+        class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.RequiredStringValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"int"</class> 
+        class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.IntRangeFieldValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"date"</class> 
+        class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.DateRangeFieldValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"expression"</class> 
+        class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.ExpressionValidator"</class>/&#62;
+&#60;/validators&#62;</pre></div>
+<h3 class="heading-1">Turning on Validation
+</h3><p class="paragraph"/>All that is required to enable validation for an Action is to put the ValidationInterceptor in the interceptor refs of the action (see <a href="configuration.html">Xwork Configuration</a>) like so:<p class="paragraph"/><div class="code"><pre>&#60;interceptor name=<span class="xml&#45;quote">"validator"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.ValidationInterceptor"</class>/&#62;</pre></div><p class="paragraph"/>Then create a file named <b class="bold">ActionName-validation.xml</b> in the same package as the Action class file. You may also create alias specific validators which add to the Action class specific validators defined in the <b class="bold">ActionName-validation.xml</b> by creating another file in the same directory name <b class="bold">ActionName-aliasname-validation.xml</b>, where <b class="bold">ActionName</b> is the name of the class, and <b class="bold">aliasname</b> is the name of the action alias defined in the <b class="bold">xwork.xml</b> configuration for this Action. The framework will also search up the inheritance tree of the action to find default validations for parent classes of the Action, just like the <a href="localisation.html">Localization with XWork</a> framework does when finding messages.<p class="paragraph"/>In this way, you may define some default interceptors for all of the alias's of a class, and then define alias specific validators in the <b class="bold">ActionName-alias-validation.xml</b>.
+<h3 class="heading-1">Defining validation rules in a validation.xml
+</h3><p class="paragraph"/>Here is an example validator.xml, SimpleAction-validation.xml, from the Xwork tests:<p class="paragraph"/><div class="code"><pre>&#60;!DOCTYPE validators PUBLIC <span class="xml&#45;quote">"&#45;//OpenSymphony Group//XWork Validator 1.0//EN"</class>
+        <span class="xml&#45;quote">"http://www.opensymphony.com/xwork/xwork&#45;validator&#45;1.0.dtd"</class>&#62;
+&#60;validators&#62;
+    &#60;field name=<span class="xml&#45;quote">"bar"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"required"</class>&#62;
+            &#60;message&#62;You must enter a value for bar.&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"int"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"min"</class>&#62;6&#60;/param&#62;
+            &#60;param name=<span class="xml&#45;quote">"max"</class>&#62;10&#60;/param&#62;
+            &#60;message&#62;bar must be between $&#123;min&#125; and $&#123;max&#125;, current value is $&#123;bar&#125;.&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+    &#60;field name=<span class="xml&#45;quote">"date"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"date"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"min"</class>&#62;12/22/2002&#60;/param&#62;
+            &#60;param name=<span class="xml&#45;quote">"max"</class>&#62;12/25/2002&#60;/param&#62;
+            &#60;message&#62;The date must be between 12&#45;22&#45;2002 and 12&#45;25&#45;2002.&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+    &#60;field name=<span class="xml&#45;quote">"foo"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"int"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"min"</class>&#62;0&#60;/param&#62;
+            &#60;param name=<span class="xml&#45;quote">"max"</class>&#62;100&#60;/param&#62;
+            &#60;message key=<span class="xml&#45;quote">"foo.range"</class>&#62;Could not find foo.range!&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+    &#60;validator type=<span class="xml&#45;quote">"expression"</class>&#62;
+        &#60;param name=<span class="xml&#45;quote">"expression"</class>&#62;foo &#62; bar&#60;/param&#62;
+        &#60;message&#62;Foo must be greater than Bar. Foo = $&#123;foo&#125;, Bar = $&#123;bar&#125;.&#60;/message&#62;
+    &#60;/validator&#62;
+&#60;/validators&#62;</pre></div><p class="paragraph"/>Here we can see the configuration of validators for the SimpleAction class. Validators (and field-validators) must have a "type" attribute, which refers to a name of an Validator registered with the ValidatorFactory as above. Validator elements may also have &#60;param&#62; elements with name and value attributes to set arbitrary parameters into the Validator instance. See below for discussion of the message element.
+<h3 class="heading-1-1">Validator vs. Field-Validator
+</h3><p class="paragraph"/>Field-Validator elements inside &#60;field&#62; elements are basically the same as Validator elements, except that they inherit a parameter with name "fieldName" and with a value of the field name set in the enclosing field element.<p class="paragraph"/>The reason for the field-&#62;field-validator structure is that it is more clear to group the validators for a particular field under one field element, and because the fieldName param would otherwise always have to be set for field validators.<p class="paragraph"/>That said, it's perfectly legal to only use validator elements without the field elements and set the fieldName parameter for each of them.
+<h3 class="heading-1-1">Message Element
+</h3><p class="paragraph"/>Each Validator or Field-Validator element must define one message element inside the validator element body. The message element has 1 attributes, key which is not required. The body of the message tag is taken as the default message which should be added to the Action if the validator fails.<p class="paragraph"/>Key gives a message key to look up in the Action's ResourceBundles using getText() from LocaleAware if the Action implements that interface (as ActionSupport does). This provides for Localized messages based on the Locale of the user making the request (or whatever Locale you've set into the LocaleAware Action).<p class="paragraph"/>After either retrieving the message from the ResourceBundle using the Key value, or using the Default message, the current Validator is pushed onto the ValueStack, then the message is parsed for &#36;&#123;...&#125; sections which are replaced with the evaluated value of the string between the &#36;&#123; and &#125;. This allows you to parameterize your messages with values from the Validator, the Action, or both. Here is an example of a parameterized message:<p class="paragraph"/><div class="code"><pre>bar must be between &#36;&#123;min&#125; and &#36;&#123;max&#125;, current value is &#36;&#123;bar&#125;.</pre></div><p class="paragraph"/>This will pull the min and max parameters from the IntRangeFieldValidator and the value of bar from the Action.
+<h3 class="heading-1">Building a Validator
+</h3><p class="paragraph"/>Validators implement the <b class="bold">com.opensymphony.xwork.validator.Validator</b> interface<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;keyword">interface</span> Validator &#123;
+    void setDefaultMessage(<span class="java&#45;object">String</span> message);<p class="paragraph"/>    <span class="java&#45;object">String</span> getDefaultMessage();<p class="paragraph"/>    <span class="java&#45;object">String</span> getMessage(<span class="java&#45;object">Object</span> object);<p class="paragraph"/>    void setMessageKey(<span class="java&#45;object">String</span> key);<p class="paragraph"/>    <span class="java&#45;object">String</span> getMessageKey();<p class="paragraph"/>    /&#42;&#42;
+     &#42; This method will be called before validate with a non&#45;<span class="java&#45;keyword">null</span> 
+     &#42; ValidatorContext.
+     &#42; @param validatorContext
+     &#42;/
+    void setValidatorContext(ValidatorContext validatorContext);<p class="paragraph"/>    ValidatorContext getValidatorContext();<p class="paragraph"/>    /&#42;&#42;
+     &#42; The validation implementation must guarantee that setValidatorContext
+     &#42; will be called with a non&#45;<span class="java&#45;keyword">null</span> ValidatorContext before validate is 
+     &#42; called.
+     &#42; @param object
+     &#42; @<span class="java&#45;keyword">throws</span> ValidationException
+     &#42;/
+    void validate(<span class="java&#45;object">Object</span> object) <span class="java&#45;keyword">throws</span> ValidationException;
+&#125;</pre></div><p class="paragraph"/>FieldValidators implement <b class="bold">com.opensymphony.xwork.validator.FieldValidator</b>, which extends Validator:<p class="paragraph"/><div class="code"><pre><span class="java&#45;keyword">public</span> <span class="java&#45;keyword">interface</span> FieldValidator <span class="java&#45;keyword">extends</span> Validator &#123;<p class="paragraph"/>    /&#42;&#42;
+     &#42; Sets the field name to validate with <span class="java&#45;keyword">this</span> FieldValidator
+     &#42; @param fieldName
+     &#42;/
+    void setFieldName(<span class="java&#45;object">String</span> fieldName);<p class="paragraph"/>    /&#42;&#42;
+     &#42; @<span class="java&#45;keyword">return</span> the field name to be validated
+     &#42;/
+    <span class="java&#45;object">String</span> getFieldName();<p class="paragraph"/>&#125;</pre></div><p class="paragraph"/>Validators and FieldValidators can extend base classes <b class="bold">com.opensymphony.xwork.validator.validators.ValidatorSupport</b> and <b class="bold">com.opensymphony.xwork.validator.validators.FieldValidatorSupport</b> to get the base message behavior, and will only need to implement validate(Action action).<p class="paragraph"/>The Support classes provide the functionality to use the message key and default message to get the localied message body and the parsing of the message body to provide for parameterized messages. Implementations of the Validator Interface which do not extend the Support base classes should provide this functionality as well for consistency.<p class="paragraph"/>The <b class="bold">ValidatorContext</b> set into the Validator is an interface which extends both <b class="bold">ValidationAware</b> and <b class="bold">LocaleAware</b> and is used for looking up message texts and settting errors. When validators are called from the ValidationInterceptor, a DelegatingValidatorContext is created which delegates these calls to the Action if it implements these interfaces. If the Action does not implement LocaleAware, a LocaleAwareSupport instance is created which uses the Action's class to look up resource bundle texts, if available. If the action does not implement ValidationAware, an implementation which simply logs the validation errors is created and delegated to. When calling the validation framework from outside the ValidationInterceptor, any ValidatorContext implementation can be passed in.<p class="paragraph"/>Validator classes may define any number of properties using the usual getX() setX() naming convention and have those properties set using &#60;param name="x"&#62;foo&#60;/param&#62; elements below the &#60;validator&#62; element. The values of these properties may then be used in the validate() method to parameterize the validation. Validators which extend the Support classes may also use the<p class="paragraph"/>Object getFieldValue(String name, Action action) method to get the field value of a named property from an Action.
+<h3 class="heading-1">Using the Expression Validator
+</h3><p class="paragraph"/>The Expression validator extends the ValidatorSupport base class and has one parameter which should be set using &#60;param name="expression"&#62; any valid ognl expression which returns a boolean&#60;/param&#62;. The expression will be evaluated against the ValueStack, allowing you to use any properties of the Action in comparisons, etc.<p class="paragraph"/>This allows for very powerful cross-property validation expressions. Here is a simple example of the ExpressionValidator in a configuration:<p class="paragraph"/><div class="code"><pre>&#60;validator type=<span class="xml&#45;quote">"expression"</class>&#62;
+        &#60;param name=<span class="xml&#45;quote">"expression"</class>&#62;foo &#62; bar&#60;/param&#62;
+        &#60;message default=<span class="xml&#45;quote">"Foo must be greater than Bar. Foo = $&#123;foo&#125;, Bar = $&#123;bar&#125;."</class>/&#62;
+&#60;/validator&#62;</pre></div>
+<h3 class="heading-1">See <a href="fieldvalidator.html">Using the VisitorFieldValidator</a></h3>
+  </div>
+</body>
+</html>

docs/validationexample.html

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <title>XWork Documentation</title>
+  <link type="text/css" href="main.css" rel="STYLESHEET"/>
+</head>
+<body>
+  <div id="page-logo">
+    <a href="index.html"><img src="logo.png" border="0"/></a>
+  </div>
+    <div class="snip-title">
+	  <h1 class="snip-name">A WebWork2 Example of Xwork Validation
+  
+  </h1>
+  </div>
+<div id="snip-content" class="snip-content">
+
+ <div class="snip-attachments"></div>
+ 
+ Included in the <a href="http://wiki.opensymphony.com/space/WebWork2">WebWork2</a> example war file is an example of using the <a href="validation.html">Xwork Validation Framework</a> in WebWork2. This example consists of three links which all use the same Action Class and view pages (Velocity).
+<h3 class="heading-1">The sources
+</h3><p class="paragraph"/>First, I had to add the <b class="bold">validators.xml</b> file to the root of the source tree for the example app
+<div class="code"><pre>&#60;validators&#62;
+    &#60;validator name=<span class="xml&#45;quote">"required"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.RequiredFieldValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"requiredstring"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.RequiredStringValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"int"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.IntRangeFieldValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"date"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.DateRangeFieldValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"expression"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.ExpressionValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"fieldexpression"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.FieldExpressionValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"email"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.EmailValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"url"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.URLValidator"</class>/&#62;
+    &#60;validator name=<span class="xml&#45;quote">"visitor"</class> class=<span class="xml&#45;quote">"com.opensymphony.xwork.validator.validators.VisitorFieldValidator"</class>/&#62;
+&#60;/validators&#62;</pre></div><p class="paragraph"/>The Action class used by all of the validation examples is <b class="bold">ValidatedAction</b>
+<div class="code"><pre><span class="java&#45;keyword">package</span> com.opensymphony.webwork.example;<p class="paragraph"/><span class="java&#45;keyword">import</span> com.opensymphony.xwork.ActionSupport;<p class="paragraph"/>/&#42;&#42;
+ &#42; ValidatedAction
+ &#42; @author Jason Carreira
+ &#42; Created Sep 12, 2003 9:23:38 PM
+ &#42;/
+<span class="java&#45;keyword">public</span> class ValidatedAction <span class="java&#45;keyword">extends</span> ActionSupport &#123;
+    <span class="java&#45;keyword">private</span> ValidatedBean bean = <span class="java&#45;keyword">new</span> ValidatedBean();
+    <span class="java&#45;keyword">private</span> <span class="java&#45;object">String</span> name;
+    <span class="java&#45;keyword">private</span> <span class="java&#45;object">String</span> validationAction = <span class="java&#45;quote">"basicValidation.action"</span>;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> ValidatedBean getBean() &#123;
+        <span class="java&#45;keyword">return</span> bean;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> void setBean(ValidatedBean bean) &#123;
+        <span class="java&#45;keyword">this</span>.bean = bean;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> getName() &#123;
+        <span class="java&#45;keyword">return</span> name;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> void setName(<span class="java&#45;object">String</span> name) &#123;
+        <span class="java&#45;keyword">this</span>.name = name;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> getValidationAction() &#123;
+        <span class="java&#45;keyword">return</span> validationAction;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> void setValidationAction(<span class="java&#45;object">String</span> validationAction) &#123;
+        <span class="java&#45;keyword">this</span>.validationAction = validationAction;
+    &#125;
+&#125;</pre></div><p class="paragraph"/>
+The base validation file for the ValidatedAction is <b class="bold">ValidatedAction-validation.xml</b>
+<div class="code"><pre>&#60;!DOCTYPE validators PUBLIC <span class="xml&#45;quote">"&#45;//OpenSymphony Group//XWork Validator 1.0//EN"</class> <span class="xml&#45;quote">"http://www.opensymphony.com/xwork/xwork&#45;validator&#45;1.0.dtd"</class>&#62;
+&#60;validators&#62;
+    &#60;field name=<span class="xml&#45;quote">"name"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"requiredstring"</class>&#62;
+            &#60;message&#62;You must enter a name.&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+&#60;/validators&#62;</pre></div>
+This and all other validation files are placed in the same package as the classes to which they apply.<p class="paragraph"/>The form for this Action is <b class="bold">validationForm.vm</b>
+<div class="code"><pre>&#60;html&#62;
+&#60;head&#62;&#60;title&#62;Webwork Validation Example&#60;/title&#62;&#60;/head&#62;
+&#60;body&#62;
+#<span class="java&#45;keyword">if</span>( $actionErrors.size() &#62; 0 )
+&#60;p&#62;
+&#60;font color=<span class="java&#45;quote">"red"</span>&#62;
+&#60;b&#62;ERRORS:&#60;/b&#62;&#60;br&#62;
+&#60;ul&#62;
+#foreach( $error in $actionErrors )
+&#60;li&#62;$error&#60;/li&#62;
+#end
+&#60;/ul&#62;
+&#60;/font&#62;
+&#60;/p&#62;
+#end
+&#60;p&#62;
+&#60;form name=<span class="java&#45;quote">"myForm"</span> action=<span class="java&#45;quote">"$&#123;validationAction&#125;"</span> method=<span class="java&#45;quote">"POST"</span>&#62;
+&#60;input type=<span class="java&#45;quote">"hidden"</span> name=<span class="java&#45;quote">"validationAction"</span> value=<span class="java&#45;quote">"$&#123;validationAction&#125;"</span>/&#62;
+Action Properties:
+&#60;br&#62;
+&#60;table&#62;
+#tag( TextField <span class="java&#45;quote">"label=Name"</span> <span class="java&#45;quote">"name=name"</span> <span class="java&#45;quote">"value=name"</span> )
+&#60;/table&#62;
+Bean Properties:
+#<span class="java&#45;keyword">if</span>( $stack.findValue(<span class="java&#45;quote">"fieldErrors"</span>) )
+    #set( $beanErrors = $stack.findValue(<span class="java&#45;quote">"fieldErrors.get('bean')"</span>) )
+    #<span class="java&#45;keyword">if</span>( $beanErrors.size() &#62; 0 )
+    &#60;br&#62;
+    &#60;font color=<span class="java&#45;quote">"red"</span>&#62;
+    &#60;b&#62;Bean Errors:&#60;/b&#62;&#60;br&#62;
+    &#60;ul&#62;
+    #foreach( $beanError in $beanErrors )
+    &#60;li&#62;$beanError&#60;/li&#62;
+    #end
+    &#60;/ul&#62;
+    &#60;/font&#62;
+    #end
+#end
+&#60;table&#62;
+#tag( TextField <span class="java&#45;quote">"label=Bean.Text"</span> <span class="java&#45;quote">"name=bean.text"</span> <span class="java&#45;quote">"value=bean.text"</span> )&#60;br&#62;
+#tag( TextField <span class="java&#45;quote">"label=Bean.Date"</span> <span class="java&#45;quote">"name=bean.date"</span> <span class="java&#45;quote">"value=bean.date"</span> )&#60;br&#62;
+#tag( TextField <span class="java&#45;quote">"label=Bean.<span class="java&#45;object">Number</span>"</span> <span class="java&#45;quote">"name=bean.number"</span> <span class="java&#45;quote">"value=bean.number"</span> )&#60;br&#62;
+#tag( TextField <span class="java&#45;quote">"label=Bean.Number2"</span> <span class="java&#45;quote">"name=bean.number2"</span> <span class="java&#45;quote">"value=bean.number2"</span> )&#60;br&#62;
+&#60;/table&#62;
+&#60;input type=<span class="java&#45;quote">"submit"</span> value=<span class="java&#45;quote">"Test Validation"</span>/&#62;
+&#60;/form&#62;
+&#60;/body&#62;</pre></div><p class="paragraph"/>The success page for these examples is a very simple page, <b class="bold">valid.xml</b>
+<div class="code"><pre>&#60;html&#62;
+&#60;head&#62;&#60;title&#62;WebWork Validation Test: Valid&#60;/title&#62;&#60;/head&#62;
+&#60;body&#62;
+Input was valid!
+&#60;/body&#62;
+&#60;/html&#62;</pre></div><p class="paragraph"/>We'll look at any other example-specific configuration files as we get to them.
+<h3 class="heading-1"><a name="BasicValidation"/><a href="validationexample.html#BasicValidation" title="Permalink to BasicValidation"><img src="http://wiki.opensymphony.com/images/permalink.png" alt="" border="0"/></a> Basic Validation
+</h3><p class="paragraph"/>
+The BasicValidation example is defined in the example <b class="bold">xwork.xml</b> file like this
+<div class="code"><pre>&#60;action name=<span class="xml&#45;quote">"basicValidation"</class> class=<span class="xml&#45;quote">"com.opensymphony.webwork.example.ValidatedAction"</class>&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"validationWorkflowStack"</class>/&#62;<p class="paragraph"/>            &#60;result name=<span class="xml&#45;quote">"success"</class> type=<span class="xml&#45;quote">"dispatcher"</class>&#62;valid.vm&#60;/result&#62;
+            &#60;result name=<span class="xml&#45;quote">"input"</class> type=<span class="xml&#45;quote">"dispatcher"</class>&#62;validationForm.vm&#60;/result&#62;
+            &#60;result name=<span class="xml&#45;quote">"error"</class> type=<span class="xml&#45;quote">"dispatcher"</class>&#62;validationForm.vm&#60;/result&#62;
+        &#60;/action&#62;</pre></div><p class="paragraph"/>The <b class="bold">interceptor-ref</b> here, to <b class="bold">"validationWorkflowStack"</b>, is defined in webwork-default.xml (see <a href="http://wiki.opensymphony.com/space/Using+webwork-default.xml">Using webwork-default.xml</a>) and provides the parameter interceptors as well as the ValidationInterceptor (see <a href="validation.html">Xwork Validation Framework</a> and the DefaultWorkFlowInterceptor (see <a href="interceptors.html#DefaultWorkflow">Xwork Interceptors#DefaultWorkflow</a>). All of the parameters from the configuration file (there are none in this case) followed by the parameters from the request will be set onto the Action. Next, the validations will be run, and finally the DefaultWorkflow will be applied (see <a href="interceptors.html#DefaultWorkflow">Xwork Interceptors#DefaultWorkflow</a>).<p class="paragraph"/>This example is very simple, and the ValidatedAction-validation.xml file is the only set of Validations which will be applied. This means that the only validation done is that you enter some text for the name field. 
+<h3 class="heading-1"><a name="VisitorValidation"/><a href="validationexample.html#VisitorValidation" title="Permalink to VisitorValidation"><img src="http://wiki.opensymphony.com/images/permalink.png" alt="" border="0"/></a> Visitor Validation Example
+</h3><p class="paragraph"/>The <b class="bold">ValidatedAction</b> holds a reference to a plain Java bean, <b class="bold">ValidatedBean</b>:
+<div class="code"><pre><span class="java&#45;keyword">package</span> com.opensymphony.webwork.example;<p class="paragraph"/><span class="java&#45;keyword">import</span> java.util.Date;<p class="paragraph"/>/&#42;&#42;
+ &#42; ValidatedBean
+ &#42; @author Jason Carreira
+ &#42; Created Sep 12, 2003 9:24:18 PM
+ &#42;/
+<span class="java&#45;keyword">public</span> class ValidatedBean &#123;
+    <span class="java&#45;keyword">private</span> <span class="java&#45;object">String</span> text;
+    <span class="java&#45;keyword">private</span> Date date = <span class="java&#45;keyword">new</span> Date(<span class="java&#45;object">System</span>.currentTimeMillis());
+    <span class="java&#45;keyword">private</span> <span class="java&#45;object">int</span> number;
+    <span class="java&#45;keyword">private</span> <span class="java&#45;object">int</span> number2;
+    <span class="java&#45;keyword">public</span> <span class="java&#45;keyword">static</span> <span class="java&#45;keyword">final</span> <span class="java&#45;object">int</span> MAX_TOTAL = 12;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> <span class="java&#45;object">String</span> getText() &#123;
+        <span class="java&#45;keyword">return</span> text;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> void setText(<span class="java&#45;object">String</span> text) &#123;
+        <span class="java&#45;keyword">this</span>.text = text;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> Date getDate() &#123;
+        <span class="java&#45;keyword">return</span> date;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> void setDate(Date date) &#123;
+        <span class="java&#45;keyword">this</span>.date = date;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> <span class="java&#45;object">int</span> getNumber() &#123;
+        <span class="java&#45;keyword">return</span> number;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> void setNumber(<span class="java&#45;object">int</span> number) &#123;
+        <span class="java&#45;keyword">this</span>.number = number;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> <span class="java&#45;object">int</span> getNumber2() &#123;
+        <span class="java&#45;keyword">return</span> number2;
+    &#125;<p class="paragraph"/>    <span class="java&#45;keyword">public</span> void setNumber2(<span class="java&#45;object">int</span> number2) &#123;
+        <span class="java&#45;keyword">this</span>.number2 = number2;
+    &#125;
+&#125;</pre></div><p class="paragraph"/>The base validation file for the ValidatedBean is <b class="bold">ValidatedBean-validation.xml</b>
+<div class="code"><pre>&#60;!DOCTYPE validators PUBLIC <span class="xml&#45;quote">"&#45;//OpenSymphony Group//XWork Validator 1.0//EN"</class> <span class="xml&#45;quote">"http://www.opensymphony.com/xwork/xwork&#45;validator&#45;1.0.dtd"</class>&#62;
+&#60;validators&#62;
+    &#60;field name=<span class="xml&#45;quote">"text"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"requiredstring"</class>&#62;
+            &#60;message key=<span class="xml&#45;quote">"invalid.text"</class>&#62;Empty Text!&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+    &#60;field name=<span class="xml&#45;quote">"date"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"date"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"min"</class>&#62;01/01/1970&#60;/param&#62;
+            &#60;message key=<span class="xml&#45;quote">"invalid.date"</class>&#62;Invalid Date!&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+    &#60;field name=<span class="xml&#45;quote">"number"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"int"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"min"</class>&#62;1&#60;/param&#62;
+            &#60;param name=<span class="xml&#45;quote">"max"</class>&#62;10&#60;/param&#62;
+            &#60;message key=<span class="xml&#45;quote">"invalid.number"</class>&#62;Invalid Number!&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+&#60;/validators&#62;</pre></div><p class="paragraph"/>In the Visitor Validation Example, we add a <b class="bold">VisitorFieldValidator</b> (see <a href="fieldvalidator.html">Using the VisitorFieldValidator</a>) to apply these validations to our <b class="bold">ValidatedBean</b>. The Action is defined in our <b class="bold">xwork.xml</b> file like this:
+<div class="code"><pre>&#60;action name=<span class="xml&#45;quote">"visitorValidation"</class> class=<span class="xml&#45;quote">"com.opensymphony.webwork.example.ValidatedAction"</class>&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"validationWorkflowStack"</class>/&#62;
+            &#60;param name=<span class="xml&#45;quote">"validationAction"</class>&#62;visitorValidation.action&#60;/param&#62;
+            &#60;result name=<span class="xml&#45;quote">"success"</class>&#62;valid.vm&#60;/result&#62;
+            &#60;result name=<span class="xml&#45;quote">"input"</class>&#62;validationForm.vm&#60;/result&#62;
+            &#60;result name=<span class="xml&#45;quote">"error"</class>&#62;validationForm.vm&#60;/result&#62;
+        &#60;/action&#62;</pre></div><p class="paragraph"/>Here we see a slight difference from the basic validation example above. I've added a static param to the Action which will be applied to the Action by the static-param interceptor. This parameter only sets the value for the action to post the form to for validation (see <b class="bold">validationForm.vm</b>).<p class="paragraph"/>The Action name above, <b class="bold">visitorValidation</b> is mapped to another set of validations defined in the file <b class="bold">ValidatedAction-visitorValidation-validation.xml</b>
+<div class="code"><pre>&#60;!DOCTYPE validators PUBLIC <span class="xml&#45;quote">"&#45;//OpenSymphony Group//XWork Validator 1.0//EN"</class> <span class="xml&#45;quote">"http://www.opensymphony.com/xwork/xwork&#45;validator&#45;1.0.dtd"</class>&#62;
+&#60;validators&#62;
+    &#60;field name=<span class="xml&#45;quote">"bean"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"required"</class>&#62;
+            &#60;message&#62;The bean must not be null.&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"visitor"</class>&#62;
+            &#60;message&#62;bean: &#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+&#60;/validators&#62;</pre></div><p class="paragraph"/>This file is found automatically by the validation framework based on the class name (ValidatedAction), the action alias, which is used as the validation context (visitorValidation) and the standard suffix (-validation.xml) to form the filename <b class="bold">ValidatedAction-visitorValidation-validation.xml</b>.<p class="paragraph"/>This file defines two validators for the "bean" field, a required validator which makes sure the bean is not null, and a VisitorFieldValidator. The VisitorFieldValidator will apply the validators for the <b class="bold">ValidatedBean</b> using the same validation context as is used in validating <b class="bold">ValidatedAction</b>, <b class="bold">visitorValidation</b>. It therefore looks for the validation files <b class="bold">ValidatedBean-validation.xml</b> (the default validations for the ValidatedBean) and <b class="bold">ValidatedBean-visitorValidation-validation.xml</b> (the validations specific to this validation context) , in that order.<p class="paragraph"/>The <b class="bold">ValidatedBean-validation.xml</b> looks like this:<p class="paragraph"/><div class="code"><pre>&#60;!DOCTYPE validators PUBLIC <span class="xml&#45;quote">"&#45;//OpenSymphony Group//XWork Validator 1.0//EN"</class> <span class="xml&#45;quote">"http://www.opensymphony.com/xwork/xwork&#45;validator&#45;1.0.dtd"</class>&#62;
+&#60;validators&#62;
+    &#60;field name=<span class="xml&#45;quote">"text"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"requiredstring"</class>&#62;
+            &#60;message key=<span class="xml&#45;quote">"invalid.text"</class>&#62;Empty Text!&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+    &#60;field name=<span class="xml&#45;quote">"date"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"date"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"min"</class>&#62;01/01/1970&#60;/param&#62;
+            &#60;message key=<span class="xml&#45;quote">"invalid.date"</class>&#62;Invalid Date!&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+    &#60;field name=<span class="xml&#45;quote">"number"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"int"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"min"</class>&#62;1&#60;/param&#62;
+            &#60;param name=<span class="xml&#45;quote">"max"</class>&#62;10&#60;/param&#62;
+            &#60;message key=<span class="xml&#45;quote">"invalid.number"</class>&#62;Invalid Number!&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+&#60;/validators&#62;</pre></div><p class="paragraph"/>This file applies validations for three fields (text, date, and number) and gives message keys and default messages for each of them. These message keys will be used to look up messages from a resource bundle specific to the <b class="bold">ValidatedBean</b> class. In the same package as the <b class="bold">ValidatedBean</b> is a file named <b class="bold">ValidatedBean.properties</b>
+<div class="code"><pre>invalid.date=You must enter a date after $&#123;min&#125;.
+invalid.text=You must enter some text.
+invalid.number=You must enter a number between $&#123;min&#125; and $&#123;max&#125;.
+invalid.total=The total of number and number2 must be less than $&#123;@com.opensymphony.webwork.example.ValidatedBean@MAX_TOTAL&#125;.</pre></div><p class="paragraph"/>These messages will be used for any errors added for the <b class="bold">ValidatedBean</b> using a message key. As you can see from the body of the messages, they can be parameterized with properties from the Bean, the Interceptor, and the Action (and they will be searched in that order). There is also an example of using a Static field <b class="bold">${@com.opensymphony.webwork.example.ValidatedBean@MAX_TOTAL}</b>.<p class="paragraph"/>The <b class="bold">ValidatedBean-visitorValidation-validation.xml</b> file would define validations specific for the <b class="bold">visitorValidation</b> validation context, but it is not there, so it is ignored.
+<h3 class="heading-1"><a name="Expression"/><a href="validationexample.html#Expression" title="Permalink to Expression"><img src="http://wiki.opensymphony.com/images/permalink.png" alt="" border="0"/></a> Visitor Validation with the Expression Validator
+</h3><p class="paragraph"/>The final example shows a similar setup to the previous visitor validation example. The <b class="bold">xwork.xml</b> configuration for this example is very similar to the <b class="bold">visitorValidation</b> example:
+<div class="code"><pre>&#60;action name=<span class="xml&#45;quote">"expressionValidation"</class> class=<span class="xml&#45;quote">"com.opensymphony.webwork.example.ValidatedAction"</class>&#62;
+            &#60;interceptor&#45;ref name=<span class="xml&#45;quote">"validationWorkflowStack"</class>/&#62;
+            &#60;param name=<span class="xml&#45;quote">"validationAction"</class>&#62;expressionValidation.action&#60;/param&#62;
+            &#60;result name=<span class="xml&#45;quote">"success"</class>&#62;valid.vm&#60;/result&#62;
+            &#60;result name=<span class="xml&#45;quote">"input"</class>&#62;validationForm.vm&#60;/result&#62;
+            &#60;result name=<span class="xml&#45;quote">"error"</class>&#62;validationForm.vm&#60;/result&#62;
+        &#60;/action&#62;</pre></div><p class="paragraph"/>The <b class="bold">ValidatedAction-expressionValidation-validation.xml</b> file defines the validations specific to this validation context:
+<div class="code"><pre>&#60;!DOCTYPE validators PUBLIC <span class="xml&#45;quote">"&#45;//OpenSymphony Group//XWork Validator 1.0//EN"</class> <span class="xml&#45;quote">"http://www.opensymphony.com/xwork/xwork&#45;validator&#45;1.0.dtd"</class>&#62;
+&#60;validators&#62;
+    &#60;field name=<span class="xml&#45;quote">"bean"</class>&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"required"</class>&#62;
+            &#60;message&#62;The bean must not be null.&#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+        &#60;field&#45;validator type=<span class="xml&#45;quote">"visitor"</class>&#62;
+            &#60;param name=<span class="xml&#45;quote">"context"</class>&#62;expression&#60;/param&#62;
+            &#60;message&#62;bean: &#60;/message&#62;
+        &#60;/field&#45;validator&#62;
+    &#60;/field&#62;
+&#60;/validators&#62;</pre></div><p class="paragraph"/>This is almost identical to the <b class="bold">ValidatedAction-visitorValidation-validation.xml</b> file, but shows an example of passing a context param to the <b class="bold">VisitorFieldValidator</b>. In this case, rather than using the same validation context as is used for the <b class="bold">ValidatedAction</b> (<b class="bold">expressionValidation</b>), it passes another context (<b class="bold">expression</b>) to be used instead.<p class="paragraph"/>In this case, the validation context specific validations for the <b class="bold">ValidatedBean</b> is present, and it's named <b class="bold">ValidatedBean-expression-validation.xml</b>
+<div class="code"><pre>&#60;!DOCTYPE validators PUBLIC <span class="xml&#45;quote">"&#45;//OpenSymphony Group//XWork Validator 1.0//EN"</class> <span class="xml&#45;quote">"http://www.opensymphony.com/xwork/xwork&#45;validator&#45;1.0.dtd"</class>&#62;
+&#60;validators&#62;
+    &#60;validator type=<span class="xml&#45;quote">"expression"</class>&#62;
+        &#60;param name=<span class="xml&#45;quote">"expression"</class>&#62;@com.opensymphony.webwork.example.ValidatedBean@MAX_TOTAL &#62; (number + number2)&#60;/param&#62;
+        &#60;message key=<span class="xml&#45;quote">"invalid.total"</class>&#62;Invalid total!&#60;/message&#62;
+    &#60;/validator&#62;
+&#60;/validators&#62;</pre></div>
+This adds an object-level (as opposed to field-level) ExpressionValidator which checks the total of the number and number2 fields against a static constant, and adds an error message if the total is more than the constant. 
+<h3 class="heading-1"><a name="ErrorMessages"/><a href="validationexample.html#ErrorMessages" title="Permalink to ErrorMessages"><img src="http://wiki.opensymphony.com/images/permalink.png" alt="" border="0"/></a> A note about error messages with the VisitorFieldValidator
+</h3><p class="paragraph"/>With the VisitorFieldValidator, message field names are appended with the field name of the field in the Action. In this case, the fields "<b class="bold">text</b>", "<b class="bold">date</b>", and "<b class="bold">number</b>" in the <b class="bold">ValidatedBean</b> would be added as field error messages to the Action with field names "<b class="bold">bean.text</b>", "<b class="bold">bean.date</b>", and "<b class="bold">bean.number</b>". The error messages added for the object-level ExpressionValidator applied in the last example will be added as field-level errors to the Action with the name "<b class="bold">bean</b>".
+
+  </div>
+</body>
+</html>
Add a comment to this file

lib/core/ognl-2.6.4.jar

Binary file added.

Add a comment to this file

lib/core/oscore-2.2.3.jar

Binary file added.

xdocs/navigation.xml

+<project name="xwork" repository="xwork" href="http://wiki.opensymphony.com">
+
+  <title>XWork</title>
+
+  <body>
+    <links>
+      <item name="WebWork" href="../webwork"/>
+    </links>
+
+    <menu name="XWork">
+      <item name="Wiki"                  href="http://wiki.opensymphony.com/space/XWork"/>
+      <item name="Issue Tracker"         href="http://jira.opensymphony.com/secure/BrowseProject.jspa?id=10050"/>
+      <item name="Clover Reports"        href="/clover/"/>
+    </menu>
+
+    <!-- Google Search -->
+    <search/>
+  </body>
+
+</project>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.