View Javadoc

    1   /*
    2    * $Id: ActionFormValidationInterceptor.java 478625 2006-11-23 17:31:52Z wsmoak $
    3    *
    4    * Copyright 2000-2004 The Apache Software Foundation.
    5    *
    6    * Licensed under the Apache License, Version 2.0 (the "License");
    7    * you may not use this file except in compliance with the License.
    8    * You may obtain a copy of the License at
    9    *
    10   *      http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18
    19  package org.apache.struts2.s1;
    20
    21  import java.io.IOException;
    22  import java.net.URL;
    23  import java.util.ArrayList;
    24  import java.util.List;
    25  import java.util.StringTokenizer;
    26
    27  import javax.servlet.ServletContext;
    28  import javax.servlet.ServletException;
    29  import javax.servlet.UnavailableException;
    30  import javax.servlet.http.HttpServletRequest;
    31
    32  import org.apache.commons.logging.Log;
    33  import org.apache.commons.logging.LogFactory;
    34  import org.apache.commons.validator.ValidatorResources;
    35  import org.apache.struts.Globals;
    36  import org.apache.struts.action.ActionErrors;
    37  import org.apache.struts.action.ActionForm;
    38  import org.apache.struts.action.ActionMapping;
    39  import org.apache.struts.action.ActionServlet;
    40  import org.apache.struts.config.ModuleConfig;
    41  import org.apache.struts.validator.ValidatorPlugIn;
    42  import org.apache.struts2.ServletActionContext;
    43  import org.apache.struts2.StrutsException;
    44  import org.apache.struts2.dispatcher.Dispatcher;
    45  import org.apache.struts2.util.ServletContextAware;
    46  import org.xml.sax.SAXException;
    47
    48  import com.opensymphony.xwork2.ActionContext;
    49  import com.opensymphony.xwork2.ActionInvocation;
    50  import com.opensymphony.xwork2.TextProvider;
    51  import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
    52  import com.opensymphony.xwork2.interceptor.ScopedModelDriven;
    53
    54  /***
    55   *  Calls the validate() method on the ActionForm, if it exists.  The errors are handled
    56   *  like regular XWork validation errors.  Action-level validation flag supported if the
    57   *  action is a subclass of Struts1Action.
    58   */
    59  public class ActionFormValidationInterceptor extends AbstractInterceptor {
    60
    61      private String pathnames;
    62      private boolean stopOnFirstError;
    63      private boolean initialized = false;
    64
    65      private static final Log log = LogFactory.getLog(ActionFormValidationInterceptor.class);
    66
    67      /***
    68       * Delimitter for Validator resources.
    69       */
    70      private final static String RESOURCE_DELIM = ",";
    71
    72      /***
    73       * Initializes the validation resources
    74       */
    75      private void initResources(ServletContext servletContext) {
    76          if (pathnames != null) {
    77              ActionContext ctx = ActionContext.getContext();
    78              try {
    79
    80                  ValidatorResources resources = this.loadResources(servletContext);
    81
    82
    83                  String prefix = ctx.getActionInvocation().getProxy().getNamespace();
    84
    85
    86                  servletContext.setAttribute(ValidatorPlugIn.VALIDATOR_KEY + prefix, resources);
    87
    88                  servletContext.setAttribute(ValidatorPlugIn.STOP_ON_ERROR_KEY + '.'
    89                      + prefix,
    90                      (this.stopOnFirstError ? Boolean.TRUE : Boolean.FALSE));
    91              } catch (Exception e) {
    92                  throw new StrutsException(
    93                      "Cannot load a validator resource from '" + pathnames + "'", e);
    94              }
    95          }
    96      }
    97
    98      @Override
    99      public String intercept(ActionInvocation invocation) throws Exception {
    100         // Lazy load the resources because the servlet context isn't available at init() time
    101         synchronized (this) {
    102             if (!initialized) {
    103                 initResources(ServletActionContext.getServletContext());
    104                 initialized = true;
    105             }
    106         }
    107         Object action = invocation.getAction();
    108
    109
    110         if ((action instanceof ScopedModelDriven) &&
    111             (!(action instanceof Struts1Action) || ((Struts1Action)action).isValidate())) {
    112             ScopedModelDriven modelDriven = (ScopedModelDriven) action;
    113             Object model = modelDriven.getModel();
    114             if (model != null) {
    115                 HttpServletRequest req = ServletActionContext.getRequest();
    116                 Struts1Factory strutsFactory = new Struts1Factory(Dispatcher.getInstance().getConfigurationManager().getConfiguration());
    117                 ActionMapping mapping = strutsFactory.createActionMapping(invocation.getProxy().getConfig());
    118                 ModuleConfig moduleConfig = strutsFactory.createModuleConfig(invocation.getProxy().getConfig().getPackageName());
    119                 req.setAttribute(Globals.MODULE_KEY, moduleConfig);
    120                 req.setAttribute(Globals.MESSAGES_KEY, new WrapperMessageResources((TextProvider)invocation.getAction()));
    121
    122                 mapping.setAttribute(modelDriven.getScopeKey());
    123
    124                 ActionForm form = (ActionForm) model;
    125                 form.setServlet(new ActionServlet(){
    126                     public ServletContext getServletContext() {
    127                         return ServletActionContext.getServletContext();
    128                     }
    129                 });
    130                 ActionErrors errors = form.validate(mapping, req);
    131                 strutsFactory.convertErrors(errors, action);
    132             }
    133         }
    134         return invocation.invoke();
    135     }
    136
    137     /***
    138      * Initialize the validator resources for this module.
    139      *
    140      * @throws IOException      if an input/output error is encountered
    141      * @throws ServletException if we cannot initialize these resources
    142      */
    143     protected ValidatorResources loadResources(ServletContext ctx)
    144         throws IOException, ServletException {
    145         if ((pathnames == null) || (pathnames.length() <= 0)) {
    146             return null;
    147         }
    148
    149         StringTokenizer st = new StringTokenizer(pathnames, RESOURCE_DELIM);
    150
    151         List urlList = new ArrayList();
    152         ValidatorResources resources = null;
    153         try {
    154             while (st.hasMoreTokens()) {
    155                 String validatorRules = st.nextToken().trim();
    156
    157                 if (log.isInfoEnabled()) {
    158                     log.info("Loading validation rules file from '"
    159                         + validatorRules + "'");
    160                 }
    161
    162                 URL input =
    163                     ctx.getResource(validatorRules);
    164
    165                 // If the config isn't in the servlet context, try the class
    166                 // loader which allows the config files to be stored in a jar
    167                 if (input == null) {
    168                     input = getClass().getResource(validatorRules);
    169                 }
    170
    171                 if (input != null) {
    172                     urlList.add(input);
    173                 } else {
    174                     throw new ServletException(
    175                         "Skipping validation rules file from '"
    176                         + validatorRules + "'.  No url could be located.");
    177                 }
    178             }
    179
    180             int urlSize = urlList.size();
    181             String[] urlArray = new String[urlSize];
    182
    183             for (int urlIndex = 0; urlIndex < urlSize; urlIndex++) {
    184                 URL url = (URL) urlList.get(urlIndex);
    185
    186                 urlArray[urlIndex] = url.toExternalForm();
    187             }
    188
    189             resources =  new ValidatorResources(urlArray);
    190         } catch (SAXException sex) {
    191             log.error("Skipping all validation", sex);
    192             throw new StrutsException("Skipping all validation because the validation files cannot be loaded", sex);
    193         }
    194         return resources;
    195     }
    196
    197     /***
    198      * @return the pathnames
    199      */
    200     public String getPathnames() {
    201         return pathnames;
    202     }
    203
    204     /***
    205      * @param pathnames the pathnames to set
    206      */
    207     public void setPathnames(String pathNames) {
    208         this.pathnames = pathNames;
    209     }
    210
    211     /***
    212      * @return the stopOnFirstError
    213      */
    214     public boolean isStopOnFirstError() {
    215         return stopOnFirstError;
    216     }
    217
    218     /***
    219      * @param stopOnFirstError the stopOnFirstError to set
    220      */
    221     public void setStopOnFirstError(boolean stopOnFirstError) {
    222         this.stopOnFirstError = stopOnFirstError;
    223     }
    224
    225 }