001 package org.apache.fulcrum.intake.validator;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import java.util.Map;
023 import java.util.regex.Pattern;
024 import java.util.regex.PatternSyntaxException;
025
026 import org.apache.commons.lang.StringUtils;
027
028 /**
029 * A validator that will compare a testValue against the following
030 * constraints:
031 * <table>
032 * <tr><th>Name</th><th>Valid Values</th><th>Default Value</th></tr>
033 * <tr><td>required</td><td>true|false</td><td>false</td></tr>
034 * <tr><td>mask</td><td>regexp</td><td> </td></tr>
035 * <tr><td>minLength</td><td>integer</td><td>0</td></tr>
036 * <tr><td>maxLength</td><td>integer</td><td> </td></tr>
037 * </table>
038 *
039 * This validator can serve as the base class for more specific validators
040 *
041 * @author <a href="mailto:jmcnally@collab.net">John McNally</a>
042 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
043 * @author <a href="mailto:Colin.Chalmers@maxware.nl">Colin Chalmers</a>
044 * @author <a href="mailto:jh@byteaction.de">Jürgen Hoffmann</a>
045 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
046 * @version $Id: StringValidator.java 832048 2009-11-02 18:55:08Z tv $
047 */
048 public class StringValidator
049 extends DefaultValidator
050 {
051 /** The matching mask String as supplied by the XML input */
052 protected String maskString = null;
053
054 /** The compiled Regular Expression */
055 protected Pattern maskPattern = null;
056
057 /** The message to report if the mask constraint is not satisfied */
058 protected String maskMessage = null;
059
060
061 /**
062 * Constructor
063 *
064 * @param paramMap a <code>Map</code> of <code>Rule</code>'s
065 * containing constraints on the input.
066 * @exception InvalidMaskException An invalid mask was specified for one of the rules
067
068 */
069 public StringValidator(Map paramMap)
070 throws InvalidMaskException
071 {
072 init(paramMap);
073 }
074
075 /**
076 * Default constructor
077 */
078 public StringValidator()
079 {
080 // do nothing
081 }
082
083 /**
084 * Extract the relevant parameters from the constraints listed
085 * in <rule> tags within the intake.xml file.
086 *
087 * @param paramMap a <code>Map</code> of <code>Rule</code>'s
088 * containing constraints on the input.
089 * @exception InvalidMaskException An invalid mask was specified for one of the rules
090 */
091 public void init(Map paramMap)
092 throws InvalidMaskException
093 {
094 super.init(paramMap);
095
096 Constraint constraint = (Constraint) paramMap.get(MASK_RULE_NAME);
097 if (constraint != null)
098 {
099 String param = constraint.getValue();
100 setMask(param);
101 maskMessage = constraint.getMessage();
102 }
103
104 }
105
106 /**
107 * Determine whether a testValue meets the criteria specified
108 * in the constraints defined for this validator
109 *
110 * @param testValue a <code>String</code> to be tested
111 * @exception ValidationException containing an error message if the
112 * testValue did not pass the validation tests.
113 */
114 public void assertValidity(String testValue)
115 throws ValidationException
116 {
117 super.assertValidity(testValue);
118
119 if ((required || StringUtils.isNotEmpty(testValue)) && maskPattern != null)
120 {
121 /** JDK 1.4 matcher */
122 boolean patternMatch = maskPattern.matcher(testValue).matches();
123
124 log.debug("Trying to match " + testValue
125 + " to pattern " + maskString);
126
127 if (!patternMatch)
128 {
129 errorMessage = maskMessage;
130 throw new ValidationException(maskMessage);
131 }
132 }
133 }
134
135 // ************************************************************
136 // ** Bean accessor methods **
137 // ************************************************************
138
139 /**
140 * Get the value of mask.
141 *
142 * @return value of mask.
143 */
144 public String getMask()
145 {
146 return maskString;
147 }
148
149 /**
150 * Set the value of mask.
151 *
152 * @param mask Value to assign to mask.
153 * @throws InvalidMaskException the mask could not be compiled.
154 */
155 public void setMask(String mask)
156 throws InvalidMaskException
157 {
158 maskString = mask;
159
160 // Fixme. We should make this configureable by the XML file -- hps
161 int maskOptions = 0;
162
163 try
164 {
165 log.debug("Compiling pattern " + maskString);
166 maskPattern = Pattern.compile(maskString, maskOptions);
167 }
168 catch (PatternSyntaxException pe)
169 {
170 throw new InvalidMaskException("Could not compile pattern " + maskString, pe);
171 }
172 }
173
174 /**
175 * Get the value of maskMessage.
176 *
177 * @return value of maskMessage.
178 */
179 public String getMaskMessage()
180 {
181 return maskMessage;
182 }
183
184 /**
185 * Set the value of maskMessage.
186 *
187 * @param message Value to assign to maskMessage.
188 */
189 public void setMaskMessage(String message)
190 {
191 this.maskMessage = message;
192 }
193 }