////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2003-2006 Adobe Macromedia Software LLC and its licensors.
// All Rights Reserved. The following is Source Code and is subject to all
// restrictions on such code as contained in the End User License Agreement
// accompanying this product.
//
////////////////////////////////////////////////////////////////////////////////
package mx.validators
{
import mx.events.ValidationResultEvent;
import mx.managers.ISystemManager;
import mx.managers.SystemManager;
import mx.resources.ResourceBundle;
/**
* The RegExpValidator class lets you use a regular expression
* to validate a field.
* You pass a regular expression to the validator using the
* <code>expression</code> property, and additional flags
* to control the regular expression pattern matching
* using the <code>flags</code> property.
*
* <p>The validation is successful if the validator can find a match
* of the regular expression in the field to validate.
* A validation error occurs when the validator finds no match.</p>
*
* <p>The RegExpValidator class dispatches the <code>valid</code>
* and <code>invalid</code> events.
* For an <code>invalid</code> event, the event object is an instance
* of the ValidationResultEvent class, and it contains an Array
* of ValidationResult objects.</p>
*
* <p>However, for a <code>valid</code> event, the ValidationResultEvent
* object contains an Array of RegExpValidationResult objects.
* The RegExpValidationResult class is a child class of the
* ValidationResult class, and contains additional properties
* used with regular expressions, including the following:</p>
* <ul>
* <li><code>matchedIndex</code> An integer that contains the starting
* index in the input String of the match.</li>
* <li><code>matchedString</code> A String that contains the substring
* of the input String that matches the regular expression.</li>
* <li><code>matchedSubStrings</code> An Array of Strings that contains
* parenthesized substring matches, if any. If no substring matches are found,
* this Array is of length 0. Use matchedSubStrings[0] to access the
* first substring match.</li>
* </ul>
*
* @mxml
*
* <p>The <code><mx:RegExpValidator></code> tag
* inherits all of the tag attributes of its superclass,
* and adds the following tag attributes:</p>
*
* <pre>
* <mx:RegExpValidator
* expression="<i>No default</i>"
* flags="<i>No default</i>"
* noExpressionError="The expression is missing."
* noMatchError="The field is invalid."
* />
* </pre>
*
* @includeExample examples/RegExValidatorExample.mxml
*
* @see mx.validators.RegExpValidationResult
* @see mx.validators.ValidationResult
* @see RegExp
*/
public class RegExpValidator extends Validator
{
include "../core/Version.as";
//--------------------------------------------------------------------------
//
// Class initialization
//
//--------------------------------------------------------------------------
loadResources();
//--------------------------------------------------------------------------
//
// Class resources
//
//--------------------------------------------------------------------------
[ResourceBundle("validators")]
/**
* @private
*/
private static var packageResources:ResourceBundle;
/**
* @private
*/
private static var resourceNoExpressionError:String;
/**
* @private
*/
private static var resourceNoMatchError:String;
//--------------------------------------------------------------------------
//
// Class methods
//
//--------------------------------------------------------------------------
/**
* @private
* Loads resources for this class.
*/
private static function loadResources():void
{
resourceNoExpressionError =
packageResources.getString("noExpressionError");
resourceNoMatchError = packageResources.getString("noMatchError");
}
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor
*/
public function RegExpValidator()
{
super();
bundleChanged();
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
*/
private var _regExp:RegExp;
/**
* @private
*/
private var _foundMatch:Boolean = false;
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// expression
//----------------------------------
/**
* @private
* Storage for the expression property.
*/
private var _expression:String;
[Inspectable(category="General")]
/**
* The regular expression to use for validation.
*/
public function get expression():String
{
return _expression;
}
/**
* @private
*/
public function set expression(value:String):void
{
if (_expression != value)
{
_expression = value;
createRegExp();
}
}
//----------------------------------
// flags
//----------------------------------
/**
* @private
* Storage for the flags property.
*/
private var _flags:String;
[Inspectable(category="General", defaultValue="null")]
/**
* The regular expression flags to use when matching.
*/
public function get flags():String
{
return _flags;
}
/**
* @private
*/
public function set flags(value:String):void
{
if (_flags != value)
{
_flags = value;
createRegExp();
}
}
//--------------------------------------------------------------------------
//
// Properties: Errors
//
//--------------------------------------------------------------------------
//----------------------------------
// noExpressionError
//----------------------------------
[Inspectable(category="Errors", defaultValue="The expression is missing.")]
/**
* Error message when there is no regular expression specifed.
* The default value is "The expression is missing."
*/
public var noExpressionError:String;
//----------------------------------
// noMatchError
//----------------------------------
[Inspectable(category="Errors", defaultValue="The field is invalid.")]
/**
* Error message when there are no matches to the regular expression.
* The default value is "The field is invalid."
*/
public var noMatchError:String;
//--------------------------------------------------------------------------
//
// Overridden methods
//
//--------------------------------------------------------------------------
/**
* Override of the base class <code>doValidation()</code> method
* to validate a regular expression.
*
* <p>You do not call this method directly;
* Flex calls it as part of performing a validation.
* If you create a custom Validator class, you must implement this method. </p>
*
* @param value Object to validate.
*
* @return For an invalid result, an Array of ValidationResult objects,
* with one ValidationResult object for each field examined by the validator.
*/
override protected function doValidation(value:Object):Array
{
var results:Array = super.doValidation(value);
// Return if there are errors
// or if the required property is set to <code>false</code> and length is 0.
var val:String = value ? String(value) : "";
if (results.length > 0 || ((val.length == 0) && !required))
return results;
return validateRegExpression(value);
}
/**
* @private
*/
override protected function handleResults(
errorResults:Array):ValidationResultEvent
{
var result:ValidationResultEvent;
if (_foundMatch)
{
result = new ValidationResultEvent(ValidationResultEvent.VALID);
result.results = errorResults;
}
else
{
result = super.handleResults(errorResults);
}
_foundMatch = false;
return result;
}
//--------------------------------------------------------------------------
//
// Methods
//
//--------------------------------------------------------------------------
/**
* @private
* Populates localizable properties from the loaded bundle for this class.
*/
private function bundleChanged():void
{
noExpressionError = resourceNoExpressionError;
noMatchError = resourceNoMatchError;
}
/**
* @private
*/
private function createRegExp():void
{
_regExp = new RegExp(_expression,_flags);
}
/**
* @private
* Performs validation on the validator
*/
private function validateRegExpression(value:Object):Array
{
var results:Array = [];
_foundMatch = false;
if (_regExp)
{
var result:Object = _regExp.exec(String(value));
if (_regExp.global)
{
while (result != null)
{
results.push(new RegExpValidationResult(
false, null, "", "", result[0],
result.index, result.slice(1)));
result = _regExp.exec(String(value));
_foundMatch = true;
}
}
else if (result != null)
{
results.push(new RegExpValidationResult(
false, null, "", "", result[0],
result.index, result.slice(1)));
_foundMatch = true;
}
if (results.length == 0)
{
results.push(new ValidationResult(
true, null, "noMatch", noMatchError));
}
}
else
{
results.push(new ValidationResult(
true, null, "noExpression", noExpressionError));
}
return results;
}
}
}