| %line | %branch | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| org.apache.commons.validator.ValidatorResources$1 |
|
|
| 1 | /* |
|
| 2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
|
| 3 | * contributor license agreements. See the NOTICE file distributed with |
|
| 4 | * this work for additional information regarding copyright ownership. |
|
| 5 | * The ASF licenses this file to You under the Apache License, Version 2.0 |
|
| 6 | * (the "License"); you may not use this file except in compliance with |
|
| 7 | * the License. You may obtain a copy of the License at |
|
| 8 | * |
|
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
| 10 | * |
|
| 11 | * Unless required by applicable law or agreed to in writing, software |
|
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
| 14 | * See the License for the specific language governing permissions and |
|
| 15 | * limitations under the License. |
|
| 16 | */ |
|
| 17 | package org.apache.commons.validator; |
|
| 18 | ||
| 19 | import java.io.IOException; |
|
| 20 | import java.io.InputStream; |
|
| 21 | import java.io.Serializable; |
|
| 22 | import java.net.URL; |
|
| 23 | import java.util.Collections; |
|
| 24 | import java.util.Iterator; |
|
| 25 | import java.util.Locale; |
|
| 26 | import java.util.Map; |
|
| 27 | ||
| 28 | import org.apache.commons.collections.FastHashMap; |
|
| 29 | import org.apache.commons.digester.Digester; |
|
| 30 | import org.apache.commons.digester.Rule; |
|
| 31 | import org.apache.commons.digester.xmlrules.DigesterLoader; |
|
| 32 | import org.apache.commons.logging.Log; |
|
| 33 | import org.apache.commons.logging.LogFactory; |
|
| 34 | import org.xml.sax.SAXException; |
|
| 35 | import org.xml.sax.Attributes; |
|
| 36 | ||
| 37 | /** |
|
| 38 | * <p> |
|
| 39 | * General purpose class for storing <code>FormSet</code> objects based |
|
| 40 | * on their associated <code>Locale</code>. Instances of this class are usually |
|
| 41 | * configured through a validation.xml file that is parsed in a constructor. |
|
| 42 | * </p> |
|
| 43 | * |
|
| 44 | * <p><strong>Note</strong> - Classes that extend this class |
|
| 45 | * must be Serializable so that instances may be used in distributable |
|
| 46 | * application server environments.</p> |
|
| 47 | * |
|
| 48 | * <p> |
|
| 49 | * The use of FastHashMap is deprecated and will be replaced in a future |
|
| 50 | * release. |
|
| 51 | * </p> |
|
| 52 | * |
|
| 53 | * @version $Revision: 478473 $ $Date: 2006-11-23 05:42:30 +0000 (Thu, 23 Nov 2006) $ |
|
| 54 | */ |
|
| 55 | public class ValidatorResources implements Serializable { |
|
| 56 | ||
| 57 | /** Name of the digester validator rules file */ |
|
| 58 | private static final String VALIDATOR_RULES = "digester-rules.xml"; |
|
| 59 | ||
| 60 | /** |
|
| 61 | * The set of public identifiers, and corresponding resource names, for |
|
| 62 | * the versions of the configuration file DTDs that we know about. There |
|
| 63 | * <strong>MUST</strong> be an even number of Strings in this list! |
|
| 64 | */ |
|
| 65 | private static final String REGISTRATIONS[] = { |
|
| 66 | "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0//EN", |
|
| 67 | "/org/apache/commons/validator/resources/validator_1_0.dtd", |
|
| 68 | "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.0.1//EN", |
|
| 69 | "/org/apache/commons/validator/resources/validator_1_0_1.dtd", |
|
| 70 | "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1//EN", |
|
| 71 | "/org/apache/commons/validator/resources/validator_1_1.dtd", |
|
| 72 | "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1.3//EN", |
|
| 73 | "/org/apache/commons/validator/resources/validator_1_1_3.dtd", |
|
| 74 | "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.2.0//EN", |
|
| 75 | "/org/apache/commons/validator/resources/validator_1_2_0.dtd", |
|
| 76 | "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.3.0//EN", |
|
| 77 | "/org/apache/commons/validator/resources/validator_1_3_0.dtd" |
|
| 78 | }; |
|
| 79 | ||
| 80 | private transient Log log = LogFactory.getLog(ValidatorResources.class); |
|
| 81 | ||
| 82 | /** |
|
| 83 | * <code>Map</code> of <code>FormSet</code>s stored under |
|
| 84 | * a <code>Locale</code> key. |
|
| 85 | * @deprecated Subclasses should use getFormSets() instead. |
|
| 86 | */ |
|
| 87 | protected FastHashMap hFormSets = new FastHashMap(); |
|
| 88 | ||
| 89 | /** |
|
| 90 | * <code>Map</code> of global constant values with |
|
| 91 | * the name of the constant as the key. |
|
| 92 | * @deprecated Subclasses should use getConstants() instead. |
|
| 93 | */ |
|
| 94 | protected FastHashMap hConstants = new FastHashMap(); |
|
| 95 | ||
| 96 | /** |
|
| 97 | * <code>Map</code> of <code>ValidatorAction</code>s with |
|
| 98 | * the name of the <code>ValidatorAction</code> as the key. |
|
| 99 | * @deprecated Subclasses should use getActions() instead. |
|
| 100 | */ |
|
| 101 | protected FastHashMap hActions = new FastHashMap(); |
|
| 102 | ||
| 103 | /** |
|
| 104 | * The default locale on our server. |
|
| 105 | */ |
|
| 106 | protected static Locale defaultLocale = Locale.getDefault(); |
|
| 107 | ||
| 108 | /** |
|
| 109 | * Create an empty ValidatorResources object. |
|
| 110 | */ |
|
| 111 | public ValidatorResources() { |
|
| 112 | super(); |
|
| 113 | } |
|
| 114 | ||
| 115 | /** |
|
| 116 | * This is the default <code>FormSet</code> (without locale). (We probably don't need |
|
| 117 | * the defaultLocale anymore.) |
|
| 118 | */ |
|
| 119 | protected FormSet defaultFormSet; |
|
| 120 | ||
| 121 | /** |
|
| 122 | * Create a ValidatorResources object from an InputStream. |
|
| 123 | * |
|
| 124 | * @param in InputStream to a validation.xml configuration file. It's the client's |
|
| 125 | * responsibility to close this stream. |
|
| 126 | * @throws IOException |
|
| 127 | * @throws SAXException if the validation XML files are not valid or well |
|
| 128 | * formed. |
|
| 129 | * @throws IOException if an I/O error occurs processing the XML files |
|
| 130 | * @since Validator 1.1 |
|
| 131 | */ |
|
| 132 | public ValidatorResources(InputStream in) throws IOException, SAXException { |
|
| 133 | this(new InputStream[]{in}); |
|
| 134 | } |
|
| 135 | ||
| 136 | /** |
|
| 137 | * Create a ValidatorResources object from an InputStream. |
|
| 138 | * |
|
| 139 | * @param streams An array of InputStreams to several validation.xml |
|
| 140 | * configuration files that will be read in order and merged into this object. |
|
| 141 | * It's the client's responsibility to close these streams. |
|
| 142 | * @throws IOException |
|
| 143 | * @throws SAXException if the validation XML files are not valid or well |
|
| 144 | * formed. |
|
| 145 | * @throws IOException if an I/O error occurs processing the XML files |
|
| 146 | * @since Validator 1.1 |
|
| 147 | */ |
|
| 148 | public ValidatorResources(InputStream[] streams) |
|
| 149 | throws IOException, SAXException { |
|
| 150 | ||
| 151 | super(); |
|
| 152 | ||
| 153 | Digester digester = initDigester(); |
|
| 154 | for (int i = 0; i < streams.length; i++) { |
|
| 155 | digester.push(this); |
|
| 156 | digester.parse(streams[i]); |
|
| 157 | } |
|
| 158 | ||
| 159 | this.process(); |
|
| 160 | } |
|
| 161 | ||
| 162 | /** |
|
| 163 | * Create a ValidatorResources object from an uri |
|
| 164 | * |
|
| 165 | * @param uri The location of a validation.xml configuration file. |
|
| 166 | * @throws IOException |
|
| 167 | * @throws SAXException if the validation XML files are not valid or well |
|
| 168 | * formed. |
|
| 169 | * @throws IOException if an I/O error occurs processing the XML files |
|
| 170 | * @since Validator 1.2 |
|
| 171 | */ |
|
| 172 | public ValidatorResources(String uri) throws IOException, SAXException { |
|
| 173 | this(new String[]{uri}); |
|
| 174 | } |
|
| 175 | ||
| 176 | /** |
|
| 177 | * Create a ValidatorResources object from several uris |
|
| 178 | * |
|
| 179 | * @param uris An array of uris to several validation.xml |
|
| 180 | * configuration files that will be read in order and merged into this object. |
|
| 181 | * @throws IOException |
|
| 182 | * @throws SAXException if the validation XML files are not valid or well |
|
| 183 | * formed. |
|
| 184 | * @throws IOException if an I/O error occurs processing the XML files |
|
| 185 | * @since Validator 1.2 |
|
| 186 | */ |
|
| 187 | public ValidatorResources(String[] uris) |
|
| 188 | throws IOException, SAXException { |
|
| 189 | ||
| 190 | super(); |
|
| 191 | ||
| 192 | Digester digester = initDigester(); |
|
| 193 | for (int i = 0; i < uris.length; i++) { |
|
| 194 | digester.push(this); |
|
| 195 | digester.parse(uris[i]); |
|
| 196 | } |
|
| 197 | ||
| 198 | this.process(); |
|
| 199 | } |
|
| 200 | ||
| 201 | /** |
|
| 202 | * Create a ValidatorResources object from a URL. |
|
| 203 | * |
|
| 204 | * @param url The URL for the validation.xml |
|
| 205 | * configuration file that will be read into this object. |
|
| 206 | * @throws IOException |
|
| 207 | * @throws SAXException if the validation XML file are not valid or well |
|
| 208 | * formed. |
|
| 209 | * @throws IOException if an I/O error occurs processing the XML files |
|
| 210 | * @since Validator 1.3.1 |
|
| 211 | */ |
|
| 212 | public ValidatorResources(URL url) |
|
| 213 | throws IOException, SAXException { |
|
| 214 | this(new URL[]{url}); |
|
| 215 | } |
|
| 216 | ||
| 217 | /** |
|
| 218 | * Create a ValidatorResources object from several URL. |
|
| 219 | * |
|
| 220 | * @param urls An array of URL to several validation.xml |
|
| 221 | * configuration files that will be read in order and merged into this object. |
|
| 222 | * @throws IOException |
|
| 223 | * @throws SAXException if the validation XML files are not valid or well |
|
| 224 | * formed. |
|
| 225 | * @throws IOException if an I/O error occurs processing the XML files |
|
| 226 | * @since Validator 1.3.1 |
|
| 227 | */ |
|
| 228 | public ValidatorResources(URL[] urls) |
|
| 229 | throws IOException, SAXException { |
|
| 230 | ||
| 231 | super(); |
|
| 232 | ||
| 233 | Digester digester = initDigester(); |
|
| 234 | for (int i = 0; i < urls.length; i++) { |
|
| 235 | digester.push(this); |
|
| 236 | InputStream stream = null; |
|
| 237 | try { |
|
| 238 | stream = urls[i].openStream(); |
|
| 239 | org.xml.sax.InputSource source = |
|
| 240 | new org.xml.sax.InputSource(urls[i].toExternalForm()); |
|
| 241 | source.setByteStream(stream); |
|
| 242 | digester.parse(source); |
|
| 243 | } finally { |
|
| 244 | if (stream != null) { |
|
| 245 | try { |
|
| 246 | stream.close(); |
|
| 247 | } catch (IOException e) { |
|
| 248 | // ignore problem closing |
|
| 249 | } |
|
| 250 | } |
|
| 251 | } |
|
| 252 | } |
|
| 253 | ||
| 254 | this.process(); |
|
| 255 | } |
|
| 256 | ||
| 257 | /** |
|
| 258 | * Initialize the digester. |
|
| 259 | */ |
|
| 260 | private Digester initDigester() { |
|
| 261 | URL rulesUrl = this.getClass().getResource(VALIDATOR_RULES); |
|
| 262 | if (rulesUrl == null) { |
|
| 263 | // Fix for Issue# VALIDATOR-195 |
|
| 264 | rulesUrl = ValidatorResources.class.getResource(VALIDATOR_RULES); |
|
| 265 | } |
|
| 266 | if (getLog().isDebugEnabled()) { |
|
| 267 | getLog().debug("Loading rules from '" + rulesUrl + "'"); |
|
| 268 | } |
|
| 269 | Digester digester = DigesterLoader.createDigester(rulesUrl); |
|
| 270 | digester.setNamespaceAware(true); |
|
| 271 | digester.setValidating(true); |
|
| 272 | digester.setUseContextClassLoader(true); |
|
| 273 | ||
| 274 | // Add rules for arg0-arg3 elements |
|
| 275 | addOldArgRules(digester); |
|
| 276 | ||
| 277 | // register DTDs |
|
| 278 | for (int i = 0; i < REGISTRATIONS.length; i += 2) { |
|
| 279 | URL url = this.getClass().getResource(REGISTRATIONS[i + 1]); |
|
| 280 | if (url != null) { |
|
| 281 | digester.register(REGISTRATIONS[i], url.toString()); |
|
| 282 | } |
|
| 283 | } |
|
| 284 | return digester; |
|
| 285 | } |
|
| 286 | ||
| 287 | private static final String ARGS_PATTERN |
|
| 288 | = "form-validation/formset/form/field/arg"; |
|
| 289 | ||
| 290 | /** |
|
| 291 | * Create a <code>Rule</code> to handle <code>arg0-arg3</code> |
|
| 292 | * elements. This will allow validation.xml files that use the |
|
| 293 | * versions of the DTD prior to Validator 1.2.0 to continue |
|
| 294 | * working. |
|
| 295 | */ |
|
| 296 | private void addOldArgRules(Digester digester) { |
|
| 297 | ||
| 298 | // Create a new rule to process args elements |
|
| 299 | Rule rule = new Rule() { |
|
| 300 | 98 | public void begin(String namespace, String name, |
| 301 | Attributes attributes) throws Exception { |
|
| 302 | // Create the Arg |
|
| 303 | 0 | Arg arg = new Arg(); |
| 304 | 0 | arg.setKey(attributes.getValue("key")); |
| 305 | 0 | arg.setName(attributes.getValue("name")); |
| 306 | 0 | if ("false".equalsIgnoreCase(attributes.getValue("resource"))) { |
| 307 | 0 | arg.setResource(false); |
| 308 | } |
|
| 309 | try { |
|
| 310 | 0 | arg.setPosition(Integer.parseInt(name.substring(3))); |
| 311 | 0 | } catch (Exception ex) { |
| 312 | 0 | getLog().error("Error parsing Arg position: " |
| 313 | + name + " " + arg + " " + ex); |
|
| 314 | } |
|
| 315 | ||
| 316 | // Add the arg to the parent field |
|
| 317 | 0 | ((Field)getDigester().peek(0)).addArg(arg); |
| 318 | 0 | } |
| 319 | }; |
|
| 320 | ||
| 321 | // Add the rule for each of the arg elements |
|
| 322 | digester.addRule(ARGS_PATTERN + "0", rule); |
|
| 323 | digester.addRule(ARGS_PATTERN + "1", rule); |
|
| 324 | digester.addRule(ARGS_PATTERN + "2", rule); |
|
| 325 | digester.addRule(ARGS_PATTERN + "3", rule); |
|
| 326 | ||
| 327 | } |
|
| 328 | ||
| 329 | /** |
|
| 330 | * Add a <code>FormSet</code> to this <code>ValidatorResources</code> |
|
| 331 | * object. It will be associated with the <code>Locale</code> of the |
|
| 332 | * <code>FormSet</code>. |
|
| 333 | * @param fs The form set to add. |
|
| 334 | * @since Validator 1.1 |
|
| 335 | */ |
|
| 336 | public void addFormSet(FormSet fs) { |
|
| 337 | String key = this.buildKey(fs); |
|
| 338 | if (key.length() == 0) {// there can only be one default formset |
|
| 339 | if (getLog().isWarnEnabled() && defaultFormSet != null) { |
|
| 340 | // warn the user he might not get the expected results |
|
| 341 | getLog().warn("Overriding default FormSet definition."); |
|
| 342 | } |
|
| 343 | defaultFormSet = fs; |
|
| 344 | } else { |
|
| 345 | FormSet formset = (FormSet) hFormSets.get(key); |
|
| 346 | if (formset == null) {// it hasn't been included yet |
|
| 347 | if (getLog().isDebugEnabled()) { |
|
| 348 | getLog().debug("Adding FormSet '" + fs.toString() + "'."); |
|
| 349 | } |
|
| 350 | } else if (getLog().isWarnEnabled()) {// warn the user he might not |
|
| 351 | // get the expected results |
|
| 352 | getLog() |
|
| 353 | .warn("Overriding FormSet definition. Duplicate for locale: " |
|
| 354 | + key); |
|
| 355 | } |
|
| 356 | hFormSets.put(key, fs); |
|
| 357 | } |
|
| 358 | } |
|
| 359 | ||
| 360 | /** |
|
| 361 | * Add a global constant to the resource. |
|
| 362 | * @param name The constant name. |
|
| 363 | * @param value The constant value. |
|
| 364 | */ |
|
| 365 | public void addConstant(String name, String value) { |
|
| 366 | if (getLog().isDebugEnabled()) { |
|
| 367 | getLog().debug("Adding Global Constant: " + name + "," + value); |
|
| 368 | } |
|
| 369 | ||
| 370 | this.hConstants.put(name, value); |
|
| 371 | } |
|
| 372 | ||
| 373 | /** |
|
| 374 | * Add a <code>ValidatorAction</code> to the resource. It also creates an |
|
| 375 | * instance of the class based on the <code>ValidatorAction</code>s |
|
| 376 | * classname and retrieves the <code>Method</code> instance and sets them |
|
| 377 | * in the <code>ValidatorAction</code>. |
|
| 378 | * @param va The validator action. |
|
| 379 | */ |
|
| 380 | public void addValidatorAction(ValidatorAction va) { |
|
| 381 | va.init(); |
|
| 382 | ||
| 383 | this.hActions.put(va.getName(), va); |
|
| 384 | ||
| 385 | if (getLog().isDebugEnabled()) { |
|
| 386 | getLog().debug("Add ValidatorAction: " + va.getName() + "," + va.getClassname()); |
|
| 387 | } |
|
| 388 | } |
|
| 389 | ||
| 390 | /** |
|
| 391 | * Get a <code>ValidatorAction</code> based on it's name. |
|
| 392 | * @param key The validator action key. |
|
| 393 | * @return The validator action. |
|
| 394 | */ |
|
| 395 | public ValidatorAction getValidatorAction(String key) { |
|
| 396 | return (ValidatorAction) hActions.get(key); |
|
| 397 | } |
|
| 398 | ||
| 399 | /** |
|
| 400 | * Get an unmodifiable <code>Map</code> of the <code>ValidatorAction</code>s. |
|
| 401 | * @return Map of validator actions. |
|
| 402 | */ |
|
| 403 | public Map getValidatorActions() { |
|
| 404 | return Collections.unmodifiableMap(hActions); |
|
| 405 | } |
|
| 406 | ||
| 407 | /** |
|
| 408 | * Builds a key to store the <code>FormSet</code> under based on it's |
|
| 409 | * language, country, and variant values. |
|
| 410 | * @param fs The Form Set. |
|
| 411 | * @return generated key for a formset. |
|
| 412 | */ |
|
| 413 | protected String buildKey(FormSet fs) { |
|
| 414 | return |
|
| 415 | this.buildLocale(fs.getLanguage(), fs.getCountry(), fs.getVariant()); |
|
| 416 | } |
|
| 417 | ||
| 418 | /** |
|
| 419 | * Assembles a Locale code from the given parts. |
|
| 420 | */ |
|
| 421 | private String buildLocale(String lang, String country, String variant) { |
|
| 422 | String key = ((lang != null && lang.length() > 0) ? lang : ""); |
|
| 423 | key += ((country != null && country.length() > 0) ? "_" + country : ""); |
|
| 424 | key += ((variant != null && variant.length() > 0) ? "_" + variant : ""); |
|
| 425 | return key; |
|
| 426 | } |
|
| 427 | ||
| 428 | /** |
|
| 429 | * <p>Gets a <code>Form</code> based on the name of the form and the |
|
| 430 | * <code>Locale</code> that most closely matches the <code>Locale</code> |
|
| 431 | * passed in. The order of <code>Locale</code> matching is:</p> |
|
| 432 | * <ol> |
|
| 433 | * <li>language + country + variant</li> |
|
| 434 | * <li>language + country</li> |
|
| 435 | * <li>language</li> |
|
| 436 | * <li>default locale</li> |
|
| 437 | * </ol> |
|
| 438 | * @param locale The Locale. |
|
| 439 | * @param formKey The key for the Form. |
|
| 440 | * @return The validator Form. |
|
| 441 | * @since Validator 1.1 |
|
| 442 | */ |
|
| 443 | public Form getForm(Locale locale, String formKey) { |
|
| 444 | return this.getForm(locale.getLanguage(), locale.getCountry(), locale |
|
| 445 | .getVariant(), formKey); |
|
| 446 | } |
|
| 447 | ||
| 448 | /** |
|
| 449 | * <p>Gets a <code>Form</code> based on the name of the form and the |
|
| 450 | * <code>Locale</code> that most closely matches the <code>Locale</code> |
|
| 451 | * passed in. The order of <code>Locale</code> matching is:</p> |
|
| 452 | * <ol> |
|
| 453 | * <li>language + country + variant</li> |
|
| 454 | * <li>language + country</li> |
|
| 455 | * <li>language</li> |
|
| 456 | * <li>default locale</li> |
|
| 457 | * </ol> |
|
| 458 | * @param language The locale's language. |
|
| 459 | * @param country The locale's country. |
|
| 460 | * @param variant The locale's language variant. |
|
| 461 | * @param formKey The key for the Form. |
|
| 462 | * @return The validator Form. |
|
| 463 | * @since Validator 1.1 |
|
| 464 | */ |
|
| 465 | public Form getForm(String language, String country, String variant, |
|
| 466 | String formKey) { |
|
| 467 | ||
| 468 | Form form = null; |
|
| 469 | ||
| 470 | // Try language/country/variant |
|
| 471 | String key = this.buildLocale(language, country, variant); |
|
| 472 | if (key.length() > 0) { |
|
| 473 | FormSet formSet = (FormSet)hFormSets.get(key); |
|
| 474 | if (formSet != null) { |
|
| 475 | form = formSet.getForm(formKey); |
|
| 476 | } |
|
| 477 | } |
|
| 478 | String localeKey = key; |
|
| 479 | ||
| 480 | ||
| 481 | // Try language/country |
|
| 482 | if (form == null) { |
|
| 483 | key = buildLocale(language, country, null); |
|
| 484 | if (key.length() > 0) { |
|
| 485 | FormSet formSet = (FormSet)hFormSets.get(key); |
|
| 486 | if (formSet != null) { |
|
| 487 | form = formSet.getForm(formKey); |
|
| 488 | } |
|
| 489 | } |
|
| 490 | } |
|
| 491 | ||
| 492 | // Try language |
|
| 493 | if (form == null) { |
|
| 494 | key = buildLocale(language, null, class="keyword">null); |
|
| 495 | if (key.length() > 0) { |
|
| 496 | FormSet formSet = (FormSet)hFormSets.get(key); |
|
| 497 | if (formSet != null) { |
|
| 498 | form = formSet.getForm(formKey); |
|
| 499 | } |
|
| 500 | } |
|
| 501 | } |
|
| 502 | ||
| 503 | // Try default formset |
|
| 504 | if (form == null) { |
|
| 505 | form = defaultFormSet.getForm(formKey); |
|
| 506 | key = "default"; |
|
| 507 | } |
|
| 508 | ||
| 509 | if (form == null) { |
|
| 510 | if (getLog().isWarnEnabled()) { |
|
| 511 | getLog().warn("Form '" + formKey + "' not found for locale '" + |
|
| 512 | localeKey + "'"); |
|
| 513 | } |
|
| 514 | } else { |
|
| 515 | if (getLog().isDebugEnabled()) { |
|
| 516 | getLog().debug("Form '" + formKey + "' found in formset '" + |
|
| 517 | key + "' for locale '" + localeKey + "'"); |
|
| 518 | } |
|
| 519 | } |
|
| 520 | ||
| 521 | return form; |
|
| 522 | ||
| 523 | } |
|
| 524 | ||
| 525 | /** |
|
| 526 | * Process the <code>ValidatorResources</code> object. Currently sets the |
|
| 527 | * <code>FastHashMap</code> s to the 'fast' mode and call the processes |
|
| 528 | * all other resources. <strong>Note </strong>: The framework calls this |
|
| 529 | * automatically when ValidatorResources is created from an XML file. If you |
|
| 530 | * create an instance of this class by hand you <strong>must </strong> call |
|
| 531 | * this method when finished. |
|
| 532 | */ |
|
| 533 | public void process() { |
|
| 534 | hFormSets.setFast(true); |
|
| 535 | hConstants.setFast(true); |
|
| 536 | hActions.setFast(true); |
|
| 537 | ||
| 538 | this.processForms(); |
|
| 539 | } |
|
| 540 | ||
| 541 | /** |
|
| 542 | * <p>Process the <code>Form</code> objects. This clones the <code>Field</code>s |
|
| 543 | * that don't exist in a <code>FormSet</code> compared to its parent |
|
| 544 | * <code>FormSet</code>.</p> |
|
| 545 | */ |
|
| 546 | private void processForms() { |
|
| 547 | if (defaultFormSet == null) {// it isn't mandatory to have a |
|
| 548 | // default formset |
|
| 549 | defaultFormSet = new FormSet(); |
|
| 550 | } |
|
| 551 | defaultFormSet.process(hConstants); |
|
| 552 | // Loop through FormSets and merge if necessary |
|
| 553 | for (Iterator i = hFormSets.keySet().iterator(); i.hasNext();) { |
|
| 554 | String key = (String) i.next(); |
|
| 555 | FormSet fs = (FormSet) hFormSets.get(key); |
|
| 556 | fs.merge(getParent(fs)); |
|
| 557 | } |
|
| 558 | ||
| 559 | // Process Fully Constructed FormSets |
|
| 560 | for (Iterator i = hFormSets.values().iterator(); i.hasNext();) { |
|
| 561 | FormSet fs = (FormSet) i.next(); |
|
| 562 | if (!fs.isProcessed()) { |
|
| 563 | fs.process(hConstants); |
|
| 564 | } |
|
| 565 | } |
|
| 566 | } |
|
| 567 | ||
| 568 | /** |
|
| 569 | * Finds the given formSet's parent. ex: A formSet with locale en_UK_TEST1 |
|
| 570 | * has a direct parent in the formSet with locale en_UK. If it doesn't |
|
| 571 | * exist, find the formSet with locale en, if no found get the |
|
| 572 | * defaultFormSet. |
|
| 573 | * |
|
| 574 | * @param fs |
|
| 575 | * the formSet we want to get the parent from |
|
| 576 | * @return fs's parent |
|
| 577 | */ |
|
| 578 | private FormSet getParent(FormSet fs) { |
|
| 579 | ||
| 580 | FormSet parent = null; |
|
| 581 | if (fs.getType() == FormSet.LANGUAGE_FORMSET) { |
|
| 582 | parent = defaultFormSet; |
|
| 583 | } else if (fs.getType() == FormSet.COUNTRY_FORMSET) { |
|
| 584 | parent = (FormSet) hFormSets.get(buildLocale(fs.getLanguage(), |
|
| 585 | null, class="keyword">null)); |
|
| 586 | if (parent == null) { |
|
| 587 | parent = defaultFormSet; |
|
| 588 | } |
|
| 589 | } else if (fs.getType() == FormSet.VARIANT_FORMSET) { |
|
| 590 | parent = (FormSet) hFormSets.get(buildLocale(fs.getLanguage(), fs |
|
| 591 | .getCountry(), null)); |
|
| 592 | if (parent == null) { |
|
| 593 | parent = (FormSet) hFormSets.get(buildLocale(fs.getLanguage(), |
|
| 594 | null, class="keyword">null)); |
|
| 595 | if (parent == null) { |
|
| 596 | parent = defaultFormSet; |
|
| 597 | } |
|
| 598 | } |
|
| 599 | } |
|
| 600 | return parent; |
|
| 601 | } |
|
| 602 | ||
| 603 | /** |
|
| 604 | * <p>Gets a <code>FormSet</code> based on the language, country |
|
| 605 | * and variant.</p> |
|
| 606 | * @param language The locale's language. |
|
| 607 | * @param country The locale's country. |
|
| 608 | * @param variant The locale's language variant. |
|
| 609 | * @return The FormSet for a locale. |
|
| 610 | * @since Validator 1.2 |
|
| 611 | */ |
|
| 612 | FormSet getFormSet(String language, String country, String variant) { |
|
| 613 | ||
| 614 | String key = buildLocale(language, country, variant); |
|
| 615 | ||
| 616 | if (key.length() == 0) { |
|
| 617 | return defaultFormSet; |
|
| 618 | } |
|
| 619 | ||
| 620 | return (FormSet)hFormSets.get(key); |
|
| 621 | } |
|
| 622 | ||
| 623 | /** |
|
| 624 | * Returns a Map of String locale keys to Lists of their FormSets. |
|
| 625 | * @return Map of Form sets |
|
| 626 | * @since Validator 1.2.0 |
|
| 627 | */ |
|
| 628 | protected Map getFormSets() { |
|
| 629 | return hFormSets; |
|
| 630 | } |
|
| 631 | ||
| 632 | /** |
|
| 633 | * Returns a Map of String constant names to their String values. |
|
| 634 | * @return Map of Constants |
|
| 635 | * @since Validator 1.2.0 |
|
| 636 | */ |
|
| 637 | protected Map getConstants() { |
|
| 638 | return hConstants; |
|
| 639 | } |
|
| 640 | ||
| 641 | /** |
|
| 642 | * Returns a Map of String ValidatorAction names to their ValidatorAction. |
|
| 643 | * @return Map of Validator Actions |
|
| 644 | * @since Validator 1.2.0 |
|
| 645 | */ |
|
| 646 | protected Map getActions() { |
|
| 647 | return hActions; |
|
| 648 | } |
|
| 649 | ||
| 650 | /** |
|
| 651 | * Accessor method for Log instance. |
|
| 652 | * |
|
| 653 | * The Log instance variable is transient and |
|
| 654 | * accessing it through this method ensures it |
|
| 655 | * is re-initialized when this instance is |
|
| 656 | * de-serialized. |
|
| 657 | * |
|
| 658 | * @return The Log instance. |
|
| 659 | */ |
|
| 660 | private Log getLog() { |
|
| 661 | if (log == null) { |
|
| 662 | log = LogFactory.getLog(ValidatorResources.class); |
|
| 663 | } |
|
| 664 | return log; |
|
| 665 | } |
|
| 666 | ||
| 667 | } |
| This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |