Save This Page
Home » struts-2.0.11.2-src » org.apache » struts2 » interceptor » [javadoc | source]
    1   /*
    2    * $Id: MessageStoreInterceptor.java 471756 2006-11-06 15:01:43Z husted $
    3    *
    4    * Licensed to the Apache Software Foundation (ASF) under one
    5    * or more contributor license agreements.  See the NOTICE file
    6    * distributed with this work for additional information
    7    * regarding copyright ownership.  The ASF licenses this file
    8    * to you under the Apache License, Version 2.0 (the
    9    * "License"); you may not use this file except in compliance
   10    * with the License.  You may obtain a copy of the License at
   11    *
   12    *  http://www.apache.org/licenses/LICENSE-2.0
   13    *
   14    * Unless required by applicable law or agreed to in writing,
   15    * software distributed under the License is distributed on an
   16    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   17    * KIND, either express or implied.  See the License for the
   18    * specific language governing permissions and limitations
   19    * under the License.
   20    */
   21   package org.apache.struts2.interceptor;
   22   
   23   import java.util.ArrayList;
   24   import java.util.Collection;
   25   import java.util.LinkedHashMap;
   26   import java.util.Map;
   27   
   28   import org.apache.commons.logging.Log;
   29   import org.apache.commons.logging.LogFactory;
   30   
   31   import com.opensymphony.xwork2.ActionContext;
   32   import com.opensymphony.xwork2.ActionInvocation;
   33   import com.opensymphony.xwork2.ValidationAware;
   34   import com.opensymphony.xwork2.interceptor.Interceptor;
   35   
   36   /**
   37    * <!-- START SNIPPET: description -->
   38    *
   39    * An interceptor to store {@link ValidationAware} action's messages / errors and field errors into
   40    * Http Session, such that it will be retrieveable at a later stage. This allows the action's message /
   41    * errors and field errors to be available longer that just the particular http request.
   42    *
   43    * <p/>
   44    *
   45    * In the 'STORE' mode, the interceptor will store the {@link ValidationAware} action's message / errors
   46    * and field errors into Http session.
   47    *
   48    * <p/>
   49    *
   50    * In the 'RETRIEVE' mode, the interceptor will retrieve the stored action's message / errors  and field
   51    * errors and put them back into the {@link ValidationAware} action.
   52    *
   53    * <p/>
   54    *
   55    * The interceptor does nothing in the 'NONE' mode, which is the default.
   56    *
   57    * <p/>
   58    *
   59    * The operation mode could be switched using :- <p/>
   60    * 1] Setting the iterceptor parameter eg.
   61    * <pre>
   62    *   &lt;action name="submitApplication" ...&gt;
   63    *      &lt;interceptor-ref name="store"&gt;
   64    *         &lt;param name="operationMode"&gtl;STORE&lt;/param&gt;
   65    *      &lt;/interceptor-ref&gt;
   66    *      &lt;interceptor-ref name="defaultStack" /&gt;
   67    *      ....
   68    *   &lt;/action&gt;
   69    * </pre>
   70    *
   71    * 2] Through request parameter (allowRequestParameterSwitch must be 'true' which is the default)
   72    * <pre>
   73    *   // the request will have the operation mode in 'STORE'
   74    *   http://localhost:8080/context/submitApplication.action?operationMode=STORE
   75    * </pre>
   76    *
   77    * <!-- END SNIPPET: description -->
   78    *
   79    *
   80    * <!-- START SNIPPET: parameters -->
   81    *
   82    * <ul>
   83    *      <li>allowRequestParameterSwitch - To enable request parameter that could switch the operation mode
   84    *                                        of this interceptor. </li>
   85    *      <li>requestParameterSwitch - The request parameter that will indicate what mode this
   86    *                                   interceptor is in. </li>
   87    *      <li>operationMode - The operation mode this interceptor should be in
   88    *                          (either 'STORE', 'RETRIEVE' or 'NONE'). 'NONE' being the default.</li>
   89    * </ul>
   90    *
   91    * <!-- END SNIPPET: parameters -->
   92    *
   93    * <p/>
   94    *
   95    * <!-- START SNIPPET: extending -->
   96    *
   97    * The following method could be overriden :-
   98    * <ul>
   99    *  <li>getRequestOperationMode - get the operation mode of this interceptor based on the request parameters</li>
  100    *  <li>mergeCollection - merge two collections</li>
  101    *  <li>mergeMap - merge two map</li>
  102    * </ul>
  103    *
  104    * <!-- END SNIPPET: extending -->
  105    *
  106    * <pre>
  107    * <!-- START SNIPPET: example -->
  108    *
  109    * &lt;action name="submitApplication" ....&gt;
  110    *    &lt;interceptor-ref name="store"&gt;
  111    *      &lt;param name="operationMode">STORE&lt;/param&gt;
  112    *    &lt;/interceptor-ref&gt;
  113    *    &lt;interceptor-ref name="defaultStack" /&gt;
  114    *    &lt;result name="input" type="redirect">applicationFailed.action&lt;/result&gt;
  115    *    &lt;result type="dispatcher"&gt;applicationSuccess.jsp&lt;/result&gt;
  116    * &lt;/action&gt;
  117    *
  118    * &lt;action name="applicationFailed" ....&gt;
  119    *    &lt;interceptor-ref name="store"&gt;
  120    *       &lt;param name="operationMode"&gt;RETRIEVE&lt;/param&gt;
  121    *    &lt;/interceptor-ref&gt;
  122    *    &lt;result&gt;applicationFailed.jsp&lt;/result&gt;
  123    * &lt;/action&gt;
  124    *
  125    * <!-- END SNIPPET: example -->
  126    * </pre>
  127    *
  128    * <!-- START SNIPPET: exampleDescription -->
  129    *
  130    * With the example above, 'submitApplication.action' will have the action messages / errors / field errors stored
  131    * in the Http Session. Later when needed, (in this case, when 'applicationFailed.action' is fired, it
  132    * will get the action messages / errors / field errors stored in the Http Session and put them back into
  133    * the action.
  134    *
  135    * <!-- END SNIPPET: exampleDescription -->
  136    *
  137    * @version $Date: 2006-11-06 16:01:43 +0100 (Mo, 06 Nov 2006) $ $Id: MessageStoreInterceptor.java 471756 2006-11-06 15:01:43Z husted $
  138    */
  139   public class MessageStoreInterceptor implements Interceptor {
  140   
  141       private static final long serialVersionUID = 4491997514314242420L;
  142   
  143       private static final Log _log = LogFactory.getLog(MessageStoreInterceptor.class);
  144   
  145   
  146       public static final String STORE_MODE = "STORE";
  147       public static final String RETRIEVE_MODE = "RETRIEVE";
  148       public static final String NONE = "NONE";
  149   
  150       private boolean allowRequestParameterSwitch = true;
  151       private String requestParameterSwitch = "operationMode";
  152       private String operationMode = NONE;
  153   
  154       public static String fieldErrorsSessionKey = "__MessageStoreInterceptor_FieldErrors_SessionKey";
  155       public static String actionErrorsSessionKey = "__MessageStoreInterceptor_ActionErrors_SessionKey";
  156       public static String actionMessagesSessionKey = "__MessageStoreInterceptor_ActionMessages_SessionKey";
  157   
  158   
  159   
  160       public void setAllowRequestParameterSwitch(boolean allowRequestParameterSwitch) {
  161           this.allowRequestParameterSwitch = allowRequestParameterSwitch;
  162       }
  163       public boolean getAllowRequestParameterSwitch() {
  164           return this.allowRequestParameterSwitch;
  165       }
  166   
  167   
  168       public void setRequestParameterSwitch(String requestParameterSwitch) {
  169           this.requestParameterSwitch = requestParameterSwitch;
  170       }
  171       public String getRequestParameterSwitch() {
  172           return this.requestParameterSwitch;
  173       }
  174   
  175   
  176   
  177       public void setOperationMode(String operationMode) {
  178           this.operationMode = operationMode;
  179       }
  180       public String getOperationModel() {
  181           return this.operationMode;
  182       }
  183   
  184   
  185       public void destroy() {
  186       }
  187   
  188       public void init() {
  189       }
  190   
  191       public String intercept(ActionInvocation invocation) throws Exception {
  192           _log.debug("entering MessageStoreInterceptor ...");
  193   
  194           before(invocation);
  195           String result = invocation.invoke();
  196           after(invocation, result);
  197   
  198           _log.debug("exit executing MessageStoreInterceptor");
  199           return result;
  200       }
  201   
  202       /**
  203        * Handle the retrieving of field errors / action messages / field errors, which is
  204        * done before action invocation, and the <code>operationMode</code> is 'RETRIEVE'.
  205        *
  206        * @param invocation
  207        * @throws Exception
  208        */
  209       protected void before(ActionInvocation invocation) throws Exception {
  210           String reqOperationMode = getRequestOperationMode(invocation);
  211   
  212           if (RETRIEVE_MODE.equalsIgnoreCase(reqOperationMode) ||
  213                   RETRIEVE_MODE.equalsIgnoreCase(operationMode)) {
  214   
  215               Object action = invocation.getAction();
  216               if (action instanceof ValidationAware) {
  217                   // retrieve error / message from session
  218                   Map session = (Map) invocation.getInvocationContext().get(ActionContext.SESSION);
  219                   ValidationAware validationAwareAction = (ValidationAware) action;
  220   
  221                   _log.debug("retrieve error / message from session to populate into action ["+action+"]");
  222   
  223                   Collection actionErrors = (Collection) session.get(actionErrorsSessionKey);
  224                   Collection actionMessages = (Collection) session.get(actionMessagesSessionKey);
  225                   Map fieldErrors = (Map) session.get(fieldErrorsSessionKey);
  226   
  227                   if (actionErrors != null && actionErrors.size() > 0) {
  228                       Collection mergedActionErrors = mergeCollection(validationAwareAction.getActionErrors(), actionErrors);
  229                       validationAwareAction.setActionErrors(mergedActionErrors);
  230                   }
  231   
  232                   if (actionMessages != null && actionMessages.size() > 0) {
  233                       Collection mergedActionMessages = mergeCollection(validationAwareAction.getActionMessages(), actionMessages);
  234                       validationAwareAction.setActionMessages(mergedActionMessages);
  235                   }
  236   
  237                   if (fieldErrors != null && fieldErrors.size() > 0) {
  238                       Map mergedFieldErrors = mergeMap(validationAwareAction.getFieldErrors(), fieldErrors);
  239                       validationAwareAction.setFieldErrors(mergedFieldErrors);
  240                   }
  241                   session.remove(actionErrorsSessionKey);
  242                   session.remove(actionMessagesSessionKey);
  243                   session.remove(fieldErrorsSessionKey);
  244               }
  245           }
  246       }
  247   
  248       /**
  249        * Handle the storing of field errors / action messages / field errors, which is
  250        * done after action invocation, and the <code>operationMode</code> is in 'STORE'.
  251        *
  252        * @param invocation
  253        * @param result
  254        * @throws Exception
  255        */
  256       protected void after(ActionInvocation invocation, String result) throws Exception {
  257   
  258           String reqOperationMode = getRequestOperationMode(invocation);
  259           if (STORE_MODE.equalsIgnoreCase(reqOperationMode) ||
  260                   STORE_MODE.equalsIgnoreCase(operationMode)) {
  261   
  262               Object action = invocation.getAction();
  263               if (action instanceof ValidationAware) {
  264                   // store error / messages into session
  265                   Map session = (Map) invocation.getInvocationContext().get(ActionContext.SESSION);
  266   
  267                   _log.debug("store action ["+action+"] error/messages into session ");
  268   
  269                   ValidationAware validationAwareAction = (ValidationAware) action;
  270                   session.put(actionErrorsSessionKey, validationAwareAction.getActionErrors());
  271                   session.put(actionMessagesSessionKey, validationAwareAction.getActionMessages());
  272                   session.put(fieldErrorsSessionKey, validationAwareAction.getFieldErrors());
  273               }
  274               else {
  275                   _log.debug("Action ["+action+"] is not ValidationAware, no message / error that are storeable");
  276               }
  277           }
  278       }
  279   
  280   
  281       /**
  282        * Get the operationMode through request paramter, if <code>allowRequestParameterSwitch</code>
  283        * is 'true', else it simply returns 'NONE', meaning its neither in the 'STORE_MODE' nor
  284        * 'RETRIEVE_MODE'.
  285        *
  286        * @return String
  287        */
  288       protected String getRequestOperationMode(ActionInvocation invocation) {
  289           String reqOperationMode = NONE;
  290           if (allowRequestParameterSwitch) {
  291               Map reqParams = (Map) invocation.getInvocationContext().get(ActionContext.PARAMETERS);
  292               boolean containsParameter = reqParams.containsKey(requestParameterSwitch);
  293               if (containsParameter) {
  294                   String[] reqParamsArr = (String[]) reqParams.get(requestParameterSwitch);
  295                   if (reqParamsArr != null && reqParamsArr.length > 0) {
  296                       reqOperationMode = reqParamsArr[0];
  297                   }
  298               }
  299           }
  300           return reqOperationMode;
  301       }
  302   
  303       /**
  304        * Merge <code>col1</code> and <code>col2</code> and return the composite
  305        * <code>Collection</code>.
  306        *
  307        * @param col1
  308        * @param col2
  309        * @return Collection
  310        */
  311       protected Collection mergeCollection(Collection col1, Collection col2) {
  312           Collection _col1 = (col1 == null ? new ArrayList() : col1);
  313           Collection _col2 = (col2 == null ? new ArrayList() : col2);
  314           _col1.addAll(_col2);
  315           return _col1;
  316       }
  317   
  318       /**
  319        * Merge <code>map1</code> and <code>map2</code> and return the composite
  320        * <code>Map</code>
  321        *
  322        * @param map1
  323        * @param map2
  324        * @return Map
  325        */
  326       protected Map mergeMap(Map map1, Map map2) {
  327           Map _map1 = (map1 == null ? new LinkedHashMap() : map1);
  328           Map _map2 = (map2 == null ? new LinkedHashMap() : map2);
  329           _map1.putAll(_map2);
  330           return _map1;
  331       }
  332   
  333   }

Save This Page
Home » struts-2.0.11.2-src » org.apache » struts2 » interceptor » [javadoc | source]