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