You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2011/12/02 17:33:45 UTC

svn commit: r1209569 [23/50] - in /struts/struts2/branches/STRUTS_3_X: apps/blank/src/main/java/example/ apps/blank/src/test/java/example/ apps/jboss-blank/src/main/java/example/ apps/jboss-blank/src/test/java/example/ apps/mailreader/src/main/java/mai...

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/TimerInterceptor.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/TimerInterceptor.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/TimerInterceptor.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/TimerInterceptor.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.interceptor;
+
+import org.apache.struts2.xwork2.ActionInvocation;
+import org.apache.struts2.xwork2.util.logging.Logger;
+import org.apache.struts2.xwork2.util.logging.LoggerFactory;
+
+/**
+ * <!-- START SNIPPET: description -->
+ * This interceptor logs the amount of time in milliseconds. In order for this interceptor to work properly, the
+ * logging framework must be set to at least the <tt>INFO</tt> level.
+ * This interceptor relies on the <a href="http://jakarta.apache.org/commons/logging/">Commons Logging API</a> to
+ * report its execution-time value.
+ * <!-- END SNIPPET: description -->
+ *
+ * <!-- START SNIPPET: parameters -->
+ *
+ * <ul>
+ *
+ * <li>logLevel (optional) - what log level should we use (<code>trace, debug, info, warn, error, fatal</code>)? - defaut is <code>info</code></li>
+ *
+ * <li>logCategory (optional) - If provided we would use this category (eg. <code>com.mycompany.app</code>).
+ * Default is to use <code>org.apache.struts2.xwork2.interceptor.TimerInterceptor</code>.</li>
+ *
+ * </ul>
+ *
+ * The parameters above enables us to log all action execution times in our own logfile.
+ *
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <!-- START SNIPPET: extending -->
+ * This interceptor can be extended to provide custom message format. Users should override the
+ * <code>invokeUnderTiming</code> method.
+ * <!-- END SNIPPET: extending -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * &lt;!-- records only the action's execution time --&gt;
+ * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
+ *     &lt;interceptor-ref name="completeStack"/&gt;
+ *     &lt;interceptor-ref name="timer"/&gt;
+ *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
+ * &lt;/action&gt;
+ *
+ * &lt;!-- records action's execution time as well as other interceptors--&gt;
+ * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
+ *     &lt;interceptor-ref name="timer"/&gt;
+ *     &lt;interceptor-ref name="completeStack"/&gt;
+ *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
+ * &lt;/action&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * This second example uses our own log category at debug level.
+ *
+ * <pre>
+ * <!-- START SNIPPET: example2 -->
+ * &lt;!-- records only the action's execution time --&gt;
+ * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
+ *     &lt;interceptor-ref name="completeStack"/&gt;
+ *     &lt;interceptor-ref name="timer"&gt;
+ *         &lt;param name="logLevel"&gt;debug&lt;/param&gt;
+ *         &lt;param name="logCategory"&gt;com.mycompany.myapp.actiontime&lt;/param&gt;
+ *     &lt;interceptor-ref/&gt;
+ *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
+ * &lt;/action&gt;
+ *
+ * &lt;!-- records action's execution time as well as other interceptors--&gt;
+ * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
+ *     &lt;interceptor-ref name="timer"/&gt;
+ *     &lt;interceptor-ref name="completeStack"/&gt;
+ *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
+ * &lt;/action&gt;
+ * <!-- END SNIPPET: example2 -->
+ * </pre>
+ *
+ * @author Jason Carreira
+ * @author Claus Ibsen
+ */
+public class TimerInterceptor extends AbstractInterceptor {
+    protected static final Logger LOG = LoggerFactory.getLogger(TimerInterceptor.class);
+
+    protected Logger categoryLogger;
+    protected String logCategory;
+    protected String logLevel;
+
+    public String getLogCategory() {
+        return logCategory;
+    }
+
+    public void setLogCategory(String logCatgory) {
+        this.logCategory = logCatgory;
+    }
+
+    public String getLogLevel() {
+        return logLevel;
+    }
+
+    public void setLogLevel(String logLevel) {
+        this.logLevel = logLevel;
+    }
+
+    @Override
+    public String intercept(ActionInvocation invocation) throws Exception {
+        if (! shouldLog()) {
+            return invocation.invoke();
+        } else {
+            return invokeUnderTiming(invocation);
+        }
+    }
+
+    /**
+     * Is called to invoke the action invocation and time the execution time.
+     *
+     * @param invocation  the action invocation.
+     * @return the result of the action execution.
+     * @throws Exception  can be thrown from the action.
+     */
+    protected String invokeUnderTiming(ActionInvocation invocation) throws Exception {
+        long startTime = System.currentTimeMillis();
+        String result = invocation.invoke();
+        long executionTime = System.currentTimeMillis() - startTime;
+
+        StringBuilder message = new StringBuilder(100);
+        message.append("Executed action [");
+        String namespace = invocation.getProxy().getNamespace();
+        if ((namespace != null) && (namespace.trim().length() > 0)) {
+            message.append(namespace).append("/");
+        }
+        message.append(invocation.getProxy().getActionName());
+        message.append("!");
+        message.append(invocation.getProxy().getMethod());
+        message.append("] took ").append(executionTime).append(" ms.");
+
+        doLog(getLoggerToUse(), message.toString());
+
+        return result;
+    }
+
+    /**
+     * Determines if we should log the time.
+     *
+     * @return  true to log, false to not log.
+     */
+    protected boolean shouldLog() {
+        // default check first
+        if (logLevel == null && logCategory == null) {
+            return LOG.isInfoEnabled();
+        }
+
+        // okay user have set some parameters
+        return isLoggerEnabled(getLoggerToUse(), logLevel);
+    }
+
+    /**
+     * Get's the logger to use.
+     *
+     * @return the logger to use.
+     */
+    protected Logger getLoggerToUse() {
+        if (logCategory != null) {
+            if (categoryLogger == null) {
+                // init category logger
+                categoryLogger = LoggerFactory.getLogger(logCategory);
+                if (logLevel == null) {
+                    logLevel = "info"; // use info as default if not provided
+                }
+            }
+            return categoryLogger;
+        }
+
+        return LOG;
+    }
+
+    /**
+     * Performs the actual logging.
+     *
+     * @param logger  the provided logger to use.
+     * @param message  the message to log.
+     */
+    protected void doLog(Logger logger, String message) {
+        if (logLevel == null) {
+            logger.info(message);
+            return;
+        }
+
+        if ("debug".equalsIgnoreCase(logLevel)) {
+            logger.debug(message);
+        } else if ("info".equalsIgnoreCase(logLevel)) {
+            logger.info(message);
+        } else if ("warn".equalsIgnoreCase(logLevel)) {
+            logger.warn(message);
+        } else if ("error".equalsIgnoreCase(logLevel)) {
+            logger.error(message);
+        } else if ("fatal".equalsIgnoreCase(logLevel)) {
+            logger.fatal(message);
+        } else if ("trace".equalsIgnoreCase(logLevel)) {
+            logger.trace(message);
+        } else {
+            throw new IllegalArgumentException("LogLevel [" + logLevel + "] is not supported");
+        }
+    }
+
+    /**
+     * Is the given logger enalbed at the given level?
+     *
+     * @param logger  the logger.
+     * @param level   the level to check if <code>isXXXEnabled</code>.
+     * @return <tt>true</tt> if enabled, <tt>false</tt> if not.
+     */
+    private static boolean isLoggerEnabled(Logger logger, String level) {
+        if ("debug".equalsIgnoreCase(level)) {
+            return logger.isDebugEnabled();
+        } else if ("info".equalsIgnoreCase(level)) {
+            return logger.isInfoEnabled();
+        } else if ("warn".equalsIgnoreCase(level)) {
+            return logger.isWarnEnabled();
+        } else if ("error".equalsIgnoreCase(level)) {
+            return logger.isErrorEnabled();
+        } else if ("fatal".equalsIgnoreCase(level)) {
+            return logger.isFatalEnabled();
+        } else if ("trace".equalsIgnoreCase(level)) {
+            return logger.isTraceEnabled();
+        } else {
+            throw new IllegalArgumentException("LogLevel [" + level + "] is not supported");
+        }
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/ValidationWorkflowAware.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/ValidationWorkflowAware.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/ValidationWorkflowAware.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/ValidationWorkflowAware.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,9 @@
+package org.apache.struts2.xwork2.interceptor;
+
+/**
+ * <code>ValidationWorkflowAware</code>
+ */
+public interface ValidationWorkflowAware {
+
+    String getInputResultName();
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/After.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/After.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/After.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/After.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <!-- START SNIPPET: description -->
+ * Marks a action method that needs to be called after the main action method and the result was
+ * executed. Return value is ignored.
+ * <!-- END SNIPPET: description -->
+ *
+ * <p/> <u>Annotation usage:</u>
+ *
+ * <!-- START SNIPPET: usage -->
+ * The After annotation can be applied at method level.
+ *
+ * <!-- END SNIPPET: usage -->
+ *
+ * <p/> <u>Annotation parameters:</u>
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <table class='confluenceTable'>
+ * <tr>
+ * <th class='confluenceTh'> Parameter </th>
+ * <th class='confluenceTh'> Required </th>
+ * <th class='confluenceTh'> Default </th>
+ * <th class='confluenceTh'> Notes </th>
+ * </tr>
+ * <tr>
+ * <td class='confluenceTd'>priority</td>
+ * <td class='confluenceTd'>no</td>
+ * <td class='confluenceTd'>10</td>
+ * <td class='confluenceTd'>Priority order of method execution</td>
+ * </tr>
+ * </table>
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <p/> <u>Example code:</u>
+ *
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * public class SampleAction extends ActionSupport {
+ *
+ *  &#64;After
+ *  public void isValid() throws ValidationException {
+ *    // validate model object, throw exception if failed
+ *  }
+ *
+ *  public String execute() {
+ *     // perform action
+ *     return SUCCESS;
+ *  }
+ * }
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author Zsolt Szasz, zsolt at lorecraft dot com
+ * @author Rainer Hermanns
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface After {
+    int priority() default 10; 
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Allowed.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Allowed.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Allowed.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Allowed.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,18 @@
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Declares that it is permitted for the field be mutated through
+ * a HttpRequest parameter.
+ *
+ * @author martin.gilday
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Allowed {
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,91 @@
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+
+import org.apache.struts2.xwork2.ActionInvocation;
+import org.apache.struts2.xwork2.interceptor.AbstractInterceptor;
+import org.apache.struts2.xwork2.util.AnnotationUtils;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Annotation based version of {@link org.apache.struts2.xwork2.interceptor.ParameterFilterInterceptor}.
+ * <p/>
+ * This {@link org.apache.struts2.xwork2.interceptor.Interceptor} must be placed in the stack before the {@link org.apache.struts2.xwork2.interceptor.ParametersInterceptor}
+ * When a parameter matches a field that is marked {@link Blocked} then it is removed from
+ * the parameter map.
+ * <p/>
+ * If an {@link org.apache.struts2.xwork2.Action} class is marked with {@link BlockByDefault} then all parameters are
+ * removed unless a field on the Action exists and is marked with {@link Allowed}
+ *
+ * @author martin.gilday
+ */
+public class AnnotationParameterFilterIntereptor extends AbstractInterceptor {
+
+    /* (non-Javadoc)
+      * @see org.apache.struts2.xwork2.interceptor.AbstractInterceptor#intercept(org.apache.struts2.xwork2.ActionInvocation)
+      */
+    @Override public String intercept(ActionInvocation invocation) throws Exception {
+
+        final Object action = invocation.getAction();
+        Map<String, Object> parameters = invocation.getInvocationContext().getParameters();
+
+        Object model = invocation.getStack().peek();
+        if (model == action) {
+            model = null;
+        }
+
+        boolean blockByDefault = action.getClass().isAnnotationPresent(BlockByDefault.class);
+        List<Field> annotatedFields = new ArrayList<Field>();
+        HashSet<String> paramsToRemove = new HashSet<String>();
+
+        if (blockByDefault) {
+            AnnotationUtils.addAllFields(Allowed.class, action.getClass(), annotatedFields);
+            if (model != null) {
+                AnnotationUtils.addAllFields(Allowed.class, model.getClass(), annotatedFields);
+            }
+
+            for (String paramName : parameters.keySet()) {
+                boolean allowed = false;
+
+                for (Field field : annotatedFields) {
+                    //TODO only matches exact field names.  need to change to it matches start of ognl expression
+                    //i.e take param name up to first . (period) and match against that
+                    if (field.getName().equals(paramName)) {
+                        allowed = true;
+                    }
+                }
+
+                if (!allowed) {
+                    paramsToRemove.add(paramName);
+                }
+            }
+        } else {
+            AnnotationUtils.addAllFields(Blocked.class, action.getClass(), annotatedFields);
+            if (model != null) {
+                AnnotationUtils.addAllFields(Blocked.class, model.getClass(), annotatedFields);
+            }
+
+            for (String paramName : parameters.keySet()) {
+
+                for (Field field : annotatedFields) {
+                    //TODO only matches exact field names.  need to change to it matches start of ognl expression
+                    //i.e take param name up to first . (period) and match against that
+                    if (field.getName().equals(paramName)) {
+                        paramsToRemove.add(paramName);
+                    }
+                }
+            }
+        }
+
+        for (String aParamsToRemove : paramsToRemove) {
+            parameters.remove(aParamsToRemove);
+        }
+
+        return invocation.invoke();
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import org.apache.struts2.xwork2.ActionInvocation;
+import org.apache.struts2.xwork2.XWorkException;
+import org.apache.struts2.xwork2.interceptor.AbstractInterceptor;
+import org.apache.struts2.xwork2.interceptor.PreResultListener;
+import org.apache.struts2.xwork2.util.AnnotationUtils;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * <p>Invokes any annotated methods on the action. Specifically, it supports the following
+ * annotations:
+ * <ul>
+ * <li> &#64;{@link Before} - will be invoked before the action method. If the returned value is not null, it is
+ * returned as the action result code</li>
+ * <li> &#64;{@link BeforeResult} - will be invoked after the action method but before the result execution</li>
+ * <li> &#64;{@link After} - will be invoked after the action method and result execution</li>
+ * </ul>
+ * </p>
+ * <p/>
+ * <p>There can be multiple methods marked with the same annotations, but the order of their execution
+ * is not guaranteed. However, the annotated methods on the superclass chain are guaranteed to be invoked before the
+ * annotated method in the current class in the case of a {@link Before} annotations and after, if the annotations is
+ * {@link After}.</p>
+ * <!-- END SNIPPET: javadoc -->
+ * <p/>
+ * <pre>
+ * <!-- START SNIPPET: javacode -->
+ *  public class BaseAnnotatedAction {
+ *  	protected String log = "";
+ * <p/>
+ *  	&#64;Before
+ *  	public String baseBefore() {
+ *  		log = log + "baseBefore-";
+ *  		return null;
+ *  	}
+ *  }
+ * <p/>
+ *  public class AnnotatedAction extends BaseAnnotatedAction {
+ *  	&#64;Before
+ *  	public String before() {
+ *  		log = log + "before";
+ *  		return null;
+ *  	}
+ * <p/>
+ *  	public String execute() {
+ *  		log = log + "-execute";
+ *  		return Action.SUCCESS;
+ *  	}
+ * <p/>
+ *  	&#64;BeforeResult
+ *  	public void beforeResult() throws Exception {
+ *  		log = log +"-beforeResult";
+ *  	}
+ * <p/>
+ *  	&#64;After
+ *  	public void after() {
+ *  		log = log + "-after";
+ *  	}
+ *  }
+ * <!-- END SNIPPET: javacode -->
+ *  </pre>
+ * <p/>
+ * <!-- START SNIPPET: example -->
+ * <p>With the interceptor applied and the action executed on <code>AnnotatedAction</code> the log
+ * instance variable will contain <code>baseBefore-before-execute-beforeResult-after</code>.</p>
+ * <!-- END SNIPPET: example -->
+ * <p/>
+ * <p/>Configure a stack in xwork.xml that replaces the PrepareInterceptor with the AnnotationWorkflowInterceptor:
+ * <pre>
+ * <!-- START SNIPPET: stack -->
+ * &lt;interceptor-stack name="annotatedStack"&gt;
+ * 	&lt;interceptor-ref name="staticParams"/&gt;
+ * 	&lt;interceptor-ref name="params"/&gt;
+ * 	&lt;interceptor-ref name="conversionError"/&gt;
+ * 	&lt;interceptor-ref name="annotationWorkflow"/&gt;
+ * &lt;/interceptor-stack&gt;
+ *  <!-- END SNIPPET: stack -->
+ * </pre>
+ *
+ * @author Zsolt Szasz, zsolt at lorecraft dot com
+ * @author Rainer Hermanns
+ * @author Dan Oxlade, dan d0t oxlade at gmail d0t c0m
+ */
+public class AnnotationWorkflowInterceptor extends AbstractInterceptor implements PreResultListener {
+
+    /**
+     * Discovers annotated methods on the action and calls them according to the workflow
+     *
+     * @see org.apache.struts2.xwork2.interceptor.Interceptor#intercept(org.apache.struts2.xwork2.ActionInvocation)
+     */
+    public String intercept(ActionInvocation invocation) throws Exception {
+        final Object action = invocation.getAction();
+        invocation.addPreResultListener(this);
+        List<Method> methods = new ArrayList<Method>(AnnotationUtils.getAnnotatedMethods(action.getClass(), Before.class));
+        if (methods.size() > 0) {
+            // methods are only sorted by priority
+            Collections.sort(methods, new Comparator<Method>() {
+                public int compare(Method method1, Method method2) {
+                    return comparePriorities(method1.getAnnotation(Before.class).priority(),
+                                method2.getAnnotation(Before.class).priority());
+                }
+            });
+            for (Method m : methods) {
+                final String resultCode = (String) m
+                        .invoke(action, (Object[]) null);
+                if (resultCode != null) {
+                    // shortcircuit execution
+                    return resultCode;
+                }
+            }
+        }
+
+        String invocationResult = invocation.invoke();
+
+        // invoke any @After methods
+        methods = new ArrayList<Method>(AnnotationUtils.getAnnotatedMethods(action.getClass(), After.class));
+
+        if (methods.size() > 0) {
+            // methods are only sorted by priority
+            Collections.sort(methods, new Comparator<Method>() {
+                public int compare(Method method1, Method method2) {
+                    return comparePriorities(method1.getAnnotation(After.class).priority(),
+                                method2.getAnnotation(After.class).priority());
+                }
+            });
+            for (Method m : methods) {
+                m.invoke(action, (Object[]) null);
+            }
+        }
+
+        return invocationResult;
+    }
+
+    protected static int comparePriorities(int val1, int val2) {
+        if (val2 < val1) {
+            return -1;
+        } else if (val2 > val1) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Invokes any &#64;BeforeResult annotated methods
+     *
+     * @see org.apache.struts2.xwork2.interceptor.PreResultListener#beforeResult(org.apache.struts2.xwork2.ActionInvocation,String)
+     */
+    public void beforeResult(ActionInvocation invocation, String resultCode) {
+        Object action = invocation.getAction();
+        List<Method> methods = new ArrayList<Method>(AnnotationUtils.getAnnotatedMethods(action.getClass(), BeforeResult.class));
+
+        if (methods.size() > 0) {
+            // methods are only sorted by priority
+            Collections.sort(methods, new Comparator<Method>() {
+                public int compare(Method method1, Method method2) {
+                    return comparePriorities(method1.getAnnotation(BeforeResult.class).priority(),
+                                method2.getAnnotation(BeforeResult.class).priority());
+                }
+            });
+            for (Method m : methods) {
+                try {
+                    m.invoke(action, (Object[]) null);
+                } catch (Exception e) {
+                    throw new XWorkException(e);
+                }
+            }
+        }
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Before.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Before.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Before.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Before.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <!-- START SNIPPET: description -->
+ * Marks a action method that needs to be executed before the main action method.
+ * <!-- END SNIPPET: description -->
+ *
+ * <p/> <u>Annotation usage:</u>
+ *
+ * <!-- START SNIPPET: usage -->
+ * The Before annotation can be applied at method level.
+ *
+ * <!-- END SNIPPET: usage -->
+ *
+ * <p/> <u>Annotation parameters:</u>
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <table class='confluenceTable'>
+ * <tr>
+ * <th class='confluenceTh'> Parameter </th>
+ * <th class='confluenceTh'> Required </th>
+ * <th class='confluenceTh'> Default </th>
+ * <th class='confluenceTh'> Notes </th>
+ * </tr>
+ * <tr>
+ * <td class='confluenceTd'>priority</td>
+ * <td class='confluenceTd'>no</td>
+ * <td class='confluenceTd'>10</td>
+ * <td class='confluenceTd'>Priority order of method execution</td>
+ * </tr>
+ * </table>
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <p/> <u>Example code:</u>
+ *
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * public class SampleAction extends ActionSupport {
+ *
+ *  &#64;Before
+ *  public void isAuthorized() throws AuthenticationException {
+ *    // authorize request, throw exception if failed
+ *  }
+ *
+ *  public String execute() {
+ *     // perform secure action
+ *     return SUCCESS;
+ *  }
+ * }
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author Zsolt Szasz, zsolt at lorecraft dot com
+ * @author Rainer Hermanns
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Before {
+    int priority() default 10; 
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/BeforeResult.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/BeforeResult.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/BeforeResult.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/BeforeResult.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <!-- START SNIPPET: description -->
+ * Marks a action method that needs to be executed before the result. Return value is ignored.
+ * <!-- END SNIPPET: description -->
+ *
+ * <p/> <u>Annotation usage:</u>
+ *
+ * <!-- START SNIPPET: usage -->
+ * The BeforeResult annotation can be applied at method level.
+ *
+ * <!-- END SNIPPET: usage -->
+ *
+ * <p/> <u>Annotation parameters:</u>
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <table class='confluenceTable'>
+ * <tr>
+ * <th class='confluenceTh'> Parameter </th>
+ * <th class='confluenceTh'> Required </th>
+ * <th class='confluenceTh'> Default </th>
+ * <th class='confluenceTh'> Notes </th>
+ * </tr>
+ * <tr>
+ * <td class='confluenceTd'>priority</td>
+ * <td class='confluenceTd'>no</td>
+ * <td class='confluenceTd'>10</td>
+ * <td class='confluenceTd'>Priority order of method execution</td>
+ * </tr>
+ * </table>
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <p/> <u>Example code:</u>
+ *
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * public class SampleAction extends ActionSupport {
+ *
+ *  &#64;BeforeResult
+ *  public void isValid() throws ValidationException {
+ *    // validate model object, throw exception if failed
+ *  }
+ *
+ *  public String execute() {
+ *     // perform action
+ *     return SUCCESS;
+ *  }
+ * }
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author Zsolt Szasz, zsolt at lorecraft dot com
+ * @author Rainer Hermanns
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface BeforeResult {
+    int priority() default 10; 
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/BlockByDefault.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/BlockByDefault.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/BlockByDefault.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/BlockByDefault.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,19 @@
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Declares that by default fields on the {@link org.apache.struts2.xwork2.Action} class
+ * are NOT permitted to be set from HttpRequest parameters.
+ * To allow access to a field it must be annotated with {@link Allowed}
+ *
+ * @author martin.gilday
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface BlockByDefault {
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Blocked.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Blocked.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Blocked.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/Blocked.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,18 @@
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Declares that the given field should NOT be able to be mutated through
+ * a HttpRequest parameter.
+ *
+ * @author martin.gilday
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Blocked {
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/InputConfig.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/InputConfig.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/InputConfig.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/InputConfig.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2002-2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.interceptor.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.apache.struts2.xwork2.Action;
+
+/**
+ * <!-- START SNIPPET: description -->
+ * Marks a action method that if it's not validated by ValidationInterceptor then execute input method or input result.
+ * <!-- END SNIPPET: description -->
+ *
+ * <p/> <u>Annotation usage:</u>
+ *
+ * <!-- START SNIPPET: usage -->
+ * The InputConfig annotation can be applied at method level.
+ *
+ * <!-- END SNIPPET: usage -->
+ *
+ * <p/> <u>Annotation parameters:</u>
+ *
+ * <!-- START SNIPPET: parameters -->
+ * <table class='confluenceTable'>
+ * <tr>
+ * <th class='confluenceTh'> Parameter </th>
+ * <th class='confluenceTh'> Required </th>
+ * <th class='confluenceTh'> Default </th>
+ * <th class='confluenceTh'> Notes </th>
+ * </tr>
+ * <tr>
+ * <td class='confluenceTd'>methodName</td>
+ * <td class='confluenceTd'>no</td>
+ * <td class='confluenceTd'></td>
+ * <td class='confluenceTd'>execute this method if specific</td>
+ * </tr>
+ * <tr>
+ * <td class='confluenceTd'>resultName</td>
+ * <td class='confluenceTd'>no</td>
+ * <td class='confluenceTd'></td>
+ * <td class='confluenceTd'>return this result if methodName not specific</td>
+ * </tr>
+ * </table>
+ * <!-- END SNIPPET: parameters -->
+ *
+ * <p/> <u>Example code:</u>
+ *
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * public class SampleAction extends ActionSupport {
+ *
+ *  public void isValid() throws ValidationException {
+ *    // validate model object, throw exception if failed
+ *  }
+ *
+ *  &#64;InputConfig(methodName="input")
+ *  public String execute() {
+ *     // perform action
+ *     return SUCCESS;
+ *  }
+ *  public String input() {
+ *     // perform some data filling
+ *     return INPUT;
+ *  }
+ * }
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ * @author zhouyanming, zhouyanming@gmail.com
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface InputConfig {
+    String methodName() default "";
+    String resultName() default Action.INPUT;
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/package.html
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/package.html?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/package.html (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/annotations/package.html Fri Dec  2 16:33:03 2011
@@ -0,0 +1 @@
+<body>Interceptor annotations.</body>

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/package.html
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/package.html?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/package.html (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/interceptor/package.html Fri Dec  2 16:33:03 2011
@@ -0,0 +1 @@
+<body>Interceptor classes.</body>

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockActionInvocation.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockActionInvocation.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockActionInvocation.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockActionInvocation.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.xwork2.mock;
+
+import org.apache.struts2.xwork2.ActionContext;
+import org.apache.struts2.xwork2.interceptor.PreResultListener;
+import org.apache.struts2.xwork2.util.ValueStack;
+import org.apache.struts2.xwork2.ActionEventListener;
+import org.apache.struts2.xwork2.ActionInvocation;
+import org.apache.struts2.xwork2.ActionProxy;
+import org.apache.struts2.xwork2.Result;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Mock for an {@link org.apache.struts2.xwork2.ActionInvocation}.
+ *
+ * @author plightbo
+ * @author Rainer Hermanns
+ * @author tm_jee
+ * @version $Id: MockActionInvocation.java 1209415 2011-12-02 11:24:48Z lukaszlenart $
+ */
+public class MockActionInvocation implements ActionInvocation {
+
+    private Object action;
+    private ActionContext invocationContext;
+    private ActionEventListener actionEventListener;
+    private ActionProxy proxy;
+    private Result result;
+    private String resultCode;
+    private ValueStack stack;
+    
+    private List<PreResultListener> preResultListeners = new ArrayList<PreResultListener>();
+
+    public Object getAction() {
+        return action;
+    }
+
+    public void setAction(Object action) {
+        this.action = action;
+    }
+
+    public ActionContext getInvocationContext() {
+        return invocationContext;
+    }
+
+    public void setInvocationContext(ActionContext invocationContext) {
+        this.invocationContext = invocationContext;
+    }
+
+    public ActionProxy getProxy() {
+        return proxy;
+    }
+
+    public void setProxy(ActionProxy proxy) {
+        this.proxy = proxy;
+    }
+
+    public Result getResult() {
+        return result;
+    }
+
+    public void setResult(Result result) {
+        this.result = result;
+    }
+
+    public String getResultCode() {
+        return resultCode;
+    }
+
+    public void setResultCode(String resultCode) {
+        this.resultCode = resultCode;
+    }
+
+    public ValueStack getStack() {
+        return stack;
+    }
+
+    public void setStack(ValueStack stack) {
+        this.stack = stack;
+    }
+
+    public boolean isExecuted() {
+        return false;
+    }
+
+    public void addPreResultListener(PreResultListener listener) {
+    	preResultListeners.add(listener);
+    }
+
+    public String invoke() throws Exception {
+        for (Object preResultListener : preResultListeners) {
+            PreResultListener listener = (PreResultListener) preResultListener;
+            listener.beforeResult(this, resultCode);
+        }
+        return resultCode;
+    }
+
+    public String invokeActionOnly() throws Exception {
+        return resultCode;
+    }
+
+    public void setActionEventListener(ActionEventListener listener) {
+        this.actionEventListener = listener;
+    }
+    
+    public ActionEventListener getActionEventListener() {
+        return this.actionEventListener;
+    }
+
+    public void init(ActionProxy proxy) {
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockActionProxy.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockActionProxy.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockActionProxy.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockActionProxy.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.xwork2.mock;
+
+import org.apache.struts2.xwork2.ActionInvocation;
+import org.apache.struts2.xwork2.ActionProxy;
+import org.apache.struts2.xwork2.config.Configuration;
+import org.apache.struts2.xwork2.config.entities.ActionConfig;
+
+/**
+ * Mock for an {@link ActionProxy}.
+ * 
+ * @author Patrick Lightbody (plightbo at gmail dot com)
+ */
+public class MockActionProxy implements ActionProxy {
+    
+    Object action;
+    String actionName;
+    ActionConfig config;
+    boolean executeResult;
+    ActionInvocation invocation;
+    String namespace;
+    String method;
+    boolean executedCalled;
+    String returnedResult;
+    Configuration configuration;
+    boolean methodSpecified;
+
+    public void prepare() throws Exception {}
+    
+    public String execute() throws Exception {
+        executedCalled = true;
+
+        return returnedResult;
+    }
+
+    public void setReturnedResult(String returnedResult) {
+        this.returnedResult = returnedResult;
+    }
+
+    public boolean isExecutedCalled() {
+        return executedCalled;
+    }
+
+    public Object getAction() {
+        return action;
+    }
+
+    public void setAction(Object action) {
+        this.action = action;
+    }
+
+    public String getActionName() {
+        return actionName;
+    }
+
+    public void setActionName(String actionName) {
+        this.actionName = actionName;
+    }
+
+    public ActionConfig getConfig() {
+        return config;
+    }
+
+    public void setConfig(ActionConfig config) {
+        this.config = config;
+    }
+
+    public boolean getExecuteResult() {
+        return executeResult;
+    }
+
+    public void setExecuteResult(boolean executeResult) {
+        this.executeResult = executeResult;
+    }
+
+    public ActionInvocation getInvocation() {
+        return invocation;
+    }
+
+    public void setInvocation(ActionInvocation invocation) {
+        this.invocation = invocation;
+    }
+
+    public String getNamespace() {
+        return namespace;
+    }
+
+    public void setNamespace(String namespace) {
+        this.namespace = namespace;
+    }
+
+    public String getMethod() {
+        return method;
+    }
+
+    public void setMethod(String method) {
+        this.method = method;
+        methodSpecified=method!=null && !"".equals(method);
+    }
+
+    public boolean isMethodSpecified()
+    {
+        return methodSpecified;
+    }
+
+    public void setMethodSpecified(boolean methodSpecified)
+    {
+        this.methodSpecified = methodSpecified;
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockInterceptor.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockInterceptor.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockInterceptor.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockInterceptor.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.mock;
+
+import org.apache.struts2.xwork2.ActionInvocation;
+import org.apache.struts2.xwork2.interceptor.Interceptor;
+import junit.framework.Assert;
+
+
+/**
+ * Mock for an {@link org.apache.struts2.xwork2.interceptor.Interceptor}.
+ *
+ * @author Jason Carreira
+ */
+public class MockInterceptor implements Interceptor {
+
+    private static final long serialVersionUID = 2692551676567227756L;
+    
+    public static final String DEFAULT_FOO_VALUE = "fooDefault";
+
+
+    private String expectedFoo = DEFAULT_FOO_VALUE;
+    private String foo = DEFAULT_FOO_VALUE;
+    private boolean executed = false;
+
+
+    public boolean isExecuted() {
+        return executed;
+    }
+
+    public void setExpectedFoo(String expectedFoo) {
+        this.expectedFoo = expectedFoo;
+    }
+
+    public String getExpectedFoo() {
+        return expectedFoo;
+    }
+
+    public void setFoo(String foo) {
+        this.foo = foo;
+    }
+
+    public String getFoo() {
+        return foo;
+    }
+
+    /**
+     * Called to let an interceptor clean up any resources it has allocated.
+     */
+    public void destroy() {
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof MockInterceptor)) {
+            return false;
+        }
+
+        final MockInterceptor testInterceptor = (MockInterceptor) o;
+
+        if (executed != testInterceptor.executed) {
+            return false;
+        }
+
+        if ((expectedFoo != null) ? (!expectedFoo.equals(testInterceptor.expectedFoo)) : (testInterceptor.expectedFoo != null))
+        {
+            return false;
+        }
+
+        if ((foo != null) ? (!foo.equals(testInterceptor.foo)) : (testInterceptor.foo != null)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result;
+        result = ((expectedFoo != null) ? expectedFoo.hashCode() : 0);
+        result = (29 * result) + ((foo != null) ? foo.hashCode() : 0);
+        result = (29 * result) + (executed ? 1 : 0);
+
+        return result;
+    }
+
+    /**
+     * Called after an Interceptor is created, but before any requests are processed using the intercept() methodName. This
+     * gives the Interceptor a chance to initialize any needed resources.
+     */
+    public void init() {
+    }
+
+    /**
+     * Allows the Interceptor to do some processing on the request before and/or after the rest of the processing of the
+     * request by the DefaultActionInvocation or to short-circuit the processing and just return a String return code.
+     */
+    public String intercept(ActionInvocation invocation) throws Exception {
+        executed = true;
+        Assert.assertNotSame(DEFAULT_FOO_VALUE, foo);
+        Assert.assertEquals(expectedFoo, foo);
+
+        return invocation.invoke();
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockObjectTypeDeterminer.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockObjectTypeDeterminer.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockObjectTypeDeterminer.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockObjectTypeDeterminer.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.mock;
+
+import org.apache.struts2.xwork2.conversion.ObjectTypeDeterminer;
+import ognl.OgnlException;
+import ognl.OgnlRuntime;
+
+import java.util.Map;
+
+/**
+ * Mocks the function of an ObjectTypeDeterminer for testing purposes.
+ *
+ * @author Gabe
+ */
+public class MockObjectTypeDeterminer implements ObjectTypeDeterminer {
+
+    private Class keyClass;
+    private Class elementClass;
+    private String keyProperty;
+    private boolean shouldCreateIfNew;
+
+    public MockObjectTypeDeterminer() {}
+
+
+    /**
+     * @param keyClass
+     * @param elementClass
+     * @param keyProperty
+     * @param shouldCreateIfNew
+     */
+    public MockObjectTypeDeterminer(Class keyClass, Class elementClass,
+                                    String keyProperty, boolean shouldCreateIfNew) {
+        super();
+        this.keyClass = keyClass;
+        this.elementClass = elementClass;
+        this.keyProperty = keyProperty;
+        this.shouldCreateIfNew = shouldCreateIfNew;
+    }
+
+    public Class getKeyClass(Class parentClass, String property) {
+        return getKeyClass();
+    }
+
+    public Class getElementClass(Class parentClass, String property, Object key) {
+        return getElementClass();
+    }
+
+    public String getKeyProperty(Class parentClass, String property) {
+        return getKeyProperty();
+    }
+
+    public boolean shouldCreateIfNew(Class parentClass, String property,
+                                     Object target, String keyProperty, boolean isIndexAccessed) {
+        try {
+            System.out.println("ognl:"+OgnlRuntime.getPropertyAccessor(Map.class)+" this:"+this);
+        } catch (OgnlException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        return isShouldCreateIfNew();
+    }
+
+    /**
+     * @return Returns the elementClass.
+     */
+    public Class getElementClass() {
+        return elementClass;
+    }
+    /**
+     * @param elementClass The elementClass to set.
+     */
+    public void setElementClass(Class elementClass) {
+        this.elementClass = elementClass;
+    }
+    /**
+     * @return Returns the keyClass.
+     */
+    public Class getKeyClass() {
+        return keyClass;
+    }
+    /**
+     * @param keyClass The keyClass to set.
+     */
+    public void setKeyClass(Class keyClass) {
+        this.keyClass = keyClass;
+    }
+    /**
+     * @return Returns the keyProperty.
+     */
+    public String getKeyProperty() {
+        return keyProperty;
+    }
+    /**
+     * @param keyProperty The keyProperty to set.
+     */
+    public void setKeyProperty(String keyProperty) {
+        this.keyProperty = keyProperty;
+    }
+    /**
+     * @return Returns the shouldCreateIfNew.
+     */
+    public boolean isShouldCreateIfNew() {
+        return shouldCreateIfNew;
+    }
+    /**
+     * @param shouldCreateIfNew The shouldCreateIfNew to set.
+     */
+    public void setShouldCreateIfNew(boolean shouldCreateIfNew) {
+        this.shouldCreateIfNew = shouldCreateIfNew;
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockResult.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockResult.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockResult.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/MockResult.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.mock;
+
+import org.apache.struts2.xwork2.ActionInvocation;
+import org.apache.struts2.xwork2.Result;
+
+/**
+ * Mock for a {@link org.apache.struts2.xwork2.Result}.
+ *
+ * @author Mike
+ * @author Rainer Hermanns
+ */
+public class MockResult implements Result {
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof MockResult)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    public void execute(ActionInvocation invocation) throws Exception {
+        // no op
+    }
+
+    @Override
+    public int hashCode() {
+        return 10;
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/package.html
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/package.html?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/package.html (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/mock/package.html Fri Dec  2 16:33:03 2011
@@ -0,0 +1 @@
+<body>XWork specific mock classes.</body>

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/ErrorMessageBuilder.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/ErrorMessageBuilder.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/ErrorMessageBuilder.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/ErrorMessageBuilder.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,58 @@
+package org.apache.struts2.xwork2.ognl;
+
+/**
+ * Helper class to build error messages.
+ */
+public class ErrorMessageBuilder {
+
+    private StringBuilder message = new StringBuilder();
+
+    public static ErrorMessageBuilder create() {
+        return new ErrorMessageBuilder();
+    }
+
+    private ErrorMessageBuilder() {
+    }
+
+    public ErrorMessageBuilder errorSettingExpressionWithValue(String expr, Object value) {
+        appenExpression(expr);
+        if (value instanceof Object[]) {
+            appendValueAsArray((Object[]) value, message);
+        } else {
+            appendValue(value);
+        }
+        return this;
+    }
+
+    private void appenExpression(String expr) {
+        message.append("Error setting expression '");
+        message.append(expr);
+        message.append("' with value ");
+    }
+
+    private void appendValue(Object value) {
+        message.append("'");
+        message.append(value);
+        message.append("'");
+    }
+
+    private void appendValueAsArray(Object[] valueArray, StringBuilder msg) {
+        msg.append("[");
+        for (int index = 0; index < valueArray.length; index++) {
+            appendValue(valueArray[index]);
+            if (hasMoreElements(valueArray, index)) {
+                msg.append(", ");
+            }
+        }
+        msg.append("]");
+    }
+
+    private boolean hasMoreElements(Object[] valueArray, int index) {
+        return index < (valueArray.length + 1);
+    }
+
+    public String build() {
+        return message.toString();
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/ObjectProxy.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/ObjectProxy.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/ObjectProxy.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/ObjectProxy.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2002-2006,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.struts2.xwork2.ognl;
+
+/**
+ * An Object to use within OGNL to proxy other Objects
+ * usually Collections that you set in a different place
+ * on the ValueStack but want to retain the context information
+ * about where they previously were.
+ *
+ * @author Gabe
+ */
+public class ObjectProxy {
+    private Object value;
+    private Class lastClassAccessed;
+    private String lastPropertyAccessed;
+
+    public Class getLastClassAccessed() {
+        return lastClassAccessed;
+    }
+
+    public void setLastClassAccessed(Class lastClassAccessed) {
+        this.lastClassAccessed = lastClassAccessed;
+    }
+
+    public String getLastPropertyAccessed() {
+        return lastPropertyAccessed;
+    }
+
+    public void setLastPropertyAccessed(String lastPropertyAccessed) {
+        this.lastPropertyAccessed = lastPropertyAccessed;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlNullHandlerWrapper.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlNullHandlerWrapper.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlNullHandlerWrapper.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlNullHandlerWrapper.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,24 @@
+package org.apache.struts2.xwork2.ognl;
+
+import org.apache.struts2.xwork2.conversion.NullHandler;
+
+import java.util.Map;
+
+public class OgnlNullHandlerWrapper implements ognl.NullHandler {
+
+    private NullHandler wrapped;
+    
+    public OgnlNullHandlerWrapper(NullHandler target) {
+        this.wrapped = target;
+    }
+    
+    public Object nullMethodResult(Map context, Object target,
+            String methodName, Object[] args) {
+        return wrapped.nullMethodResult(context, target, methodName, args);
+    }
+
+    public Object nullPropertyValue(Map context, Object target, Object property) {
+        return wrapped.nullPropertyValue(context, target, property);
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlReflectionContextFactory.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlReflectionContextFactory.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlReflectionContextFactory.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlReflectionContextFactory.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,14 @@
+package org.apache.struts2.xwork2.ognl;
+
+import org.apache.struts2.xwork2.util.reflection.ReflectionContextFactory;
+import ognl.Ognl;
+
+import java.util.Map;
+
+public class OgnlReflectionContextFactory implements ReflectionContextFactory {
+
+    public Map createDefaultContext(Object root) {
+        return Ognl.createDefaultContext(root);
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlReflectionProvider.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlReflectionProvider.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlReflectionProvider.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlReflectionProvider.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,126 @@
+package org.apache.struts2.xwork2.ognl;
+
+import org.apache.struts2.xwork2.inject.Inject;
+import org.apache.struts2.xwork2.util.reflection.ReflectionException;
+import org.apache.struts2.xwork2.util.reflection.ReflectionProvider;
+import ognl.Ognl;
+import ognl.OgnlException;
+import ognl.OgnlRuntime;
+
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Map;
+
+public class OgnlReflectionProvider implements ReflectionProvider {
+    
+    private OgnlUtil ognlUtil;
+    
+    @Inject
+    public void setOgnlUtil(OgnlUtil ognlUtil) {
+        this.ognlUtil = ognlUtil;
+    }
+
+    public Field getField(Class inClass, String name) {
+        return OgnlRuntime.getField(inClass, name);
+    }
+
+    public Method getGetMethod(Class targetClass, String propertyName)
+            throws IntrospectionException, ReflectionException {
+        try {
+            return OgnlRuntime.getGetMethod(null, targetClass, propertyName);
+        } catch (OgnlException e) {
+            throw new ReflectionException(e);
+        }
+    }
+
+    public Method getSetMethod(Class targetClass, String propertyName)
+            throws IntrospectionException, ReflectionException {
+        try {
+            return OgnlRuntime.getSetMethod(null, targetClass, propertyName);
+        } catch (OgnlException e) {
+            throw new ReflectionException(e);
+        }
+    }
+
+    public void setProperties(Map<String, String> props, Object o, Map<String, Object> context) {
+        ognlUtil.setProperties(props, o, context);
+    }
+
+    public void setProperties(Map<String, String> props, Object o, Map<String, Object> context,
+            boolean throwPropertyExceptions) throws ReflectionException{
+        ognlUtil.setProperties(props, o, context, throwPropertyExceptions);
+        
+    }
+
+    public void setProperties(Map<String, String> properties, Object o) {
+        ognlUtil.setProperties(properties, o);
+    }
+
+    public PropertyDescriptor getPropertyDescriptor(Class targetClass,
+            String propertyName) throws IntrospectionException,
+            ReflectionException {
+        try {
+            return OgnlRuntime.getPropertyDescriptor(targetClass, propertyName);
+        } catch (OgnlException e) {
+            throw new ReflectionException(e);
+        }
+    }
+
+    public void copy(Object from, Object to, Map<String, Object> context,
+            Collection<String> exclusions, Collection<String> inclusions) {
+        ognlUtil.copy(from, to, context, exclusions, inclusions);
+    }
+
+    public Object getRealTarget(String property, Map<String, Object> context, Object root)
+            throws ReflectionException {
+        try {
+            return ognlUtil.getRealTarget(property, context, root);
+        } catch (OgnlException e) {
+            throw new ReflectionException(e);
+        }
+    }
+
+    public void setProperty(String name, Object value, Object o, Map<String, Object> context) {
+        ognlUtil.setProperty(name, value, o, context);
+    }
+
+    public void setProperty(String name, Object value, Object o, Map<String, Object> context, boolean throwPropertyExceptions) {
+        ognlUtil.setProperty(name, value, o, context, throwPropertyExceptions);
+    }
+
+    public Map getBeanMap(Object source) throws IntrospectionException,
+            ReflectionException {
+        try {
+            return ognlUtil.getBeanMap(source);
+        } catch (OgnlException e) {
+            throw new ReflectionException(e);
+        }
+    }
+
+    public Object getValue(String expression, Map<String, Object> context, Object root)
+            throws ReflectionException {
+        try {
+            return ognlUtil.getValue(expression, context, root);
+        } catch (OgnlException e) {
+            throw new ReflectionException(e);
+        }
+    }
+
+    public void setValue(String expression, Map<String, Object> context, Object root,
+            Object value) throws ReflectionException {
+        try {
+            Ognl.setValue(expression, context, root, value);
+        } catch (OgnlException e) {
+            throw new ReflectionException(e);
+        }
+    }
+
+    public PropertyDescriptor[] getPropertyDescriptors(Object source)
+            throws IntrospectionException {
+        return ognlUtil.getPropertyDescriptors(source);
+    }
+
+}

Added: struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlTypeConverterWrapper.java
URL: http://svn.apache.org/viewvc/struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlTypeConverterWrapper.java?rev=1209569&view=auto
==============================================================================
--- struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlTypeConverterWrapper.java (added)
+++ struts/struts2/branches/STRUTS_3_X/xwork-core/src/main/java/org/apache/struts2/xwork2/ognl/OgnlTypeConverterWrapper.java Fri Dec  2 16:33:03 2011
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2002-2007,2009 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.xwork2.ognl;
+
+import org.apache.struts2.xwork2.conversion.TypeConverter;
+
+import java.lang.reflect.Member;
+import java.util.Map;
+
+/**
+ * Wraps an XWork type conversion class for as an OGNL TypeConverter
+ */
+public class OgnlTypeConverterWrapper implements ognl.TypeConverter {
+
+    private TypeConverter typeConverter;
+    
+    public OgnlTypeConverterWrapper(TypeConverter conv) {
+        if (conv == null) {
+            throw new IllegalArgumentException("Wrapped type converter cannot be null");
+        }
+        this.typeConverter = conv;
+    }
+    
+    public Object convertValue(Map context, Object target, Member member,
+            String propertyName, Object value, Class toType) {
+        return typeConverter.convertValue(context, target, member, propertyName, value, toType);
+    }
+    
+    public TypeConverter getTarget() {
+        return typeConverter;
+    }
+}