001: /*
002: * $Id: ValidatorPlugIn.java 483039 2006-12-06 11:34:28Z niallp $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts.validator;
022:
023: import org.apache.commons.logging.Log;
024: import org.apache.commons.logging.LogFactory;
025: import org.apache.commons.validator.ValidatorResources;
026: import org.apache.struts.action.ActionServlet;
027: import org.apache.struts.action.PlugIn;
028: import org.apache.struts.config.ModuleConfig;
029: import org.xml.sax.SAXException;
030:
031: import javax.servlet.ServletException;
032: import javax.servlet.UnavailableException;
033:
034: import java.io.IOException;
035:
036: import java.net.URL;
037:
038: import java.util.ArrayList;
039: import java.util.List;
040: import java.util.StringTokenizer;
041:
042: /**
043: * Loads <code>ValidatorResources</code> based on configuration in the
044: * struts-config.xml file.
045: *
046: * @version $Rev: 483039 $ $Date: 2005-08-30 00:22:27 -0400 (Tue, 30 Aug 2005)
047: * $
048: * @since Struts 1.1
049: */
050: public class ValidatorPlugIn implements PlugIn {
051: /**
052: * Commons Logging instance.
053: */
054: private static Log log = LogFactory.getLog(ValidatorPlugIn.class);
055:
056: /**
057: * Delimitter for Validator resources.
058: */
059: private final static String RESOURCE_DELIM = ",";
060:
061: /**
062: * Application scope key that <code>ValidatorResources</code> is stored
063: * under.
064: */
065: public final static String VALIDATOR_KEY = "org.apache.commons.validator.VALIDATOR_RESOURCES";
066:
067: /**
068: * Application scope key that <code>StopOnError</code> is stored under.
069: *
070: * @since Struts 1.2
071: */
072: public final static String STOP_ON_ERROR_KEY = "org.apache.struts.validator.STOP_ON_ERROR";
073:
074: /**
075: * The module configuration for our owning module.
076: */
077: private ModuleConfig config = null;
078:
079: /**
080: * The {@link ActionServlet} owning this application.
081: */
082: private ActionServlet servlet = null;
083:
084: /**
085: * The set of Form instances that have been created and initialized, keyed
086: * by the struts form name.
087: */
088: protected ValidatorResources resources = null;
089:
090: // ------------------------------------------------------------- Properties
091:
092: /**
093: * A comma delimitted list of Validator resource.
094: */
095: private String pathnames = null;
096:
097: /**
098: * Informs the Validators if it has to stop validation when finding the
099: * first error or if it should continue. Default to <code>true</code> to
100: * keep Struts 1.1 backwards compatibility.
101: */
102: private boolean stopOnFirstError = true;
103:
104: /**
105: * Gets a comma delimitted list of Validator resources.
106: *
107: * @return comma delimited list of Validator resource path names
108: */
109: public String getPathnames() {
110: return pathnames;
111: }
112:
113: /**
114: * Sets a comma delimitted list of Validator resources.
115: *
116: * @param pathnames delimited list of Validator resource path names
117: */
118: public void setPathnames(String pathnames) {
119: this .pathnames = pathnames;
120: }
121:
122: /**
123: * Gets the value for stopOnFirstError.
124: *
125: * @return A boolean indicating whether JavaScript validation should stop
126: * when it finds the first error (Struts 1.1 behaviour) or
127: * continue validation.
128: * @since Struts 1.2
129: */
130: public boolean isStopOnFirstError() {
131: return this .stopOnFirstError;
132: }
133:
134: /**
135: * Sets the value for stopOnFirstError.
136: *
137: * @param stopOnFirstError A boolean indicating whether JavaScript
138: * validation should stop when it finds the first
139: * error (Struts 1.1 behaviour) or continue
140: * validation.
141: * @since Struts 1.2
142: */
143: public void setStopOnFirstError(boolean stopOnFirstError) {
144: this .stopOnFirstError = stopOnFirstError;
145: }
146:
147: /**
148: * Initialize and load our resources.
149: *
150: * @param servlet The ActionServlet for our application
151: * @param config The ModuleConfig for our owning module
152: * @throws ServletException if we cannot configure ourselves correctly
153: */
154: public void init(ActionServlet servlet, ModuleConfig config)
155: throws ServletException {
156: // Remember our associated configuration and servlet
157: this .config = config;
158: this .servlet = servlet;
159:
160: // Load our database from persistent storage
161: try {
162: this .initResources();
163:
164: servlet.getServletContext().setAttribute(
165: VALIDATOR_KEY + config.getPrefix(), resources);
166:
167: servlet.getServletContext().setAttribute(
168: STOP_ON_ERROR_KEY + '.' + config.getPrefix(),
169: (this .stopOnFirstError ? Boolean.TRUE
170: : Boolean.FALSE));
171: } catch (Exception e) {
172: log.error(e.getMessage(), e);
173: throw new UnavailableException(
174: "Cannot load a validator resource from '"
175: + pathnames + "'");
176: }
177: }
178:
179: /**
180: * Gracefully shut down, releasing any resources that were allocated at
181: * initialization.
182: */
183: public void destroy() {
184: if (log.isDebugEnabled()) {
185: log.debug("Destroying ValidatorPlugin");
186: }
187:
188: servlet = null;
189: config = null;
190:
191: destroyResources();
192: }
193:
194: /**
195: * Initialize the validator resources for this module.
196: *
197: * @throws IOException if an input/output error is encountered
198: * @throws ServletException if we cannot initialize these resources
199: */
200: protected void initResources() throws IOException, ServletException {
201: if ((pathnames == null) || (pathnames.length() <= 0)) {
202: return;
203: }
204:
205: StringTokenizer st = new StringTokenizer(pathnames,
206: RESOURCE_DELIM);
207:
208: List urlList = new ArrayList();
209:
210: try {
211: while (st.hasMoreTokens()) {
212: String validatorRules = st.nextToken().trim();
213:
214: if (log.isInfoEnabled()) {
215: log.info("Loading validation rules file from '"
216: + validatorRules + "'");
217: }
218:
219: URL input = servlet.getServletContext().getResource(
220: validatorRules);
221:
222: // If the config isn't in the servlet context, try the class
223: // loader which allows the config files to be stored in a jar
224: if (input == null) {
225: input = getClass().getResource(validatorRules);
226: }
227:
228: if (input != null) {
229: urlList.add(input);
230: } else {
231: throw new ServletException(
232: "Skipping validation rules file from '"
233: + validatorRules
234: + "'. No url could be located.");
235: }
236: }
237:
238: int urlSize = urlList.size();
239: URL[] urlArray = new URL[urlSize];
240:
241: for (int urlIndex = 0; urlIndex < urlSize; urlIndex++) {
242: urlArray[urlIndex] = (URL) urlList.get(urlIndex);
243: }
244:
245: this .resources = new ValidatorResources(urlArray);
246: } catch (SAXException sex) {
247: log.error("Skipping all validation", sex);
248: throw new ServletException(sex);
249: }
250: }
251:
252: /**
253: * Destroy <code>ValidatorResources</code>.
254: */
255: protected void destroyResources() {
256: resources = null;
257: }
258: }
|