1////////////////////////////////////////////////////////////////////////////////
2//
3//  ADOBE SYSTEMS INCORPORATED
4//  Copyright 2003-2007 Adobe Systems Incorporated
5//  All Rights Reserved.
6//
7//  NOTICE: Adobe permits you to use, modify, and distribute this file
8//  in accordance with the terms of the license agreement accompanying it.
9//
10////////////////////////////////////////////////////////////////////////////////
11
12package mx.validators
13{
14
15import mx.managers.ISystemManager;
16import mx.managers.SystemManager;
17import mx.resources.IResourceManager;
18import mx.resources.ResourceManager;
19
20[ResourceBundle("validators")]
21
22/**
23 *  The SocialSecurityValidator class validates that a String
24 *  is a valid United States Social Security number.
25 *  It does not check whether it is an existing Social Security number.
26 *
27 *  @mxml
28 *
29 *  <p>The <code>&lt;mx:SocialSecurityValidator&gt;</code> tag
30 *  inherits all of the tag attributes of its superclass,
31 *  and adds the following tag attributes:</p>
32 *
33 *  <pre>
34 *  &lt;mx:SocialSecurityValidator
35 *    allowedFormatChars=" -"
36 *    invalidCharError="You entered invalid characters in your Social Security number."
37 *    wrongFormatError="The Social Security number must be 9 digits or in the form NNN-NN-NNNN."
38 *    zeroStartError="Invalid Social Security number; the number cannot start with 000."
39 *  /&gt;
40 *  </pre>
41 *
42 *  @includeExample examples/SocialSecurityValidatorExample.mxml
43 */
44public class SocialSecurityValidator extends Validator
45{
46	include "../core/Version.as";
47
48	//--------------------------------------------------------------------------
49	//
50	//  Class methods
51	//
52	//--------------------------------------------------------------------------
53
54	/**
55	 *  Convenience method for calling a validator.
56	 *  Each of the standard Flex validators has a similar convenience method.
57	 *
58	 *  @param validator The SocialSecurityValidator instance.
59	 *
60	 *  @param value A field to validate.
61	 *
62	 *  @param baseField Text representation of the subfield
63	 *  specified in the <code>value</code> parameter.
64	 *  For example, if the <code>value</code> parameter specifies
65	 *  value.social, the <code>baseField</code> value is <code>social</code>.
66	 *
67	 *  @return An Array of ValidationResult objects, with one ValidationResult
68	 *  object for each field examined by the validator.
69	 *
70	 *  @see mx.validators.ValidationResult
71	 */
72	public static function validateSocialSecurity(
73								validator:SocialSecurityValidator,
74								value:Object,
75								baseField:String):Array
76	{
77		var results:Array = [];
78
79		// Resource-backed properties of the validator.
80		var allowedFormatChars:String = validator.allowedFormatChars;
81
82		var resourceManager:IResourceManager = ResourceManager.getInstance();
83
84		var hyphencount:int = 0;
85		var len:int = value.toString().length;
86		var checkForFormatChars:Boolean = false;
87
88		var n:int;
89		var i:int;
90
91		if ((len != 9) && (len != 11))
92		{
93			results.push(new ValidationResult(
94				true, baseField, "wrongFormat",
95				validator.wrongFormatError));
96			return results;
97		}
98
99		n = allowedFormatChars.length;
100		for (i = 0; i < n; i++)
101		{
102			if (DECIMAL_DIGITS.indexOf(allowedFormatChars.charAt(i)) != -1)
103			{
104				var message:String = resourceManager.getString(
105					"validators", "invalidFormatChars");
106				throw new Error(message);
107			}
108		}
109
110		if (len == 11)
111			checkForFormatChars = true;
112
113		for (i = 0; i < len; i++)
114		{
115			var allowedChars:String;
116			if (checkForFormatChars && (i == 3 || i == 6))
117				allowedChars = allowedFormatChars;
118			else
119				allowedChars = DECIMAL_DIGITS;
120
121			if (allowedChars.indexOf(value.charAt(i)) == -1)
122			{
123				results.push(new ValidationResult(
124					true, baseField, "invalidChar",
125					validator.invalidCharError));
126				return results;
127			}
128		}
129
130		if (value.substring(0, 3) == "000")
131		{
132			results.push(new ValidationResult(
133				true, baseField, "zeroStart",
134				validator.zeroStartError));
135			return results;
136		}
137
138		return results;
139	}
140
141	//--------------------------------------------------------------------------
142	//
143	//  Constructor
144	//
145	//--------------------------------------------------------------------------
146
147	/**
148	 *  Constructor.
149	 */
150	public function SocialSecurityValidator()
151	{
152		super();
153	}
154
155	//--------------------------------------------------------------------------
156	//
157	//  Properties
158	//
159	//--------------------------------------------------------------------------
160
161	//----------------------------------
162	//  allowedFormatChars
163	//----------------------------------
164
165	/**
166	 *  @private
167	 */
168	private var _allowedFormatChars:String;
169
170    /**
171	 *  @private
172	 */
173	private var allowedFormatCharsOverride:String;
174
175	[Inspectable(category="General", defaultValue="null")]
176
177	/**
178	 *  Specifies the set of formatting characters allowed in the input.
179	 *
180	 *  @default "()- .+" // ?????
181	 */
182	public function get allowedFormatChars():String
183	{
184		return _allowedFormatChars;
185	}
186
187    /**
188	 *  @private
189	 */
190	public function set allowedFormatChars(value:String):void
191	{
192		if (value != null)
193		{
194			var n:int = value.length;
195			for (var i:int = 0; i < n; i++)
196			{
197				if (DECIMAL_DIGITS.indexOf(value.charAt(i)) != -1)
198				{
199					var message:String = resourceManager.getString(
200						"validators", "invalidFormatChars");
201					throw new Error(message);
202				}
203			}
204		}
205
206		allowedFormatCharsOverride = value;
207
208		_allowedFormatChars = value != null ?
209							  value :
210							  resourceManager.getString(
211								  "validators",
212								  "socialSecurityValidatorAllowedFormatChars");
213	}
214
215	//--------------------------------------------------------------------------
216	//
217	//  Properties: Errors
218	//
219	//--------------------------------------------------------------------------
220
221	//----------------------------------
222	//  invalidCharError
223	//----------------------------------
224
225    /**
226	 *  @private
227	 *  Storage for the invalidCharError property.
228	 */
229	private var _invalidCharError:String;
230
231    /**
232	 *  @private
233	 */
234	private var invalidCharErrorOverride:String;
235
236	[Inspectable(category="Errors", defaultValue="null")]
237
238	/**
239	 *  Error message when the value contains characters
240	 *  other than digits and formatting characters
241	 *  defined by the <code>allowedFormatChars</code> property.
242	 *
243	 *  @default "You entered invalid characters in your Social Security number."
244	 */
245	public function get invalidCharError():String
246	{
247		return _invalidCharError;
248	}
249
250	/**
251	 *  @private
252	 */
253	public function set invalidCharError(value:String):void
254	{
255		invalidCharErrorOverride = value;
256
257		_invalidCharError = value != null ?
258							value :
259							resourceManager.getString(
260								"validators", "invalidCharErrorSSV");
261	}
262
263	//----------------------------------
264	//  wrongFormatError
265	//----------------------------------
266
267    /**
268	 *  @private
269	 *  Storage for the wrongFormatError property.
270	 */
271	private var _wrongFormatError:String;
272
273    /**
274	 *  @private
275	 */
276	private var wrongFormatErrorOverride:String;
277
278	[Inspectable(category="Errors", defaultValue="null")]
279
280	/**
281	 *  Error message when the value is incorrectly formatted.
282	 *
283	 *  @default "The Social Security number must be 9 digits or in the form NNN-NN-NNNN."
284	 */
285	public function get wrongFormatError():String
286	{
287		return _wrongFormatError;
288	}
289
290	/**
291	 *  @private
292	 */
293	public function set wrongFormatError(value:String):void
294	{
295		wrongFormatErrorOverride = value;
296
297		_wrongFormatError = value != null ?
298							value :
299							resourceManager.getString(
300								"validators", "wrongFormatError");
301	}
302
303	//----------------------------------
304	//  zeroStartError
305	//----------------------------------
306
307    /**
308	 *  @private
309	 *  Storage for the zeroStartError property.
310	 */
311	private var _zeroStartError:String;
312
313    /**
314	 *  @private
315	 */
316	private var zeroStartErrorOverride:String;
317
318	[Inspectable(category="Errors", defaultValue="null")]
319
320	/**
321	 *  Error message when the value contains an invalid Social Security number.
322	 *
323	 *  @default "Invalid Social Security number; the number cannot start with 000."
324	 */
325	public function get zeroStartError():String
326	{
327		return _zeroStartError;
328	}
329
330	/**
331	 *  @private
332	 */
333	public function set zeroStartError(value:String):void
334	{
335		zeroStartErrorOverride = value;
336
337		_zeroStartError = value != null ?
338						  value :
339						  resourceManager.getString(
340						      "validators", "zeroStartError");
341	}
342
343	//--------------------------------------------------------------------------
344	//
345	//  Overridden methods
346	//
347	//--------------------------------------------------------------------------
348
349    /**
350	 *  @private
351     */
352	override protected function resourcesChanged():void
353	{
354		super.resourcesChanged();
355
356		allowedFormatChars = allowedFormatChars;
357
358		invalidCharError = invalidCharErrorOverride;
359		wrongFormatError = wrongFormatErrorOverride;
360		zeroStartError = zeroStartErrorOverride;
361	}
362
363	/**
364     *  Override of the base class <code>doValidation()</code> method
365     *  to validate a Social Security number.
366     *
367	 *  <p>You do not call this method directly;
368	 *  Flex calls it as part of performing a validation.
369	 *  If you create a custom Validator class, you must implement this method.</p>
370	 *
371     *  @param value Object to validate.
372     *
373	 *  @return An Array of ValidationResult objects, with one ValidationResult
374	 *  object for each field examined by the validator.
375	 */
376	override protected function doValidation(value:Object):Array
377    {
378		var results:Array = super.doValidation(value);
379
380		// Return if there are errors
381		// or if the required property is set to <code>false</code> and length is 0.
382		var val:String = value ? String(value) : "";
383		if (results.length > 0 || ((val.length == 0) && !required))
384			return results;
385		else
386		    return SocialSecurityValidator.validateSocialSecurity(this, value, null);
387    }
388}
389
390}
391