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 2015/06/17 23:09:05 UTC
[05/57] [partial] struts git commit: Merges xwork packages into struts
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java
deleted file mode 100644
index 8496610..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParametersInterceptor.java
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * 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 com.opensymphony.xwork2.interceptor;
-
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.ValidationAware;
-import com.opensymphony.xwork2.XWorkConstants;
-import com.opensymphony.xwork2.conversion.impl.InstantiatingNullHandler;
-import com.opensymphony.xwork2.conversion.impl.XWorkConverter;
-import com.opensymphony.xwork2.inject.Inject;
-import com.opensymphony.xwork2.security.AcceptedPatternsChecker;
-import com.opensymphony.xwork2.security.ExcludedPatternsChecker;
-import com.opensymphony.xwork2.util.*;
-import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.TreeMap;
-
-
-/**
- * <!-- START SNIPPET: description -->
- * This interceptor sets all parameters on the value stack.
- *
- * This interceptor gets all parameters from {@link ActionContext#getParameters()} and sets them on the value stack by
- * calling {@link ValueStack#setValue(String, Object)}, typically resulting in the values submitted in a form
- * request being applied to an action in the value stack. Note that the parameter map must contain a String key and
- * often containers a String[] for the value.
- *
- * The interceptor takes one parameter named 'ordered'. When set to true action properties are guaranteed to be
- * set top-down which means that top action's properties are set first. Then it's subcomponents properties are set.
- * The reason for this order is to enable a 'factory' pattern. For example, let's assume that one has an action
- * that contains a property named 'modelClass' that allows to choose what is the underlying implementation of model.
- * By assuring that modelClass property is set before any model properties are set, it's possible to choose model
- * implementation during action.setModelClass() call. Similiarily it's possible to use action.setPrimaryKey()
- * property set call to actually load the model class from persistent storage. Without any assumption on parameter
- * order you have to use patterns like 'Preparable'.
- *
- * Because parameter names are effectively OGNL statements, it is important that security be taken in to account.
- * This interceptor will not apply any values in the parameters map if the expression contains an assignment (=),
- * multiple expressions (,), or references any objects in the context (#). This is all done in the {@link
- * #acceptableName(String)} method. In addition to this method, if the action being invoked implements the {@link
- * ParameterNameAware} interface, the action will be consulted to determine if the parameter should be set.
- *
- * In addition to these restrictions, a flag ({@link ReflectionContextState#DENY_METHOD_EXECUTION}) is set such that
- * no methods are allowed to be invoked. That means that any expression such as <i>person.doSomething()</i> or
- * <i>person.getName()</i> will be explicitely forbidden. This is needed to make sure that your application is not
- * exposed to attacks by malicious users.
- *
- * While this interceptor is being invoked, a flag ({@link ReflectionContextState#CREATE_NULL_OBJECTS}) is turned
- * on to ensure that any null reference is automatically created - if possible. See the type conversion documentation
- * and the {@link InstantiatingNullHandler} javadocs for more information.
- *
- * Finally, a third flag ({@link XWorkConverter#REPORT_CONVERSION_ERRORS}) is set that indicates any errors when
- * converting the the values to their final data type (String[] -> int) an unrecoverable error occured. With this
- * flag set, the type conversion errors will be reported in the action context. See the type conversion documentation
- * and the {@link XWorkConverter} javadocs for more information.
- *
- * If you are looking for detailed logging information about your parameters, turn on DEBUG level logging for this
- * interceptor. A detailed log of all the parameter keys and values will be reported.
- *
- * <b>Note:</b> Since XWork 2.0.2, this interceptor extends {@link MethodFilterInterceptor}, therefore being
- * able to deal with excludeMethods / includeMethods parameters. See [Workflow Interceptor]
- * (class {@link DefaultWorkflowInterceptor}) for documentation and examples on how to use this feature.
- * <!-- END SNIPPET: description -->
- *
- * <u>Interceptor parameters:</u>
- *
- * <!-- START SNIPPET: parameters -->
- *
- * <ul>
- * <li>ordered - set to true if you want the top-down property setter behaviour</li>
- * <li>acceptParamNames - a comma delimited list of regular expressions to describe a whitelist of accepted parameter names.
- * Don't change the default unless you know what you are doing in terms of security implications</li>
- * <li>excludeParams - a comma delimited list of regular expressions to describe a blacklist of not allowed parameter names</li>
- * <li>paramNameMaxLength - the maximum length of parameter names; parameters with longer names will be ignored; the default is 100 characters</li>
- * </ul>
- *
- * <!-- END SNIPPET: parameters -->
- *
- * <u>Extending the interceptor:</u>
- *
- * <!-- START SNIPPET: extending -->
- *
- * The best way to add behavior to this interceptor is to utilize the {@link ParameterNameAware} interface in your
- * actions. However, if you wish to apply a global rule that isn't implemented in your action, then you could extend
- * this interceptor and override the {@link #acceptableName(String)} method.
- *
- * <!-- END SNIPPET: extending -->
- *
- *
- * <!-- START SNIPPET: extending-warning -->
- * Using {@link ParameterNameAware} could be dangerous as {@link ParameterNameAware#acceptableParameterName(String)} takes precedence
- * over ParametersInterceptor which means if ParametersInterceptor excluded given parameter name you can accept it with
- * {@link ParameterNameAware#acceptableParameterName(String)}.
- *
- * The best idea is to define very tight restrictions with ParametersInterceptor and relax them per action with
- * {@link ParameterNameAware#acceptableParameterName(String)}
- * <!-- END SNIPPET: extending-warning -->
- *
- *
- * <u>Example code:</u>
- *
- * <pre>
- * <!-- START SNIPPET: example -->
- * <action name="someAction" class="com.examples.SomeAction">
- * <interceptor-ref name="params"/>
- * <result name="success">good_result.ftl</result>
- * </action>
- * <!-- END SNIPPET: example -->
- * </pre>
- *
- * @author Patrick Lightbody
- */
-public class ParametersInterceptor extends MethodFilterInterceptor {
-
- private static final Logger LOG = LogManager.getLogger(ParametersInterceptor.class);
-
- protected static final int PARAM_NAME_MAX_LENGTH = 100;
-
- private int paramNameMaxLength = PARAM_NAME_MAX_LENGTH;
- private boolean devMode = false;
-
- protected boolean ordered = false;
-
- private ValueStackFactory valueStackFactory;
- private ExcludedPatternsChecker excludedPatterns;
- private AcceptedPatternsChecker acceptedPatterns;
-
- @Inject
- public void setValueStackFactory(ValueStackFactory valueStackFactory) {
- this.valueStackFactory = valueStackFactory;
- }
-
- @Inject(XWorkConstants.DEV_MODE)
- public void setDevMode(String mode) {
- this.devMode = BooleanUtils.toBoolean(mode);
- }
-
- @Inject
- public void setExcludedPatterns(ExcludedPatternsChecker excludedPatterns) {
- this.excludedPatterns = excludedPatterns;
- }
-
- @Inject
- public void setAcceptedPatterns(AcceptedPatternsChecker acceptedPatterns) {
- this.acceptedPatterns = acceptedPatterns;
- }
-
- /**
- * If the param name exceeds the configured maximum length it will not be
- * accepted.
- *
- * @param paramNameMaxLength Maximum length of param names
- */
- public void setParamNameMaxLength(int paramNameMaxLength) {
- this.paramNameMaxLength = paramNameMaxLength;
- }
-
- static private int countOGNLCharacters(String s) {
- int count = 0;
- for (int i = s.length() - 1; i >= 0; i--) {
- char c = s.charAt(i);
- if (c == '.' || c == '[') count++;
- }
- return count;
- }
-
- /**
- * Compares based on number of '.' and '[' characters (fewer is higher)
- */
- static final Comparator<String> rbCollator = new Comparator<String>() {
- public int compare(String s1, String s2) {
- int l1 = countOGNLCharacters(s1),
- l2 = countOGNLCharacters(s2);
- return l1 < l2 ? -1 : (l2 < l1 ? 1 : s1.compareTo(s2));
- }
-
- };
-
- @Override
- public String doIntercept(ActionInvocation invocation) throws Exception {
- Object action = invocation.getAction();
- if (!(action instanceof NoParameters)) {
- ActionContext ac = invocation.getInvocationContext();
- final Map<String, Object> parameters = retrieveParameters(ac);
-
- if (LOG.isDebugEnabled()) {
- LOG.debug("Setting params {}", getParameterLogMap(parameters));
- }
-
- if (parameters != null) {
- Map<String, Object> contextMap = ac.getContextMap();
- try {
- ReflectionContextState.setCreatingNullObjects(contextMap, true);
- ReflectionContextState.setDenyMethodExecution(contextMap, true);
- ReflectionContextState.setReportingConversionErrors(contextMap, true);
-
- ValueStack stack = ac.getValueStack();
- setParameters(action, stack, parameters);
- } finally {
- ReflectionContextState.setCreatingNullObjects(contextMap, false);
- ReflectionContextState.setDenyMethodExecution(contextMap, false);
- ReflectionContextState.setReportingConversionErrors(contextMap, false);
- }
- }
- }
- return invocation.invoke();
- }
-
- /**
- * Gets the parameter map to apply from wherever appropriate
- *
- * @param ac The action context
- * @return The parameter map to apply
- */
- protected Map<String, Object> retrieveParameters(ActionContext ac) {
- return ac.getParameters();
- }
-
-
- /**
- * Adds the parameters into context's ParameterMap
- *
- * @param ac The action context
- * @param newParams The parameter map to apply
- * <p/>
- * In this class this is a no-op, since the parameters were fetched from the same location.
- * In subclasses both retrieveParameters() and addParametersToContext() should be overridden.
- */
- protected void addParametersToContext(ActionContext ac, Map<String, Object> newParams) {
- }
-
- protected void setParameters(final Object action, ValueStack stack, final Map<String, Object> parameters) {
- Map<String, Object> params;
- Map<String, Object> acceptableParameters;
- if (ordered) {
- params = new TreeMap<>(getOrderedComparator());
- acceptableParameters = new TreeMap<>(getOrderedComparator());
- params.putAll(parameters);
- } else {
- params = new TreeMap<>(parameters);
- acceptableParameters = new TreeMap<>();
- }
-
- for (Map.Entry<String, Object> entry : params.entrySet()) {
- String name = entry.getKey();
- Object value = entry.getValue();
- if (isAcceptableParameter(name, action) && isAcceptableValue(value)) {
- acceptableParameters.put(name, entry.getValue());
- }
- }
-
- ValueStack newStack = valueStackFactory.createValueStack(stack);
- boolean clearableStack = newStack instanceof ClearableValueStack;
- if (clearableStack) {
- //if the stack's context can be cleared, do that to prevent OGNL
- //from having access to objects in the stack, see XW-641
- ((ClearableValueStack)newStack).clearContextValues();
- Map<String, Object> context = newStack.getContext();
- ReflectionContextState.setCreatingNullObjects(context, true);
- ReflectionContextState.setDenyMethodExecution(context, true);
- ReflectionContextState.setReportingConversionErrors(context, true);
-
- //keep locale from original context
- context.put(ActionContext.LOCALE, stack.getContext().get(ActionContext.LOCALE));
- }
-
- boolean memberAccessStack = newStack instanceof MemberAccessValueStack;
- if (memberAccessStack) {
- //block or allow access to properties
- //see WW-2761 for more details
- MemberAccessValueStack accessValueStack = (MemberAccessValueStack) newStack;
- accessValueStack.setAcceptProperties(acceptedPatterns.getAcceptedPatterns());
- accessValueStack.setExcludeProperties(excludedPatterns.getExcludedPatterns());
- }
-
- for (Map.Entry<String, Object> entry : acceptableParameters.entrySet()) {
- String name = entry.getKey();
- Object value = entry.getValue();
- try {
- newStack.setParameter(name, value);
- } catch (RuntimeException e) {
- if (devMode) {
- notifyDeveloperParameterException(action, name, e.getMessage());
- }
- }
- }
-
- if (clearableStack && (stack.getContext() != null) && (newStack.getContext() != null))
- stack.getContext().put(ActionContext.CONVERSION_ERRORS, newStack.getContext().get(ActionContext.CONVERSION_ERRORS));
-
- addParametersToContext(ActionContext.getContext(), acceptableParameters);
- }
-
- protected void notifyDeveloperParameterException(Object action, String property, String message) {
- String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification",
- ActionContext.getContext().getLocale(), "Developer Notification:\n{0}",
- new Object[]{
- "Unexpected Exception caught setting '" + property + "' on '" + action.getClass() + ": " + message
- }
- );
- LOG.error(developerNotification);
- // see https://issues.apache.org/jira/browse/WW-4066
- if (action instanceof ValidationAware) {
- Collection<String> messages = ((ValidationAware) action).getActionMessages();
- messages.add(message);
- ((ValidationAware) action).setActionMessages(messages);
- }
- }
-
- /**
- * Checks if name of parameter can be accepted or thrown away
- *
- * @param name parameter name
- * @param action current action
- * @return true if parameter is accepted
- */
- protected boolean isAcceptableParameter(String name, Object action) {
- ParameterNameAware parameterNameAware = (action instanceof ParameterNameAware) ? (ParameterNameAware) action : null;
- return acceptableName(name) && (parameterNameAware == null || parameterNameAware.acceptableParameterName(name));
- }
-
- /**
- * Checks if given value doesn't match global excluded patterns to avoid passing malicious code
- *
- * @param value incoming parameter's value
- * @return true if value is safe
- *
- * FIXME: can be removed when parameters won't be represented as simple Strings
- */
- protected boolean isAcceptableValue(Object value) {
- if (value == null) {
- return true;
- }
- Object[] values;
- if (value.getClass().isArray()) {
- values = (Object[]) value;
- } else {
- values = new Object[] { value };
- }
- boolean result = true;
- for (Object obj : values) {
- if (isExcluded(String.valueOf(obj))) {
- result = false;
- }
- }
- return result;
- }
-
- /**
- * Gets an instance of the comparator to use for the ordered sorting. Override this
- * method to customize the ordering of the parameters as they are set to the
- * action.
- *
- * @return A comparator to sort the parameters
- */
- protected Comparator<String> getOrderedComparator() {
- return rbCollator;
- }
-
- protected String getParameterLogMap(Map<String, Object> parameters) {
- if (parameters == null) {
- return "NONE";
- }
-
- StringBuilder logEntry = new StringBuilder();
- for (Map.Entry entry : parameters.entrySet()) {
- logEntry.append(String.valueOf(entry.getKey()));
- logEntry.append(" => ");
- if (entry.getValue() instanceof Object[]) {
- Object[] valueArray = (Object[]) entry.getValue();
- logEntry.append("[ ");
- if (valueArray.length > 0 ) {
- for (int indexA = 0; indexA < (valueArray.length - 1); indexA++) {
- Object valueAtIndex = valueArray[indexA];
- logEntry.append(String.valueOf(valueAtIndex));
- logEntry.append(", ");
- }
- logEntry.append(String.valueOf(valueArray[valueArray.length - 1]));
- }
- logEntry.append(" ] ");
- } else {
- logEntry.append(String.valueOf(entry.getValue()));
- }
- }
-
- return logEntry.toString();
- }
-
- protected boolean acceptableName(String name) {
- boolean accepted = isWithinLengthLimit(name) && !isExcluded(name) && isAccepted(name);
- if (devMode && accepted) { // notify only when in devMode
- LOG.debug("Parameter [{}] was accepted and will be appended to action!", name);
- }
- return accepted;
- }
-
- protected boolean isWithinLengthLimit( String name ) {
- boolean matchLength = name.length() <= paramNameMaxLength;
- if (!matchLength) {
- notifyDeveloper("Parameter [{}] is too long, allowed length is [{}]", name, String.valueOf(paramNameMaxLength));
- }
- return matchLength;
- }
-
- protected boolean isAccepted(String paramName) {
- AcceptedPatternsChecker.IsAccepted result = acceptedPatterns.isAccepted(paramName);
- if (result.isAccepted()) {
- return true;
- }
- notifyDeveloper("Parameter [{}] didn't match accepted pattern [{}]!", paramName, result.getAcceptedPattern());
- return false;
- }
-
- protected boolean isExcluded(String paramName) {
- ExcludedPatternsChecker.IsExcluded result = excludedPatterns.isExcluded(paramName);
- if (result.isExcluded()) {
- notifyDeveloper("Parameter [{}] matches excluded pattern [{}]!", paramName, result.getExcludedPattern());
- return true;
- }
- return false;
- }
-
- private void notifyDeveloper(String message, String... parameters) {
- if (devMode) {
- LOG.warn(message, parameters);
- } else {
- LOG.debug(message, parameters);
- }
- }
-
- /**
- * Whether to order the parameters or not
- *
- * @return True to order
- */
- public boolean isOrdered() {
- return ordered;
- }
-
- /**
- * Set whether to order the parameters by object depth or not
- *
- * @param ordered True to order them
- */
- public void setOrdered(boolean ordered) {
- this.ordered = ordered;
- }
-
- /**
- * Sets a comma-delimited list of regular expressions to match
- * parameters that are allowed in the parameter map (aka whitelist).
- * <p/>
- * Don't change the default unless you know what you are doing in terms
- * of security implications.
- *
- * @param commaDelim A comma-delimited list of regular expressions
- */
- public void setAcceptParamNames(String commaDelim) {
- acceptedPatterns.setAcceptedPatterns(commaDelim);
- }
-
- /**
- * Sets a comma-delimited list of regular expressions to match
- * parameters that should be removed from the parameter map.
- *
- * @param commaDelim A comma-delimited list of regular expressions
- */
- public void setExcludeParams(String commaDelim) {
- excludedPatterns.setExcludedPatterns(commaDelim);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PreResultListener.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PreResultListener.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PreResultListener.java
deleted file mode 100644
index 12643a3..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PreResultListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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 com.opensymphony.xwork2.interceptor;
-
-import com.opensymphony.xwork2.ActionInvocation;
-
-
-/**
- * PreResultListeners may be registered with an {@link ActionInvocation} to get a callback after the
- * {@link com.opensymphony.xwork2.Action} has been executed but before the {@link com.opensymphony.xwork2.Result}
- * is executed.
- *
- * @author Jason Carreira
- */
-public interface PreResultListener {
-
- /**
- * This callback method will be called after the {@link com.opensymphony.xwork2.Action} execution and
- * before the {@link com.opensymphony.xwork2.Result} execution.
- *
- * @param invocation the action invocation
- * @param resultCode the result code returned by the action (eg. <code>success</code>).
- */
- void beforeResult(ActionInvocation invocation, String resultCode);
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtil.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtil.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtil.java
deleted file mode 100644
index 5a6e5a1..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtil.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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 com.opensymphony.xwork2.interceptor;
-
-import com.opensymphony.xwork2.ActionInvocation;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * A utility class for invoking prefixed methods in action class.
- *
- * Interceptors that made use of this class are:
- * <ul>
- * <li>DefaultWorkflowInterceptor</li>
- * <li>PrepareInterceptor</li>
- * </ul>
- *
- * <p/>
- *
- * <!-- START SNIPPET: javadocDefaultWorkflowInterceptor -->
- *
- * <b>In DefaultWorkflowInterceptor</b>
- * <p>applies only when action implements {@link com.opensymphony.xwork2.Validateable}</p>
- * <ol>
- * <li>if the action class have validate{MethodName}(), it will be invoked</li>
- * <li>else if the action class have validateDo{MethodName}(), it will be invoked</li>
- * <li>no matter if 1] or 2] is performed, if alwaysInvokeValidate property of the interceptor is "true" (which is by default "true"), validate() will be invoked.</li>
- * </ol>
- *
- * <!-- END SNIPPET: javadocDefaultWorkflowInterceptor -->
- *
- *
- * <!-- START SNIPPET: javadocPrepareInterceptor -->
- *
- * <b>In PrepareInterceptor</b>
- * <p>Applies only when action implements Preparable</p>
- * <ol>
- * <li>if the action class have prepare{MethodName}(), it will be invoked</li>
- * <li>else if the action class have prepareDo(MethodName()}(), it will be invoked</li>
- * <li>no matter if 1] or 2] is performed, if alwaysinvokePrepare property of the interceptor is "true" (which is by default "true"), prepare() will be invoked.</li>
- * </ol>
- *
- * <!-- END SNIPPET: javadocPrepareInterceptor -->
- *
- * @author Philip Luppens
- * @author tm_jee
- */
-public class PrefixMethodInvocationUtil {
-
- private static final Logger LOG = LogManager.getLogger(PrefixMethodInvocationUtil.class);
-
- private static final String DEFAULT_INVOCATION_METHODNAME = "execute";
-
- private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
-
- /**
- * This method will prefix <code>actionInvocation</code>'s <code>ActionProxy</code>'s
- * <code>method</code> with <code>prefixes</code> before invoking the prefixed method.
- * Order of the <code>prefixes</code> is important, as this method will return once
- * a prefixed method is found in the action class.
- *
- * <p/>
- *
- * For example, with
- * <pre>
- * invokePrefixMethod(actionInvocation, new String[] { "prepare", "prepareDo" });
- * </pre>
- *
- * Assuming <code>actionInvocation.getProxy(),getMethod()</code> returns "submit",
- * the order of invocation would be as follows:-
- * <ol>
- * <li>prepareSubmit()</li>
- * <li>prepareDoSubmit()</li>
- * </ol>
- *
- * If <code>prepareSubmit()</code> exists, it will be invoked and this method
- * will return, <code>prepareDoSubmit()</code> will NOT be invoked.
- *
- * <p/>
- *
- * On the other hand, if <code>prepareDoSubmit()</code> does not exists, and
- * <code>prepareDoSubmit()</code> exists, it will be invoked.
- *
- * <p/>
- *
- * If none of those two methods exists, nothing will be invoked.
- *
- * @param actionInvocation the action invocation
- * @param prefixes prefixes for method names
- * @throws InvocationTargetException is thrown if invocation of a method failed.
- * @throws IllegalAccessException is thrown if invocation of a method failed.
- */
- public static void invokePrefixMethod(ActionInvocation actionInvocation, String[] prefixes) throws InvocationTargetException, IllegalAccessException {
- Object action = actionInvocation.getAction();
-
- String methodName = actionInvocation.getProxy().getMethod();
-
- if (methodName == null) {
- // if null returns (possible according to the docs), use the default execute
- methodName = DEFAULT_INVOCATION_METHODNAME;
- }
-
- Method method = getPrefixedMethod(prefixes, methodName, action);
- if (method != null) {
- method.invoke(action, new Object[0]);
- }
- }
-
-
- /**
- * This method returns a {@link Method} in <code>action</code>. The method
- * returned is found by searching for method in <code>action</code> whose method name
- * is equals to the result of appending each <code>prefixes</code>
- * to <code>methodName</code>. Only the first method found will be returned, hence
- * the order of <code>prefixes</code> is important. If none is found this method
- * will return null.
- *
- * @param prefixes the prefixes to prefix the <code>methodName</code>
- * @param methodName the method name to be prefixed with <code>prefixes</code>
- * @param action the action class of which the prefixed method is to be search for.
- * @return a {@link Method} if one is found, else <tt>null</tt>.
- */
- public static Method getPrefixedMethod(String[] prefixes, String methodName, Object action) {
- assert(prefixes != null);
- String capitalizedMethodName = capitalizeMethodName(methodName);
- for (String prefixe : prefixes) {
- String prefixedMethodName = prefixe + capitalizedMethodName;
- try {
- return action.getClass().getMethod(prefixedMethodName, EMPTY_CLASS_ARRAY);
- }
- catch (NoSuchMethodException e) {
- // hmm -- OK, try next prefix
- LOG.debug("Cannot find method [{}] in action [{}]", prefixedMethodName, action);
- }
- }
- return null;
- }
-
- /**
- * This method capitalized the first character of <code>methodName</code>.
- * <br/>
- * eg. <code>capitalizeMethodName("someMethod");</code> will return <code>"SomeMethod"</code>.
- *
- * @param methodName the method name
- * @return capitalized method name
- */
- public static String capitalizeMethodName(String methodName) {
- assert(methodName != null);
- return methodName.substring(0, 1).toUpperCase() + methodName.substring(1);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java
deleted file mode 100644
index 6a327c3..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/PrepareInterceptor.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * $Id$
- * 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 com.opensymphony.xwork2.interceptor;
-
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.Preparable;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
-
-import java.lang.reflect.InvocationTargetException;
-
-
-/**
- * <!-- START SNIPPET: description -->
- *
- * This interceptor calls <code>prepare()</code> on actions which implement
- * {@link Preparable}. This interceptor is very useful for any situation where
- * you need to ensure some logic runs before the actual execute method runs.
- *
- * <p/> A typical use of this is to run some logic to load an object from the
- * database so that when parameters are set they can be set on this object. For
- * example, suppose you have a User object with two properties: <i>id</i> and
- * <i>name</i>. Provided that the params interceptor is called twice (once
- * before and once after this interceptor), you can load the User object using
- * the id property, and then when the second params interceptor is called the
- * parameter <i>user.name</i> will be set, as desired, on the actual object
- * loaded from the database. See the example for more info.
- *
- * <p/>
- * <b>Note:</b> Since XWork 2.0.2, this interceptor extends {@link MethodFilterInterceptor}, therefore being
- * able to deal with excludeMethods / includeMethods parameters. See [Workflow Interceptor]
- * (class {@link DefaultWorkflowInterceptor}) for documentation and examples on how to use this feature.
- *
- * <p/><b>Update</b>: Added logic to execute a prepare{MethodName} and conditionally
- * the a general prepare() Method, depending on the 'alwaysInvokePrepare' parameter/property
- * which is by default true. This allows us to run some logic based on the method
- * name we specify in the {@link com.opensymphony.xwork2.ActionProxy}. For example, you can specify a
- * prepareInput() method that will be run before the invocation of the input method.
- *
- * <!-- END SNIPPET: description -->
- *
- * <p/> <u>Interceptor parameters:</u>
- *
- * <!-- START SNIPPET: parameters -->
- *
- * <ul>
- *
- * <li>alwaysInvokePrepare - Default to true. If true, prepare will always be invoked,
- * otherwise it will not.</li>
- *
- * </ul>
- *
- * <!-- END SNIPPET: parameters -->
- *
- * <p/> <u>Extending the interceptor:</u>
- *
- * <p/>
- *
- * <!-- START SNIPPET: extending -->
- *
- * There are no known extension points to this interceptor.
- *
- * <!-- END SNIPPET: extending -->
- *
- * <p/> <u>Example code:</u>
- *
- * <pre>
- * <!-- START SNIPPET: example -->
- * <!-- Calls the params interceptor twice, allowing you to
- * pre-load data for the second time parameters are set -->
- * <action name="someAction" class="com.examples.SomeAction">
- * <interceptor-ref name="params"/>
- * <interceptor-ref name="prepare"/>
- * <interceptor-ref name="basicStack"/>
- * <result name="success">good_result.ftl</result>
- * </action>
- * <!-- END SNIPPET: example -->
- * </pre>
- *
- * @author Jason Carreira
- * @author Philip Luppens
- * @author tm_jee
- * @see com.opensymphony.xwork2.Preparable
- */
-public class PrepareInterceptor extends MethodFilterInterceptor {
-
- private static final long serialVersionUID = -5216969014510719786L;
-
- private final static String PREPARE_PREFIX = "prepare";
- private final static String ALT_PREPARE_PREFIX = "prepareDo";
-
- private boolean alwaysInvokePrepare = true;
- private boolean firstCallPrepareDo = false;
-
- /**
- * Sets if the <code>preapare</code> method should always be executed.
- * <p/>
- * Default is <tt>true</tt>.
- *
- * @param alwaysInvokePrepare if <code>prepare</code> should always be executed or not.
- */
- public void setAlwaysInvokePrepare(String alwaysInvokePrepare) {
- this.alwaysInvokePrepare = Boolean.parseBoolean(alwaysInvokePrepare);
- }
-
- /**
- * Sets if the <code>prepareDoXXX</code> method should be called first
- * <p/>
- * Default is <tt>false</tt> for backward compatibility
- *
- * @param firstCallPrepareDo if <code>prepareDoXXX</code> should be called first
- */
- public void setFirstCallPrepareDo(String firstCallPrepareDo) {
- this.firstCallPrepareDo = Boolean.parseBoolean(firstCallPrepareDo);
- }
-
- @Override
- public String doIntercept(ActionInvocation invocation) throws Exception {
- Object action = invocation.getAction();
-
- if (action instanceof Preparable) {
- try {
- String[] prefixes;
- if (firstCallPrepareDo) {
- prefixes = new String[] {ALT_PREPARE_PREFIX, PREPARE_PREFIX};
- } else {
- prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX};
- }
- PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);
- }
- catch (InvocationTargetException e) {
- /*
- * The invoked method threw an exception and reflection wrapped it
- * in an InvocationTargetException.
- * If possible re-throw the original exception so that normal
- * exception handling will take place.
- */
- Throwable cause = e.getCause();
- if (cause instanceof Exception) {
- throw (Exception) cause;
- } else if(cause instanceof Error) {
- throw (Error) cause;
- } else {
- /*
- * The cause is not an Exception or Error (must be Throwable) so
- * just re-throw the wrapped exception.
- */
- throw e;
- }
- }
-
- if (alwaysInvokePrepare) {
- ((Preparable) action).prepare();
- }
- }
-
- return invocation.invoke();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDriven.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDriven.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDriven.java
deleted file mode 100644
index e381373..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDriven.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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 com.opensymphony.xwork2.interceptor;
-
-import com.opensymphony.xwork2.ModelDriven;
-
-/**
- * Adds the ability to set a model, probably retrieved from a given state.
- */
-public interface ScopedModelDriven<T> extends ModelDriven<T> {
-
- /**
- * Sets the model
- */
- void setModel(T model);
-
- /**
- * Sets the key under which the model is stored
- * @param key The model key
- */
- void setScopeKey(String key);
-
- /**
- * Gets the key under which the model is stored
- */
- String getScopeKey();
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java
deleted file mode 100644
index 9d32fbe..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptor.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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 com.opensymphony.xwork2.interceptor;
-
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.ObjectFactory;
-import com.opensymphony.xwork2.XWorkException;
-import com.opensymphony.xwork2.config.entities.ActionConfig;
-import com.opensymphony.xwork2.inject.Inject;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-
-/**
- * <!-- START SNIPPET: description -->
- *
- * An interceptor that enables scoped model-driven actions.
- *
- * <p/>This interceptor only activates on actions that implement the {@link ScopedModelDriven} interface. If
- * detected, it will retrieve the model class from the configured scope, then provide it to the Action.
- *
- * <!-- END SNIPPET: description -->
- *
- * <p/> <u>Interceptor parameters:</u>
- *
- * <!-- START SNIPPET: parameters -->
- *
- * <ul>
- *
- * <li>className - The model class name. Defaults to the class name of the object returned by the getModel() method.</li>
- *
- * <li>name - The key to use when storing or retrieving the instance in a scope. Defaults to the model
- * class name.</li>
- *
- * <li>scope - The scope to store and retrieve the model. Defaults to 'request' but can also be 'session'.</li>
- * </ul>
- *
- * <!-- END SNIPPET: parameters -->
- *
- * <p/> <u>Extending the interceptor:</u>
- *
- * <p/>
- *
- * <!-- START SNIPPET: extending -->
- *
- * There are no known extension points for this interceptor.
- *
- * <!-- END SNIPPET: extending -->
- *
- * <p/> <u>Example code:</u>
- *
- * <pre>
- * <!-- START SNIPPET: example -->
- *
- * <-- Basic usage -->
- * <interceptor name="scopedModelDriven" class="com.opensymphony.interceptor.ScopedModelDrivenInterceptor" />
- *
- * <-- Using all available parameters -->
- * <interceptor name="gangsterForm" class="com.opensymphony.interceptor.ScopedModelDrivenInterceptor">
- * <param name="scope">session</param>
- * <param name="name">gangsterForm</param>
- * <param name="className">com.opensymphony.example.GangsterForm</param>
- * </interceptor>
- *
- * <!-- END SNIPPET: example -->
- * </pre>
- */
-public class ScopedModelDrivenInterceptor extends AbstractInterceptor {
-
- private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
-
- private static final String GET_MODEL = "getModel";
- private String scope;
- private String name;
- private String className;
- private ObjectFactory objectFactory;
-
- @Inject
- public void setObjectFactory(ObjectFactory factory) {
- this.objectFactory = factory;
- }
-
- protected Object resolveModel(ObjectFactory factory, ActionContext actionContext, String modelClassName, String modelScope, String modelName) throws Exception {
- Object model;
- Map<String, Object> scopeMap = actionContext.getContextMap();
- if ("session".equals(modelScope)) {
- scopeMap = actionContext.getSession();
- }
-
- model = scopeMap.get(modelName);
- if (model == null) {
- model = factory.buildBean(modelClassName, null);
- scopeMap.put(modelName, model);
- }
- return model;
- }
-
- @Override
- public String intercept(ActionInvocation invocation) throws Exception {
- Object action = invocation.getAction();
-
- if (action instanceof ScopedModelDriven) {
- ScopedModelDriven modelDriven = (ScopedModelDriven) action;
- if (modelDriven.getModel() == null) {
- ActionContext ctx = ActionContext.getContext();
- ActionConfig config = invocation.getProxy().getConfig();
-
- String cName = className;
- if (cName == null) {
- try {
- Method method = action.getClass().getMethod(GET_MODEL, EMPTY_CLASS_ARRAY);
- Class cls = method.getReturnType();
- cName = cls.getName();
- } catch (NoSuchMethodException e) {
- throw new XWorkException("The " + GET_MODEL + "() is not defined in action " + action.getClass() + "", config);
- }
- }
- String modelName = name;
- if (modelName == null) {
- modelName = cName;
- }
- Object model = resolveModel(objectFactory, ctx, cName, scope, modelName);
- modelDriven.setModel(model);
- modelDriven.setScopeKey(modelName);
- }
- }
- return invocation.invoke();
- }
-
- /**
- * @param className the className to set
- */
- public void setClassName(String className) {
- this.className = className;
- }
-
- /**
- * @param name the name to set
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * @param scope the scope to set
- */
- public void setScope(String scope) {
- this.scope = scope;
- }
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java
deleted file mode 100644
index 25fd8d6..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * 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 com.opensymphony.xwork2.interceptor;
-
-import com.opensymphony.xwork2.ActionContext;
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.ValidationAware;
-import com.opensymphony.xwork2.XWorkConstants;
-import com.opensymphony.xwork2.config.entities.ActionConfig;
-import com.opensymphony.xwork2.config.entities.Parameterizable;
-import com.opensymphony.xwork2.inject.Inject;
-import com.opensymphony.xwork2.util.*;
-import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.TreeMap;
-
-
-/**
- * <!-- START SNIPPET: description -->
- *
- * This interceptor populates the action with the static parameters defined in the action configuration. If the action
- * implements {@link Parameterizable}, a map of the static parameters will be also be passed directly to the action.
- * The static params will be added to the request params map, unless "merge" is set to false.
- *
- * <p/> Parameters are typically defined with <param> elements within xwork.xml.
- *
- * <!-- END SNIPPET: description -->
- *
- * <p/> <u>Interceptor parameters:</u>
- *
- * <!-- START SNIPPET: parameters -->
- *
- * <ul>
- *
- * <li>None</li>
- *
- * </ul>
- *
- * <!-- END SNIPPET: parameters -->
- *
- * <p/> <u>Extending the interceptor:</u>
- *
- * <!-- START SNIPPET: extending -->
- *
- * <p/>There are no extension points to this interceptor.
- *
- * <!-- END SNIPPET: extending -->
- *
- * <p/> <u>Example code:</u>
- *
- * <pre>
- * <!-- START SNIPPET: example -->
- * <action name="someAction" class="com.examples.SomeAction">
- * <interceptor-ref name="staticParams">
- * <param name="parse">true</param>
- * <param name="overwrite">false</param>
- * </interceptor-ref>
- * <result name="success">good_result.ftl</result>
- * </action>
- * <!-- END SNIPPET: example -->
- * </pre>
- *
- * @author Patrick Lightbody
- */
-public class StaticParametersInterceptor extends AbstractInterceptor {
-
- private boolean parse;
- private boolean overwrite;
- private boolean merge = true;
- private boolean devMode = false;
-
- private static final Logger LOG = LogManager.getLogger(StaticParametersInterceptor.class);
-
- private ValueStackFactory valueStackFactory;
-
- @Inject
- public void setValueStackFactory(ValueStackFactory valueStackFactory) {
- this.valueStackFactory = valueStackFactory;
- }
-
- @Inject(XWorkConstants.DEV_MODE)
- public void setDevMode(String mode) {
- devMode = BooleanUtils.toBoolean(mode);
- }
-
- public void setParse(String value) {
- this.parse = BooleanUtils.toBoolean(value);
- }
-
- public void setMerge(String value) {
- this.merge = BooleanUtils.toBoolean(value);
- }
-
- /**
- * Overwrites already existing parameters from other sources.
- * Static parameters are the successor over previously set parameters, if true.
- *
- * @param value
- */
- public void setOverwrite(String value) {
- this.overwrite = BooleanUtils.toBoolean(value);
- }
-
- @Override
- public String intercept(ActionInvocation invocation) throws Exception {
- ActionConfig config = invocation.getProxy().getConfig();
- Object action = invocation.getAction();
-
- final Map<String, String> parameters = config.getParams();
-
- LOG.debug("Setting static parameters: {}", parameters);
-
- // for actions marked as Parameterizable, pass the static parameters directly
- if (action instanceof Parameterizable) {
- ((Parameterizable) action).setParams(parameters);
- }
-
- if (parameters != null) {
- ActionContext ac = ActionContext.getContext();
- Map<String, Object> contextMap = ac.getContextMap();
- try {
- ReflectionContextState.setCreatingNullObjects(contextMap, true);
- ReflectionContextState.setReportingConversionErrors(contextMap, true);
- final ValueStack stack = ac.getValueStack();
-
- ValueStack newStack = valueStackFactory.createValueStack(stack);
- boolean clearableStack = newStack instanceof ClearableValueStack;
- if (clearableStack) {
- //if the stack's context can be cleared, do that to prevent OGNL
- //from having access to objects in the stack, see XW-641
- ((ClearableValueStack)newStack).clearContextValues();
- Map<String, Object> context = newStack.getContext();
- ReflectionContextState.setCreatingNullObjects(context, true);
- ReflectionContextState.setDenyMethodExecution(context, true);
- ReflectionContextState.setReportingConversionErrors(context, true);
-
- //keep locale from original context
- context.put(ActionContext.LOCALE, stack.getContext().get(ActionContext.LOCALE));
- }
-
- for (Map.Entry<String, String> entry : parameters.entrySet()) {
- Object val = entry.getValue();
- if (parse && val instanceof String) {
- val = TextParseUtil.translateVariables(val.toString(), stack);
- }
- try {
- newStack.setValue(entry.getKey(), val);
- } catch (RuntimeException e) {
- if (devMode) {
- String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{
- "Unexpected Exception caught setting '" + entry.getKey() + "' on '" + action.getClass() + ": " + e.getMessage()
- });
- LOG.error(developerNotification);
- if (action instanceof ValidationAware) {
- ((ValidationAware) action).addActionMessage(developerNotification);
- }
- }
- }
- }
-
- if (clearableStack && (stack.getContext() != null) && (newStack.getContext() != null))
- stack.getContext().put(ActionContext.CONVERSION_ERRORS, newStack.getContext().get(ActionContext.CONVERSION_ERRORS));
-
- if (merge)
- addParametersToContext(ac, parameters);
- } finally {
- ReflectionContextState.setCreatingNullObjects(contextMap, false);
- ReflectionContextState.setReportingConversionErrors(contextMap, false);
- }
- }
- return invocation.invoke();
- }
-
-
- /**
- * @param ac The action context
- * @return the parameters from the action mapping in the context. If none found, returns
- * an empty map.
- */
- protected Map<String, String> retrieveParameters(ActionContext ac) {
- ActionConfig config = ac.getActionInvocation().getProxy().getConfig();
- if (config != null) {
- return config.getParams();
- } else {
- return Collections.emptyMap();
- }
- }
-
- /**
- * Adds the parameters into context's ParameterMap.
- * As default, static parameters will not overwrite existing paramaters from other sources.
- * If you want the static parameters as successor over already existing parameters, set overwrite to <tt>true</tt>.
- *
- * @param ac The action context
- * @param newParams The parameter map to apply
- */
- protected void addParametersToContext(ActionContext ac, Map<String, ?> newParams) {
- Map<String, Object> previousParams = ac.getParameters();
-
- Map<String, Object> combinedParams;
- if ( overwrite ) {
- if (previousParams != null) {
- combinedParams = new TreeMap<>(previousParams);
- } else {
- combinedParams = new TreeMap<>();
- }
- if ( newParams != null) {
- combinedParams.putAll(newParams);
- }
- } else {
- if (newParams != null) {
- combinedParams = new TreeMap<>(newParams);
- } else {
- combinedParams = new TreeMap<>();
- }
- if ( previousParams != null) {
- combinedParams.putAll(previousParams);
- }
- }
- ac.setParameters(combinedParams);
- }
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/TimerInterceptor.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/TimerInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/TimerInterceptor.java
deleted file mode 100644
index 7cc4918..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/TimerInterceptor.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * 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 com.opensymphony.xwork2.interceptor;
-
-import com.opensymphony.xwork2.ActionInvocation;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- * <!-- 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>com.opensymphony.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 -->
- * <!-- records only the action's execution time -->
- * <action name="someAction" class="com.examples.SomeAction">
- * <interceptor-ref name="completeStack"/>
- * <interceptor-ref name="timer"/>
- * <result name="success">good_result.ftl</result>
- * </action>
- *
- * <!-- records action's execution time as well as other interceptors-->
- * <action name="someAction" class="com.examples.SomeAction">
- * <interceptor-ref name="timer"/>
- * <interceptor-ref name="completeStack"/>
- * <result name="success">good_result.ftl</result>
- * </action>
- * <!-- END SNIPPET: example -->
- * </pre>
- *
- * This second example uses our own log category at debug level.
- *
- * <pre>
- * <!-- START SNIPPET: example2 -->
- * <!-- records only the action's execution time -->
- * <action name="someAction" class="com.examples.SomeAction">
- * <interceptor-ref name="completeStack"/>
- * <interceptor-ref name="timer">
- * <param name="logLevel">debug</param>
- * <param name="logCategory">com.mycompany.myapp.actiontime</param>
- * <interceptor-ref/>
- * <result name="success">good_result.ftl</result>
- * </action>
- *
- * <!-- records action's execution time as well as other interceptors-->
- * <action name="someAction" class="com.examples.SomeAction">
- * <interceptor-ref name="timer"/>
- * <interceptor-ref name="completeStack"/>
- * <result name="success">good_result.ftl</result>
- * </action>
- * <!-- END SNIPPET: example2 -->
- * </pre>
- *
- * @author Jason Carreira
- * @author Claus Ibsen
- */
-public class TimerInterceptor extends AbstractInterceptor {
- protected static final Logger LOG = LogManager.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 (StringUtils.isNotBlank(namespace)) {
- 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 = LogManager.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");
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationErrorAware.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationErrorAware.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationErrorAware.java
deleted file mode 100644
index 5d0fd6b..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationErrorAware.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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 com.opensymphony.xwork2.interceptor;
-
-/**
- * ValidationErrorAware classes can be notified about validation errors
- * before {@link com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor} will return 'inputResultName' result
- * to allow change or not the result name
- *
- * This interface can be only applied to action which already implements {@link com.opensymphony.xwork2.ValidationAware} interface!
- *
- * @since 2.3.15
- */
-public interface ValidationErrorAware {
-
- /**
- * Allows to notify action about occurred action/field errors
- *
- * @param currentResultName current result name, action can change it or return the same
- * @return new result name or passed currentResultName
- */
- String actionErrorOccurred(final String currentResultName);
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationWorkflowAware.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationWorkflowAware.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationWorkflowAware.java
deleted file mode 100644
index 51bdf71..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ValidationWorkflowAware.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.opensymphony.xwork2.interceptor;
-
-/**
- * ValidationWorkflowAware classes can programmatically change result name when errors occurred
- *
- * This interface can be only applied to action which already implements {@link com.opensymphony.xwork2.ValidationAware} interface!
- */
-public interface ValidationWorkflowAware {
-
- String getInputResultName();
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/After.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/After.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/After.java
deleted file mode 100644
index 3fc2fcd..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/After.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * 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 com.opensymphony.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 {
- *
- * @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;
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/Allowed.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/Allowed.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/Allowed.java
deleted file mode 100644
index 4263344..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/Allowed.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package com.opensymphony.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 {
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java
deleted file mode 100644
index f978e46..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterIntereptor.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package com.opensymphony.xwork2.interceptor.annotations;
-
-
-import com.opensymphony.xwork2.Action;
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
-import com.opensymphony.xwork2.interceptor.Interceptor;
-import com.opensymphony.xwork2.interceptor.ParameterFilterInterceptor;
-import com.opensymphony.xwork2.interceptor.ParametersInterceptor;
-import com.opensymphony.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 ParameterFilterInterceptor}.
- * <p/>
- * This {@link Interceptor} must be placed in the stack before the {@link ParametersInterceptor}
- * When a parameter matches a field that is marked {@link Blocked} then it is removed from
- * the parameter map.
- * <p/>
- * If an {@link 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 com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.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<>();
- HashSet<String> paramsToRemove = new HashSet<>();
-
- 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;
- break;
- }
- }
-
- 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();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java
deleted file mode 100644
index 665ed1c..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationWorkflowInterceptor.java
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * 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 com.opensymphony.xwork2.interceptor.annotations;
-
-import com.opensymphony.xwork2.ActionInvocation;
-import com.opensymphony.xwork2.XWorkException;
-import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
-import com.opensymphony.xwork2.interceptor.PreResultListener;
-import com.opensymphony.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> @{@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> @{@link BeforeResult} - will be invoked after the action method but before the result execution</li>
- * <li> @{@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/>
- * @Before
- * public String baseBefore() {
- * log = log + "baseBefore-";
- * return null;
- * }
- * }
- * <p/>
- * public class AnnotatedAction extends BaseAnnotatedAction {
- * @Before
- * public String before() {
- * log = log + "before";
- * return null;
- * }
- * <p/>
- * public String execute() {
- * log = log + "-execute";
- * return Action.SUCCESS;
- * }
- * <p/>
- * @BeforeResult
- * public void beforeResult() throws Exception {
- * log = log +"-beforeResult";
- * }
- * <p/>
- * @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 -->
- * <interceptor-stack name="annotatedStack">
- * <interceptor-ref name="staticParams"/>
- * <interceptor-ref name="params"/>
- * <interceptor-ref name="conversionError"/>
- * <interceptor-ref name="annotationWorkflow"/>
- * </interceptor-stack>
- * <!-- 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 com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
- */
- public String intercept(ActionInvocation invocation) throws Exception {
- final Object action = invocation.getAction();
- invocation.addPreResultListener(this);
- List<Method> methods = new ArrayList<>(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 @BeforeResult annotated methods
- *
- * @see com.opensymphony.xwork2.interceptor.PreResultListener#beforeResult(com.opensymphony.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);
- }
- }
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/Before.java
----------------------------------------------------------------------
diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/Before.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/Before.java
deleted file mode 100644
index cb0e555..0000000
--- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/Before.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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 com.opensymphony.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 {
- *
- * @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;
-}