Coverage Report - javax.faces.validator.RegexValidator
 
Classes in this File Line Coverage Branch Coverage Complexity
RegexValidator
0%
0/42
0%
0/18
2.5
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package javax.faces.validator;
 20  
 
 21  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFJspProperty;
 22  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
 23  
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFValidator;
 24  
 
 25  
 import javax.faces.component.PartialStateHolder;
 26  
 import javax.faces.component.UIComponent;
 27  
 import javax.faces.context.FacesContext;
 28  
 import java.util.regex.Pattern;
 29  
 import java.util.regex.PatternSyntaxException;
 30  
 
 31  
 /**
 32  
  * <p>
 33  
  *   <strong>RegexValidator</strong> is a {@link javax.faces.validator.Validator}
 34  
  *   that checks the value of the corresponding component against specified
 35  
  *   pattern using Java regular expression syntax.
 36  
  *
 37  
  *   The regular expression syntax accepted by the RegexValidator class is
 38  
  *   same as mentioned in class {@link java.util.regex.Pattern} in package
 39  
  *   <code>java.util.regex</code>.
 40  
  * </p>
 41  
  *
 42  
  * <p>
 43  
  *   The following algorithm is implemented:
 44  
  * </p>
 45  
  *
 46  
  * <ul>
 47  
  *   <li>If the passed value is <code>null</code>, exit immediately.</li>
 48  
  *   <li>
 49  
  *     If the passed value is not a String, exit with a {@link #NOT_MATCHED_MESSAGE_ID}
 50  
  *     error message.
 51  
  *   </li>
 52  
  *   <li>
 53  
  *     If no pattern has been set, or pattern resolves to <code>null</code> or an
 54  
  *     empty String, throw a {@link javax.faces.validator.ValidatorException}
 55  
  *     with a {@link #PATTERN_NOT_SET_MESSAGE_ID} message.
 56  
  *   </li>
 57  
  *   <li>
 58  
  *     If pattern is not a valid regular expression, according to the rules as defined
 59  
  *     in class {@link java.util.regex.Pattern}, throw a {@link ValidatorException}
 60  
  *     with a (@link #MATCH_EXCEPTION_MESSAGE_ID} message.
 61  
  *   </li>
 62  
  *   <li>
 63  
  *     If a <code>pattern</code> property has been configured on this
 64  
  *     {@link javax.faces.validator.Validator}, check the passed value against this pattern.
 65  
  *     If value does not match pattern throw a {@link ValidatorException}
 66  
  *     containing a {@link #NOT_MATCHED_MESSAGE_ID} message.
 67  
  *   </li>
 68  
  * </ul>
 69  
  *
 70  
  * @since 2.0
 71  
  */
 72  
 @JSFValidator(
 73  
     name="f:validateRegex",
 74  
     bodyContent="empty",
 75  
     tagClass="org.apache.myfaces.taglib.core.ValidateRegexTag")
 76  
 @JSFJspProperty(
 77  
     name="binding",
 78  
     returnType = "javax.faces.validator.RegexValidator",
 79  
     longDesc = "A ValueExpression that evaluates to a RegexValidator.")
 80  0
 public class RegexValidator implements Validator, PartialStateHolder
 81  
 {
 82  
 
 83  
     /**
 84  
      * Converter ID, as defined by the JSF 2.0 specification.
 85  
      */
 86  
     public static final String VALIDATOR_ID = "javax.faces.RegularExpression";
 87  
 
 88  
     /**
 89  
      * This message ID is used when the pattern is <code>null</code>, or an empty String.
 90  
      */
 91  
     public static final String PATTERN_NOT_SET_MESSAGE_ID = "javax.faces.validator.RegexValidator.PATTERN_NOT_SET";
 92  
 
 93  
     /**
 94  
      * This message ID is used when the passed value is not a String, or when
 95  
      * the pattern does not match the passed value.
 96  
      */
 97  
     public static final String NOT_MATCHED_MESSAGE_ID = "javax.faces.validator.RegexValidator.NOT_MATCHED";
 98  
 
 99  
     /**
 100  
      * This message ID is used when the pattern is not a valid regular expression, according
 101  
      * to the rules as defined in class {@link java.util.regex.Pattern}
 102  
      */
 103  
     public static final String MATCH_EXCEPTION_MESSAGE_ID = "javax.faces.validator.RegexValidator.MATCH_EXCEPTION";
 104  
 
 105  
     //TODO: Find a better place for such a common constant
 106  
     private static final String EMPTY_STRING = "";
 107  
 
 108  
     private String pattern;
 109  
 
 110  0
     private boolean isTransient = false;
 111  
 
 112  
     // VALIDATE
 113  
     /** {@inheritDoc} */
 114  
     public void validate(FacesContext context,
 115  
                          UIComponent component,
 116  
                          Object value)
 117  
     {
 118  0
         if (context == null)
 119  
         {
 120  0
             throw new NullPointerException("context");
 121  
         }
 122  0
         if (component == null)
 123  
         {
 124  0
             throw new NullPointerException("component");
 125  
         }
 126  
 
 127  0
         if (value == null)
 128  
         {
 129  0
             return;
 130  
         }
 131  0
         if (!(value instanceof String))
 132  
         {
 133  0
             throw new ValidatorException(_MessageUtils.getErrorMessage(context, NOT_MATCHED_MESSAGE_ID, null));
 134  
         }
 135  
 
 136  0
         String string = (String) value;
 137  
 
 138  
         Pattern thePattern;
 139  0
         if (pattern == null
 140  
          || pattern.equals(EMPTY_STRING))
 141  
         {
 142  0
             throw new ValidatorException(_MessageUtils.getErrorMessage(context, PATTERN_NOT_SET_MESSAGE_ID, null));
 143  
         }
 144  
 
 145  
         try
 146  
         {
 147  0
             thePattern = Pattern.compile(pattern);
 148  
         }
 149  0
         catch (PatternSyntaxException pse)
 150  
         {
 151  0
             throw new ValidatorException(_MessageUtils.getErrorMessage(context, MATCH_EXCEPTION_MESSAGE_ID, null));
 152  0
         }
 153  
 
 154  0
         if (!thePattern.matcher(string).matches())
 155  
         {
 156  
             //TODO: Present the patternExpression in a more user friendly way
 157  0
             Object[] args = {thePattern, _MessageUtils.getLabel(context, component)};
 158  0
             throw new ValidatorException(_MessageUtils.getErrorMessage(context, NOT_MATCHED_MESSAGE_ID, args));
 159  
         }
 160  0
     }
 161  
 
 162  
     // RESTORE & SAVE STATE
 163  
 
 164  
     /** {@inheritDoc} */
 165  
     public Object saveState(FacesContext context)
 166  
     {
 167  0
         if (!initialStateMarked())
 168  
         {
 169  0
             return pattern;
 170  
         }
 171  0
         return null;
 172  
     }
 173  
 
 174  
     /** {@inheritDoc} */
 175  
     public void restoreState(FacesContext context, Object state)
 176  
     {
 177  0
         if (state != null)
 178  
         {
 179  
             //Since pattern is required, if state is null
 180  
             //nothing has changed
 181  0
             this.pattern = (String) state;
 182  
         }
 183  0
     }
 184  
 
 185  
     // SETTER & GETTER
 186  
 
 187  
     /** {@inheritDoc} */
 188  
     public boolean isTransient()
 189  
     {
 190  0
         return isTransient;
 191  
     }
 192  
 
 193  
     /** {@inheritDoc} */
 194  
     public void setTransient(boolean isTransient)
 195  
     {
 196  0
         this.isTransient = isTransient;
 197  0
     }
 198  
 
 199  
     /**
 200  
      * The Regular Expression property to validate against. This property must be a ValueExpression
 201  
      * that resolves to a String in the format of the java.util.regex patterns.
 202  
      *
 203  
      * @param pattern a ValueExpression that evaluates to a String that is the regular expression pattern
 204  
      */
 205  
     public void setPattern(String pattern)
 206  
     {
 207  
         //TODO: Validate input parameter
 208  0
         this.pattern = pattern;
 209  0
         clearInitialState();
 210  0
     }
 211  
 
 212  
     /**
 213  
      * Return the ValueExpression that yields the regular expression pattern when evaluated.
 214  
      *
 215  
      * @return The pattern.
 216  
      */
 217  
     @JSFProperty(required = true)
 218  
     public String getPattern()
 219  
     {
 220  0
         return this.pattern;
 221  
     }
 222  
 
 223  0
     private boolean _initialStateMarked = false;
 224  
 
 225  
     public void clearInitialState()
 226  
     {
 227  0
         _initialStateMarked = false;
 228  0
     }
 229  
 
 230  
     public boolean initialStateMarked()
 231  
     {
 232  0
         return _initialStateMarked;
 233  
     }
 234  
 
 235  
     public void markInitialState()
 236  
     {
 237  0
         _initialStateMarked = true;
 238  0
     }
 239  
     
 240  
     @JSFProperty(faceletsOnly=true)
 241  
     @SuppressWarnings("unused")
 242  
     private Boolean isDisabled()
 243  
     {
 244  0
         return null;
 245  
     }
 246  
     
 247  
     @JSFProperty(faceletsOnly=true)
 248  
     @SuppressWarnings("unused")
 249  
     private String getFor()
 250  
     {
 251  0
         return null;
 252  
     }
 253  
 }