Clover coverage report - Code Coverage for tapestry release 4.0-alpha-2
Coverage timestamp: Thu May 5 2005 09:57:44 EDT
file stats: LOC: 327   Methods: 16
NCLOC: 118   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
BaseValidator.java 83.3% 93.9% 81.2% 89.1%
coverage coverage
 1   
 // Copyright 2004, 2005 The Apache Software Foundation
 2   
 //
 3   
 // Licensed under the Apache License, Version 2.0 (the "License");
 4   
 // you may not use this file except in compliance with the License.
 5   
 // You may obtain a copy of the License at
 6   
 //
 7   
 //     http://www.apache.org/licenses/LICENSE-2.0
 8   
 //
 9   
 // Unless required by applicable law or agreed to in writing, software
 10   
 // distributed under the License is distributed on an "AS IS" BASIS,
 11   
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12   
 // See the License for the specific language governing permissions and
 13   
 // limitations under the License.
 14   
 
 15   
 package org.apache.tapestry.valid;
 16   
 
 17   
 import java.text.MessageFormat;
 18   
 import java.util.HashMap;
 19   
 import java.util.Locale;
 20   
 import java.util.Map;
 21   
 import java.util.ResourceBundle;
 22   
 
 23   
 import org.apache.hivemind.ApplicationRuntimeException;
 24   
 import org.apache.hivemind.HiveMind;
 25   
 import org.apache.hivemind.Resource;
 26   
 import org.apache.hivemind.util.ClasspathResource;
 27   
 import org.apache.tapestry.IEngine;
 28   
 import org.apache.tapestry.IForm;
 29   
 import org.apache.tapestry.IMarkupWriter;
 30   
 import org.apache.tapestry.IRequestCycle;
 31   
 import org.apache.tapestry.IScript;
 32   
 import org.apache.tapestry.PageRenderSupport;
 33   
 import org.apache.tapestry.TapestryUtils;
 34   
 import org.apache.tapestry.engine.IScriptSource;
 35   
 import org.apache.tapestry.form.FormEventType;
 36   
 import org.apache.tapestry.form.IFormComponent;
 37   
 import org.apache.tapestry.html.Body;
 38   
 
 39   
 /**
 40   
  * Abstract base class for {@link IValidator}. Supports a required and locale property.
 41   
  * 
 42   
  * @author Howard Lewis Ship
 43   
  * @since 1.0.8
 44   
  */
 45   
 
 46   
 public abstract class BaseValidator implements IValidator
 47   
 {
 48   
     /**
 49   
      * Input Symbol used to represent the field being validated.
 50   
      * 
 51   
      * @see #processValidatorScript(String, IRequestCycle, IFormComponent, Map)
 52   
      * @since 2.2
 53   
      */
 54   
 
 55   
     public static final String FIELD_SYMBOL = "field";
 56   
 
 57   
     /**
 58   
      * Input symbol used to represent the validator itself to the script.
 59   
      * 
 60   
      * @see #processValidatorScript(String, IRequestCycle, IFormComponent, Map)
 61   
      * @since 2.2
 62   
      */
 63   
 
 64   
     public static final String VALIDATOR_SYMBOL = "validator";
 65   
 
 66   
     /**
 67   
      * Input symbol used to represent the {@link IForm}containing the field to the script.
 68   
      * 
 69   
      * @see #processValidatorScript(String, IRequestCycle, IFormComponent, Map)
 70   
      * @since 2.2
 71   
      */
 72   
 
 73   
     public static final String FORM_SYMBOL = "form";
 74   
 
 75   
     /**
 76   
      * Output symbol set by the script asthe name of the validator JavaScript function. The function
 77   
      * implemented must return true or false (true if the field is valid, false otherwise). After
 78   
      * the script is executed, the function is added to the {@link IForm}as a
 79   
      * {@link org.apache.tapestry.form.FormEventType#SUBMIT}.
 80   
      * 
 81   
      * @see #processValidatorScript(String, IRequestCycle, IFormComponent, Map)
 82   
      * @since 2.2
 83   
      */
 84   
 
 85   
     public static final String FUNCTION_SYMBOL = "function";
 86   
 
 87   
     private boolean _required;
 88   
 
 89   
     /** @since 3.0 */
 90   
 
 91   
     private String _requiredMessage;
 92   
 
 93   
     /**
 94   
      * @since 2.2
 95   
      */
 96   
 
 97   
     private boolean _clientScriptingEnabled = false;
 98   
 
 99   
     /**
 100   
      * Standard constructor. Leaves locale as system default and required as false.
 101   
      */
 102   
 
 103  68
     public BaseValidator()
 104   
     {
 105   
     }
 106   
 
 107  0
     protected BaseValidator(boolean required)
 108   
     {
 109  0
         _required = required;
 110   
     }
 111   
 
 112  20
     public boolean isRequired()
 113   
     {
 114  20
         return _required;
 115   
     }
 116   
 
 117  5
     public void setRequired(boolean required)
 118   
     {
 119  5
         _required = required;
 120   
     }
 121   
 
 122   
     /**
 123   
      * Gets a pattern, either as the default value, or as a localized key. If override is null, then
 124   
      * the key from the <code>org.apache.tapestry.valid.ValidationStrings</code>
 125   
      * {@link ResourceBundle}(in the specified locale) is used. The pattern can then be used with
 126   
      * {@link #formatString(String, Object[])}.
 127   
      * <p>
 128   
      * Why do we not just lump these strings into TapestryStrings.properties? because
 129   
      * TapestryStrings.properties is localized to the server's locale, which is fine for the
 130   
      * logging, debugging and error messages it contains. For field validation, whose errors are
 131   
      * visible to the end user normally, we want to localize to the page's locale.
 132   
      * 
 133   
      * @param override
 134   
      *            The override value for the localized string from the bundle.
 135   
      * @param key
 136   
      *            used to lookup pattern from bundle, if override is null.
 137   
      * @param locale
 138   
      *            used to get right localization of bundle.
 139   
      * @since 3.0
 140   
      */
 141   
 
 142  35
     protected String getPattern(String override, String key, Locale locale)
 143   
     {
 144  35
         if (override != null)
 145  10
             return override;
 146   
 
 147  25
         ResourceBundle strings = ResourceBundle.getBundle(
 148   
                 "org.apache.tapestry.valid.ValidationStrings",
 149   
                 locale);
 150   
 
 151  25
         return strings.getString(key);
 152   
     }
 153   
 
 154   
     /**
 155   
      * Gets a string from the standard resource bundle. The string in the bundle is treated as a
 156   
      * pattern for {@link MessageFormat#format(java.lang.String, java.lang.Object[])}.
 157   
      * 
 158   
      * @param pattern
 159   
      *            string the input pattern to be used with
 160   
      *            {@link MessageFormat#format(java.lang.String, java.lang.Object[])}. It may
 161   
      *            contain replaceable parameters, {0}, {1}, etc.
 162   
      * @param args
 163   
      *            the arguments used to fill replaceable parameters {0}, {1}, etc.
 164   
      * @since 3.0
 165   
      */
 166   
 
 167  40
     protected String formatString(String pattern, Object[] args)
 168   
     {
 169  40
         return MessageFormat.format(pattern, args);
 170   
     }
 171   
 
 172   
     /**
 173   
      * Convienience method for invoking {@link #formatString(String, Object[])}.
 174   
      * 
 175   
      * @since 3.0
 176   
      */
 177   
 
 178  16
     protected String formatString(String pattern, Object arg)
 179   
     {
 180  16
         return formatString(pattern, new Object[]
 181   
         { arg });
 182   
     }
 183   
 
 184   
     /**
 185   
      * Convienience method for invoking {@link #formatString(String, Object[])}.
 186   
      * 
 187   
      * @since 3.0
 188   
      */
 189   
 
 190  24
     protected String formatString(String pattern, Object arg1, Object arg2)
 191   
     {
 192  24
         return formatString(pattern, new Object[]
 193   
         { arg1, arg2 });
 194   
     }
 195   
 
 196   
     /**
 197   
      * Invoked to check if the value is null. If the value is null (or empty), but the required flag
 198   
      * is set, then this method throws a {@link ValidatorException}. Otherwise, returns true if the
 199   
      * value is null.
 200   
      */
 201   
 
 202  58
     protected boolean checkRequired(IFormComponent field, String value) throws ValidatorException
 203   
     {
 204  58
         boolean isEmpty = HiveMind.isBlank(value);
 205   
 
 206  58
         if (_required && isEmpty)
 207  3
             throw new ValidatorException(buildRequiredMessage(field), ValidationConstraint.REQUIRED);
 208   
 
 209  55
         return isEmpty;
 210   
     }
 211   
 
 212   
     /**
 213   
      * Builds an error message indicating a value for a required field was not supplied.
 214   
      * 
 215   
      * @since 3.0
 216   
      */
 217   
 
 218  8
     protected String buildRequiredMessage(IFormComponent field)
 219   
     {
 220  8
         String pattern = getPattern(_requiredMessage, "field-is-required", field.getPage()
 221   
                 .getLocale());
 222   
 
 223  8
         return formatString(pattern, field.getDisplayName());
 224   
     }
 225   
 
 226   
     /**
 227   
      * This implementation does nothing. Subclasses may supply their own implementation.
 228   
      * 
 229   
      * @since 2.2
 230   
      */
 231   
 
 232  0
     public void renderValidatorContribution(IFormComponent field, IMarkupWriter writer,
 233   
             IRequestCycle cycle)
 234   
     {
 235   
     }
 236   
 
 237   
     /**
 238   
      * Invoked (from sub-class implementations of
 239   
      * {@link #renderValidatorContribution(IFormComponent, IMarkupWriter, IRequestCycle)}to process
 240   
      * a standard validation script. This expects that:
 241   
      * <ul>
 242   
      * <li>The {@link IFormComponent}is (ultimately) wrapped by a {@link Body}
 243   
      * <li>The script generates a symbol named "function" (as per {@link #FUNCTION_SYMBOL})
 244   
      * </ul>
 245   
      * 
 246   
      * @param scriptPath
 247   
      *            the resource path of the script to execute
 248   
      * @param cycle
 249   
      *            The active request cycle
 250   
      * @param field
 251   
      *            The field to be validated
 252   
      * @param symbols
 253   
      *            a set of input symbols needed by the script. These symbols are augmented with
 254   
      *            symbols for the field, form and validator. symbols may be null, but will be
 255   
      *            modified if not null.
 256   
      * @throws ApplicationRuntimeException
 257   
      *             if there's an error processing the script.
 258   
      * @since 2.2
 259   
      */
 260   
 
 261  5
     protected void processValidatorScript(String scriptPath, IRequestCycle cycle,
 262   
             IFormComponent field, Map symbols)
 263   
     {
 264  5
         IEngine engine = field.getPage().getEngine();
 265  5
         IScriptSource source = engine.getScriptSource();
 266  5
         IForm form = field.getForm();
 267   
 
 268  5
         Map finalSymbols = (symbols == null) ? new HashMap() : symbols;
 269   
 
 270  5
         finalSymbols.put(FIELD_SYMBOL, field);
 271  5
         finalSymbols.put(FORM_SYMBOL, form);
 272  5
         finalSymbols.put(VALIDATOR_SYMBOL, this);
 273   
 
 274  5
         Resource location = new ClasspathResource(engine.getClassResolver(), scriptPath);
 275   
 
 276  5
         IScript script = source.getScript(location);
 277   
 
 278   
         // If there's an error, report it against the field (this validator object doesn't
 279   
         // have a location).
 280   
 
 281  5
         PageRenderSupport pageRenderSupport = TapestryUtils.getPageRenderSupport(cycle, field);
 282   
 
 283  4
         script.execute(cycle, pageRenderSupport, finalSymbols);
 284   
 
 285  4
         String functionName = (String) finalSymbols.get(FUNCTION_SYMBOL);
 286   
 
 287  4
         form.addEventHandler(FormEventType.SUBMIT, functionName);
 288   
     }
 289   
 
 290   
     /**
 291   
      * Returns true if client scripting is enabled. Some validators are capable of generating
 292   
      * client-side scripting to perform validation when the form is submitted. By default, this flag
 293   
      * is false and subclasses should check it (in
 294   
      * {@link #renderValidatorContribution(IFormComponent, IMarkupWriter, IRequestCycle)}) before
 295   
      * generating client side script.
 296   
      * 
 297   
      * @since 2.2
 298   
      */
 299   
 
 300  7
     public boolean isClientScriptingEnabled()
 301   
     {
 302  7
         return _clientScriptingEnabled;
 303   
     }
 304   
 
 305  2
     public void setClientScriptingEnabled(boolean clientScriptingEnabled)
 306   
     {
 307  2
         _clientScriptingEnabled = clientScriptingEnabled;
 308   
     }
 309   
 
 310  0
     public String getRequiredMessage()
 311   
     {
 312  0
         return _requiredMessage;
 313   
     }
 314   
 
 315   
     /**
 316   
      * Overrides the <code>field-is-required</code> bundle key. Parameter {0} is the display name
 317   
      * of the field.
 318   
      * 
 319   
      * @since 3.0
 320   
      */
 321   
 
 322  1
     public void setRequiredMessage(String string)
 323   
     {
 324  1
         _requiredMessage = string;
 325   
     }
 326   
 
 327   
 }