| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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; |
| |
| /** |
| * <p> |
| * A utility class for invoking prefixed methods in action class. |
| * |
| * Interceptors that made use of this class are: |
| * </p> |
| * <ul> |
| * <li>DefaultWorkflowInterceptor</li> |
| * <li>PrepareInterceptor</li> |
| * </ul> |
| * * |
| * <!-- 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]; |
| |
| /** |
| * <p> |
| * 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> |
| * |
| * <p> |
| * For example, with |
| * </p> |
| * |
| * <pre> |
| * invokePrefixMethod(actionInvocation, new String[] { "prepare", "prepareDo" }); |
| * </pre> |
| * |
| * <p> |
| * Assuming <code>actionInvocation.getProxy(),getMethod()</code> returns "submit", |
| * the order of invocation would be as follows:- |
| * </p> |
| * |
| * <ol> |
| * <li>prepareSubmit()</li> |
| * <li>prepareDoSubmit()</li> |
| * </ol> |
| * |
| * <p> |
| * If <code>prepareSubmit()</code> exists, it will be invoked and this method |
| * will return, <code>prepareDoSubmit()</code> will NOT be invoked. |
| * </p> |
| * |
| * <p> |
| * On the other hand, if <code>prepareDoSubmit()</code> does not exists, and |
| * <code>prepareDoSubmit()</code> exists, it will be invoked. |
| * </p> |
| * |
| * <p> |
| * If none of those two methods exists, nothing will be invoked. |
| * </p> |
| * |
| * @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 prefix : prefixes) { |
| String prefixedMethodName = prefix + 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; |
| } |
| |
| /** |
| * <p> |
| * This method capitalized the first character of <code>methodName</code>. |
| * <br> |
| * eg. <code>capitalizeMethodName("someMethod");</code> will return <code>"SomeMethod"</code>. |
| * </p> |
| * |
| * @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); |
| } |
| |
| } |