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