http://git-wip-us.apache.org/repos/asf/struts-site/blob/7498a081/source/plugins/plugin-developers.md
----------------------------------------------------------------------
diff --git a/source/plugins/plugin-developers.md 
b/source/plugins/plugin-developers.md
new file mode 100644
index 0000000..2653fd7
--- /dev/null
+++ b/source/plugins/plugin-developers.md
@@ -0,0 +1,7514 @@
+---
+layout: default
+title: Plugins Developers Guide (WIP)
+---
+
+#Plugin Developers Guide# {#PAGE_44163}
+
+
+Apache Struts 2 provides a simple [plugin architecture](#PAGE_13868) so that 
developers can extend the framework just by adding a JAR to the application's 
classpath\. Since plugins are contained in a JAR, they are easy to share with 
others\. Several plugins are bundled with the framework, and others are 
available from third\-party sources\.
+
+| 
+
+| 
+
+| + [Plugins](#PAGE_13868)
+
+| 
+
+| + _Extending an Application with Custom Plugins_ 
+
+| 
+
+| 
+
+| 
+
+| __Bundled Plugins__
+
+| 
+
+| 
+
+| 
+
+| |\
+\
++ [Bean Validation Plugin](#PAGE_57904184) (2\.5\+)\
+\
++ [CDI (JSR 299) Plugin](#PAGE_27842284) (2\.3\.1\+)\
+\
++ [Codebehind Plugin](#PAGE_29637) (\< 2\.5)\
+\
++ [Config Browser Plugin](#PAGE_44185)\
+\
++ [Convention Plugin](#PAGE_105613) (2\.1\.3\+)\
+\
++ [DWR Plugin](#PAGE_82454)\
+\
++ [Embedded JSP Plugin](#PAGE_2852037) (2\.1\.7\+)\
+\
++ [JasperReports Plugin](#PAGE_14258)\
+\
++ [Java 8 Support Plugin](#PAGE_50857342) (2\.3\.21 \- 2\.5\.2)\
+\
++ [Javatemplates Plugin](#PAGE_105841) (2\.1\.3\+)\
+\
++ [JFreeChart Plugin](#PAGE_14300)\
+\
++ [JSF Plugin](#PAGE_44198)( \< 2\.5)\
+\
++ [JSON Plugin](#PAGE_2850922)  (2\.1\.7\+)\
+\
++ [JUnit Plugin](#PAGE_82304)\
+|\
+\
++ [OVal Plugin](#PAGE_114997) (2\.1\.7\+)\
+\
++ [OSGi Plugin](#PAGE_114995) (2\.1\.7\+)\
+\
++ [Plexus Plugin](#PAGE_44204)\
+\
++ [Portlet Plugin](#PAGE_74033)\
+\
++ [Portlet Tiles Plugin](#PAGE_30150178) (2\.3\.5\+)\
+\
++ [REST Plugin](#PAGE_70699) (2\.1\.1\+)\
+\
++ Deprecated: [SiteGraph Plugin](#PAGE_14137)\
+\
++ [SiteMesh Plugin](#PAGE_14142)\
+\
++ [Spring Plugin](#PAGE_14281)\
+\
++ [Struts 1 Plugin](#PAGE_44227)( \< 2\.5)\
+\
++ [TestNG Plugin](#PAGE_82452)\
+\
++ [Tiles Plugin](#PAGE_27401)\
+\
++ [Tiles 3 Plugin](#PAGE_30750969)  (\< 2\.5)\
+|
+|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+
+
+| 
+
+| 
+
+|  (ok)  For a complete list of bundled and third\-party plugins, visit the 
[Plugin 
Registry\.](http://cwiki\.apache\.org/S2PLUGINS/home\.html)^[http://cwiki\.apache\.org/S2PLUGINS/home\.html]\.
+
+| 
+
+###Next:###
+
+##Bean Validation Plugin## {#PAGE_57904184}
+
+###Bean Validation###
+
+The Bean Validation plugin implements a bridge to use Bean Validation in 
struts actions\. Bean Validation has been specified in JSR 303 and is part of 
the JavaEE platform\. Full\-fledged application servers already bring 
validation providers which can be leveraged by this plugin\. The plugin 
integrates with other struts features like:
+
++ i18n
+
++ model driven
+
++ AJAX Validation
+
++ workflow
+
+###Setup###
+
+In order to use the Bean Validation plugin, you first need to add the JAR file 
to the 
+
+~~~~~~~
+WEB-INF/lib
+~~~~~~~
+ directory of your application or include the dependency in your project's 
Maven POM file\.
+
+**pom\.xml**
+
+
+~~~~~~~
+<dependency>
+    <groupId>org.apache.struts</groupId>
+    <artifactId>struts2-bean-validation-plugin</artifactId>
+    <version>X.X.X</version>
+</dependency>
+
+~~~~~~~
+
+Where X\.X\.X is the current version of Struts 2\. Please remember that the 
Bean Validation Plugin is available from version 2\.5\.
+
+###Configuration###
+
+This sample shows the configuration constants the plugin provides\. It also 
shows how to enable bean\-validation by extending your own application package 
from 
+
+~~~~~~~
+struts-bean-validation
+~~~~~~~
+ which comes along with the plugin\.
+
+**struts\.xml**
+
+
+~~~~~~~
+    <constant name="struts.beanValidation.providerClass" 
value="org.hibernate.validator.HibernateValidator"/>
+    <constant name="struts.beanValidation.ignoreXMLConfiguration" 
value="false"/>
+    <constant name="struts.beanValidation.convertMessageToUtf" value="false"/>
+    <constant name="struts.beanValidation.convertMessageFromEncoding" 
value="ISO-8859-1"/>
+ 
+       <package name="my-bean-validation" extends="struts-bean-validation">
+       </package>
+~~~~~~~
+
+Here is another example that shows how you can combine bean\-validation with 
other plugins by configuring your own Interceptor\-Stack (note: this is just a 
very short example\. In a real app you should take more care about your 
stack)\. You can combine bean validation with classic struts validation (or 
disable either) by putting the according interceptors in your stack (or by 
removing them from your stack)\.
+
+**struts\.xml**
+
+
+~~~~~~~
+       <package name="my-app-package" extends="struts-default">
+               <interceptors>
+                       <interceptor
+                                name="beanValidation"
+                                
class="org.apache.struts.beanvalidation.validation.interceptor.BeanValidationInterceptor"/>
+
+                       <interceptor-stack name="appDefaultStack">
+                               <interceptor-ref name="beanValidation"/>
+                               <interceptor-ref name="defaultStack"/>
+                       </interceptor-stack>
+               </interceptors>
+       </package>
+~~~~~~~
+
+ 
+
+###Bean Validation Example###
+
+Here is an example Action that makes use of bean validation\. Note that some 
of the validation annotations are taken from 
+
+~~~~~~~
+javax
+~~~~~~~
+ package (which is defined in the JSR) while others are taken from the 
validaton provider (in this case: 
+
+~~~~~~~
+hibernate
+~~~~~~~
+)\. You can specifiy own text keys in the 
+
+~~~~~~~
+message
+~~~~~~~
+ attribute of the annotations\. If you do that the whole struts i18n mechanism 
kicks in to resolve those text keys\.
+
+**com\.example\.actions\.BeanValidationAction**
+
+
+~~~~~~~
+package com.example.actions;
+
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts.beanvalidation.constraints.FieldMatch;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Namespace;
+import org.apache.struts2.convention.annotation.ParentPackage;
+import org.apache.struts2.convention.annotation.Result;
+import org.apache.struts2.interceptor.validation.SkipValidation;
+import org.hibernate.validator.constraints.Email;
+import org.hibernate.validator.constraints.NotBlank;
+import org.hibernate.validator.constraints.ScriptAssert;
+import org.hibernate.validator.constraints.URL;
+import javax.validation.constraints.*;
+import java.util.Date;
+
+
+@Namespace("/bean-validation")
+@ParentPackage("my-bean-validation")
+@Action(results = {
+        @Result(name = "input", location = "bean-validation.jsp"),
+        @Result(name = "success", location = 
"/WEB-INF/validation/successFieldValidatorsExample.jsp")
+})
+@FieldMatch(first = "fieldExpressionValidatorField", second = 
"requiredValidatorField", message = "requiredValidatorField and 
fieldExpressionValidatorField are not matching")
+@ScriptAssert(lang = "javascript", script = "_this.dateValidatorField != null 
&& _this.dateValidatorField.before(new java.util.Date())", message = "Date need 
to before now")
+public class BeanValidationExampleAction extends ActionSupport {
+    @NotNull
+    private String requiredValidatorField = null;
+
+    @NotBlank
+    private String requiredStringValidatorField = null;
+
+    @NotNull(message="your.text.key.here")
+    @Min(1)
+    @Max(10)
+    private Integer integerValidatorField = null;
+
+    @NotNull
+    private Date dateValidatorField = null;
+
+    @NotNull
+    @Size(min = 4, max = 64)
+    @Email
+
+    private String emailValidatorField = null;
+
+    @NotNull
+    @Size(min = 4, max = 64)
+    @URL
+    private String urlValidatorField = null;
+
+    @NotNull
+    @Size(min = 2, max = 4)
+    private String stringLengthValidatorField = null;
+
+    @Pattern(regexp = "[^<>]+")
+    private String regexValidatorField = null;
+
+    private String fieldExpressionValidatorField = null;
+
+
+ public Date getDateValidatorField() {
+
+        return dateValidatorField;
+    }
+    public void setDateValidatorField(Date dateValidatorField) {
+        this.dateValidatorField = dateValidatorField;
+    }
+    public String getEmailValidatorField() {
+        return emailValidatorField;
+    }
+    public void setEmailValidatorField(String emailValidatorField) {
+        this.emailValidatorField = emailValidatorField;
+    }
+    public Integer getIntegerValidatorField() {
+        return integerValidatorField;
+    }
+    public void setIntegerValidatorField(Integer integerValidatorField) {
+        this.integerValidatorField = integerValidatorField;
+    }
+    public String getRegexValidatorField() {
+        return regexValidatorField;
+    }
+    public void setRegexValidatorField(String regexValidatorField) {
+        this.regexValidatorField = regexValidatorField;
+    }
+    public String getRequiredStringValidatorField() {
+        return requiredStringValidatorField;
+    }
+    public void setRequiredStringValidatorField(String 
requiredStringValidatorField) {
+        this.requiredStringValidatorField = requiredStringValidatorField;
+    }
+    public String getRequiredValidatorField() {
+        return requiredValidatorField;
+    }
+    public void setRequiredValidatorField(String requiredValidatorField) {
+        this.requiredValidatorField = requiredValidatorField;
+    }
+    public String getStringLengthValidatorField() {
+        return stringLengthValidatorField;
+    }
+    public void setStringLengthValidatorField(String 
stringLengthValidatorField) {
+        this.stringLengthValidatorField = stringLengthValidatorField;
+    }
+    public String getFieldExpressionValidatorField() {
+        return fieldExpressionValidatorField;
+    }
+    public void setFieldExpressionValidatorField(
+            String fieldExpressionValidatorField) {
+        this.fieldExpressionValidatorField = fieldExpressionValidatorField;
+    }
+    public String getUrlValidatorField() {
+        return urlValidatorField;
+    }
+    public void setUrlValidatorField(String urlValidatorField) {
+        this.urlValidatorField = urlValidatorField;
+    }
+}
+~~~~~~~
+
+##CDI Plugin## {#PAGE_27842284}
+
+###Overview###
+
+CDI \- short for Contexts and Dependency Injection \- is the new standard for 
Java EE (though not limited to it) dependency injection frameworks\. It was 
introduced as [JSR 
299](http://jcp\.org/en/jsr/summary?id=299)^[http://jcp\.org/en/jsr/summary?id=299],
 being a part of the [Java EE 
6](http://jcp\.org/en/jsr/detail?id=316)^[http://jcp\.org/en/jsr/detail?id=316] 
umbrella specification\. It is also important to note that it builds on top of 
JSR 330 (Dependency Injection for Java SE), often referenced as 
[@Inject](http://jcp\.org/en/jsr/summary?id=330)^[http://jcp\.org/en/jsr/summary?id=330]\.
+
+It can be used as standalone solution packed with your web applications to run 
in lightweight servlet containers such as Apache Tomcat or Jetty, utilizing 
standalone CDI implementations such as [JBoss 
Weld](http://seamframework\.org/Weld)^[http://seamframework\.org/Weld] (the JSR 
299 reference implementation) or [Apache 
OpenWebBeans](http://openwebbeans\.apache\.org/)^[http://openwebbeans\.apache\.org/]\.
 On the other hand, each JEE 6 compliant application server such as 
[Glassfish](http://glassfish\.java\.net/)^[http://glassfish\.java\.net/], 
[JBoss AS](http://www\.jboss\.org/jbossas)^[http://www\.jboss\.org/jbossas] or 
[Apache 
TomEE](http://openejb\.apache\.org/apache\-tomee\.html)^[http://openejb\.apache\.org/apache\-tomee\.html]
 is required to have a CDI container on board, making it easy for developers to 
pack lightweight web or enterprise archives while being able to use a 
compelling dependency injection feature set\.
+
+With the Struts 2 CDI plugin, your application is open to be embedded into 
this modern, comprehensive and type safe framework and take full use of it\.
+
+###Setup###
+
+As with all Struts 2 plugins, usage of the CDI plugin is as easy as delivering 
the right jars with your web application\. The plugin then registers itself as 
the standard ObjectFactory for your Struts 2 application\.
+
+**(i) Don't mess up Object Factory Providers**
+
+
+> 
+
+> 
+
+> Struts 2 delivers integration into all relevant dependency injection 
containers via plugins, such as the [Spring Plugin](#PAGE_14281) or the 
externally provided [Guice Struts 2 
Plugin](http://code\.google\.com/p/google\-guice/wiki/Struts2Integration)^[http://code\.google\.com/p/google\-guice/wiki/Struts2Integration]\.
 Be aware that the central feature of all those, as well as the CDI plugin, is 
to register itself as Struts 2 Object factory\. Usually you will want to use 
**exactly one of those plugins** in your application, since there will only be 
**one ObjectFactory** implementation for Struts 2 to chose\. If you pack more 
than one of those plugins, the factory to be chosen will be undetermined\. One 
will win in the end, but who knows which \.\.\.
+
+> 
+
+####Maven Setup####
+
+The most easy and recommended way use is to simply add a maven dependency for 
it, along with a dependency to the CDI API for development time usage:
+
+**pom\.xml**
+
+
+~~~~~~~
+
+<dependencies>
+    ...
+    <dependency>
+        <groupId>org.apache.struts</groupId>
+        <artifactId>struts2-cdi-plugin</artifactId>
+        <version>${struts2.version}</version>
+    </dependency>
+    <dependency>
+        <groupId>javax.enterprise</groupId>
+        <artifactId>cdi-api</artifactId>
+        <version>1.0-SP1</version>
+        <scope>provided</scope>
+    </dependency>
+    ...
+</dependencies>
+
+~~~~~~~
+
+whereas 
+
+
+~~~~~~~
+${struts2.version}
+~~~~~~~
+
+ should be set either as a property in your pom (recommended) or substituted 
by a concrete version information, such as 2\.3\.2 by the time of writing of 
this document\. If you want to use CDI without an application server providing 
it, you may also want to add a dependency to a CDI implementation of your 
choice, for example Weld:
+
+**pom\.xml with CDI implementation**
+
+
+~~~~~~~
+
+<dependencies>
+    ...
+    <dependency>
+        <groupId>org.apache.struts</groupId>
+        <artifactId>struts2-cdi-plugin</artifactId>
+        <version>${struts2.version}</version>
+    </dependency>
+    <dependency>
+        <groupId>javax.enterprise</groupId>
+        <artifactId>cdi-api</artifactId>
+        <version>1.0-SP1</version>
+        <scope>provided</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.jboss.weld</groupId>
+        <artifactId>weld-core</artifactId>
+        <version>1.0.1-Final</version>
+    </dependency>
+    <dependency>
+        <groupId>org.jboss.weld</groupId>
+        <artifactId>weld-se</artifactId>
+        <version>1.0.1-Final</version>
+    </dependency>
+    ...
+</dependencies>
+
+~~~~~~~
+
+####Manual Integration####
+
+Ensure that the struts2\-cdi\-plugin jar matching your used Struts 2 framework 
version \- it is part of the [Struts 2 
distribution](http://struts\.apache\.org/download\.cgi)^[http://struts\.apache\.org/download\.cgi]
 \- is packed within the application archive that will be delivered\. If a CDI 
implementation is provided within your container, no other dependencies are 
needed\. If the latter is not the case, you may want to install a CDI container 
into your container (as commmon installation or packed with your app) according 
to the installation instructions of the CDI provider of choice\.
+
+For IDE integration, be sure to add both the 
struts2\-cdi\-plugin\-VERSION\.jar as well as the cdi\-api\.jar to your project 
setup\. Remember, the API jar should not be delivered with your application 
archive since you will have the API provided by the CDI container your 
application will be running with\.
+
+####Configuration####
+
+Not much to see here\. The CDI specification requires the CDI container to be 
exposed via JNDI context, and the CDI plugin will pick it up just there\. 
Nevertheless, since there are different JNDI namespaces in use, the plugin will 
try to automatically find the right one among known references, that is
+
++ java:comp/BeanManager as the CDI docs point out
+
++ java:app/BeanManager as the Weld docs point out
+
++ java:comp/env/BeanManager for containers limited to that namespace, such as 
tomcat
+
+If your container of choice uses other naming references, the plugin has a 
single configuration option to point to the right name\. Just add a constant 
like this to your struts\.xml to be on the happy path again:
+
+**struts\.xml**
+
+
+~~~~~~~
+
+    <constant name="struts.objectFactory.cdi.jndiKey" 
value="java:comp/some/weird/BeanManagerReference" />
+
+~~~~~~~
+
+###Usage###
+
+CDI has an extremely rich feature set, and this section is not intended as a 
replacement for the CDI reference documentation or the excellent documentation 
found on the [JBoss 
Weld](http://seamframework\.org/Weld)^[http://seamframework\.org/Weld] 
homepage\. The whole Struts 2 CDI integration works just as you would think it 
works, using JSR\-299 and JSR\-330 Annotations in your Struts 2 actions or 
interceptors\. Be aware of the following, though:
+
+
+
+| CDI is designed to act in a type safe and modern way, thus using annotations 
for all aspects of the framework\. Nevertheless, you are allowed to eternalize 
configuration into a XML file called beans\.xml to be placed in your WEB\-INF 
directory\. Even if you don't intend to use such external configuration, it is 
an **inevitable requirement to provide at least an empty beans\.xml in WEB\-INF 
\!**
+
+| 
+
+####Example Usage####
+
+Implement your Struts 2 actions or interceptors just as usual, enriched with 
CDI and @Inject annotations:
+
+**NumberGuess\.java**
+
+
+~~~~~~~
+
+package org.apache.struts2.example.cdi;
+
+import com.opensymphony.xwork2.ActionSupport;
+import javax.inject.Inject;
+
+public class NumberGuess extends ActionSupport {
+
+    @Inject
+    Game game;
+
+    public Game getGame() {
+        return game;
+    }
+
+    @Override
+    public String execute() throws Exception {
+        return SUCCESS;
+    }
+
+    public String guess() throws Exception {
+        final String errorMessage = game.check();
+        addActionError(errorMessage);
+
+        if (Game.CORRECT.equals(errorMessage)) {
+            game.reset();
+        } else if (game.getRemainingGuesses() == 0) {
+            addActionError("The correct guess was " + game.getGuess() + ". 
Game is reset.");
+            game.reset();
+        }
+
+
+        return SUCCESS;
+    }
+
+
+}
+
+~~~~~~~
+
+See the @Inject annotation from javax\.inject\.Inject? While you could use all 
the other nice stuff, we usually would \- following the separation of concerns 
principle \- use @Inject most of the time only in our actions, keeping the more 
fancy stuff in the business layer as shown below\. Using @Inject brings us to 
the most common pitfall when using Struts 2 together with JSR\-330 / CDI:
+
+**(i) Use the right @Inject**
+
+
+> 
+
+> 
+
+> Struts 2 and it's core component XWork use it's own internal dependency 
injection container\. Interestingly, you could name it JSR\-330's grandma, 
since it is an early pre\-release version of [Google 
Guice](http://code\.google\.com/p/google\-guice/)^[http://code\.google\.com/p/google\-guice/]
 once developed by [Crazybob 
Lee](http://blog\.crazybob\.org/)^[http://blog\.crazybob\.org/] \- the same Bob 
Lee that, together with SpringSource's Rod Johnson, lead the JSR\-330 
specification\.
+
+> 
+
+> 
+
+> That said, you will find the @Inject annotation both as 
com\.opensymphony\.xwork2\.inject\.Inject and javax\.inject\.Inject\. **Don't 
mix up those two \- javax\.inject\.Inject is the one you want to use with your 
Struts 2 CDI plugin and CDI integration in general\!** While you could use 
Struts' internal annotation as well, the effect may be strange to undefined \- 
so check your imports\!
+
+> 
+
+Now that you are aware of that, here is the rest of the inevitable NumberGuess 
CDI example in Struts 2 flavour\. Add a JSP view similar to this:
+
+
+~~~~~~~
+
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+<html>
+<head>
+    <title>Numberguess</title>
+</head>
+
+<body>
+<h2>Numberguess Game - Struts 2 CDI Example</h2>
+
+<h3>I've picked a number between <s:property value="game.smallest"/> and 
<s:property value="game.biggest"/>.
+    You have <s:property value="game.remainingGuesses"/>remaining guesses.</h3>
+
+<s:form action="guess">
+    <s:textfield name="game.guess" label="Your Guess"/>
+    <s:submit/>
+</s:form>
+<p/>
+<s:actionerror/>
+
+</body>
+</html>
+
+~~~~~~~
+
+along \- if not using the fabulous and recommended Struts 2 [Convention 
Plugin](#PAGE_105613) \- with a struts\.xml like this
+
+
+~~~~~~~
+
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE struts PUBLIC
+          "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"    
   
+          "http://struts.apache.org/dtds/struts-2.3.dtd";>
+<struts>
+  <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
+  <constant name="struts.devMode" value="true"/>
+  
+    <package name="numberguess" extends="struts-default">
+
+        <action name="NumberGuess" 
class="org.apache.struts2.example.cdi.NumberGuess">
+            <result>/WEB-INF/pages/NumberGuess.jsp</result>
+        </action>
+
+        <action name="guess" 
class="org.apache.struts2.example.cdi.NumberGuess" method="guess">
+            <result>/WEB-INF/pages/NumberGuess.jsp</result>
+        </action>
+
+    </package>
+
+</struts>
+
+~~~~~~~
+
+Now you can add the business logic we want to be managed and injected by CDI\. 
Start with two qualifier annotations:
+
+
+~~~~~~~
+
+package org.apache.struts2.example.cdi;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+@Target( { TYPE, METHOD, PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+@Qualifier
+public @interface Random {}
+
+~~~~~~~
+
+
+~~~~~~~
+
+package org.apache.struts2.example.cdi;
+
+import javax.inject.Qualifier;
+import java.lang.annotation.Documented;
+import static java.lang.annotation.ElementType.*;
+import java.lang.annotation.Retention;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import java.lang.annotation.Target;
+
+@Target( { TYPE, METHOD, PARAMETER, FIELD })
+@Retention(RUNTIME)
+@Documented
+@Qualifier
+public @interface MaxNumber {}
+
+~~~~~~~
+
+Now on to the actual business beans, the Game and the Generator bean:
+
+
+~~~~~~~
+
+package org.apache.struts2.example.cdi;
+
+import javax.annotation.PostConstruct;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.inject.Instance;
+import javax.inject.Inject;
+import javax.inject.Named;
+import java.io.Serializable;
+
+@Named
+@SessionScoped
+public class Game implements Serializable {
+
+    public static final String CORRECT = "Correct !!!";
+    public static final String WRONG = "Sorry, wrong number !!!";
+
+    private int number;
+    private int guess;
+    private int smallest;
+
+    @MaxNumber
+    @Inject
+    private int maxNumber;
+
+    private int biggest;
+    private int remainingGuesses;
+
+    @Random
+    @Inject
+    Instance<Integer> randomNumber;
+
+    public Game() {
+    }
+
+    public int getNumber() {
+        return number;
+    }
+
+    public int getGuess() {
+        return guess;
+    }
+
+    public void setGuess( int guess ) {
+        this.guess = guess;
+    }
+
+    public int getSmallest() {
+        return smallest;
+    }
+
+    public int getBiggest() {
+        return biggest;
+    }
+
+    public int getRemainingGuesses() {
+        return remainingGuesses;
+    }
+
+    public String check() throws InterruptedException {
+        if (guess > number) {
+            biggest = guess - 1;
+        }
+        if (guess < number) {
+            smallest = guess + 1;
+        }
+        if (guess == number) {
+            return CORRECT;
+        }
+        remainingGuesses--;
+        return WRONG;
+    }
+
+    @PostConstruct
+    public void reset() {
+        this.smallest = 0;
+        this.guess = 0;
+        this.remainingGuesses = 10;
+        this.biggest = maxNumber;
+        this.number = randomNumber.get();
+    }
+
+}
+
+~~~~~~~
+
+
+~~~~~~~
+
+package org.apache.struts2.example.cdi;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import java.io.Serializable;
+
+@ApplicationScoped
+public class Generator implements Serializable {
+   
+   private java.util.Random random = new java.util.Random( 
System.currentTimeMillis() );
+   
+   private int maxNumber = 100;
+   
+   java.util.Random getRandom() {
+      return random;
+   }
+   
+   @Produces @Random int next() { 
+      return getRandom().nextInt(maxNumber); 
+   }
+   
+   @Produces @MaxNumber int getMaxNumber() {
+      return maxNumber;
+   }
+
+} 
+
+~~~~~~~
+
+If you understand that code at a glance, you are either already an CDI expert 
or profit from the readable, natural language oriented way the CDI stack 
works\. If neither of this is the case, now it's time to check the CDI and Weld 
documentation\. Remember, this is a trivial example \- there is much more to 
know about CDI\.
+
+Ready you are now \- use the Force\!
+
+##Codebehind Plugin## {#PAGE_29637}
+
+**(\!) Deprecated Plugin**
+
+
+> 
+
+> 
+
+> Since 2\.1 this plugin has been deprecated in favor of the [Convention 
Plugin](#PAGE_105613)\. See [this page](#PAGE_106500) for details on how to 
port your application to the Convention plugin\.
+
+> 
+
+The Codebehind Plugin 
+
+reduces mundane configuration by adding "Page Controller" conventions
+
+
+There are two common situations where the plugin applies convention over 
configuration:
+
+1. **Default mappings** - (or "pages with no mappings") These are cases where 
the page is mostly static and doesn't require an Action class to execute logic. 
 Common examples are index pages and those that heavily use JSP tags or JSF 
components.
+
+2. **Default results** - The purpose of most Actions is to execute code to 
prepare the data for a specific page. The name of this page is often the same 
as the Action itself.
+
+To improve the first case, the plugin will detect the presence of a page with 
no corresponding Struts mapping and automatically substitute a mapping that 
uses the default Action class for the package, which is usually ActionSupport, 
a NO\-OP Action\.  
+
+For the problem of default results, the plugin will make it unnecessary to 
define those results by detecting the presence of a page for that Action and 
creating the appropriate configuration on\-the\-fly\. 
+
+In these two ways, the plugin encourages a page\-based development style, 
handling the linking of Struts actions with pages and pages with Results in a 
common way\.
+
+ (ok)  To see the plugin in action, review the "Person Manager" example in the 
Showcase application\.
+
+####Features####
+
++ Provides default mappings for pages that don't have Actions
+
++ Provides default results by auto\-discovering pages
+
+####Usage####
+
+To use this plugin, simply copy its jar into your application\.  The plugin 
can be used to find default mappings and results\.
+
+#####Default Mappings#####
+
+To better facilitate a code\-behind development approach, the plugin will 
detect the case where the request has no defined Struts action mapping, yet 
there exists a corresponding page\.  It will then create a dummy action mapping 
referencing the default Action class (usually ActionSupport), allowing the page 
to be displayed normally\.  Additionally, the default interceptor stack for the 
configured package will be applied, bringing the workflow benefits of 
interceptor stacks to simple pages\.
+
+When no explicitly configured Action can be found for a request, the plugin 
searches the web application for a likely page\. Specifically, the following 
pattern is used to locate a page:
+
+
+
+~~~~~~~
+/NAMESPACE/ACTION.(jsp|vm|ftl)
+~~~~~~~
+
+For example, if the request is for 
+
+~~~~~~~
+http://www.company.com/myapp/member/login.action
+~~~~~~~
+, the plugin will look for the following pages, in this order: 
+
+1. 
+
+~~~~~~~
+/member/login.jsp
+~~~~~~~
+
+2. 
+
+~~~~~~~
+/member/login.vm
+~~~~~~~
+
+3. 
+
+~~~~~~~
+/member/login.ftl
+~~~~~~~
+
+If any of those pages are found, the plugin will construct an ActionConfig 
object on the fly, using the ActionSupport class for the Action and a single 
Result that points to the discovered page\.  The ActionConfig will be put in 
the configured package, meaning that it will inherit the default Interceptor 
stack for that package\.  The default package is 
+
+~~~~~~~
+codebehind-default
+~~~~~~~
+, however, it can be configured in any _configuration file_  via the 
+
+~~~~~~~
+struts.codebehind.defaultPackage
+~~~~~~~
+ constant\.
+
+#####Default Results#####
+
+In many applications, a majority of Results could have the same root name as 
the action mapping\.  To reduce this unnecessary configuration, the Struts 
plugin will try to guess the appropriate Result, if none is explicitly 
configured\.  This technique works for any result code, including 
+
+~~~~~~~
+success
+~~~~~~~
+\. When combined with the _Zero Configuration_  style, the amount of 
configuration in an application dwindles to next to nothing\.
+
+When no explicitly configured Result is found for an Action's result code, the 
plugin, again, searches the web application for a matching page\. Specifically, 
the following patterns, in the following order, are used to locate a page:
+
+1. 
+
+~~~~~~~
+/NAMESPACE/ACTION-RESULT_CODE.(jsp|vm|ftl)
+~~~~~~~
+
+2. 
+
+~~~~~~~
+/NAMESPACE/ACTION.(jsp|vm|ftl)
+~~~~~~~
+
+These two patterns are searched for each of the three default page extensions: 
jsp, vm, and ftl\.  For example, if the request is for 
+
+~~~~~~~
+http://www.company.com/myapp/member/login.action
+~~~~~~~
+, so that the action name is 
+
+~~~~~~~
+login
+~~~~~~~
+ and the namespace is 
+
+~~~~~~~
+member
+~~~~~~~
+, and the Action class returned a code of 
+
+~~~~~~~
+success
+~~~~~~~
+, the plugin will look for the following pages, in this order: 
+
+1. 
+
+~~~~~~~
+/member/login-success.jsp
+~~~~~~~
+
+2. 
+
+~~~~~~~
+/member/login.jsp
+~~~~~~~
+
+3. 
+
+~~~~~~~
+/member/login-success.vm
+~~~~~~~
+
+4. 
+
+~~~~~~~
+/member/login.vm
+~~~~~~~
+
+5. 
+
+~~~~~~~
+/member/login-success.ftl
+~~~~~~~
+
+6. 
+
+~~~~~~~
+/member/login.ftl
+~~~~~~~
+
+If any of those pages are found, the appropriate Result will be constructed 
and processed\.
+
+#####Settings#####
+
+The following settings can be customized\.  See the [developer 
guide](http://cwiki\.apache\.org/confluence/display/WW/Configuration\+Files)^[http://cwiki\.apache\.org/confluence/display/WW/Configuration\+Files]\.
+
+|Setting|Description|Default|Possible Values|
+|-------|-----------|-------|---------------|
+|struts\.codebehind\.defaultPackage|The default package to use for created 
Action mappings|codebehind\-default|Any existing package name|
+|struts\.configuration\.classpath\.disableActionScanning|Whether to disable 
scanning the classpath for Action classes or not|false|true or false|
+
+#####Installation#####
+
+This plugin can be installed by copying the plugin jar into your application's 
+
+~~~~~~~
+/WEB-INF/lib
+~~~~~~~
+ directory\.  No other files need to be copied or created\.
+
+##Config Browser Plugin## {#PAGE_44185}
+
+The Config Browser Plugin is 
+
+a simple tool to help view an application's configuration at runtime
+
+
+This plugin should be used only during development phase and access to it 
should be strictly restricted\!
+
+> 
+
+####Features####
+
++ Browsable view of loaded configuration
+
++ Shows all accessible action URLs
+
+####Usage####
+
+To use the plugin, simply copy the jar into your application\.  Once 
installed, you can access the tool by opening to the action named _index_  in 
the _config\-browser_  namespace\.
+
+(information) In most cases (if you are using the default _ActionMapper_ ), 
the URL is something like 
[http://localhost:8080/starter/config\-browser/index\.action](http://localhost:8080/starter/config\-browser/index\.action)
 or 
[http://localhost:8080/starter/config\-browser/index](http://localhost:8080/starter/config\-browser/index)\.
+
+#####Example#####
+
+![config\-browser\-example\.png](/Users/lukaszlenart/Projects/Apache/struts\-site/target/md/attachments/att30966155\_config\-browser\-example\.png)
+
+#####Settings#####
+
+This plugin provides no customizable settings\.
+
+#####Installation#####
+
+This plugin can be installed by copying the plugin jar into your application's 
+
+~~~~~~~
+/WEB-INF/lib
+~~~~~~~
+ directory\.  No other files need to be copied or created\.
+
+##Convention Plugin## {#PAGE_105613}
+
+This page is DEPRECATED, please refer to the new source 
[http://struts\.apache\.org/plugins/convention/](http://struts\.apache\.org/plugins/convention/)
+
+> 
+
+
+###Introduction###
+
+The Convention Plugin is bundled with Struts since 2\.1 and replaces the 
[Codebehind Plugin](#PAGE_29637) and Zero Config plugins\. It provides the 
following features:
+
++ Action location by package naming conventions
+
++ Result (JSP, FreeMarker, etc) location by naming conventions
+
++ Class name to URL naming convention
+
++ Package name to namespace convention
+
++ SEO compliant URLs (i\.e\. my\-action rather than MyAction)
+
++ Action name overrides using annotations
+
++ Interceptor overrides using annotations
+
++ Namespace overrides using annotations
+
++ XWork package overrides using annotations
+
++ Default action and result handling (i\.e\. /products will try 
com\.example\.actions\.Products as well as 
com\.example\.actions\.products\.Index)
+
+The Convention Plugin should require no configuration to use\. Many of the 
conventions can be controlled using configuration properties and many of the 
classes can be extended or overridden\.
+
+###Setup###
+
+In order to use the Convention plugin, you first need to add the JAR file to 
the 
+
+~~~~~~~
+WEB-INF/lib
+~~~~~~~
+ directory of your application or include the dependency in your project's 
Maven POM file\.
+
+
+~~~~~~~
+<dependency>
+    <groupId>org.apache.struts</groupId>
+    <artifactId>struts2-convention-plugin</artifactId>
+    <version>X.X.X</version>
+</dependency>
+
+~~~~~~~
+
+Where X\.X\.X is the current version of Struts 2\. Please remember that the 
Convention Plugin is available from version 2\.1\.6\.
+
+###Converting a Codebehind based application to Convention###
+
+See [this page](#PAGE_106500) for the required changes and tips\.
+
+If you are using REST with the Convention plugin, make sure you set these 
constants in struts\.xml:
+
+
+~~~~~~~
+<constant name="struts.convention.action.suffix" value="Controller"/>
+<constant name="struts.convention.action.mapAllMatches" value="true"/>
+<constant name="struts.convention.default.parent.package" 
value="rest-default"/>
+
+~~~~~~~
+
+###Hello world###
+
+Now that the Convention plugin has been added to your application, let's start 
with a very simple example\. This example will use an actionless result that is 
identified by the URL\. By default, the Convention plugin assumes that all of 
the results are stored in **WEB\-INF/content**\. This can be changed by setting 
the property 
+
+~~~~~~~
+struts.convention.result.path
+~~~~~~~
+ in the Struts properties file to the new location\. Don't worry about 
trailing slashes, the Convention plugin handles this for you\. Here is our 
hello world JSP:
+
+
+~~~~~~~
+<html>
+<body>
+Hello world!
+</body>
+</html>
+
+~~~~~~~
+
+If you start Tomcat (or whichever J2EE container you are using) and type in 
[http://localhost:8080/hello\-world](http://localhost:8080/hello\-world) 
(assuming that your context path is "
+
+~~~~~~~
+/
+~~~~~~~
+", ie\. starting application from Eclipse) into your browser you should get 
this result:
+
+**WEB\-INF/content/hello\-world\.jsp**
+
+
+~~~~~~~
+Hello world!
+
+~~~~~~~
+
+This illustrates that the Convention plugin will find results even when no 
action exists and it is all based on the URL passed to Struts\.
+
+###Code behind hello world###
+
+Let's expand on this example and add a code behind class\. In order to do this 
we need to ensure that the Convention plugin is able to find our action 
classes\. By default, the Convention plugin will find all action classes that 
implement 
+
+~~~~~~~
+com.opensymphony.xwork2.Action
+~~~~~~~
+ or whose name ends with the word **Action** in specific packages\.
+
+These packages are located by the Convention plugin using a search 
methodology\. First the Convention plugin finds packages named 
+
+~~~~~~~
+struts
+~~~~~~~
+, 
+
+~~~~~~~
+struts2
+~~~~~~~
+, 
+
+~~~~~~~
+action
+~~~~~~~
+ or 
+
+~~~~~~~
+actions
+~~~~~~~
+\. Any packages that match those names are considered the root packages for 
the Convention plugin\. Next, the plugin looks at all of the classes in those 
packages as well as sub\-packages and determines if the classes implement 
+
+~~~~~~~
+com.opensymphony.xwork2.Action
+~~~~~~~
+ or if their name ends with **Action** (i\.e\. FooAction)\. Here's an example 
of a few classes that the Convention plugin will find:
+
+**Classes**
+
+
+~~~~~~~
+com.example.actions.MainAction
+com.example.actions.products.Display (implements 
com.opensymphony.xwork2.Action)
+com.example.struts.company.details.ShowCompanyDetailsAction
+
+~~~~~~~
+
+Each of the action classes that the plugin finds will be configured to respond 
to specific URLs\. The URL is based on the package name that the class is 
defined in and the class name itself\. First the plugin determines the 
namespace of the URL using the package names between the root package and the 
package the class is defined in\. For our examples above, the namespaces would 
be:
+
+**Namespaces**
+
+
+~~~~~~~
+com.example.actions.MainAction -> /
+com.example.actions.products.Display -> /products
+com.example.struts.company.details.ShowCompanyDetailsAction -> /company/details
+
+~~~~~~~
+
+Next, the plugin determines the URL of the resource using the class name\. It 
first removes the word **Action** from the end of the class name and then 
converts camel case names to dashes\. In our example the full URLs would be:
+
+**Full URLs**
+
+
+~~~~~~~
+com.example.actions.MainAction -> /main
+com.example.actions.products.Display -> /products/display
+com.example.struts.company.details.ShowCompanyDetailsAction -> 
/company/details/show-company-details
+
+~~~~~~~
+
+You can tell the Convention plugin to ignore certain packages using the 
property 
+
+~~~~~~~
+struts.convention.exclude.packages
+~~~~~~~
+\. You can also tell the plugin to use different strings to locate root 
packages using the property 
+
+~~~~~~~
+struts.convention.package.locators
+~~~~~~~
+\. Finally, you can tell the plugin to search specific root packages using the 
property 
+
+~~~~~~~
+struts.convention.action.packages
+~~~~~~~
+\.
+
+Here is our code behind action class:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class HelloWorld extends ActionSupport {
+  private String message;
+
+  public String getMessage() {
+    return message;
+  }
+
+  public String execute() {
+    message = "Hello World!";
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+If you compile this class and place it into your application in the 
WEB\-INF/classes, the Convention plugin will find the class and map the URL 
**/hello\-world** to it\. Next, we need to update our JSP to print out the 
message we setup in the action class\. Here is the new JSP:
+
+**WEB\-INF/content/hello\-world\.jsp**
+
+
+~~~~~~~
+<html>
+<body>
+The message is ${message}
+</body>
+</html>
+
+~~~~~~~
+
+
+
+| Please notice that the expression \$\{message\}  will work without adding 
JSP directive isELIgnored="false"\.
+
+| 
+
+ 
+
+If start up the application server and open up 
[http://localhost:8080/hello\-world](http://localhost:8080/hello\-world) in our 
browser, we should get this result:
+
+**Result**
+
+
+~~~~~~~
+The message is Hello World!
+
+~~~~~~~
+
+###Results and result codes###
+
+The Convention Plugin will pre\-configure all of you action classes when 
Struts is started\. By default, this configuration will also contain results 
for any JSPs that it can find within the application\. The JSPs have an 
additional feature that allows different JSPs to be used based on the result 
code of the action\. Since action methods return Strings and these Strings are 
traditionally used to locate results for the action, the Convention plugin 
allows you to define different results based on the result code\.
+
+Building on our example from above, let's say we want to provide a different 
result if the result code from our action is the String 
+
+~~~~~~~
+zero
+~~~~~~~
+ rather than 
+
+~~~~~~~
+success
+~~~~~~~
+\. First, we update the action class to return different result codes:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class HelloWorld extends ActionSupport {
+  private String message;
+
+  public String getMessage() {
+    return message;
+  }
+
+  public String execute() {
+    if (System.currentTimeMillis() % 2 == 0) {
+      message = "It's 0";
+      return "zero";
+    }
+
+    message = "It's 1";
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+Next, we add a new JSP to the application named 
+
+~~~~~~~
+WEB-INF/content/hello-world-zero.jsp
+~~~~~~~
+\. Notice that the first part of the file name is the same as the URL of the 
action and the last part of the name is the result code\. This is the 
convention that the plugin uses to determine which results to render\. Here is 
our new JSP:
+
+**WEB\-INF/content/hello\-world\.jsp**
+
+
+~~~~~~~
+<html>
+<body>
+The error message is ${message}
+</body>
+</html>
+
+~~~~~~~
+
+Now, if you compile the action and restart the application, based on the 
current time, you'll either see the result from 
+
+~~~~~~~
+WEB-INF/content/hello-world.jsp
+~~~~~~~
+ or 
+
+~~~~~~~
+WEB-INF/content/hello-world-zero.jsp
+~~~~~~~
+\.
+
+The result type is based on the extension of the file\. The supported 
extensions are: jsp,ftl,vm,html,html\. Examples of Action and Result to 
Template mapping:
+
+|URL|Result|File that could match|Result Type|
+|---|------|---------------------|-----------|
+|/hello|success|/WEB\-INF/content/hello\.jsp|Dispatcher|
+|/hello|success|/WEB\-INF/content/hello\-success\.htm|Dispatcher|
+|/hello|success|/WEB\-INF/content/hello\.ftl|FreeMarker|
+|/hello\-world|input|/WEB\-INF/content/hello\-world\-input\.vm|Velocity|
+|/test1/test2/hello|error|/WEB\-INF/content/test/test2/hello\-error\.html|Dispatcher|
+
+#####Multiple names#####
+
+It is possible to define multiple names for the same result:
+
+
+~~~~~~~
+@Action(results = {
+    @Result(name={"error", "input"}, location="input-form.jsp"),
+    @Result(name="success", location="success.jsp")
+})
+~~~~~~~
+
+Such functionality was added in Struts 2\.5
+
+###Chaining###
+
+If one action returns the name of another action in the same package, they 
will be chained together, if the first action doesn't have any result defined 
for that code\. In the following example:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.Action;
+import com.opensymphony.xwork2.ActionSupport;
+
+public class HelloAction extends ActionSupport {
+    @Action("foo")
+    public String foo() {
+        return "bar";
+    }
+
+    @Action("foo-bar")
+    public String bar() {
+        return SUCCESS;
+    }
+}
+
+~~~~~~~
+
+The "foo" action will be executed, because no result is found, the Convention 
plugin tries to find an action named "foo\-bar" on the same package where "foo" 
is defined\. If such an action is found, it will be invoked using the "chain" 
result\.
+
+###XWork packages###
+
+Actions are placed on a custom XWork package which prevents conflicts\. The 
name of this package is based on the Java package the action is defined in, the 
namespace part of the URL for the action and the parent XWork package for the 
action\. The parent XWork package is determined based on the property named 
+
+~~~~~~~
+struts.convention.default.parent.package
+~~~~~~~
+(defaults to 
+
+~~~~~~~
+convention-default
+~~~~~~~
+), which is a custom XWork package that extends 
+
+~~~~~~~
+struts-default
+~~~~~~~
+\.
+
+Therefore the naming for XWork packages used by the Convention plugin are in 
the form:
+
+**XWork package naming**
+
+
+~~~~~~~
+<java-package>#<namespace>#<parent-package>
+
+~~~~~~~
+
+Using our example from above, the XWork package for our action would be:
+
+**XWork package naming**
+
+
+~~~~~~~
+com.example.actions#/#conventionDefault
+
+~~~~~~~
+
+###Annotation reference###
+
+The Convention plugin uses a number of different annotations to override the 
default conventions that are used to map actions to URLs and locate results\. 
In addition, you can modify the parent XWork package that actions are 
configured with\.
+
+####Action annotation####
+
+The Convention plugin allows action classes to change the URL that they are 
mapped to using the **Action** annotation\. This annotation can also be used 
inside the **Actions** annotation to allow multiple URLs to map to a single 
action class\. This annotation must be defined on action methods like this:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+
+public class HelloWorld extends ActionSupport {
+  @Action("/different/url")
+  public String execute() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+Our action class will now map to the URL 
+
+~~~~~~~
+/different/url
+~~~~~~~
+ rather than 
+
+~~~~~~~
+/hello-world
+~~~~~~~
+\. If no 
+
+~~~~~~~
+@Result
+~~~~~~~
+ (see next section) is specified, then the namespace of the action will be 
used as the path to the result, on our last example it would be 
+
+~~~~~~~
+/WEB-INF/content/different/url.jsp
+~~~~~~~
+\.
+
+A single method within an action class can also map to multiple URLs using the 
**Actions** annotation like this:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Actions;
+
+public class HelloWorld extends ActionSupport {
+  @Actions({
+    @Action("/different/url"),
+    @Action("/another/url")
+  })
+  public String execute() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+Another usage of the **Action** or **Actions** annotation is to define 
multiple action methods within a single action class, each of which respond to 
a different URL\. Here is an example of multiple action methods:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Actions;
+
+public class HelloWorld extends ActionSupport {
+  @Action("/different/url")
+  public String execute() {
+    return SUCCESS;
+
+
+  }
+
+  @Action("url")
+  public String doSomething() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+The previous example defines a second URL that is not fully qualified\. This 
means that the namespace for the URL is determined using the Java package name 
rather than the Action annotation\.
+
+Interceptor and interceptor stacks can be specified using the 
+
+~~~~~~~
+interceptorRefs
+~~~~~~~
+ attribute\. The following example applies the 
+
+~~~~~~~
+validation
+~~~~~~~
+ interceptor and the 
+
+~~~~~~~
+defaultStack
+~~~~~~~
+ interceptor stack to the action:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Actions;
+
+public class HelloWorld extends ActionSupport {
+  @Action(interceptorRefs={@InterceptorRef("validation"), 
@InterceptorRef("defaultStack")})
+  public String execute() {
+    return SUCCESS;
+  }
+
+  @Action("url")
+  public String doSomething() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+Parameters can be passed to results using the **params** attribute\. The value 
of this attribute is a string array with an even number of elements in the form 
\{"key0", "value0, "key1", "value1" \.\.\. "keyN", "valueN"\}\. For example:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Actions;
+
+public class HelloWorld extends ActionSupport {
+  
@Action(interceptorRefs=@InterceptorRef(value="validation",params={"programmatic",
 "false", "declarative", "true}))
+  public String execute() {
+    return SUCCESS;
+  }
+
+  @Action("url")
+  public String doSomething() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+If interceptors are not specified, the default stack is applied\.
+
+
+> 
+
+> 
+
+> You can specify className parameter which can be especially useful when 
Spring Framework is used to instantiate actions\.
+
+> 
+
+#####Applying @Action and @Actions at the class level#####
+
+There are circumstances when this is desired, like when using _Dynamic Method 
Invocation_ \. If an 
+
+~~~~~~~
+execute
+~~~~~~~
+ method is defined in the class, then it will be used for the action mapping, 
otherwise the method to be used will be determined when a request is made (by 
Dynamic Method Invocation for example)
+
+####InterceptorRef annotation####
+
+Interceptors can be specified at the method level, using the **Action** 
annotation or at the class level using the 
+
+~~~~~~~
+InterceptorRefs
+~~~~~~~
+ annotation\. Interceptors specified at the class level will be applied to all 
actions defined on that class\. In the following example:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Actions;
+
+@InterceptorRefs({
+    @InterceptorRef("interceptor-1"),
+    @InterceptorRef("defaultStack")
+})
+public class HelloWorld extends ActionSupport {
+  @Action(value="action1", interceptorRefs=@InterceptorRef("validation"))
+  public String execute() {
+    return SUCCESS;
+  }
+
+  @Action(value="action2")
+  public String doSomething() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+The following interceptors will be applied to "action1": 
+
+~~~~~~~
+interceptor-1
+~~~~~~~
+, all interceptors from 
+
+~~~~~~~
+defaultStack
+~~~~~~~
+, 
+
+~~~~~~~
+validation
+~~~~~~~
+\.
+ All interceptors from 
+
+~~~~~~~
+defaultStack
+~~~~~~~
+ will be applied to "action2"\.
+
+
+
+| If you get errors like "Unable to find interceptor class referenced by 
ref\-name XYZ"\. This means that the package where Convention is placing your 
actions, does not extend the package where the interceptor is defined\. To fix 
this problem either 1)Use @ParentPackage annotation(or 
struts\.convention\.default\.parent\.package) passing the name of the package 
that defines the interceptor, or 2) Create a package in XML that extends the 
package that defines the interceptor, and use @ParentPackage(or 
struts\.convention\.default\.parent\.package) to point to it\.
+
+| 
+
+####Result annotation####
+
+The Convention plugin allows action classes to define different results for an 
action\. Results fall into two categories, global and local\. Global results 
are shared across all actions defined within the action class\. These results 
are defined as annotations on the action class\. Local results apply only to 
the action method they are defined on\. Here is an example of the different 
types of result annotations:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Actions;
+import org.apache.struts2.convention.annotation.Result;
+import org.apache.struts2.convention.annotation.Results;
+
+@Results({
+  @Result(name="failure", location="fail.jsp")
+})
+public class HelloWorld extends ActionSupport {
+  @Action(value="/different/url",
+    results={@Result(name="success", location="http://struts.apache.org";, 
type="redirect")}
+  )
+  public String execute() {
+    return SUCCESS;
+  }
+
+  @Action("/another/url")
+
+  public String doSomething() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+Parameters can be passed to results using the **params** attribute\. The value 
of this attribute is a string array with an even number of elements in the form 
\{"key0", "value0, "key1", "value1" \.\.\. "keyN", "valueN"\}\. For example:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Actions;
+import org.apache.struts2.convention.annotation.Result;
+import org.apache.struts2.convention.annotation.Results;
+
+public class HelloWorld extends ActionSupport {
+  @Action(value="/different/url",
+    results={@Result(name="success", type="httpheader", params={"status", 
"500", "errorMessage", "Internal Error"})}
+  )
+  public String execute() {
+    return SUCCESS;
+  }
+
+  @Action("/another/url")
+  public String doSomething() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+From 2\.1\.7 on, global results (defined on the class level) defined using 
annotations will be inherited\. Child classes can override the inherited 
result(s) by redefining it\. Also, results defined at the method level take 
precedence (overwrite), over results with the same name at the action level\.
+
+####Namespace annotation####
+
+The namespace annotation allows the namespace for action classes to be changed 
instead of using the convention of the Java package name\. This annotation can 
be placed on an action class or within the package\-info\.java class that 
allows annotations to be placed on Java packages\. When this annotation is put 
on an action class, it applies to all actions defined in the class, that are 
not fully qualified action URLs\. When this annotation is place in the 
package\-info\.java file, it changes the default namespace for all actions 
defined in the Java package\. Here is an example of the annotation on an action 
class:
+
+**com\.example\.actions\.HelloWorl**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.Namespace;
+
+@Namespace("/custom")
+public class HelloWorld extends ActionSupport {
+  @Action("/different/url")
+  public String execute() {
+    return SUCCESS;
+  }
+
+  @Action("url")
+  public String doSomething() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+In this example, the action will respond to two different URLs 
+
+~~~~~~~
+/different/url
+~~~~~~~
+ and 
+
+~~~~~~~
+/custom/url
+~~~~~~~
+\.
+
+Here is an example of using this annotation in the package\-info\.java file:
+
+**com/example/actions/package\-info\.java**
+
+
+~~~~~~~
+@org.apache.struts2.convention.annotation.Namespace("/custom")
+package com.example.actions;
+
+~~~~~~~
+
+This changes the default namespace for all actions defined in the package 
+
+~~~~~~~
+com.example.actions
+~~~~~~~
+\. This annotation however doesn't apply to sub\-packages\.
+
+####ResultPath annotation####
+
+The ResultPath annotation allows applications to change the location where 
results are stored\. This annotation can be placed on an action class and also 
in the package\-info\.java file\. Here is an example of using this annotation:
+
+**com\.example\.actions\.HelloWorl**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.ResultPath;
+
+@ResultPath("/WEB-INF/jsps")
+public class HelloWorld extends ActionSupport {
+  public String execute() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+The result for this class will be located in 
+
+~~~~~~~
+WEB-INF/jsps
+~~~~~~~
+ rather than the default of 
+
+~~~~~~~
+WEB-INF/content
+~~~~~~~
+\.
+
+####ParentPackage annotation####
+
+The ParentPackage annotation allows applications to define different parent 
Struts package for specific action classes or Java packages\. Here is an 
example of using the annotation on an action class:
+
+**com\.example\.actions\.HelloWorld**
+
+
+~~~~~~~
+package com.example.actions;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.convention.annotation.Action;
+import org.apache.struts2.convention.annotation.ParentPackage;
+
+@ParentPackage("customXWorkPackage")
+public class HelloWorld extends ActionSupport {
+  public String execute() {
+    return SUCCESS;
+  }
+}
+
+~~~~~~~
+
+To apply this annotation to all actions in a package (and subpackages), add it 
to package\-info\.java\. An alternative to this annotation is to set 
+
+~~~~~~~
+struts.convention.default.parent.package
+~~~~~~~
+ in XML\.
+
+####ExceptionMapping Annotation####
+
+This annotation can be used to define exception mappings to actions\. See the 
_exception mapping documentation_  for more details\. These mappings can be 
applied to the class level, in which case they will be applied to all actions 
defined on that class:
+
+**ExceptionsActionLevelAction\.java**
+
+
+~~~~~~~
+@ExceptionMappings({
+    @ExceptionMapping(exception = "java.lang.NullPointerException", result = 
"success", params = {"param1", "val1"})
+})
+public class ExceptionsActionLevelAction {
+
+    public String execute() throws Exception {
+        return null;
+    }
+}
+
+~~~~~~~
+
+The parameters defined by 
+
+~~~~~~~
+params
+~~~~~~~
+ are passed to the result\. Exception mappings can also be applied to the 
action level:
+
+
+~~~~~~~
+public class ExceptionsMethodLevelAction {
+    @Action(value = "exception1", exceptionMappings = {
+            @ExceptionMapping(exception = "java.lang.NullPointerException", 
result = "success", params = {"param1", "val1"})
+    })
+    public String run1() throws Exception {
+        return null;
+    }
+}
+
+~~~~~~~
+
+###Actions in jar files###
+
+By default the Convention plugin will **not** scan jar files for actions\. For 
a jar to be scanned, its URL needs to match at least one of the regular 
expressions in 
+
+~~~~~~~
+struts.convention.action.includeJars
+~~~~~~~
+\. In this example 
+
+~~~~~~~
+myjar1.jar
+~~~~~~~
+ and 
+
+~~~~~~~
+myjar2.jar
+~~~~~~~
+ will be scanned:
+
+
+~~~~~~~
+<constant name="struts.convention.action.includeJars" 
value=".*?/myjar1.*?jar(!/)?,.*?/myjar2*?jar(!/)?"
+
+~~~~~~~
+
+Note that **the regular expression will be evaluated against the URL of the 
jar, and not the file name**, the jar URL can contain a path to the jar file 
and a trailing "\!/"\.
+
+###Automatic configuration reloading###
+
+The Convention plugin can automatically reload configuration changes, made in 
classes the contain actions, without restarting the container\. This is a 
similar behavior to the automatic xml configuration reloading\. To enable this 
feature, add this to your 
+
+~~~~~~~
+struts.xml
+~~~~~~~
+ file:
+
+
+~~~~~~~
+<constant name="struts.devMode" value="true"/>
+<constant name="struts.convention.classes.reload" value="true" />
+
+~~~~~~~
+
+This feature is experimental and has not been tested on all container, and it 
is **strongly** advised not to use it in production environments\.
+
+###JBoss###
+
+When using this plugin with JBoss, you need to set the following constants:
+
+
+~~~~~~~
+<constant name="struts.convention.exclude.parentClassLoader" value="true" />
+<constant name="struts.convention.action.fileProtocols" 
value="jar,vfsfile,vfszip" />
+
+~~~~~~~
+
+You can also check the _JBoss 5_  page for more details\.
+
+###Jetty (embedded)###
+
+When using this plugin with Jetty in embedded mode, you need to set the 
following constants:
+
+
+~~~~~~~
+<constant name="struts.convention.exclude.parentClassLoader" value="false" />
+<constant name="struts.convention.action.fileProtocols" 
value="jar,code-source" />
+
+~~~~~~~
+
+###Troubleshooting###
+
+####Tips####
+
+
+Make sure the namespace of the action is matched by one of the locators\. The 
rest of the namespace after the locator, will be the namespace of the action, 
and will be used to find the results\. For example, a class called "ViewAction" 
in the package "my\.example\.actions\.orders" will be mapped to the URL 
/orders/view\.action, and the results must be under /WEB\-INF/content/orders, 
like /WEB\-INF/content/orders/view\-success\.jsp\.
+
+| 
+
+
+Add the [Config Browser Plugin](#PAGE_44185) plugin to the lib folder or maven 
dependencies, and then visit: 
[http://localhost:8080/CONTEXT/config\-browser/index\.action](http://localhost:8080/CONTEXT/config\-browser/index\.action),
 to see the current action mappings\.
+
+| 
+
+
+The Convention plugin can generate a rather verbose output when set to debug 
mode for logging\. Use "Trace" logging level if you are using the JDK logger\. 
If you are using Log4J, you can do something like:
+
+| 
+
+| 
+
+| log4j\.logger\.org\.apache\.struts2\.convention=DEBUG
+
+| 
+
+####Common Errors####
+
+1. I get an error like "There is no Action mapped for namespace /orders and 
action name view.". This means that the URL 
+
+~~~~~~~
+/orders/view.action
+~~~~~~~
+ is not mapping to any action class. Check the namespace and the name of the 
action.
+
+2. I get an error like "No result defined for action 
my.example.actions.orders.ViewAction and result success". This means that the 
action was mapped to the right URL, but the Convention plugin was unable to 
find a 
+
+~~~~~~~
+success
+~~~~~~~
+ result for it. Check that the result file exists, like 
+
+~~~~~~~
+/WEB-INF/content/orders/view-success.jsp
+~~~~~~~
+.
+
+3. I get lots of errors like "java.lang.Exception: Could not load 
org/apache/velocity/runtime/resource/loader/ClasspathResourceLoader.class". 
This happens when 
+
+~~~~~~~
+struts.convention.action.includeJars
+~~~~~~~
+ is matching jar URLs from external jars.
+
+4. I am using a custom interceptor stack and I get an error like "Unable to 
find interceptor class referenced by ref-name XYZ". This means that the package 
where Convention is placing your actions, does not extend the package where the 
interceptor is defined. To fix this problem either 1)Use @ParentPackage 
annotation(or 
+
+~~~~~~~
+struts.convention.default.parent.package
+~~~~~~~
+) passing the name of the package that defines the interceptor, or 2) Create a 
package in XML that extends the package that defines the interceptor, and use 
@ParentPackage(or 
+
+~~~~~~~
+struts.convention.default.parent.package
+~~~~~~~
+) to point to it.
+
+###Overwriting plugin classes###
+
+The Convention plugin can be extended in the same fashion that Struts does\. 
The following beans are defined by default:
+
+
+~~~~~~~
+<bean type="org.apache.struts2.convention.ActionConfigBuilder" 
name="convention" 
class="org.apache.struts2.convention.PackageBasedActionConfigBuilder"/>
+This interface defines how the action configurations for the current web 
application can be constructed. This must find all actions that are not 
specifically defined in the struts XML files or any plugins. Furthermore, it 
must make every effort to locate all action results as well.
+
+<bean type="org.apache.struts2.convention.ActionNameBuilder" name="convention" 
class="org.apache.struts2.convention.SEOActionNameBuilder"/>
+This interface defines the method that is used to create action names based on 
the name of a class.
+
+<bean type="org.apache.struts2.convention.ResultMapBuilder" name="convention" 
class="org.apache.struts2.convention.DefaultResultMapBuilder"/>
+This interface defines how results are constructed for an Action. The action 
information is supplied and the result is a mapping of ResultConfig instances 
to the result name.
+
+<bean type="org.apache.struts2.convention.InterceptorMapBuilder" 
name="convention" 
class="org.apache.struts2.convention.DefaultInterceptorMapBuilder"/>
+This interface defines how interceptors are built from annotations.
+
+<bean type="org.apache.struts2.convention.ConventionsService" 
name="convention" class="org.apache.struts2.convention.ConventionsServiceImpl"/>
+This interface defines the conventions that are used by the convention plugin. 
In most cases the methods on this class will provide the best default for any 
values and also handle locating overrides of the default via the annotations 
that are part of the plugin.
+
+<constant name="struts.convention.actionConfigBuilder" value="convention"/>
+<constant name="struts.convention.actionNameBuilder" value="convention"/>
+<constant name="struts.convention.resultMapBuilder" value="convention"/>
+<constant name="struts.convention.interceptorMapBuilder" value="convention"/>
+<constant name="struts.convention.conventionsService" value="convention"/>
+
+~~~~~~~
+
+To plugin a different implementation for one of these classes, implement the 
interface, define a bean for it, and set the appropriate constant's value with 
the name of the new bean, for example:
+
+
+~~~~~~~
+<bean type="org.apache.struts2.convention.ActionNameBuilder" 
name="MyActionNameBuilder" class="example.SultansOfSwingNameBuilder"/>
+<constant name="struts.convention.actionNameBuilder" 
value="MyActionNameBuilder"/>
+
+~~~~~~~
+
+###Configuration reference###
+
+Add a **constant** element to your struts config file to change the value of a 
configuration setting, like:
+
+
+~~~~~~~
+<constant name="struts.convention.result.path" value="/WEB-INF/mytemplates/"/>
+
+~~~~~~~
+
+|Name|Default Value|Description|
+|----|-------------|-----------|
+|struts\.convention\.action\.alwaysMapExecute|true|Set to false, to prevent 
Convention from creating a default mapping to "execute" when there are other 
methods annotated as actions in the class|
+|struts\.convention\.action\.includeJars| |Comma separated list of regular 
expressions of jar URLs to be scanned\. eg\. 
"\.**myJar\-0\\\.2\.**,\.**thirdparty\-0\\\.1\.**"|
+|struts\.convention\.action\.packages| |An optional list of action packages 
that this should create configuration for (they don't need to match a locator 
pattern)|
+|struts\.convention\.result\.path|/WEB\-INF/content/|Directory where templates 
are located|
+|struts\.convention\.result\.flatLayout|true|If set to false, the result can 
be put in its own directory: resultsRoot/namespace/actionName/result\.extension|
+|struts\.convention\.action\.suffix|Action|Suffix used to find actions based 
on class names|
+|struts\.convention\.action\.disableScanning|false|Scan packages for actions|
+|struts\.convention\.action\.mapAllMatches|false|Create action mappings, even 
if no @Action is found|
+|struts\.convention\.action\.checkImplementsAction|true|Check if an action 
implements com\.opensymphony\.xwork2\.Action to create an action mapping|
+|struts\.convention\.default\.parent\.package|convention\-default|Default 
parent package for action mappins|
+|struts\.convention\.action\.name\.lowercase|true|Convert action name to 
lowercase|
+|struts\.convention\.action\.name\.separator|\-|Separator used to build the 
action name, MyAction \-\> my\-action\. This character is also used as the 
separator between the action name and the result in templates, like 
action\-result\.jsp|
+|struts\.convention\.package\.locators|action,actions,struts,struts2|Packages 
whose name end with one of these strings will be scanned for actions|
+|struts\.convention\.package\.locators\.disable|false|Disable the scanning of 
packages based on package locators|
+|struts\.convention\.exclude\.packages|org\.apache\.struts\.\*, \
+ org\.apache\.struts2\.\*, \
+ org\.springframework\.web\.struts\.\*, \
+ org\.springframework\.web\.struts2\.\*, \
+ org\.hibernate\.\*|Packages excluded from the action scanning, packages 
already excluded cannot be included in other way, eg\. 
org\.demo\.actions\.exclude is specified as a part of the 
struts\.convention\.exclude\.packages so all packages below are also excluded, 
eg\. org\.demo\.actions\.exclude\.include even if **include** is specified as a 
struts\.convention\.package\.locators or struts\.convention\.action\.packages|
+|struts\.convention\.package\.locators\.basePackage| |If set, only packages 
that start with its value will be scanned for actions|
+|struts\.convention\.relative\.result\.types|dispatcher,velocity,freemarker|The
 list of result types that can have locations that are relative and the result 
location (which is the resultPath plus the namespace) prepended to them|
+|struts\.convention\.redirect\.to\.slash|true|A boolean parameter that 
controls whether or not this will handle unknown actions in the same manner as 
Apache, Tomcat and other web servers\. This handling will send back a redirect 
for URLs such as /foo to /foo/ if there doesn't exist an action that responds 
to /foo|
+|struts\.convention\.classLoader\.excludeParent|true|Exclude URLs found by the 
parent class loader from the list of URLs scanned to find actions (needs to be 
set to false for JBoss 5)|
+|struts\.convention\.action\.eagerLoading|false|If set, found action classes 
will be instantiated by the ObjectFactory to accelerate future use, setting it 
up can clash with Spring managed beans|
+
+###Converting application from Codebehind to Convention Plugin### 
{#PAGE_106500}
+
+__Changes required__
+
++ Replace org\.apache\.struts2\.config\.Namespace with 
org\.apache\.struts2\.convention\.annotation\.Namespace
+
++ Replace org\.apache\.struts2\.config\.Results with 
org\.apache\.struts2\.convention\.annotation\.Results
+
++ Replace org\.apache\.struts2\.config\.Result with 
org\.apache\.struts2\.convention\.annotation\.Result
+
++ Update @Result uses to use result **name** instead of Class\<Result\>
+
++ Update @Result uses to use **location** instead of value attribute
+
++ Update web\.xml and remove Codebehind params from filter
+
++ Update CamelCase action results and references to match Convention\. For 
example:
+
+
+~~~~~~~
+
+Previously in Codebehind:
+Given an action named AnExampleAction, a request to /anExample -> 
AnExampleAction.execute() -> > anExample-index.ftl
+
+Now in Convention:
+Given an action named AnExampleAction, a request to /an-example -> 
AnExampleAction.execute() -> an-example-index.ftl
+
+~~~~~~~
+
+__When REST plugin is used__
+
+Add these constants to struts\.xml
+
+
+~~~~~~~
+
+<constant name="struts.convention.action.suffix" value="Controller"/>
+<constant name="struts.convention.action.mapAllMatches" value="true"/>
+<constant name="struts.convention.default.parent.package" 
value="rest-default"/>
+<constant name="struts.convention.package.locators" value="example"/>
+
+~~~~~~~
+
+##DWR Plugin## {#PAGE_82454}
+
+The DWR plugin 
+
+provides integration with the Ajax framework [Direct Web 
Remoting](http://getahead\.org/dwr)^[http://getahead\.org/dwr]
+
+
+This plugin works by allowing DWR to execute a Struts 2 action and return any 
validation errors\.
+
+
+
+| This plugin is only available with Struts 2\.1\.1 or later
+
+| 
+
+####Features####
+
++ Expose Struts 2 validations via DWR
+
+####Usage####
+
+To expose Struts 2 validations via DWR, add this to your DWR configuration:
+
+
+~~~~~~~
+{snippet:id=dwrConfiguration|javadoc=true|lang=xml|url=struts2/plugins/dwr/src/main/java/org/apache/struts2/validators/DWRValidator.java}
+~~~~~~~
+
+####Settings####
+
+This plugin doesn't support any global settings\.
+
+####Installation####
+
+To install, simply include the DWR Plugin in your 
+
+~~~~~~~
+WEB-INF/lib
+~~~~~~~
+ directory\.  Ensure that DWR has been correctly installed and configured\.
+
+##Embedded JSP Plugin## {#PAGE_2852037}
+
+The Embedded JSP plugin 
+
+allows you to use JSPs from the classpath (from jar files)
+
+
+###Introduction###
+
+JSPs are usually served from the file system\. Using this plugin you can 
deploy JSPs inside jar files, which is sometimes desired, like when writing a 
plugin\. 
+
+####Wait\.\.\.what?####
+
+The plugin containes a modified version of Jasper 6, which reads JSPs from the 
classpath, and generates the java code in memory (no \.java file is written)\. 
The Java Compiler API is then used to compile the java source code into 
bytecode (in memory, no \.class file is generated), and it is turned into a 
Servlet, which is cached for future use\.
+
+####About includes####
+
+Because the JSP files are read from the classpath, "includes" work differently 
than they do from the file system\. Assume you want to include "Hello\.jsp", 
when searching for that file in the classpath, multiple files might be found on 
different jars, like 
+
+~~~~~~~
+somejar.jar!/Hello.jsp
+~~~~~~~
+ and 
+
+~~~~~~~
+otherjar.jar!/Hello.jsp
+~~~~~~~
+\. That's why relative paths do not work in this plugin\. Instead, create 
directory structures for the JSPs\. For example, given 2 jsps under 
+
+~~~~~~~
+org/myexample/jsps
+~~~~~~~
+ in a jar file:
+
+Who\.jsp:
+
+
+~~~~~~~
+
+Hello there, I am the Doctor.
+
+~~~~~~~
+
+Hello\.jsp:
+
+
+~~~~~~~
+
+<jsp:include page="org/myexample/jsps/Who.jsp" />
+
+~~~~~~~
+
+Mapping:
+
+
+~~~~~~~
+
+ <package name="example" namespace="/example" extends="embeddedjsp-default">
+     <action name="HelloWorld" class="example.HelloWorld">
+         <result type="embeddedJsp">org/myexample/jsps/Hello.jsp</result>
+     </action>
+ </package>
+
+~~~~~~~
+
+####Requirements####
+
+1. Java 6 or later
+
+#####Tomcat#####
+
+Tested with Tomcat 6\.0\.20\.
+
+#####Jetty#####
+
+This plugin requires Jetty 7 to work\. And the Tomcat libraries must be 
deployed with the application, adding this to your 
+
+~~~~~~~
+pom.xml
+~~~~~~~
+ should take care of that: 
+
+
+~~~~~~~
+
+<dependency>
+     <groupId>org.apache.tomcat</groupId>
+     <artifactId>jasper</artifactId>
+     <version>6.0.18</version>
+</dependency>
+
+~~~~~~~
+
+To use Jetty 7 with the maven plugin add this to your 
+
+~~~~~~~
+pom.xml
+~~~~~~~
+:
+
+
+~~~~~~~
+
+<build>
+    <plugins>
+        <plugin>
+             <groupId>org.mortbay.jetty</groupId>
+             <artifactId>jetty-maven-plugin</artifactId>
+        </plugin>
+    </plugins>
+</build>
+
+~~~~~~~
+
+##JFreeChart Plugin## {#PAGE_14300}
+
+[JFreeChart](http://www\.jfree\.org/jfreechart/)^[http://www\.jfree\.org/jfreechart/]
 is a free 100% Java (LGPL) chart library that makes it easy for developers to 
display professional quality charts in their applications\.
+
+> 
+
+The JFreeChart plugin 
+
+allows Actions to easily return generated charts and graphs
+
+
+Instead of streaming a generated chart directly to the HTTP response, this 
plugin provides a ChartResult, which handles the generation for you\.  This 
allows you to generate the chart in one class, and render it out in another 
class, effectively decoupling the view from the Actions\. You can easily render 
it out to a file or some view other than a web HTTP response if you wish\.
+
+####Features####
+
++ Handles rendering charts to the HTTP response
+
++ Can be used in other non\-web contexts
+
+#####Future Work#####
+
+Currently the "chart" property is hardcoded\. There should be a better way of 
transferring data from the Action to the Result, via some externally defined 
variable or something\.
+
+As mentioned by John Patterson (mailing list), the Action is still dependant 
on a JFreeChart Chart class\. This can be improved\. The seperation between 
Action and View can be made cleaner\. A chart\-agonistic List or Array can be 
used as the data, and the configuration of the chart details (font, axis, 
etc\.\.\.) be done via the result properties in the xwork\.xml\.
+
+But hey, the above works for now\. Any suggestions are welcome\.
+
+
+
+| You can also create charts via the CeWolf library directly\.  See _CeWolf 
charts using Velocity templates_ \.
+
+| 
+
+####Usage####
+
+To use the plugin, have your Struts configuration package extend the 
+
+~~~~~~~
+jfreechart-default
+~~~~~~~
+ package, which provides the 
+
+~~~~~~~
+chart
+~~~~~~~
+ result type\.  Next, use it as a result in an action:
+
+**Chart example in struts\.xml**
+
+
+~~~~~~~
+
+<action name="viewModerationChart" 
class="myapp.actions.ViewModerationChartAction">
+  <result name="success" type="chart">
+    <param name="width">400</param>
+    <param name="height">300</param> 
+  </result>
+</action>
+
+~~~~~~~
+
+In your Action class, provide a 
+
+~~~~~~~
+getChart()
+~~~~~~~
+ method that returns the chart to be rendered\.  This method will be called by 
the chart result\.
+
+#####Example#####
+
+**Struts Action that provides a chart**
+
+
+~~~~~~~
+
+public class ViewModerationChartAction extends ActionSupport {
+
+       private JFreeChart chart;
+
+       public String execute() throws Exception {
+               // chart creation logic...
+               XYSeries dataSeries = new XYSeries(new Integer(1)); //pass a 
key for this serie
+               for (int i = 0; i <= 100; i++) {
+                       dataSeries.add(i, RandomUtils.nextInt());
+               }
+               XYSeriesCollection xyDataset = new 
XYSeriesCollection(dataSeries);
+
+               ValueAxis xAxis = new NumberAxis("Raw Marks");
+               ValueAxis yAxis = new NumberAxis("Moderated Marks");
+
+               // set my chart variable
+               chart =
+                       new JFreeChart(
+                               "Moderation Function",
+                               JFreeChart.DEFAULT_TITLE_FONT,
+                               new XYPlot(
+                                       xyDataset,
+                                       xAxis,
+                                       yAxis,
+                                       new 
StandardXYItemRenderer(StandardXYItemRenderer.LINES)),
+                               false);
+               chart.setBackgroundPaint(java.awt.Color.white);
+
+               return super.SUCCESS;
+       }
+
+       public JFreeChart getChart() {
+               return chart;
+       }
+
+}
+
+~~~~~~~
+
+#####Settings#####
+
+This plugin doesn't provides any global settings\.
+
+#####Installation#####
+
+This plugin can be installed by copying the plugin jar into your application's 
+
+~~~~~~~
+/WEB-INF/lib
+~~~~~~~
+ directory\.  The JFreeChart library will need to be downloaded separately, as 
its LGPL license doesn't allow it to be distributed with Struts\.
+
+##JSF Plugin## {#PAGE_44198}
+
+[JavaServer 
Faces](http://java\.sun\.com/j2ee/javaserverfaces)^[http://java\.sun\.com/j2ee/javaserverfaces]
 technology simplifies building user interfaces for JavaServer applications\. 
Developers of various skill levels can quickly build web applications by: 
assembling reusable UI components in a page; connecting these components to an 
application data source; and wiring client\-generated events to server\-side 
event handlers\.
+
+> 
+
+The JSF Plugin 
+
+provides support for JavaServer Faces components with no additional 
configuration
+
+
+The JSF support works by breaking up the JSF Licycle class into Struts 
Interceptors, one for each JSF phase\.  When you include the 
+
+~~~~~~~
+jsfStack
+~~~~~~~
+ stack, you are ensuring the JSF page has its phases execute correctly\.  At 
the end of the phases, the Struts Action itself is executed just like non\-JSF 
pages\.  The String return code of the Action is treated like any other Action 
as well\.  Finally, the JSF "render" phase has been transformed into a Result\.
+
+JavaServer Faces also has a concept of an "action", which are generally 
executed in response to a button click\.  The handling of the JSF action is 
preserved through the 
+
+~~~~~~~
+jsfStack
+~~~~~~~
+ Interceptor stack, but its String result code, rather than being applied 
against a JSF navigation rule, is treated as a Struts result code thereby 
keeping the navigation responsibility within Struts\.
+
+The limitations of this approach include:
+
+1. Any custom Lifecycle class is ignored
+
+2. Any custom NavigationHandler is delegated to only when a Struts 2 
navigation option cannot be found
+
+On the other hand, the rest of the JSF functionality, including 
PhaseListeners, components, multiple backing beans, etc\. are preserved\.  The 
Showcase example has a section demonstrating the JSF integration approach\.
+
+####Features####
+
++ Allows JSF components on normal Struts pages
+
++ Requires no additional configuration
+
++ Allows the JSF lifecycle to be completely customized
+
++ Preserves most JSF framework features so even complex components should work 
out of the box
+
+####Usage####
+
+The JSF plugin splits the JSF lifecycle into an optional Interceptor stack and 
Result, yet retains the page's Action and navigation\. Therefore, to use a page 
with JSF components, you need to:
+
+1. Add the 
+
+~~~~~~~
+jsfStack
+~~~~~~~
+ interceptor stack to your action definition.  This is easiest done by having 
your package extend 
+
+~~~~~~~
+jsf-default
+~~~~~~~
+.
+
+2. Add a 
+
+~~~~~~~
+jsf
+~~~~~~~
+ result associated with the name 
+
+~~~~~~~
+success
+~~~~~~~
+
+You can still add additional interceptors and results, including those that 
don't use JSF at all\.  In fact, the recommended approach is to use regular 
Struts results to handle inter\-page navigation to avoid a common problem of 
JSF applications where every page request is a HTTP POST\.
+
+This approach brings an additional advantage to JSF \- every page can have an 
Action to execute page setup code, and the same Action instance will be 
automatically available later in the JSF page's expression language as 
+
+~~~~~~~
+action
+~~~~~~~
+\.  This means any common page logic such as retrieving data from a database 
can remain in your Action, and having that instance available later in your JSF 
components means the JSF configuration file is completely optional\.  The JSF 
configuration file, 
+
+~~~~~~~
+faces-config.xml
+~~~~~~~
+, generally contains backing bean definitions and navigation rules, both of 
which can be solely handled by Struts\.
+
+#####Example#####
+
+The following is an example of a regular Struts Action 2 page definition:
+
+**Regular JSF Action**
+
+
+~~~~~~~
+
+<action name="employee" 
class="org.apache.struts.action2.showcase.jsf.EmployeeAction">
+    <interceptor-ref name="basicStack"/>
+    <result name="success">employee.jsp</result>
+    <result name="index" type="redirect-action">index</result>
+</action>
+
+~~~~~~~
+
+This is the same action but as a JSF\-enabled page:
+
+**JSF\-enabled Action**
+
+
+~~~~~~~
+
+<action name="employee" 
class="org.apache.struts.action2.showcase.jsf.EmployeeAction">
+    <interceptor-ref name="basicStack"/>
+    <interceptor-ref name="jsfStack"/>
+    <result name="success" type="jsf" />
+    <result name="index" type="redirect-action">index</result>
+</action>
+
+~~~~~~~
+
+Notice the Action\-based navigation remains, but now you can use a page with 
JSF components and have complete access to the JSF lifecycle\. This even 
supports JSF components that post back to themselves or add PhaseListeners to 
provide advanced AJAX support\.
+
+#####Settings#####
+
+This plugin does not have any customizable settings\.
+
+#####Installation#####
+
+This plugin can be installed by copying the plugin jar into your application's 
+
+~~~~~~~
+/WEB-INF/lib
+~~~~~~~
+ directory\.  No other files need to be copied or created\.
+
+####Resources####
+
++ [Integrating Struts 2 \+ JSF \+ 
Facelets](http://raibledesigns\.com/rd/entry/integrating\_struts\_2\_jsf\_facelets)^[http://raibledesigns\.com/rd/entry/integrating\_struts\_2\_jsf\_facelets]
 (Matt Raible)
+
+##JSON Plugin## {#PAGE_2850922}
+
+This page is DEPRECATED, please refer to the new source 
[http://struts\.apache\.org/plugins/json/](http://struts\.apache\.org/plugins/json/)
+
+> 
+
+ 
+
+
+The JSON plugin
+
+provides a "json" result type that serializes actions into JSON
+
+
+1. The "content-type" must be "application/json"
+
+2. The JSON content must be well formed, see 
[json.org](http://www.json.org)^[http://www.json.org] for grammar.
+
+3. Action must have a public "setter" method for fields that must be populated.
+
+4. Supported types for population are: Primitives (int,long...String), Date, 
List, Map, Primitive Arrays, Other class (more on this later), and Array of 
Other class.
+
+5. Any object in JSON, that is to be populated inside a list, or a map, will 
be of type Map (mapping from properties to values), any whole number will be of 
type Long, any decimal number will be of type Double, and any array of type 
List.
+
+Given this JSON string:
+
+
+~~~~~~~
+{
+   "doubleValue": 10.10,
+   "nestedBean": {
+      "name": "Mr Bean"
+   },
+   "list": ["A", 10, 20.20, {
+      "firstName": "El Zorro"
+   }],
+   "array": [10, 20] 
+}
+
+~~~~~~~
+
+The action must have a "setDoubleValue" method, taking either a "float" or a 
"double" argument (the interceptor will convert the value to the right one)\. 
There must be a "setNestedBean" whose argument type can be any class, that has 
a "setName" method taking as argument an "String"\. There must be a "setList" 
method that takes a "List" as argument, that list will contain: "A" (String), 
10 (Long), 20\.20 (Double), Map ("firstName" \-\> "El Zorro")\. The "setArray" 
method can take as parameter either a "List", or any numeric array\.
+
+
+
+| So serialize your objects to JSON in javascript see 
[json2](http://json\.org/json2\.js)^[http://json\.org/json2\.js]\.
+
+| 
+
+
+root attribute must be set on the JSONInterceptor when dealing with JSON 
array\.
+
+| 
+
+
+This plugin also provides _AJAX Validation_ \.
+
+| 
+
+####Installation####
+
+This plugin can be installed by copying the plugin jar into your application's 
+
+~~~~~~~
+/WEB-INF/lib
+~~~~~~~
+ directory\. No other files need to be copied or created\.
+
+To use maven, add this to your pom:
+
+
+~~~~~~~
+<dependencies>
+   ...
+   <dependency>
+       <groupId>org.apache.struts</groupId>
+       <artifactId>struts2-json-plugin</artifactId>
+       <version>STRUTS_VERSION</version>
+   </dependency>
+   ...
+</dependencies>
+
+~~~~~~~
+
+####Customizing Serialization and Deserialization####
+
+Use the JSON annotation to customize the serialization/deserialization 
process\. Available JSON annotation fields:
+
+|Name|Description|Default Value|Serialization|Deserialization|
+|----|-----------|-------------|-------------|---------------|
+|name|Customize field name|empty|yes|no|
+|serialize|Include in serialization|true|yes|no|
+|deserialize|Include in deserialization|true|no|yes|
+|format|Format used to format/parse a Date 
field|"yyyy\-MM\-dd'T'HH:mm:ss"|yes|yes|
+
+#####Excluding properties#####
+
+A comma\-delimited list of regular expressions can be passed to the JSON 
Result and Interceptor, properties matching any of these regular expressions 
will be ignored on the serialization process:
+
+
+~~~~~~~
+<!-- Result fragment -->
+<result type="json">
+  <param name="excludeProperties">
+    login.password,
+    studentList.*\.sin
+  </param>
+</result>
+
+<!-- Interceptor fragment -->
+<interceptor-ref name="json">
+  <param name="enableSMD">true</param>
+  <param name="excludeProperties">
+    login.password,
+    studentList.*\.sin
+  </param>
+</interceptor-ref>
+
+~~~~~~~
+
+#####Including properties#####
+
+A comma\-delimited list of regular expressions can be passed to the JSON 
Result to restrict which properties will be serialized\. ONLY properties 
matching any of these regular expressions will be included in the serialized 
output\.
+
+
+
+| Exclude property expressions take precedence over include property 
expressions\. That is, if you use include and exclude property expressions on 
the same result, include property expressions will not be applied if an exclude 
exclude property expression matches a property first\.
+
+| 
+
+
+
+~~~~~~~
+<!-- Result fragment -->
+<result type="json">
+  <param name="includeProperties">
+    ^entries\[\d+\]\.clientNumber,
+    ^entries\[\d+\]\.scheduleNumber,
+    ^entries\[\d+\]\.createUserId
+  </param>
+</result>
+
+~~~~~~~
+
+#####Root Object#####
+
+Use the "root" attribute(OGNL expression) to 

<TRUNCATED>

Reply via email to