All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.opensymphony.xwork2.interceptor.ChainingInterceptor Maven / Gradle / Ivy

There is a newer version: 6.4.0
Show newest version
/*
 * 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.ActionChainResult;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;
import com.opensymphony.xwork2.Unchainable;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.ProxyUtil;
import com.opensymphony.xwork2.util.CompoundRoot;
import com.opensymphony.xwork2.util.TextParseUtil;
import com.opensymphony.xwork2.util.ValueStack;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
import com.opensymphony.xwork2.util.reflection.ReflectionProvider;

import java.util.*;


/**
 * 
 * 

* An interceptor that copies all the properties of every object in the value stack to the currently executing object, * except for any object that implements {@link Unchainable}. A collection of optional includes and * excludes may be provided to control how and which parameters are copied. Only includes or excludes may be * specified. Specifying both results in undefined behavior. See the javadocs for {@link ReflectionProvider#copy(Object, Object, * java.util.Map, java.util.Collection, java.util.Collection)} for more information. *

* *

* Note: It is important to remember that this interceptor does nothing if there are no objects already on the stack. *
This means two things: *
One, you can safely apply it to all your actions without any worry of adverse affects. *
Two, it is up to you to ensure an object exists in the stack prior to invoking this action. The most typical way this is done * is through the use of the chain result type, which combines with this interceptor to make up the action * chaining feature. *

* *

* Note: By default Errors, Field errors and Message aren't copied during chaining, to change the behaviour you can specify * the below three constants in struts.properties or struts.xml: *

* *
    *
  • struts.xwork.chaining.copyErrors - set to true to copy Action Errors
  • *
  • struts.xwork.chaining.copyFieldErrors - set to true to copy Field Errors
  • *
  • struts.xwork.chaining.copyMessages - set to true to copy Action Messages
  • *
* *

* Example: *

* *
 * <constant name="struts.xwork.chaining.copyErrors" value="true"/>
 * 
* *

* Note: By default actionErrors and actionMessages are excluded when copping object's properties. *

* * Interceptor parameters: * *
    *
  • excludes (optional) - the list of parameter names to exclude from copying (all others will be included).
  • *
  • includes (optional) - the list of parameter names to include when copying (all others will be excluded).
  • *
* * Extending the interceptor: * *

* There are no known extension points to this interceptor. *

* * Example code: * * *
 * <action name="someAction" class="com.examples.SomeAction">
 *     <interceptor-ref name="basicStack"/>
 *     <result name="success" type="chain">otherAction</result>
 * </action>
 * 
* *
 * <action name="otherAction" class="com.examples.OtherAction">
 *     <interceptor-ref name="chain"/>
 *     <interceptor-ref name="basicStack"/>
 *     <result name="success">good_result.ftl</result>
 * </action>
 * 
* * * * @author mrdon * @author tm_jee ( tm_jee(at)yahoo.co.uk ) * @see com.opensymphony.xwork2.ActionChainResult */ public class ChainingInterceptor extends AbstractInterceptor { private static final Logger LOG = LogManager.getLogger(ChainingInterceptor.class); private static final String ACTION_ERRORS = "actionErrors"; private static final String FIELD_ERRORS = "fieldErrors"; private static final String ACTION_MESSAGES = "actionMessages"; private boolean copyMessages = false; private boolean copyErrors = false; private boolean copyFieldErrors = false; protected Collection excludes; protected Collection includes; protected ReflectionProvider reflectionProvider; @Inject public void setReflectionProvider(ReflectionProvider prov) { this.reflectionProvider = prov; } @Inject(value = "struts.xwork.chaining.copyErrors", required = false) public void setCopyErrors(String copyErrors) { this.copyErrors = "true".equalsIgnoreCase(copyErrors); } @Inject(value = "struts.xwork.chaining.copyFieldErrors", required = false) public void setCopyFieldErrors(String copyFieldErrors) { this.copyFieldErrors = "true".equalsIgnoreCase(copyFieldErrors); } @Inject(value = "struts.xwork.chaining.copyMessages", required = false) public void setCopyMessages(String copyMessages) { this.copyMessages = "true".equalsIgnoreCase(copyMessages); } @Override public String intercept(ActionInvocation invocation) throws Exception { ValueStack stack = invocation.getStack(); CompoundRoot root = stack.getRoot(); if (shouldCopyStack(invocation, root)) { copyStack(invocation, root); } return invocation.invoke(); } private void copyStack(ActionInvocation invocation, CompoundRoot root) { List list = prepareList(root); Map ctxMap = invocation.getInvocationContext().getContextMap(); for (Object object : list) { if (shouldCopy(object)) { Object action = invocation.getAction(); Class editable = null; if(ProxyUtil.isProxy(action)) { editable = ProxyUtil.ultimateTargetClass(action); } reflectionProvider.copy(object, action, ctxMap, prepareExcludes(), includes, editable); } } } private Collection prepareExcludes() { Collection localExcludes = excludes; if (!copyErrors || !copyMessages ||!copyFieldErrors) { if (localExcludes == null) { localExcludes = new HashSet(); if (!copyErrors) { localExcludes.add(ACTION_ERRORS); } if (!copyMessages) { localExcludes.add(ACTION_MESSAGES); } if (!copyFieldErrors) { localExcludes.add(FIELD_ERRORS); } } } return localExcludes; } private boolean shouldCopy(Object o) { return o != null && !(o instanceof Unchainable); } @SuppressWarnings("unchecked") private List prepareList(CompoundRoot root) { List list = new ArrayList(root); list.remove(0); Collections.reverse(list); return list; } private boolean shouldCopyStack(ActionInvocation invocation, CompoundRoot root) throws Exception { Result result = invocation.getResult(); return root.size() > 1 && (result == null || ActionChainResult.class.isAssignableFrom(result.getClass())); } /** * Gets list of parameter names to exclude * * @return the exclude list */ public Collection getExcludes() { return excludes; } /** * Sets the list of parameter names to exclude from copying (all others will be included). * * @param excludes the excludes list as comma separated String */ public void setExcludes(String excludes) { this.excludes = TextParseUtil.commaDelimitedStringToSet(excludes); } /** * Sets the list of parameter names to exclude from copying (all others will be included). * * @param excludes the excludes list */ public void setExcludesCollection(Collection excludes) { this.excludes = excludes; } /** * Gets list of parameter names to include * * @return the include list */ public Collection getIncludes() { return includes; } /** * Sets the list of parameter names to include when copying (all others will be excluded). * * @param includes the includes list as comma separated String */ public void setIncludes(String includes) { this.includes = TextParseUtil.commaDelimitedStringToSet(includes); } /** * Sets the list of parameter names to include when copying (all others will be excluded). * * @param includes the includes list */ public void setIncludesCollection(Collection includes) { this.includes = includes; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy