http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java deleted file mode 100644 index 13cea0e..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptor.java +++ /dev/null @@ -1,214 +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.Action; -import com.opensymphony.xwork2.ActionInvocation; -import com.opensymphony.xwork2.ValidationAware; -import com.opensymphony.xwork2.interceptor.annotations.InputConfig; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.lang.reflect.Method; - -/** - * <!-- START SNIPPET: description --> - * <p/> - * An interceptor that makes sure there are not validation errors before allowing the interceptor chain to continue. - * <b>This interceptor does not perform any validation</b>. - * <p/> - * This interceptor does nothing if the name of the method being invoked is specified in the <b>excludeMethods</b> - * parameter. <b>excludeMethods</b> accepts a comma-delimited list of method names. For example, requests to - * <b>foo!input.action</b> and <b>foo!back.action</b> will be skipped by this interceptor if you set the - * <b>excludeMethods</b> parameter to "input, back". - * <p/> - * <b>Note:</b> As this method extends off MethodFilterInterceptor, it is capable of - * deciding if it is applicable only to selective methods in the action class. This is done by adding param tags - * for the interceptor element, naming either a list of excluded method names and/or a list of included method - * names, whereby includeMethods overrides excludedMethods. A single * sign is interpreted as wildcard matching - * all methods for both parameters. - * See {@link MethodFilterInterceptor} for more info. - * <p/> - * This interceptor also supports the following interfaces which can implemented by actions: - * <ul> - * <li>ValidationAware - implemented by ActionSupport class</li> - * <li>ValidationWorkflowAware - allows changing result name programmatically</li> - * <li>ValidationErrorAware - notifies action about errors and also allow change result name</li> - * </ul> - * - * You can also use InputConfig annotation to change result name returned when validation errors occurred. - * - * <!-- END SNIPPET: description --> - * - * <u>Interceptor parameters:</u> - * - * <!-- START SNIPPET: parameters --> - * <ul> - * <li>inputResultName - Default to "input". Determine the result name to be returned when - * an action / field error is found.</li> - * </ul> - * <!-- END SNIPPET: parameters --> - * - * <u>Extending the interceptor:</u> - * - * <!-- START SNIPPET: extending --> - * - * There are no known extension points for this interceptor. - * - * <!-- END SNIPPET: extending --> - * - * <u>Example code:</u> - * - * <pre> - * <!-- START SNIPPET: example --> - * - * <action name="someAction" class="com.examples.SomeAction"> - * <interceptor-ref name="params"/> - * <interceptor-ref name="validation"/> - * <interceptor-ref name="workflow"/> - * <result name="success">good_result.ftl</result> - * </action> - * - * <-- In this case myMethod as well as mySecondMethod of the action class - * will not pass through the workflow process --> - * <action name="someAction" class="com.examples.SomeAction"> - * <interceptor-ref name="params"/> - * <interceptor-ref name="validation"/> - * <interceptor-ref name="workflow"> - * <param name="excludeMethods">myMethod,mySecondMethod</param> - * </interceptor-ref name="workflow"> - * <result name="success">good_result.ftl</result> - * </action> - * - * <-- In this case, the result named "error" will be used when - * an action / field error is found --> - * <-- The Interceptor will only be applied for myWorkflowMethod method of action - * classes, since this is the only included method while any others are excluded --> - * <action name="someAction" class="com.examples.SomeAction"> - * <interceptor-ref name="params"/> - * <interceptor-ref name="validation"/> - * <interceptor-ref name="workflow"> - * <param name="inputResultName">error</param> - * <param name="excludeMethods">*</param> - * <param name="includeMethods">myWorkflowMethod</param> - * </interceptor-ref> - * <result name="success">good_result.ftl</result> - * </action> - * - * <!-- END SNIPPET: example --> - * </pre> - * - * @author Jason Carreira - * @author Rainer Hermanns - * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a> - * @author Philip Luppens - * @author tm_jee - */ -public class DefaultWorkflowInterceptor extends MethodFilterInterceptor { - - private static final long serialVersionUID = 7563014655616490865L; - - private static final Logger LOG = LogManager.getLogger(DefaultWorkflowInterceptor.class); - - private static final Class[] EMPTY_CLASS_ARRAY = new Class[0]; - - private String inputResultName = Action.INPUT; - - /** - * Set the <code>inputResultName</code> (result name to be returned when - * a action / field error is found registered). Default to {@link Action#INPUT} - * - * @param inputResultName what result name to use when there was validation error(s). - */ - public void setInputResultName(String inputResultName) { - this.inputResultName = inputResultName; - } - - /** - * Intercept {@link ActionInvocation} and returns a <code>inputResultName</code> - * when action / field errors is found registered. - * - * @return String result name - */ - @Override - protected String doIntercept(ActionInvocation invocation) throws Exception { - Object action = invocation.getAction(); - - if (action instanceof ValidationAware) { - ValidationAware validationAwareAction = (ValidationAware) action; - - if (validationAwareAction.hasErrors()) { - LOG.debug("Errors on action [{}], returning result name [{}]", validationAwareAction, inputResultName); - - String resultName = inputResultName; - resultName = processValidationWorkflowAware(action, resultName); - resultName = processInputConfig(action, invocation.getProxy().getMethod(), resultName); - resultName = processValidationErrorAware(action, resultName); - - return resultName; - } - } - - return invocation.invoke(); - } - - /** - * Process {@link ValidationWorkflowAware} interface - */ - private String processValidationWorkflowAware(final Object action, final String currentResultName) { - String resultName = currentResultName; - if (action instanceof ValidationWorkflowAware) { - resultName = ((ValidationWorkflowAware) action).getInputResultName(); - LOG.debug("Changing result name from [{}] to [{}] because of processing [{}] interface applied to [{}]", - currentResultName, resultName, InputConfig.class.getSimpleName(), ValidationWorkflowAware.class.getSimpleName(), action); - } - return resultName; - } - - /** - * Process {@link InputConfig} annotation applied to method - */ - protected String processInputConfig(final Object action, final String method, final String currentResultName) throws Exception { - String resultName = currentResultName; - InputConfig annotation = action.getClass().getMethod(method, EMPTY_CLASS_ARRAY).getAnnotation(InputConfig.class); - if (annotation != null) { - if (StringUtils.isNotEmpty(annotation.methodName())) { - Method m = action.getClass().getMethod(annotation.methodName()); - resultName = (String) m.invoke(action); - } else { - resultName = annotation.resultName(); - } - LOG.debug("Changing result name from [{}] to [{}] because of processing annotation [{}] on action [{}]", - currentResultName, resultName, InputConfig.class.getSimpleName(), action); - } - return resultName; - } - - /** - * Notify action if it implements {@see ValidationErrorAware} interface - */ - protected String processValidationErrorAware(final Object action, final String currentResultName) { - String resultName = currentResultName; - if (action instanceof ValidationErrorAware) { - resultName = ((ValidationErrorAware) action).actionErrorOccurred(currentResultName); - LOG.debug("Changing result name from [{}] to [{}] because of processing interface [{}] on action [{}]", - currentResultName, resultName, ValidationErrorAware.class.getSimpleName(), action); - } - return resultName; - } - -}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionHolder.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionHolder.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionHolder.java deleted file mode 100644 index 6959357..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionHolder.java +++ /dev/null @@ -1,77 +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 java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.Serializable; - -/** - * <!-- START SNIPPET: javadoc --> - * - * A simple wrapper around an exception, providing an easy way to print out the stack trace of the exception as well as - * a way to get a handle on the exception itself. - * - * <!-- END SNIPPET: javadoc --> - * - * @author Matthew E. Porter (matthew dot porter at metissian dot com) - */ -public class ExceptionHolder implements Serializable { - - private static final long serialVersionUID = 1L; - private Exception exception; - - /** - * Holds the given exception - * - * @param exception the exception to hold. - */ - public ExceptionHolder(Exception exception) { - this.exception = exception; - } - - /** - * Gets the held exception - * - * @return the held exception - */ - public Exception getException() { - return this.exception; - } - - /** - * Gets the held exception stack trace using {@link Exception#printStackTrace()}. - * - * @return stack trace - */ - public String getExceptionStack() { - String exceptionStack = null; - - if (getException() != null) { - try (StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw)) { - getException().printStackTrace(pw); - exceptionStack = sw.toString(); - } catch (IOException e) { - // Ignore exception generating stack trace. - } - } - - return exceptionStack; - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java deleted file mode 100644 index d1a5319..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java +++ /dev/null @@ -1,323 +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 com.opensymphony.xwork2.config.entities.ExceptionMappingConfig; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.LogManager; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * <!-- START SNIPPET: description --> - * - * This interceptor forms the core functionality of the exception handling feature. Exception handling allows you to map - * an exception to a result code, just as if the action returned a result code instead of throwing an unexpected - * exception. When an exception is encountered, it is wrapped with an {@link ExceptionHolder} and pushed on the stack, - * providing easy access to the exception from within your result. - * - * <b>Note:</b> While you can configure exception mapping in your configuration file at any point, the configuration - * will not have any effect if this interceptor is not in the interceptor stack for your actions. It is recommended that - * you make this interceptor the first interceptor on the stack, ensuring that it has full access to catch any - * exception, even those caused by other interceptors. - * - * <!-- END SNIPPET: description --> - * - * <p/> <u>Interceptor parameters:</u> - * - * <!-- START SNIPPET: parameters --> - * - * <ul> - * - * <li>logEnabled (optional) - Should exceptions also be logged? (boolean true|false)</li> - * - * <li>logLevel (optional) - what log level should we use (<code>trace, debug, info, warn, error, fatal</code>)? - defaut is <code>debug</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.ExceptionMappingInterceptor</code>.</li> - * - * </ul> - * - * The parameters above enables us to log all thrown exceptions with stacktace in our own logfile, - * and present a friendly webpage (with no stacktrace) to the end user. - * - * <!-- END SNIPPET: parameters --> - * - * <p/> <u>Extending the interceptor:</u> - * - * <p/> - * - * <!-- START SNIPPET: extending --> - * - * If you want to add custom handling for publishing the Exception, you may override - * {@link #publishException(com.opensymphony.xwork2.ActionInvocation, ExceptionHolder)}. The default implementation - * pushes the given ExceptionHolder on value stack. A custom implementation could add additional logging etc. - * - * <!-- END SNIPPET: extending --> - * - * <p/> <u>Example code:</u> - * - * <pre> - * <!-- START SNIPPET: example --> - * <xwork> - * <package name="default" extends="xwork-default"> - * <global-results> - * <result name="error" type="freemarker">error.ftl</result> - * </global-results> - * - * <global-exception-mappings> - * <exception-mapping exception="java.lang.Exception" result="error"/> - * </global-exception-mappings> - * - * <action name="test"> - * <interceptor-ref name="exception"/> - * <interceptor-ref name="basicStack"/> - * <exception-mapping exception="com.acme.CustomException" result="custom_error"/> - * <result name="custom_error">custom_error.ftl</result> - * <result name="success" type="freemarker">test.ftl</result> - * </action> - * </package> - * </xwork> - * <!-- END SNIPPET: example --> - * </pre> - * - * <p/> - * This second example will also log the exceptions using our own category - * <code>com.mycompany.app.unhandled<code> at WARN level. - * - * <pre> - * <!-- START SNIPPET: example2 --> - * <xwork> - * <package name="something" extends="xwork-default"> - * <interceptors> - * <interceptor-stack name="exceptionmappingStack"> - * <interceptor-ref name="exception"> - * <param name="logEnabled">true</param> - * <param name="logCategory">com.mycompany.app.unhandled</param> - * <param name="logLevel">WARN</param> - * </interceptor-ref> - * <interceptor-ref name="i18n"/> - * <interceptor-ref name="staticParams"/> - * <interceptor-ref name="params"/> - * <interceptor-ref name="validation"> - * <param name="excludeMethods">input,back,cancel,browse</param> - * </interceptor-ref> - * </interceptor-stack> - * </interceptors> - * - * <default-interceptor-ref name="exceptionmappingStack"/> - * - * <global-results> - * <result name="unhandledException">/unhandled-exception.jsp</result> - * </global-results> - * - * <global-exception-mappings> - * <exception-mapping exception="java.lang.Exception" result="unhandledException"/> - * </global-exception-mappings> - * - * <action name="exceptionDemo" class="org.apache.struts2.showcase.exceptionmapping.ExceptionMappingAction"> - * <exception-mapping exception="org.apache.struts2.showcase.exceptionmapping.ExceptionMappingException" - * result="damm"/> - * <result name="input">index.jsp</result> - * <result name="success">success.jsp</result> - * <result name="damm">damm.jsp</result> - * </action> - * - * </package> - * </xwork> - * <!-- END SNIPPET: example2 --> - * </pre> - * - * @author Matthew E. Porter (matthew dot porter at metissian dot com) - * @author Claus Ibsen - */ -public class ExceptionMappingInterceptor extends AbstractInterceptor { - - protected static final Logger LOG = LogManager.getLogger(ExceptionMappingInterceptor.class); - - protected Logger categoryLogger; - protected boolean logEnabled = false; - protected String logCategory; - protected String logLevel; - - - public boolean isLogEnabled() { - return logEnabled; - } - - public void setLogEnabled(boolean logEnabled) { - this.logEnabled = logEnabled; - } - - 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 { - String result; - - try { - result = invocation.invoke(); - } catch (Exception e) { - if (isLogEnabled()) { - handleLogging(e); - } - List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings(); - ExceptionMappingConfig mappingConfig = this.findMappingFromExceptions(exceptionMappings, e); - if (mappingConfig != null && mappingConfig.getResult()!=null) { - Map parameterMap = mappingConfig.getParams(); - // create a mutable HashMap since some interceptors will remove parameters, and parameterMap is immutable - invocation.getInvocationContext().setParameters(new HashMap<String, Object>(parameterMap)); - result = mappingConfig.getResult(); - publishException(invocation, new ExceptionHolder(e)); - } else { - throw e; - } - } - - return result; - } - - /** - * Handles the logging of the exception. - * - * @param e the exception to log. - */ - protected void handleLogging(Exception e) { - if (logCategory != null) { - if (categoryLogger == null) { - // init category logger - categoryLogger = LogManager.getLogger(logCategory); - } - doLog(categoryLogger, e); - } else { - doLog(LOG, e); - } - } - - /** - * Performs the actual logging. - * - * @param logger the provided logger to use. - * @param e the exception to log. - */ - protected void doLog(Logger logger, Exception e) { - if (logLevel == null) { - logger.debug(e.getMessage(), e); - return; - } - - if ("trace".equalsIgnoreCase(logLevel)) { - logger.trace(e.getMessage(), e); - } else if ("debug".equalsIgnoreCase(logLevel)) { - logger.debug(e.getMessage(), e); - } else if ("info".equalsIgnoreCase(logLevel)) { - logger.info(e.getMessage(), e); - } else if ("warn".equalsIgnoreCase(logLevel)) { - logger.warn(e.getMessage(), e); - } else if ("error".equalsIgnoreCase(logLevel)) { - logger.error(e.getMessage(), e); - } else if ("fatal".equalsIgnoreCase(logLevel)) { - logger.fatal(e.getMessage(), e); - } else { - throw new IllegalArgumentException("LogLevel [" + logLevel + "] is not supported"); - } - } - - /** - * @deprecated since 2.3.15 please use #findMappingFromExceptions directly instead - */ - protected String findResultFromExceptions(List<ExceptionMappingConfig> exceptionMappings, Throwable t) { - ExceptionMappingConfig result = findMappingFromExceptions(exceptionMappings, t); - return result==null?null:result.getResult(); - } - - /** - * Try to find appropriate {@link ExceptionMappingConfig} based on provided Throwable - * - * @param exceptionMappings list of defined exception mappings - * @param t caught exception - * @return appropriate mapping or null - */ - protected ExceptionMappingConfig findMappingFromExceptions(List<ExceptionMappingConfig> exceptionMappings, Throwable t) { - ExceptionMappingConfig config = null; - // Check for specific exception mappings. - if (exceptionMappings != null) { - int deepest = Integer.MAX_VALUE; - for (Object exceptionMapping : exceptionMappings) { - ExceptionMappingConfig exceptionMappingConfig = (ExceptionMappingConfig) exceptionMapping; - int depth = getDepth(exceptionMappingConfig.getExceptionClassName(), t); - if (depth >= 0 && depth < deepest) { - deepest = depth; - config = exceptionMappingConfig; - } - } - } - return config; - } - - /** - * Return the depth to the superclass matching. 0 means ex matches exactly. Returns -1 if there's no match. - * Otherwise, returns depth. Lowest depth wins. - * - * @param exceptionMapping the mapping classname - * @param t the cause - * @return the depth, if not found -1 is returned. - */ - public int getDepth(String exceptionMapping, Throwable t) { - return getDepth(exceptionMapping, t.getClass(), 0); - } - - private int getDepth(String exceptionMapping, Class exceptionClass, int depth) { - if (exceptionClass.getName().contains(exceptionMapping)) { - // Found it! - return depth; - } - // If we've gone as far as we can go and haven't found it... - if (exceptionClass.equals(Throwable.class)) { - return -1; - } - return getDepth(exceptionMapping, exceptionClass.getSuperclass(), depth + 1); - } - - /** - * Default implementation to handle ExceptionHolder publishing. Pushes given ExceptionHolder on the stack. - * Subclasses may override this to customize publishing. - * - * @param invocation The invocation to publish Exception for. - * @param exceptionHolder The exceptionHolder wrapping the Exception to publish. - */ - protected void publishException(ActionInvocation invocation, ExceptionHolder exceptionHolder) { - invocation.getStack().push(exceptionHolder); - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java deleted file mode 100644 index afdd534..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/I18nInterceptor.java +++ /dev/null @@ -1,288 +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 com.opensymphony.xwork2.util.LocalizedTextUtil; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.Locale; -import java.util.Map; - -/** - * <!-- START SNIPPET: description --> - * <p/> - * An interceptor that handles setting the locale specified in a session as the locale for the current action request. - * In addition, this interceptor will look for a specific HTTP request parameter and set the locale to whatever value is - * provided. This means that this interceptor can be used to allow for your application to dynamically change the locale - * for the user's session or, alternatively, only for the current request (since XWork 2.1.3). - * This is very useful for applications that require multi-lingual support and want the user to - * be able to set his or her language preference at any point. The locale parameter is removed during the execution of - * this interceptor, ensuring that properties aren't set on an action (such as request_locale) that have no typical - * corresponding setter in your action. - * <p/> - * <p/>For example, using the default parameter name, a request to <b>foo.action?request_locale=en_US</b>, then the - * locale for US English is saved in the user's session and will be used for all future requests. - * <p/> - if there is no locale set (for example with the first visit), the interceptor uses the browser locale. - * <p/> - * <!-- END SNIPPET: description --> - * <p/> - * <p/> <u>Interceptor parameters:</u> - * <p/> - * <!-- START SNIPPET: parameters --> - * <p/> - * <ul> - * <p/> - * <li>parameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to and save - * in the session. By default this is <b>request_locale</b></li> - * <p/> - * <li>requestOnlyParameterName (optional) - the name of the HTTP request parameter that dictates the locale to switch to - * for the current request only, without saving it in the session. By default this is <b>request_only_locale</b></li> - * <p/> - * <li>attributeName (optional) - the name of the session key to store the selected locale. By default this is - * <b>WW_TRANS_I18N_LOCALE</b></li> - * <p/> - * </ul> - * <p/> - * <!-- END SNIPPET: parameters --> - * <p/> - * <p/> <u>Extending the interceptor:</u> - * <p/> - * <p/> - * <p/> - * <!-- START SNIPPET: extending --> - * <p/> - * There are no known extensions points for this interceptor. - * <p/> - * <!-- END SNIPPET: extending --> - * <p/> - * <p/> <u>Example code:</u> - * <p/> - * <pre> - * <!-- START SNIPPET: example --> - * <action name="someAction" class="com.examples.SomeAction"> - * <interceptor-ref name="i18n"/> - * <interceptor-ref name="basicStack"/> - * <result name="success">good_result.ftl</result> - * </action> - * <!-- END SNIPPET: example --> - * </pre> - * - * @author Aleksei Gopachenko - */ -public class I18nInterceptor extends AbstractInterceptor { - private static final long serialVersionUID = 2496830135246700300L; - - protected static final Logger LOG = LogManager.getLogger(I18nInterceptor.class); - - public static final String DEFAULT_SESSION_ATTRIBUTE = "WW_TRANS_I18N_LOCALE"; - public static final String DEFAULT_PARAMETER = "request_locale"; - public static final String DEFAULT_REQUESTONLY_PARAMETER = "request_only_locale"; - - protected String parameterName = DEFAULT_PARAMETER; - protected String requestOnlyParameterName = DEFAULT_REQUESTONLY_PARAMETER; - protected String attributeName = DEFAULT_SESSION_ATTRIBUTE; - - // Request-Only = None - protected enum Storage { SESSION, NONE } - - public I18nInterceptor() { - LOG.debug("new I18nInterceptor()"); - } - - public void setParameterName(String parameterName) { - this.parameterName = parameterName; - } - - public void setRequestOnlyParameterName(String requestOnlyParameterName) { - this.requestOnlyParameterName = requestOnlyParameterName; - } - - public void setAttributeName(String attributeName) { - this.attributeName = attributeName; - } - - @Override - public String intercept(ActionInvocation invocation) throws Exception { - if (LOG.isDebugEnabled()) { - LOG.debug("Intercept '{}/{}' {", invocation.getProxy().getNamespace(), invocation.getProxy().getActionName()); - } - - LocaleFinder localeFinder = new LocaleFinder(invocation); - Locale locale = getLocaleFromParam(localeFinder.getRequestedLocale()); - locale = storeLocale(invocation, locale, localeFinder.getStorage()); - saveLocale(invocation, locale); - - if (LOG.isDebugEnabled()) { - LOG.debug("before Locale: {}", invocation.getStack().findValue("locale")); - } - - final String result = invocation.invoke(); - - if (LOG.isDebugEnabled()) { - LOG.debug("after Locale {}", invocation.getStack().findValue("locale")); - LOG.debug("intercept } "); - } - - return result; - } - - /** - * Store the locale to the chosen storage, like f. e. the session - * - * @param invocation the action invocation - * @param locale the locale to store - * @param storage the place to store this locale (like Storage.SESSSION.toString()) - */ - protected Locale storeLocale(ActionInvocation invocation, Locale locale, String storage) { - //save it in session - Map<String, Object> session = invocation.getInvocationContext().getSession(); - - if (session != null) { - synchronized (session) { - if (locale == null) { - storage = Storage.NONE.toString(); - locale = readStoredLocale(invocation, session); - } - - if (Storage.SESSION.toString().equals(storage)) { - session.put(attributeName, locale); - } - } - } - return locale; - } - - protected class LocaleFinder { - protected String storage = Storage.SESSION.toString(); - protected Object requestedLocale = null; - - protected ActionInvocation actionInvocation = null; - - protected LocaleFinder(ActionInvocation invocation) { - actionInvocation = invocation; - find(); - } - - protected void find() { - //get requested locale - Map<String, Object> params = actionInvocation.getInvocationContext().getParameters(); - - storage = Storage.SESSION.toString(); - - requestedLocale = findLocaleParameter(params, parameterName); - if (requestedLocale != null) { - return; - } - - requestedLocale = findLocaleParameter(params, requestOnlyParameterName); - if (requestedLocale != null) { - storage = Storage.NONE.toString(); - } - } - - public String getStorage() { - return storage; - } - - public Object getRequestedLocale() { - return requestedLocale; - } - } - - /** - * Creates a Locale object from the request param, which might - * be already a Local or a String - * - * @param requestedLocale the parameter from the request - * @return the Locale - */ - protected Locale getLocaleFromParam(Object requestedLocale) { - Locale locale = null; - if (requestedLocale != null) { - locale = (requestedLocale instanceof Locale) ? - (Locale) requestedLocale : - LocalizedTextUtil.localeFromString(requestedLocale.toString(), null); - if (locale != null) { - LOG.debug("Applied request locale: {}", locale); - } - } - return locale; - } - - /** - * Reads the locale from the session, and if not found from the - * current invocation (=browser) - * - * @param invocation the current invocation - * @param session the current session - * @return the read locale - */ - protected Locale readStoredLocale(ActionInvocation invocation, Map<String, Object> session) { - Locale locale = this.readStoredLocalFromSession(invocation, session); - - if (locale != null) { - return locale; - } - - return this.readStoredLocalFromCurrentInvocation(invocation); - } - - protected Locale readStoredLocalFromSession(ActionInvocation invocation, Map<String, Object> session) { - // check session for saved locale - Object sessionLocale = session.get(attributeName); - if (sessionLocale != null && sessionLocale instanceof Locale) { - Locale locale = (Locale) sessionLocale; - LOG.debug("Applied session locale: {}", locale); - return locale; - } - return null; - } - - protected Locale readStoredLocalFromCurrentInvocation(ActionInvocation invocation) { - // no overriding locale definition found, stay with current invocation (=browser) locale - Locale locale = invocation.getInvocationContext().getLocale(); - if (locale != null) { - LOG.debug("Applied invocation context locale: {}", locale); - } - return locale; - } - - protected Object findLocaleParameter(Map<String, Object> params, String parameterName) { - Object requestedLocale = params.remove(parameterName); - if (requestedLocale != null && requestedLocale.getClass().isArray() - && ((Object[]) requestedLocale).length > 0) { - requestedLocale = ((Object[]) requestedLocale)[0]; - - LOG.debug("Requested locale: {}", requestedLocale); - } - return requestedLocale; - } - - /** - * Save the given locale to the ActionInvocation. - * - * @param invocation The ActionInvocation. - * @param locale The locale to save. - */ - protected void saveLocale(ActionInvocation invocation, Locale locale) { - invocation.getInvocationContext().setLocale(locale); - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java deleted file mode 100644 index 4266236..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/Interceptor.java +++ /dev/null @@ -1,213 +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 java.io.Serializable; - - -/** - * <!-- START SNIPPET: introduction --> - * <p/> - * An interceptor is a stateless class that follows the interceptor pattern, as - * found in {@link javax.servlet.Filter} and in AOP languages. - * <p/> - * <p/> - * <p/> - * Interceptors are objects that dynamically intercept Action invocations. - * They provide the developer with the opportunity to define code that can be executed - * before and/or after the execution of an action. They also have the ability - * to prevent an action from executing. Interceptors provide developers a way to - * encapulate common functionality in a re-usable form that can be applied to - * one or more Actions. - * <p/> - * <p/> - * <p/> - * Interceptors <b>must</b> be stateless and not assume that a new instance will be created for each request or Action. - * Interceptors may choose to either short-circuit the {@link ActionInvocation} execution and return a return code - * (such as {@link com.opensymphony.xwork2.Action#SUCCESS}), or it may choose to do some processing before - * and/or after delegating the rest of the procesing using {@link ActionInvocation#invoke()}. - * <p/> - * <!-- END SNIPPET: introduction --> - * <p/> - * <p/> - * <p/> - * <!-- START SNIPPET: parameterOverriding --> - * <p/> - * Interceptor's parameter could be overriden through the following ways :- - * <p/> - * <p/> - * <p/> - * <b>Method 1:</b> - * <pre> - * <action name="myAction" class="myActionClass"> - * <interceptor-ref name="exception"/> - * <interceptor-ref name="alias"/> - * <interceptor-ref name="params"/> - * <interceptor-ref name="servletConfig"/> - * <interceptor-ref name="prepare"/> - * <interceptor-ref name="i18n"/> - * <interceptor-ref name="chain"/> - * <interceptor-ref name="modelDriven"/> - * <interceptor-ref name="fileUpload"/> - * <interceptor-ref name="staticParams"/> - * <interceptor-ref name="params"/> - * <interceptor-ref name="conversionError"/> - * <interceptor-ref name="validation"> - * <param name="excludeMethods">myValidationExcudeMethod</param> - * </interceptor-ref> - * <interceptor-ref name="workflow"> - * <param name="excludeMethods">myWorkflowExcludeMethod</param> - * </interceptor-ref> - * </action> - * </pre> - * <p/> - * <b>Method 2:</b> - * <pre> - * <action name="myAction" class="myActionClass"> - * <interceptor-ref name="defaultStack"> - * <param name="validation.excludeMethods">myValidationExcludeMethod</param> - * <param name="workflow.excludeMethods">myWorkflowExcludeMethod</param> - * </interceptor-ref> - * </action> - * </pre> - * <p/> - * <p/> - * <p/> - * In the first method, the whole default stack is copied and the parameter then - * changed accordingly. - * <p/> - * <p/> - * <p/> - * In the second method, the 'interceptor-ref' refer to an existing - * interceptor-stack, namely defaultStack in this example, and override the validator - * and workflow interceptor excludeMethods typically in this case. Note that in the - * 'param' tag, the name attribute contains a dot (.) the word before the dot(.) - * specifies the interceptor name whose parameter is to be overridden and the word after - * the dot (.) specifies the parameter itself. Essetially it is as follows :- - * <p/> - * <pre> - * <interceptor-name>.<parameter-name> - * </pre> - * <p/> - * <b>Note</b> also that in this case the 'interceptor-ref' name attribute - * is used to indicate an interceptor stack which makes sense as if it is referring - * to the interceptor itself it would be just using Method 1 describe above. - * <p/> - * <!-- END SNIPPET: parameterOverriding --> - * <p/> - * <p/> - * <b>Nested Interceptor param overriding</b> - * <p/> - * <!-- START SNIPPET: nestedParameterOverriding --> - * <p/> - * Interceptor stack parameter overriding could be nested into as many level as possible, though it would - * be advisable not to nest it too deep as to avoid confusion, For example, - * <pre> - * <interceptor name="interceptor1" class="foo.bar.Interceptor1" /> - * <interceptor name="interceptor2" class="foo.bar.Interceptor2" /> - * <interceptor name="interceptor3" class="foo.bar.Interceptor3" /> - * <interceptor name="interceptor4" class="foo.bar.Interceptor4" /> - * <interceptor-stack name="stack1"> - * <interceptor-ref name="interceptor1" /> - * </interceptor-stack> - * <interceptor-stack name="stack2"> - * <interceptor-ref name="intercetor2" /> - * <interceptor-ref name="stack1" /> - * </interceptor-stack> - * <interceptor-stack name="stack3"> - * <interceptor-ref name="interceptor3" /> - * <interceptor-ref name="stack2" /> - * </interceptor-stack> - * <interceptor-stack name="stack4"> - * <interceptor-ref name="interceptor4" /> - * <interceptor-ref name="stack3" /> - * </interceptor-stack> - * </pre> - * Assuming the interceptor has the following properties - * <table border="1" width="100%"> - * <tr> - * <td>Interceptor</td> - * <td>property</td> - * </tr> - * <tr> - * <td>Interceptor1</td> - * <td>param1</td> - * </tr> - * <tr> - * <td>Interceptor2</td> - * <td>param2</td> - * </tr> - * <tr> - * <td>Interceptor3</td> - * <td>param3</td> - * </tr> - * <tr> - * <td>Interceptor4</td> - * <td>param4</td> - * </tr> - * </table> - * We could override them as follows :- - * <pre> - * <action ... > - * <!-- to override parameters of interceptor located directly in the stack --> - * <interceptor-ref name="stack4"> - * <param name="interceptor4.param4"> ... </param> - * </interceptor-ref> - * </action> - * <p/> - * <action ... > - * <!-- to override parameters of interceptor located under nested stack --> - * <interceptor-ref name="stack4"> - * <param name="stack3.interceptor3.param3"> ... </param> - * <param name="stack3.stack2.interceptor2.param2"> ... </param> - * <param name="stack3.stack2.stack1.interceptor1.param1"> ... </param> - * </interceptor-ref> - * </action> - * </pre> - * <p/> - * <!-- END SNIPPET: nestedParameterOverriding --> - * - * @author Jason Carreira - * @author tmjee - * @version $Date$ $Id$ - */ -public interface Interceptor extends Serializable { - - /** - * Called to let an interceptor clean up any resources it has allocated. - */ - void destroy(); - - /** - * Called after an interceptor is created, but before any requests are processed using - * {@link #intercept(com.opensymphony.xwork2.ActionInvocation) intercept} , giving - * the Interceptor a chance to initialize any needed resources. - */ - 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 {@link ActionInvocation} or to short-circuit the processing and just return a String return code. - * - * @param invocation the action invocation - * @return the return code, either returned from {@link ActionInvocation#invoke()}, or from the interceptor itself. - * @throws Exception any system-level error, as defined in {@link com.opensymphony.xwork2.Action#execute()}. - */ - String intercept(ActionInvocation invocation) throws Exception; - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/LoggingInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/LoggingInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/LoggingInterceptor.java deleted file mode 100644 index c82532f..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/LoggingInterceptor.java +++ /dev/null @@ -1,86 +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; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - - -/** - * <!-- START SNIPPET: description --> - * This interceptor logs the start and end of the execution an action (in English-only, not internationalized). - * <br/> - * <b>Note:</b>: This interceptor will log at <tt>INFO</tt> level. - * <p/> - * <!-- END SNIPPET: description --> - * - * <!-- START SNIPPET: parameters --> - * There are no parameters for this interceptor. - * <!-- END SNIPPET: parameters --> - * - * <!-- START SNIPPET: extending --> - * There are no obvious extensions to the existing interceptor. - * <!-- END SNIPPET: extending --> - * - * <pre> - * <!-- START SNIPPET: example --> - * <!-- prints out a message before and after the immediate action execution --> - * <action name="someAction" class="com.examples.SomeAction"> - * <interceptor-ref name="completeStack"/> - * <interceptor-ref name="logger"/> - * <result name="success">good_result.ftl</result> - * </action> - * - * <!-- prints out a message before any more interceptors continue and after they have finished --> - * <action name="someAction" class="com.examples.SomeAction"> - * <interceptor-ref name="logger"/> - * <interceptor-ref name="completeStack"/> - * <result name="success">good_result.ftl</result> - * </action> - * <!-- END SNIPPET: example --> - * </pre> - * - * @author Jason Carreira - */ -public class LoggingInterceptor extends AbstractInterceptor { - private static final Logger LOG = LogManager.getLogger(LoggingInterceptor.class); - private static final String FINISH_MESSAGE = "Finishing execution stack for action "; - private static final String START_MESSAGE = "Starting execution stack for action "; - - @Override - public String intercept(ActionInvocation invocation) throws Exception { - logMessage(invocation, START_MESSAGE); - String result = invocation.invoke(); - logMessage(invocation, FINISH_MESSAGE); - return result; - } - - private void logMessage(ActionInvocation invocation, String baseMessage) { - if (LOG.isInfoEnabled()) { - StringBuilder message = new StringBuilder(baseMessage); - String namespace = invocation.getProxy().getNamespace(); - - if ((namespace != null) && (namespace.trim().length() > 0)) { - message.append(namespace).append("/"); - } - - message.append(invocation.getProxy().getActionName()); - LOG.info(message.toString()); - } - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptor.java deleted file mode 100644 index a46cf34..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptor.java +++ /dev/null @@ -1,122 +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 com.opensymphony.xwork2.util.TextParseUtil; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.Collections; -import java.util.Set; - - -/** - * <!-- START SNIPPET: javadoc --> - * - * MethodFilterInterceptor is an abstract <code>Interceptor</code> used as - * a base class for interceptors that will filter execution based on method - * names according to specified included/excluded method lists. - * - * <p/> - * - * Settable parameters are as follows: - * - * <ul> - * <li>excludeMethods - method names to be excluded from interceptor processing</li> - * <li>includeMethods - method names to be included in interceptor processing</li> - * </ul> - * - * <p/> - * - * <b>NOTE:</b> If method name are available in both includeMethods and - * excludeMethods, it will be considered as an included method: - * includeMethods takes precedence over excludeMethods. - * - * <p/> - * - * Interceptors that extends this capability include: - * - * <ul> - * <li>TokenInterceptor</li> - * <li>TokenSessionStoreInterceptor</li> - * <li>DefaultWorkflowInterceptor</li> - * <li>ValidationInterceptor</li> - * </ul> - * - * <!-- END SNIPPET: javadoc --> - * - * @author <a href='mailto:the_mindstorm[at]evolva[dot]ro'>Alexandru Popescu</a> - * @author Rainer Hermanns - * - * @see org.apache.struts2.interceptor.TokenInterceptor - * @see org.apache.struts2.interceptor.TokenSessionStoreInterceptor - * @see com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor - * @see com.opensymphony.xwork2.validator.ValidationInterceptor - * - * @version $Date$ $Id$ - */ -public abstract class MethodFilterInterceptor extends AbstractInterceptor { - protected transient Logger log = LogManager.getLogger(getClass()); - - protected Set<String> excludeMethods = Collections.emptySet(); - protected Set<String> includeMethods = Collections.emptySet(); - - public void setExcludeMethods(String excludeMethods) { - this.excludeMethods = TextParseUtil.commaDelimitedStringToSet(excludeMethods); - } - - public Set<String> getExcludeMethodsSet() { - return excludeMethods; - } - - public void setIncludeMethods(String includeMethods) { - this.includeMethods = TextParseUtil.commaDelimitedStringToSet(includeMethods); - } - - public Set<String> getIncludeMethodsSet() { - return includeMethods; - } - - @Override - public String intercept(ActionInvocation invocation) throws Exception { - if (applyInterceptor(invocation)) { - return doIntercept(invocation); - } - return invocation.invoke(); - } - - protected boolean applyInterceptor(ActionInvocation invocation) { - String method = invocation.getProxy().getMethod(); - // ValidationInterceptor - boolean applyMethod = MethodFilterInterceptorUtil.applyMethod(excludeMethods, includeMethods, method); - if (!applyMethod) { - log.debug("Skipping Interceptor... Method [{}] found in exclude list.", method); - } - return applyMethod; - } - - /** - * Subclasses must override to implement the interceptor logic. - * - * @param invocation the action invocation - * @return the result of invocation - * @throws Exception - */ - protected abstract String doIntercept(ActionInvocation invocation) throws Exception; - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java deleted file mode 100644 index 987d782..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtil.java +++ /dev/null @@ -1,145 +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.util.TextParseUtil; -import com.opensymphony.xwork2.util.WildcardHelper; - -import java.util.HashMap; -import java.util.Set; - -/** - * Utility class contains common methods used by - * {@link com.opensymphony.xwork2.interceptor.MethodFilterInterceptor}. - * - * @author tm_jee - */ -public class MethodFilterInterceptorUtil { - - /** - * Static method to decide if the specified <code>method</code> should be - * apply (not filtered) depending on the set of <code>excludeMethods</code> and - * <code>includeMethods</code>. - * - * <ul> - * <li> - * <code>includeMethods</code> takes precedence over <code>excludeMethods</code> - * </li> - * </ul> - * <b>Note:</b> Supports wildcard listings in includeMethods/excludeMethods - * - * @param excludeMethods list of methods to exclude. - * @param includeMethods list of methods to include. - * @param method the specified method to check - * @return <tt>true</tt> if the method should be applied. - */ - public static boolean applyMethod(Set<String> excludeMethods, Set<String> includeMethods, String method) { - - // quick check to see if any actual pattern matching is needed - boolean needsPatternMatch = false; - for (String includeMethod : includeMethods) { - if (!"*".equals(includeMethod) && includeMethod.contains("*")) { - needsPatternMatch = true; - break; - } - } - - for (String excludeMethod : excludeMethods) { - if (!"*".equals(excludeMethod) && excludeMethod.contains("*")) { - needsPatternMatch = true; - break; - } - } - - // this section will try to honor the original logic, while - // still allowing for wildcards later - if (!needsPatternMatch && (includeMethods.contains("*") || includeMethods.size() == 0) ) { - if (excludeMethods != null - && excludeMethods.contains(method) - && !includeMethods.contains(method) ) { - return false; - } - } - - // test the methods using pattern matching - WildcardHelper wildcard = new WildcardHelper(); - String methodCopy ; - if (method == null ) { // no method specified - methodCopy = ""; - } - else { - methodCopy = new String(method); - } - for (String pattern : includeMethods) { - if (pattern.contains("*")) { - int[] compiledPattern = wildcard.compilePattern(pattern); - HashMap<String, String> matchedPatterns = new HashMap<>(); - boolean matches = wildcard.match(matchedPatterns, methodCopy, compiledPattern); - if (matches) { - return true; // run it, includeMethods takes precedence - } - } - else { - if (pattern.equals(methodCopy)) { - return true; // run it, includeMethods takes precedence - } - } - } - if (excludeMethods.contains("*") ) { - return false; - } - - // CHECK ME: Previous implementation used include method - for ( String pattern : excludeMethods) { - if (pattern.contains("*")) { - int[] compiledPattern = wildcard.compilePattern(pattern); - HashMap<String, String> matchedPatterns = new HashMap<>(); - boolean matches = wildcard.match(matchedPatterns, methodCopy, compiledPattern); - if (matches) { - // if found, and wasn't included earlier, don't run it - return false; - } - } - else { - if (pattern.equals(methodCopy)) { - // if found, and wasn't included earlier, don't run it - return false; - } - } - } - - - // default fall-back from before changes - return includeMethods.size() == 0 || includeMethods.contains(method) || includeMethods.contains("*"); - } - - /** - * Same as {@link #applyMethod(Set, Set, String)}, except that <code>excludeMethods</code> - * and <code>includeMethods</code> are supplied as comma separated string. - * - * @param excludeMethods comma seperated string of methods to exclude. - * @param includeMethods comma seperated string of methods to include. - * @param method the specified method to check - * @return <tt>true</tt> if the method should be applied. - */ - public static boolean applyMethod(String excludeMethods, String includeMethods, String method) { - Set<String> includeMethodsSet = TextParseUtil.commaDelimitedStringToSet(includeMethods == null? "" : includeMethods); - Set<String> excludeMethodsSet = TextParseUtil.commaDelimitedStringToSet(excludeMethods == null? "" : excludeMethods); - - return applyMethod(excludeMethodsSet, includeMethodsSet, method); - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java deleted file mode 100644 index 06a91b5..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptor.java +++ /dev/null @@ -1,144 +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 com.opensymphony.xwork2.ModelDriven; -import com.opensymphony.xwork2.util.CompoundRoot; -import com.opensymphony.xwork2.util.ValueStack; - - -/** - * <!-- START SNIPPET: description --> - * - * Watches for {@link ModelDriven} actions and adds the action's model on to the value stack. - * - * <p/> <b>Note:</b> The ModelDrivenInterceptor must come before the both {@link StaticParametersInterceptor} and - * {@link ParametersInterceptor} if you want the parameters to be applied to the model. - * - * <p/> <b>Note:</b> The ModelDrivenInterceptor will only push the model into the stack when the - * model is not null, else it will be ignored. - * - * <!-- END SNIPPET: description --> - * - * <p/> <u>Interceptor parameters:</u> - * - * <!-- START SNIPPET: parameters --> - * - * <ul> - * - * <li>refreshModelBeforeResult - set to true if you want the model to be refreshed on the value stack after action - * execution and before result execution. The setting is useful if you want to change the model instance during the - * action execution phase, like when loading it from the data layer. This will result in getModel() being called at - * least twice.</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 --> - * <action name="someAction" class="com.examples.SomeAction"> - * <interceptor-ref name="modelDriven"/> - * <interceptor-ref name="basicStack"/> - * <result name="success">good_result.ftl</result> - * </action> - * <!-- END SNIPPET: example --> - * </pre> - * - * @author tm_jee - * @version $Date$ $Id$ - */ -public class ModelDrivenInterceptor extends AbstractInterceptor { - - protected boolean refreshModelBeforeResult = false; - - public void setRefreshModelBeforeResult(boolean val) { - this.refreshModelBeforeResult = val; - } - - @Override - public String intercept(ActionInvocation invocation) throws Exception { - Object action = invocation.getAction(); - - if (action instanceof ModelDriven) { - ModelDriven modelDriven = (ModelDriven) action; - ValueStack stack = invocation.getStack(); - Object model = modelDriven.getModel(); - if (model != null) { - stack.push(model); - } - if (refreshModelBeforeResult) { - invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model)); - } - } - return invocation.invoke(); - } - - /** - * Refreshes the model instance on the value stack, if it has changed - */ - protected static class RefreshModelBeforeResult implements PreResultListener { - private Object originalModel = null; - protected ModelDriven action; - - - public RefreshModelBeforeResult(ModelDriven action, Object model) { - this.originalModel = model; - this.action = action; - } - - public void beforeResult(ActionInvocation invocation, String resultCode) { - ValueStack stack = invocation.getStack(); - CompoundRoot root = stack.getRoot(); - - boolean needsRefresh = true; - Object newModel = action.getModel(); - - // Check to see if the new model instance is already on the stack - for (Object item : root) { - if (item.equals(newModel)) { - needsRefresh = false; - break; - } - } - - // Add the new model on the stack - if (needsRefresh) { - - // Clear off the old model instance - if (originalModel != null) { - root.remove(originalModel); - } - if (newModel != null) { - stack.push(newModel); - } - } - } - } -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/NoParameters.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/NoParameters.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/NoParameters.java deleted file mode 100644 index 8db8fbc..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/NoParameters.java +++ /dev/null @@ -1,32 +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; - - -/** - * Marker interface to incidate no auto setting of parameters. - * <p/> - * This marker interface should be implemented by actions that do not want any - * request parameters set on them automatically (by the ParametersInterceptor). - * This may be useful if one is using the action tag and want to supply - * the parameters to the action manually using the param tag. - * It may also be useful if one for security reasons wants to make sure that - * parameters cannot be set by malicious users. - * - * @author Dick Zetterberg ([email protected]) - */ -public interface NoParameters { -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java deleted file mode 100644 index 46767d5..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java +++ /dev/null @@ -1,236 +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; -import com.opensymphony.xwork2.util.TextParseUtil; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Map; -import java.util.TreeMap; - -/** - * <!-- START SNIPPET: description --> - * - * The Parameter Filter Interceptor blocks parameters from getting - * to the rest of the stack or your action. You can use multiple - * parameter filter interceptors for a given action, so, for example, - * you could use one in your default stack that filtered parameters - * you wanted blocked from every action and those you wanted blocked - * from an individual action you could add an additional interceptor - * for each action. - * - * <!-- END SNIPPET: description --> - * - * <!-- START SNIPPET: parameters --> - * - * <ul> - * <li>allowed - a comma delimited list of parameter prefixes - * that are allowed to pass to the action</li> - * <li>blocked - a comma delimited list of parameter prefixes - * that are not allowed to pass to the action</li> - * <li>defaultBlock - boolean (default to false) whether by - * default a given parameter is blocked. If true, then a parameter - * must have a prefix in the allowed list in order to be able - * to pass to the action - * </ul> - * - * <p>The way parameters are filtered for the least configuration is that - * if a string is in the allowed or blocked lists, then any parameter - * that is a member of the object represented by the parameter is allowed - * or blocked respectively.</p> - * - * <p>For example, if the parameters are: - * <ul> - * <li>blocked: person,person.address.createDate,personDao</li> - * <li>allowed: person.address</li> - * <li>defaultBlock: false</li> - * </ul> - * <br> - * The parameters person.name, person.phoneNum etc would be blocked - * because 'person' is in the blocked list. However, person.address.street - * and person.address.city would be allowed because person.address is - * in the allowed list (the longer string determines permissions).</p> - * <!-- END SNIPPET: parameters --> - * - * <!-- START SNIPPET: extending --> - * There are no known extension points to this interceptor. - * <!-- END SNIPPET: extending --> - * - * <pre> - * <!-- START SNIPPET: example --> - * <interceptors> - * ... - * <interceptor name="parameterFilter" class="com.opensymphony.xwork2.interceptor.ParameterFilterInterceptor"/> - * ... - * </interceptors> - * - * <action ....> - * ... - * <interceptor-ref name="parameterFilter"> - * <param name="blocked">person,person.address.createDate,personDao</param> - * </interceptor-ref> - * ... - * </action> - * <!-- END SNIPPET: example --> - * </pre> - * - * @author Gabe - */ -public class ParameterFilterInterceptor extends AbstractInterceptor { - - private static final Logger LOG = LogManager.getLogger(ParameterFilterInterceptor.class); - - private Collection<String> allowed; - private Collection<String> blocked; - private Map<String, Boolean> includesExcludesMap; - private boolean defaultBlock = false; - - @Override - public String intercept(ActionInvocation invocation) throws Exception { - - Map<String, Object> parameters = invocation.getInvocationContext().getParameters(); - HashSet<String> paramsToRemove = new HashSet<>(); - - Map<String, Boolean> includesExcludesMap = getIncludesExcludesMap(); - - for (String param : parameters.keySet()) { - boolean currentAllowed = !isDefaultBlock(); - - for (String currRule : includesExcludesMap.keySet()) { - if (param.startsWith(currRule) - && (param.length() == currRule.length() - || isPropertySeparator(param.charAt(currRule.length())))) { - currentAllowed = includesExcludesMap.get(currRule).booleanValue(); - } - } - if (!currentAllowed) { - paramsToRemove.add(param); - } - } - - LOG.debug("Params to remove: {}", paramsToRemove); - - for (Object aParamsToRemove : paramsToRemove) { - parameters.remove(aParamsToRemove); - } - - return invocation.invoke(); - } - - /** - * Tests if the given char is a property separator char <code>.([</code>. - * - * @param c the char - * @return <tt>true</tt>, if char is property separator, <tt>false</tt> otherwise. - */ - private static boolean isPropertySeparator(char c) { - return c == '.' || c == '(' || c == '['; - } - - private Map<String, Boolean> getIncludesExcludesMap() { - if (this.includesExcludesMap == null) { - this.includesExcludesMap = new TreeMap<>(); - - if (getAllowedCollection() != null) { - for (String e : getAllowedCollection()) { - this.includesExcludesMap.put(e, Boolean.TRUE); - } - } - if (getBlockedCollection() != null) { - for (String b : getBlockedCollection()) { - this.includesExcludesMap.put(b, Boolean.FALSE); - } - } - } - - return this.includesExcludesMap; - } - - /** - * @return Returns the defaultBlock. - */ - public boolean isDefaultBlock() { - return defaultBlock; - } - - /** - * @param defaultExclude The defaultExclude to set. - */ - public void setDefaultBlock(boolean defaultExclude) { - this.defaultBlock = defaultExclude; - } - - /** - * @return Returns the blocked. - */ - public Collection<String> getBlockedCollection() { - return blocked; - } - - /** - * @param blocked The blocked to set. - */ - public void setBlockedCollection(Collection<String> blocked) { - this.blocked = blocked; - } - - /** - * @param blocked The blocked paramters as comma separated String. - */ - public void setBlocked(String blocked) { - setBlockedCollection(asCollection(blocked)); - } - - /** - * @return Returns the allowed. - */ - public Collection<String> getAllowedCollection() { - return allowed; - } - - /** - * @param allowed The allowed to set. - */ - public void setAllowedCollection(Collection<String> allowed) { - this.allowed = allowed; - } - - /** - * @param allowed The allowed paramters as comma separated String. - */ - public void setAllowed(String allowed) { - setAllowedCollection(asCollection(allowed)); - } - - /** - * Return a collection from the comma delimited String. - * - * @param commaDelim the comma delimited String. - * @return A collection from the comma delimited String. Returns <tt>null</tt> if the string is empty. - */ - private Collection<String> asCollection(String commaDelim) { - if (StringUtils.isBlank(commaDelim)) { - return null; - } - return TextParseUtil.commaDelimitedStringToSet(commaDelim); - } - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterNameAware.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterNameAware.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterNameAware.java deleted file mode 100644 index 46ba188..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterNameAware.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; - -/** - * <!-- START SNIPPET: javadoc --> - * This interface is implemented by actions that want to declare acceptable parameters. Works in conjunction with {@link - * ParametersInterceptor}. For example, actions may want to create a whitelist of parameters they will accept or a - * blacklist of paramters they will reject to prevent clients from setting other unexpected (and possibly dangerous) - * parameters. - * <!-- END SNIPPET: javadoc --> - * - * @author Bob Lee ([email protected]) - */ -public interface ParameterNameAware { - - /** - * Tests if the the action will accept the parameter with the given name. - * - * @param parameterName the parameter name - * @return <tt> if accepted, <tt>false</tt> otherwise - */ - boolean acceptableParameterName(String parameterName); - -} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java ---------------------------------------------------------------------- diff --git a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java b/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java deleted file mode 100644 index 68bb154..0000000 --- a/xwork-core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java +++ /dev/null @@ -1,143 +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.util.TextParseUtil; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -/** - * <!-- START SNIPPET: description --> - * This is a simple XWork interceptor that allows parameters (matching - * one of the paramNames attribute csv value) to be - * removed from the parameter map if they match a certain value - * (matching one of the paramValues attribute csv value), before they - * are set on the action. A typical usage would be to want a dropdown/select - * to map onto a boolean value on an action. The select had the options - * none, yes and no with values -1, true and false. The true and false would - * map across correctly. However the -1 would be set to false. - * This was not desired as one might needed the value on the action to stay null. - * This interceptor fixes this by preventing the parameter from ever reaching - * the action. - * <!-- END SNIPPET: description --> - * - * - * <!-- START SNIPPET: parameters --> - * <ul> - * <li>paramNames - A comma separated value (csv) indicating the parameter name - * whose param value should be considered that if they match any of the - * comma separated value (csv) from paramValues attribute, shall be - * removed from the parameter map such that they will not be applied - * to the action</li> - * <li>paramValues - A comma separated value (csv) indicating the parameter value that if - * matched shall have its parameter be removed from the parameter map - * such that they will not be applied to the action</li> - * </ul> - * <!-- END SNIPPET: parameters --> - * - * - * <!-- START SNIPPET: extending --> - * No intended extension point - * <!-- END SNIPPET: extending --> - * - * <pre> - * <!-- START SNIPPET: example --> - * - * <action name="sample" class="org.martingilday.Sample"> - * <interceptor-ref name="paramRemover"> - * <param name="paramNames">aParam,anotherParam</param> - * <param name="paramValues">--,-1</param> - * </interceptor-ref> - * <interceptor-ref name="defaultStack" /> - * ... - * </action> - * - * <!-- END SNIPPET: example --> - * </pre> - * - * - * @author martin.gilday - */ -public class ParameterRemoverInterceptor extends AbstractInterceptor { - - private static final Logger LOG = LogManager.getLogger(ParameterRemoverInterceptor.class); - - private static final long serialVersionUID = 1; - - private Set<String> paramNames = Collections.emptySet(); - private Set<String> paramValues = Collections.emptySet(); - - - /** - * Decide if the parameter should be removed from the parameter map based on - * <code>paramNames</code> and <code>paramValues</code>. - * - * @see com.opensymphony.xwork2.interceptor.AbstractInterceptor - */ - @Override - public String intercept(ActionInvocation invocation) throws Exception { - if (!(invocation.getAction() instanceof NoParameters) - && (null != this.paramNames)) { - ActionContext ac = invocation.getInvocationContext(); - final Map<String, Object> parameters = ac.getParameters(); - - if (parameters != null) { - for (String removeName : paramNames) { - // see if the field is in the parameter map - if (parameters.containsKey(removeName)) { - - try { - String[] values = (String[]) parameters.get(removeName); - String value = values[0]; - if (null != value && this.paramValues.contains(value)) { - parameters.remove(removeName); - } - } catch (Exception e) { - LOG.error("Failed to convert parameter to string", e); - } - } - } - } - } - return invocation.invoke(); - } - - /** - * Allows <code>paramNames</code> attribute to be set as comma-separated-values (csv). - * - * @param paramNames the paramNames to set - */ - public void setParamNames(String paramNames) { - this.paramNames = TextParseUtil.commaDelimitedStringToSet(paramNames); - } - - - /** - * Allows <code>paramValues</code> attribute to be set as a comma-separated-values (csv). - * - * @param paramValues the paramValues to set - */ - public void setParamValues(String paramValues) { - this.paramValues = TextParseUtil.commaDelimitedStringToSet(paramValues); - } -} -
