View Javadoc

1   /*
2    * $Id: ValidatorPlugIn.java 421119 2006-07-12 04:49:11Z 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  package org.apache.struts.validator;
19  
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  import org.apache.commons.validator.ValidatorResources;
23  import org.apache.struts.action.ActionServlet;
24  import org.apache.struts.action.PlugIn;
25  import org.apache.struts.config.ModuleConfig;
26  import org.xml.sax.SAXException;
27  
28  import javax.servlet.ServletException;
29  import javax.servlet.UnavailableException;
30  
31  import java.io.IOException;
32  
33  import java.net.URL;
34  
35  import java.util.ArrayList;
36  import java.util.List;
37  import java.util.StringTokenizer;
38  
39  /***
40   * Loads <code>ValidatorResources</code> based on configuration in the
41   * struts-config.xml file.
42   *
43   * @version $Rev: 421119 $ $Date: 2005-08-30 00:22:27 -0400 (Tue, 30 Aug 2005)
44   *          $
45   * @since Struts 1.1
46   */
47  public class ValidatorPlugIn implements PlugIn {
48      /***
49       * Commons Logging instance.
50       */
51      private static Log log = LogFactory.getLog(ValidatorPlugIn.class);
52  
53      /***
54       * Delimitter for Validator resources.
55       */
56      private final static String RESOURCE_DELIM = ",";
57  
58      /***
59       * Application scope key that <code>ValidatorResources</code> is stored
60       * under.
61       */
62      public final static String VALIDATOR_KEY =
63          "org.apache.commons.validator.VALIDATOR_RESOURCES";
64  
65      /***
66       * Application scope key that <code>StopOnError</code> is stored under.
67       *
68       * @since Struts 1.2
69       */
70      public final static String STOP_ON_ERROR_KEY =
71          "org.apache.struts.validator.STOP_ON_ERROR";
72  
73      /***
74       * The module configuration for our owning module.
75       */
76      private ModuleConfig config = null;
77  
78      /***
79       * The {@link ActionServlet} owning this application.
80       */
81      private ActionServlet servlet = null;
82  
83      /***
84       * The set of Form instances that have been created and initialized, keyed
85       * by the struts form name.
86       */
87      protected ValidatorResources resources = null;
88  
89      // ------------------------------------------------------------- Properties
90  
91      /***
92       * A comma delimitted list of Validator resource.
93       */
94      private String pathnames = null;
95  
96      /***
97       * Informs the Validators if it has to stop validation when finding the
98       * first error or if it should continue.  Default to <code>true</code> to
99       * keep Struts 1.1 backwards compatibility.
100      */
101     private boolean stopOnFirstError = true;
102 
103     /***
104      * Gets a comma delimitted list of Validator resources.
105      *
106      * @return comma delimited list of Validator resource path names
107      */
108     public String getPathnames() {
109         return pathnames;
110     }
111 
112     /***
113      * Sets a comma delimitted list of Validator resources.
114      *
115      * @param pathnames delimited list of Validator resource path names
116      */
117     public void setPathnames(String pathnames) {
118         this.pathnames = pathnames;
119     }
120 
121     /***
122      * Gets the value for stopOnFirstError.
123      *
124      * @return A boolean indicating whether JavaScript validation should stop
125      *         when it finds the first error (Struts 1.1 behaviour) or
126      *         continue validation.
127      * @since Struts 1.2
128      */
129     public boolean isStopOnFirstError() {
130         return this.stopOnFirstError;
131     }
132 
133     /***
134      * Sets the value for stopOnFirstError.
135      *
136      * @param stopOnFirstError A boolean indicating whether JavaScript
137      *                         validation should stop when it finds the first
138      *                         error (Struts 1.1 behaviour) or continue
139      *                         validation.
140      * @since Struts 1.2
141      */
142     public void setStopOnFirstError(boolean stopOnFirstError) {
143         this.stopOnFirstError = stopOnFirstError;
144     }
145 
146     /***
147      * Initialize and load our resources.
148      *
149      * @param servlet The ActionServlet for our application
150      * @param config  The ModuleConfig for our owning module
151      * @throws ServletException if we cannot configure ourselves correctly
152      */
153     public void init(ActionServlet servlet, ModuleConfig config)
154         throws ServletException {
155         // Remember our associated configuration and servlet
156         this.config = config;
157         this.servlet = servlet;
158 
159         // Load our database from persistent storage
160         try {
161             this.initResources();
162 
163             servlet.getServletContext().setAttribute(VALIDATOR_KEY
164                 + config.getPrefix(), resources);
165 
166             servlet.getServletContext().setAttribute(STOP_ON_ERROR_KEY + '.'
167                 + config.getPrefix(),
168                 (this.stopOnFirstError ? Boolean.TRUE : Boolean.FALSE));
169         } catch (Exception e) {
170             log.error(e.getMessage(), e);
171             throw new UnavailableException(
172                 "Cannot load a validator resource from '" + pathnames + "'");
173         }
174     }
175 
176     /***
177      * Gracefully shut down, releasing any resources that were allocated at
178      * initialization.
179      */
180     public void destroy() {
181         if (log.isDebugEnabled()) {
182             log.debug("Destroying ValidatorPlugin");
183         }
184 
185         servlet = null;
186         config = null;
187 
188         destroyResources();
189     }
190 
191     /***
192      * Initialize the validator resources for this module.
193      *
194      * @throws IOException      if an input/output error is encountered
195      * @throws ServletException if we cannot initialize these resources
196      */
197     protected void initResources()
198         throws IOException, ServletException {
199         if ((pathnames == null) || (pathnames.length() <= 0)) {
200             return;
201         }
202 
203         StringTokenizer st = new StringTokenizer(pathnames, RESOURCE_DELIM);
204 
205         List urlList = new ArrayList();
206 
207         try {
208             while (st.hasMoreTokens()) {
209                 String validatorRules = st.nextToken().trim();
210 
211                 if (log.isInfoEnabled()) {
212                     log.info("Loading validation rules file from '"
213                         + validatorRules + "'");
214                 }
215 
216                 URL input =
217                     servlet.getServletContext().getResource(validatorRules);
218 
219                 // If the config isn't in the servlet context, try the class
220                 // loader which allows the config files to be stored in a jar
221                 if (input == null) {
222                     input = getClass().getResource(validatorRules);
223                 }
224 
225                 if (input != null) {
226                     urlList.add(input);
227                 } else {
228                     throw new ServletException(
229                         "Skipping validation rules file from '"
230                         + validatorRules + "'.  No url could be located.");
231                 }
232             }
233 
234             int urlSize = urlList.size();
235             String[] urlArray = new String[urlSize];
236 
237             for (int urlIndex = 0; urlIndex < urlSize; urlIndex++) {
238                 URL url = (URL) urlList.get(urlIndex);
239 
240                 urlArray[urlIndex] = url.toExternalForm();
241             }
242 
243             this.resources = new ValidatorResources(urlArray);
244         } catch (SAXException sex) {
245             log.error("Skipping all validation", sex);
246             throw new ServletException(sex);
247         }
248     }
249 
250     /***
251      * Destroy <code>ValidatorResources</code>.
252      */
253     protected void destroyResources() {
254         resources = null;
255     }
256 }