|
WebObjects 5.4.2 | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
public interface NSValidation
The NSValidation interface defines a validation mechanism in which the properties of an object are validated indirectly by name (or key), rather than directly through invocation of an specific validation method. Thus, all of an object's properties can be validated in a consistent
manner. The validateValueForKey
method confirms that a value is legal for a particular property, and validateTakeValueForKeyPath
performs the validation and assigns the value if it's legal and different from the current value.
The NSValidation interface contains two inner classes, NSValidation.DefaultImplementation and NSValidation.Utility. The former provides a default implementation of the interface, making it easy to implement custom classes. The latter is a convenience class that allows you to access the properties of NSValidation objects and non-NSValidation objects using the same code.
The methods in the NSValidation.DefaultImplementation class are just like the methods defined by the NSValidation interface, except they are static methods and they take an extra argument -- the object on which the default implementation should operate.
For example, suppose you want to implement an Employee class that implements NSValidation using NSValidation.DefaultImplementation. Employee's validateValueForKey method would then look like this:
<blockquote> public Object validateValueForKey(Object value, String key) { return NSValidation.DefaultImplementation.validateValueForKey(this, value, key); } </blockquote>
The NSValidation.DefaultImplementation methods search for property- specific methods of the form validateKey and invoke them if they exist. Thus an NSValidation class should implement a validate method for each property that has associated validation logic. For
example, a validateAge
method could check that the value a user enters as an age is within acceptable limits and throw an NSValidation.ValidationException if it finds an unacceptable value.
Because custom validation logic is implements in the validateKey methods, you rarely need to implement the NSValidation methods from scratch. Rather, the default implementation provided by NSValidation.DefaultImplementation is generally sufficient.
Note:The default implementations have significant performance optimizations. To benefit from them, implement NSValidation on a custom class as shown above by using the methods in NSValidation.DefaultImplementation, or if the class inherits from a WebObjects class that implements NSValidation, don't override the inherited implementation. Using a custom implementation incurs significant performance penalties.Recall that the NSValidation.Utility class is a convenience class that allows you to access the properties of NSValidation objects and non-NSValidation objects using the same code.
Utility's methods are similar to DefaultImplementation's methods in that they are static methods and they take an extra argument -- the object on which the method should operate. However, Utility's methods simply check to see if the object on which they operate is an NSValidation object and invoke the corresponding NSValidation method on the object if it is. Otherwise, they invoke the corresponding DefaultImplementation method, passing the object on which to operate.
For example, suppose that you want to access an object with the NSValidation API but doesn't know if the object is an NSValidation object. To do so, you simply use the corresponding Utility API, as in the following line of code:
<blockquote> theValue = NSValidation.Utility.validateValueForKey(object, value, key); </blockquote>
The above line of code is simply a short-cut for the following:
<blockquote> if (object instanceof NSValidation) { theValue = ((NSValidation)object).validateValueForKey(key); } else { theValue = validateValueForKey.DefaultImplementation.validateValueForKey( object, value, key); } </blockquote>
To implement validation logic in an NSValidation class, a validateKey method is created for each property needing validation. The default implementations of NSValidation's methods look for these validateKey methods and use them to perform the actual validation.
A class's validateKey methods should have the following form:
<blockquote> public Object validateKey(Object aValue) throws NSValidation.ValidationException </blockquote>
The implementation should confirm that the value passed in is legal and throw an NSValidation.ValidationException if it's not. It should also coerce the argument to the proper type, if necessary. Note that a validateKey method's argument type is Object, and not specifically the class of the corresponding property (String, Integer, or NSTimestamp, for example). Thus, a validateKey method needs to check the type of the argument and convert it to a different type if necessary. The return type of a validateKey method doesn't have to be Object. In fact, it's a good idea to specify the class of the value the method returns, which is generally the class of the corresponding property. The argument type, on the other hand, should generally be Object.
The following validateAge method is an example that validates values for a property named age
that's stored as an Integer. The method handles arguments of type String and Number. If the argument is an instance of any other class, the method throws a
NSValidation.ValidationException.
<blockquote> public Number validateAge(Object aValue) throws NSValidation.ValidationException { Integer numberValue; int age; if (aValue instanceof String) { // Convert the String to an Integer. try { numberValue = new Integer((String)aValue); } catch (NumberFormatException numberFormatException) { throw new NSValidation.ValidationException("Validation exception: Unable to convert the String " + aValue + " to an Integer"); } } else if (aValue instanceof Number) { numberValue = new Integer(((Number)aValue).intValue()); } else { throw new NSValidation.ValidationException("Validation exception: Unable to convert the Object " + aValue + " to an Integer"); } age = numberValue.intValue(); if (age < 16) { throw new NSValidation.ValidationException("Age of " + age + " is below minimum.", this, "age"); } return numberValue; } </blockquote>
The validateAge method checks the argument's class. If the argument is a String or Number, it creates an Integer from the argument and validates it. If the Integer fails the validation test (if the value is less than 16), the method throws an NSValidation.ValidationException inserting the NSValidation object and the key into the exception's userInfo dictionary by providing them to the constructor. On the other hand, if the Integer passes the validation test, the method returns the Integer.
The code that invokes the validation process is expected to use the value returned from the validateKey method instead of the original value it provided. Thus, a validateKey method has an opportunity to coerce a value into a type it prefers. As another
example of coercion, a validateKey method can return null
. A method might do this, for example, if it is invoked with the empty string as the argument.
The argument type of a validateKey method doesn't have to be specifically Object; it can be Object or any subclass. However, generally Object is the most appropriate type for a validateKey method's argument (the one exception is described later in this section). As explained in "Writing validateKey Methods", a validateKey method should be able to handle any reasonable argument type. You can type the argument to the common superclass of all reasonable arguments, but this is frequently Object.
You should not overload a validateKey method for a particular property, creating different validateKey methods for each argument type. Instead you should create one version of the validateKey method for the property that takes Object as its argument (or at least a superclass of all the possible argument types). The method's implementation should test the argument's type and coerce it appropriately.
There's one situation in which the argument type should be more specific than Object. If the property corresponding to the validateKey method is a to-one relationship to an enterprise object, the argument's type should be EOEnterpriseObject.
NSValidation.validateValueForKey(java.lang.Object, java.lang.String)
,
NSValidation.validateTakeValueForKeyPath(java.lang.Object, java.lang.String)
,
NSValidation.DefaultImplementation
,
NSValidation.Utility
,
NSKeyValueCoding
Nested Class Summary | |
---|---|
static class |
NSValidation.DefaultImplementation
The methods in the NSValidation.DefaultImplementation class are just like the methods defined by the NSValidation interface, except they are static methods and they take an additional argument, which is the object on which the default implementation should operate. |
static class |
NSValidation.Utility
This class is a convenience that allows you to access the properties of NSValidation objects and non-NSValidation objects using the same code. |
static class |
NSValidation.ValidationException
Instances of the NSValidation.ValidationException class are created and thrown when an error condition is encountered during the validation of an object that implements NSValidation. |
Method Summary | |
---|---|
Object |
validateTakeValueForKeyPath(Object value,
String keyPath)
Confirms that value is legal for the object's property named by keyPath and then assigns it to the property. |
Object |
validateValueForKey(Object value,
String key)
Confirms that value is legal for the object's property named by key . |
Method Detail |
---|
Object validateValueForKey(Object value, String key) throws NSValidation.ValidationException
value
is legal for the object's property named by key
.
It returns the validated value
if it's legal, or throws an NSValidation.ValidationException
. Custom implementations may return something other than value
, including a coerced value or a substitution.
The default implementation of this method (provided by NSValidation.DefaultImplementation) checks for a method of the form validate
Key (for example, validateBudget
for a key of "budget
"). If such a method exists, it invokes it and
returns the result. Thus, NSValidation objects can implement individual validate
Key methods to check limits, test for nonsense values, and coerce values (convert strings to dates or numbers, for example). If no such method exists, it simply returns
value
value
- the value to be examined for validitykey
- the key for the property corresponding to value
value
, value
coerced to a different type or precision, or an entirely different substitution
NSValidation.ValidationException
- value
is invalidNSKeyValueCoding.valueForKey(java.lang.String)
,
NSValidation.DefaultImplementation
Object validateTakeValueForKeyPath(Object value, String keyPath) throws NSValidation.ValidationException
value
is legal for the object's property named by keyPath
and then assigns it to the property.
If value
is valid, this method then assigns a new value to the property. The new value may be different than value
if a custom validation method performed any coercions or substitutions. Finally, this method returns the Object actually assigned to the property.
By default, this is value
If value
is an invalid value for this property, this method throws an NSValidation.ValidationException
A keyPath
has the form relationship.property
(with one or more relationships); for example "movieRole.roleName
" or "movieRole.talent.lastName
".
The default implementation of this method (provided by NSValidation.DefaultImplementation) gets the destination object for each relationship using valueForKey
, and sends the final object a validateValueForKey
message with value
and
property.
value
- the value to be examined for validity, and then assigned to the property at keyPath
keyPath
- the key path describing the property to operate upon
value
, value
coerced to a different type or precision, or an entirely different substitution
NSValidation.ValidationException
- if value
is invalidNSKeyValueCoding.takeValueForKey(java.lang.Object, java.lang.String)
,
NSKeyValueCoding.valueForKey(java.lang.String)
,
NSValidation.validateValueForKey(java.lang.Object, java.lang.String)
,
NSValidation.DefaultImplementation
|
Last updated June 2008 | ||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |