Home » xwork-2.1.5 » com.opensymphony » xwork2 » interceptor » [javadoc | source]

    1   /*
    2    * Copyright (c) 2002-2006 by OpenSymphony
    3    * All rights reserved.
    4    */
    5   package com.opensymphony.xwork2.interceptor;
    6   
    7   import com.opensymphony.xwork2.ActionContext;
    8   import com.opensymphony.xwork2.ActionInvocation;
    9   import com.opensymphony.xwork2.ValidationAware;
   10   import com.opensymphony.xwork2.inject.Inject;
   11   import com.opensymphony.xwork2.config.entities.ActionConfig;
   12   import com.opensymphony.xwork2.config.entities.Parameterizable;
   13   import com.opensymphony.xwork2.util;
   14   import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
   15   import com.opensymphony.xwork2.util.logging.Logger;
   16   import com.opensymphony.xwork2.util.logging.LoggerFactory;
   17   
   18   import java.util.Collections;
   19   import java.util.Map;
   20   import java.util.TreeMap;
   21   
   22   
   23   /**
   24    * <!-- START SNIPPET: description -->
   25    *
   26    * This interceptor populates the action with the static parameters defined in the action configuration. If the action
   27    * implements {@link Parameterizable}, a map of the static parameters will be also be passed directly to the action.
   28    * The static params will be added to the request params map, unless "merge" is set to false.
   29    *
   30    * <p/> Parameters are typically defined with &lt;param&gt; elements within xwork.xml.
   31    *
   32    * <!-- END SNIPPET: description -->
   33    *
   34    * <p/> <u>Interceptor parameters:</u>
   35    *
   36    * <!-- START SNIPPET: parameters -->
   37    *
   38    * <ul>
   39    *
   40    * <li>None</li>
   41    *
   42    * </ul>
   43    *
   44    * <!-- END SNIPPET: parameters -->
   45    *
   46    * <p/> <u>Extending the interceptor:</u>
   47    *
   48    * <!-- START SNIPPET: extending -->
   49    *
   50    * <p/>There are no extension points to this interceptor.
   51    *
   52    * <!-- END SNIPPET: extending -->
   53    *
   54    * <p/> <u>Example code:</u>
   55    *
   56    * <pre>
   57    * <!-- START SNIPPET: example -->
   58    * &lt;action name="someAction" class="com.examples.SomeAction"&gt;
   59    *     &lt;interceptor-ref name="staticParams"&gt;
   60    *          &lt;param name="parse"&gt;true&lt;/param&gt;
   61    *          &lt;param name="overwrite"&gt;false&lt;/param&gt;
   62    *     &lt;/interceptor-ref&gt;
   63    *     &lt;result name="success"&gt;good_result.ftl&lt;/result&gt;
   64    * &lt;/action&gt;
   65    * <!-- END SNIPPET: example -->
   66    * </pre>
   67    *
   68    * @author Patrick Lightbody
   69    */
   70   public class StaticParametersInterceptor extends AbstractInterceptor {
   71   
   72       private boolean parse;
   73       private boolean overwrite;
   74       private boolean merge = true;
   75   
   76       static boolean devMode = false;
   77   
   78       private static final Logger LOG = LoggerFactory.getLogger(StaticParametersInterceptor.class);
   79   
   80       private ValueStackFactory valueStackFactory;
   81   
   82       @Inject
   83       public void setValueStackFactory(ValueStackFactory valueStackFactory) {
   84           this.valueStackFactory = valueStackFactory;
   85       }
   86   
   87       @Inject("devMode")
   88       public static void setDevMode(String mode) {
   89           devMode = "true".equals(mode);
   90       }    
   91   
   92       public void setParse(String value) {
   93           this.parse = Boolean.valueOf(value).booleanValue();
   94       }
   95   
   96        public void setMerge(String value) {
   97           this.merge = Boolean.valueOf(value).booleanValue();
   98       }
   99   
  100       /**
  101        * Overwrites already existing parameters from other sources.
  102        * Static parameters are the successor over previously set parameters, if true.
  103        *
  104        * @param value
  105        */
  106       public void setOverwrite(String value) {
  107           this.overwrite = Boolean.valueOf(value).booleanValue();
  108       }
  109   
  110       @Override
  111       public String intercept(ActionInvocation invocation) throws Exception {
  112           ActionConfig config = invocation.getProxy().getConfig();
  113           Object action = invocation.getAction();
  114   
  115           final Map<String, String> parameters = config.getParams();
  116   
  117           if (LOG.isDebugEnabled()) {
  118               LOG.debug("Setting static parameters " + parameters);
  119           }
  120   
  121           // for actions marked as Parameterizable, pass the static parameters directly
  122           if (action instanceof Parameterizable) {
  123               ((Parameterizable) action).setParams(parameters);
  124           }
  125   
  126           if (parameters != null) {
  127               ActionContext ac = ActionContext.getContext();
  128               Map<String, Object> contextMap = ac.getContextMap();
  129               try {
  130                   ReflectionContextState.setCreatingNullObjects(contextMap, true);
  131                   ReflectionContextState.setReportingConversionErrors(contextMap, true);
  132                   final ValueStack stack = ac.getValueStack();
  133   
  134                   ValueStack newStack = valueStackFactory.createValueStack(stack);
  135                   boolean clearableStack = newStack instanceof ClearableValueStack;
  136                   if (clearableStack) {
  137                       //if the stack's context can be cleared, do that to prevent OGNL
  138                       //from having access to objects in the stack, see XW-641
  139                       ((ClearableValueStack)newStack).clearContextValues();
  140                       Map<String, Object> context = newStack.getContext();
  141                       ReflectionContextState.setCreatingNullObjects(context, true);
  142                       ReflectionContextState.setDenyMethodExecution(context, true);
  143                       ReflectionContextState.setReportingConversionErrors(context, true);
  144   
  145                       //keep locale from original context
  146                       context.put(ActionContext.LOCALE, stack.getContext().get(ActionContext.LOCALE));
  147                   }
  148   
  149                   for (Map.Entry<String, String> entry : parameters.entrySet()) {
  150                       Object val = entry.getValue();
  151                       if (parse && val instanceof String) {
  152                           val = TextParseUtil.translateVariables(val.toString(), stack);
  153                       }
  154                       try {
  155                           newStack.setValue(entry.getKey(), val);
  156                       } catch (RuntimeException e) {
  157                           if (devMode) {
  158                               String developerNotification = LocalizedTextUtil.findText(ParametersInterceptor.class, "devmode.notification", ActionContext.getContext().getLocale(), "Developer Notification:\n{0}", new Object[]{
  159                                       "Unexpected Exception caught setting '" + entry.getKey() + "' on '" + action.getClass() + ": " + e.getMessage()
  160                               });
  161                               LOG.error(developerNotification);
  162                               if (action instanceof ValidationAware) {
  163                                   ((ValidationAware) action).addActionMessage(developerNotification);
  164                               }
  165                           }
  166                       }
  167                   }
  168   
  169                    if (clearableStack && (stack.getContext() != null) && (newStack.getContext() != null))
  170                       stack.getContext().put(ActionContext.CONVERSION_ERRORS, newStack.getContext().get(ActionContext.CONVERSION_ERRORS));
  171   
  172                   if (merge)
  173                       addParametersToContext(ac, parameters);
  174               } finally {
  175                   ReflectionContextState.setCreatingNullObjects(contextMap, false);
  176                   ReflectionContextState.setReportingConversionErrors(contextMap, false);
  177               }
  178           }
  179           return invocation.invoke();
  180       }
  181   
  182   
  183       /**
  184        * @param ac The action context
  185        * @return the parameters from the action mapping in the context.  If none found, returns
  186        *         an empty map.
  187        */
  188       protected Map<String, String> retrieveParameters(ActionContext ac) {
  189           ActionConfig config = ac.getActionInvocation().getProxy().getConfig();
  190           if (config != null) {
  191               return config.getParams();
  192           } else {
  193               return Collections.emptyMap();
  194           }
  195       }
  196   
  197       /**
  198        * Adds the parameters into context's ParameterMap.
  199        * As default, static parameters will not overwrite existing paramaters from other sources.
  200        * If you want the static parameters as successor over already existing parameters, set overwrite to <tt>true</tt>.
  201        *
  202        * @param ac        The action context
  203        * @param newParams The parameter map to apply
  204        */
  205       protected void addParametersToContext(ActionContext ac, Map<String, ?> newParams) {
  206           Map<String, Object> previousParams = ac.getParameters();
  207   
  208           Map<String, Object> combinedParams;
  209           if ( overwrite ) {
  210               if (previousParams != null) {
  211                   combinedParams = new TreeMap<String, Object>(previousParams);
  212               } else {
  213                   combinedParams = new TreeMap<String, Object>();
  214               }
  215               if ( newParams != null) {
  216                   combinedParams.putAll(newParams);
  217               }
  218           } else {
  219               if (newParams != null) {
  220                   combinedParams = new TreeMap<String, Object>(newParams);
  221               } else {
  222                   combinedParams = new TreeMap<String, Object>();
  223               }
  224               if ( previousParams != null) {
  225                   combinedParams.putAll(previousParams);
  226               }
  227           }
  228           ac.setParameters(combinedParams);
  229       }
  230   }

Home » xwork-2.1.5 » com.opensymphony » xwork2 » interceptor » [javadoc | source]