Types of validation
Validation
rules are applied to an entity to make sure that only valid values are
committed
to the
database and to prevent any invalid data from getting saved to the database. In
ADF,
we use
validation rules for the entity object to make sure the row is valid all the
time.
There are
three types of validation rules that can be set for the entity objects; they
are
as follows:
Entity-level validation
Attribute-level validation
Transaction-level validation
Entity-level validation
As we know,
an entity represents a row in the database table. Entity-level validation is the
business
rule that is added to the database row. For example, the validation rule that
has
to be
applied to a row is termed as entity-level validation.
There are
two unique declarative validators that will be available only for entity-level
validation—Collection and UniqueKey. The following diagram explains that
entity-level
validations
are applied on a single row in the EMP table. The validated row is highlighted
in bold.
Attribute-level validation
Attribute-level
validations are applied to attributes. Business logic mostly involves specific
validations
to compare different attribute values or to restrict the attributes to a
specific
range.
These kinds of validations are done in attribute-level validation. Some of the
declarative
validators
available in ADF are Compare, Length, and Range.
Transaction-level validation
Transaction-level
validations are done after all entity-level validations are completed. If you
want to add
any kind of validation at the end of the process, you can defer the validation
to
the
transaction level to ensure that the validation is performed only once.
Built-in declarative validators
ADF Business Components includes some built-in validators to
support and apply validations for entity objects.
The Business Rules section for the EmpEO.xml file will list all the validations for the EmpEO
entity. In
the previous screenshot, we will see that the there are no entity-level
validators
defined and
some of the attribute-level validations are listed in the Attributes folder.
Collection validator
A
Collection validator is available only for entity-level validation. To perform
operations such as
average, min, max, count, and sum for the collection of rows, we use the
collection validator.
Collection
validators are compared to the GROUP BY operation in an SQL query with a
validation.
The aggregate functions, such as count, sum, min, and max are added to validate
the entity
row. The validator is operated against the literal value, expression, query
result,
and so on.
You must have the association accessor to add a collection validation.
Now, we
will add a Collection validator to DeptEO.xml for adding a count validation rule.
Imagine a
business rule that says that the number of employees added to department
number 10 should be more than
five. In this case, you will have a count operation for the
employees
added to department number 10 and show a message if the count is less
than
5 for a particular department.
1.
Go to the Business Rules section of DeptEO.xml. You will find the Business
Rules
section in
the Overview tab.
2.
Select Entity Validators and click on the + button. You may right-click on the Entity
Validators folder and then select New Validator to add a validator.
3.
Select Collection as Rule Type and move on
to the Rule Definition tab.
4.
In this section,
select Count for the Operation field; Accessor is the association
accessor
that gets added through a composition
association relationship.
Only the
composition
association accessor will be listed in the Accessor
drop-down menu.
Select the
accessor for EmpEO listed in the dropdown, with Empno as the value
for Attribute.
In order to
create a composition association accessor, you will
have to
create an association between DeptEO.xml and
EmpEO.xml based on the Deptno attribute
with cardinality
of 1 to *. The Composition Association option has
to be
selected to enable a composition relationship between
the two
entities.
5.
The value of the Operator option
should be selected as Greater Than. Compare
with will be a literal value, which is 5 that can be entered
in the Enter Literal Value
section
below.
Specifying the execution rule
Following
are the steps to specify the execution:
1.
Now to set the
execution rule, we will move to the Validation
Execution tab.
2.
In the Conditional Execution section, add Deptno = '10' as the value for
Conditional
Execution Expression.
3.
In the Triggering Attribute section, select the Execute
only if one of the Selected
Attributes has
been changed checkbox.
4.
Move the Empno attribute
to the Selected Attributes list. This will make sure that
the
validation is fired only if the Empno attribute is changed:
Displaying the error message
Following
are the steps to display the error message:
1.
Go to the Failure Handling section and select the Error
option for Validation
Failure Severity.
2.
In the Failure Message section, enter the following text:
Please enter more than 5
Employees.
3.
You can add the
message stored in a resource bundle to Failure
Message by
clicking on
the magnifying glass icon.
What just happened?
We have added a collection validation for our EmpEO.xml object.
Every time a new employee is added to the department, the validation rule fires
as we have selected Empno as our
triggering attribute. The rule is also validated against the condition that we
have provided to check if the department number is 10. If the department number is 10, the count for that
department is calculated. When the user is ready to commit the data to the
database, the rule is validated to check if the count is greater than 5. If the number of
employees added is less than 5, the
error message is displayed to the user.
When we add a collection validator, the EmpEO.xml file gets updated with
appropriate entries. The following entries get added for the aforementioned
validation in the EmpEO.
xml file:
<validation:CollectionValidationBean
Name="EmpEO_Rule_0"
ResId= "com.empdirectory.model.entity.EmpEO_Rule_0"
OnAttribute="Empno"
OperandType="LITERAL"
Inverse="false"
CompareType="GREATERTHAN"
CompareValue="5"
Operation="count">
<validation:OnCondition>
<![CDATA[Deptno = '10']]>
</validation:OnCondition>
</validation:CollectionValidationBean>
<ResourceBundle>
<PropertiesBundle
PropertiesFile=
"com.empdirectory.model.ModelBundle"/>
</ResourceBundle>
The error message that is added in the Failure Handling section
is automatically added to the resource bundle.
|
The
Compare validator
The
Compare validator is used
to compare the current attribute value with other values. The attribute value
can be compared against the literal value, query result, expression, view
object attribute, and so on. The operators supported are equal, not-equal,
less-than, greater-than, less-than or equal to, and greater-than or equal to.
The Key Exists validator
This
validator is used to check if the key value exists for an entity object. The
key value can
be a
primary key, foreign key, or an alternate key. The Key Exists validator
is used to find
the key
from the entity cache, and if the key is not found, the value is determined
from the
database.
Because of this reason, the Key Exists validator is considered to give better
performance.
For example, when an employee is assigned to a department deptNo 50
and you
want to make sure that deptNo 50 already exists in the DEPT table.
The Length validator
This
validator is used to check the string length of an attribute value. The
comparison is
based on
the character or byte length.
The List validator
This
validator is used to create a validation for the attribute in a list. The
operators included
in this
validation are In and NotIn. These two operators help the validation rule check if an
attribute
value is in a list.
The Method validator
Sometimes,
we would like to add our own validation with some extra logic coded in our Java
class file.
For this purpose, ADF provides a declarative validator to map the validation
rule
against a
method in the entity-implementation class. The implementation class is
generated
in the Java
section of the entity object. We need to create and select a method to handle
method
validation. The method is named as validateXXX(), and the returned value will
be of the Boolean type.
The Range validator
This
validator is used to add a rule to validate a range for the attribute value.
The operators
included
are Between and NotBetween. The range will have a minimum and maximum
value that
can be entered for the attribute.
The Regular Expression
validator
For
example, let us consider that we have a validation rule to check if the e-mail
ID provided
by the user
is in the correct format. For the e-mail validation, we have some common rules
such as the
following:
The e-mail ID should start with a string and end with the @ character
The e-mail ID's last character cannot be the dot (.) character
Two @ characters are not allowed within an
e-mail ID
For this
purpose, ADF provides a declarative Regular Expression validator.
We can use the
regex pattern to check the value of the
attribute. The e-mail address and the US phone
number pattern
is provided by default:
Email: [A-Z0-9._%+-]+@[A-Z0-,9.-]+\.[A-Z]{2,4}
Phone Number (US): [0-9]{3}-?[0-9]{3}-?[0-9]{4}
You should
select the required pattern and then click on the Use Pattern button
to use it. Matches and NotMatches are the two
operators that are included
with this
validator.
The Script validator
If we want
to include an expression and validate the business rule, the Script validator
is the best
choice. ADF supports Groovy expressions to provide Script validation
for
an
attribute.
The UniqueKey validator
This
validator is available for use only for entity-level validation. To check for
uniqueness in
the record,
we would be using this validator. If we have a primary key defined for the
entity
object, the
Uniqueness Check Definition section will list the primary keys
defined to check
for
uniqueness
Currently,
the DeptEO.xml file has Deptno as the primary key. We would add business
validation
that states that there should not be a way to create a duplicate of the
department
name that
is already available. The following steps show how to create an alternate key:
1.
Go to the General section of
the DeptEO.xml file and expand the Alternate
Keys
section.
Alternate keys are keys that are not part of the primary key.
2.
Click on the little
+ icon to add a new alternate key.
3.
Move the Dname attribute
from the Available list to the Selected list and click on
the OK button.
What just happened?
We have
created an alternate key against the Dname attribute to prepare for a unique check
validation
for the department name. When the alternate key is added to an entity object,
we will see
the AltKey attribute listed in the Alternate
Key section of the General tab.
In the DeptEO.xml file, you
will find the following code that gets added for the alternate
key
definition:
<Key
Name="AltKey"
AltKey="true">
<DesignTime>
<Attr
Name="_isUnique" Value="true"/>
<Attr
Name="_DBObjectName" Value="HR.DEPT"/>
</DesignTime>
<AttrArray
Name="Attributes">
<Item Value=
"com.empdirectory.model.entity.DeptEO.Dname"/>
</AttrArray>
</Key>
Groovy expression
ADF
Business Components utilize Groovy expressions to support scripting. Groovy is
an open
source, Java-like scripting language that can be stored in an XML definition
file.
For
instance, the attribute name for the employee name Ename can
directly be used in
a Groovy
expression to represent the value of the Ename attribute.
Groovy
follows the same JavaBeans way of accessing the methods of an entity object
that is
defined in
the Java class. Following are some of the ways to call the method of entity
objects
in a Groovy
expression:
Java method
Groovy expression
isEmployee() employee
getEmployee() employee
getEmpNo(int n)
source.emp(5)
checkEmployeeName()
source.checkEmployeeName()
checkEmployeeNo(int n)
source.checkEmployeeNo(5)
Setting a default value
We can set
a default value for an attribute in the entity or view object by using the
Groovy
expression.
The Default Value section for the attribute is provided
with three options—Literal,
Expression, and SQL. For the Literal value, we
can provide a literal value. The Expression option
is used to
provide a value that is evaluated at runtime and to dynamically assign a
default value
to the
attribute.
For
example, consider a case wherein we want to set a default value for the salary
attribute
in
the EmpEO.xml file based on the Deptno attribute.
In this case, we have to provide an
expression
that will be evaluated at runtime to provide the default value. The following
steps
show
us how to do this:
1. Click
on the Sal attribute from the list of attributes displayed in the Attributes
section
of EmpEO.xml.
2. In
the Default Value section, select the Expression option. Now the pencil icon
will
be enabled for the textbox below the Expression option.
3. Click
on the pencil icon to open an Edit Expression Editor window, and add the
following
code in the Expression editor box:
if(Job ==
'MANAGER'){
Sal = 1000;
}
else{
Sal = 2000;
}
www.it-ebooks.info
Validating and Using the Model Data
[ 110 ]
4. Select
the Job attribute as the calculation is dependent on it.
5. Now
click on the OK button to add the expression
for setting a default value for
the
Sal attribute.
We have now learned to set
the default attribute using Groovy expressions. We will perform the following exercises
to get familiar with the language:
1. Set the default value for Job to
CONTRACTOR when the value of Empno is greater than 100 in
EmpEO.
2. The Loc attribute
for the DeptEO object will default to CHICAGO every time.
Validation execution
Validation execution is a section in attribute
validation to set the execution rule. This is similar to the execution rule
that we had set for entity-level validation. The validation for the attribute
is executed only if the condition added to the expression editor is satisfied.
For
example, we can have a compare validation set on the Sal attribute
against 1000, say 9, and set the validation execution condition as Job == 'MANAGER'. This means the compare validation is executed only if
the Job attribute is equal to MANAGER.
Some commonly used expressions
Groovy
expressions are used in ADF Business Components to evaluate and validate
business logic. Groovy expression is preferred declarative expression language for
the entity and view objects.
The
following table gives the expressions and their functionalities:
Expression
Functionality
getAttribute("Sal")
This expression will fetch
the Sal attribute.
(Date)getAttribute("HireDate")
This expression will cast the
HireDate
attribute
value to Date.
new
TimeStamp(System.
currentTimeMillis())
This
expression will create a new Timestamp
object
from the current system time in long.
newValue This expression will get the
new value for the
attribute
in the attribute-level validator.
oldValue This expression will get the
old value for the
attribute
in the attribute-level validator.
source This expression will refer to
the current entity
object.
adf.context This expression will refer to
the ADFContext
object.
adf.object This expression will refer to
the current object
to
which the expression is applied.
adf.error This expression will give the
reference for the
current
error handler object.
adf.error.raise
This expression will raise an
exception.
adf.error.warn
This expression will raise a
warning.
adf.currentDate
This expression will refer to
the current
date with no time.
adf.currentDateTime
This expression will refer to
the current date
and
time.
rowSetAttr.sum(),rowSetAttr.
count(),
rowSetAttr.min(),
rowSetAttr.max(),
rowSetAttr.
avg()
You
can call the aggregate function on the ADF
RowSet object. RowSet is
a collection of rows
returned
through an association accessor.
Most
of the Java methods such as subString(), compareTo(),
and
equals() can also be used in Groovy
expressions along with
some
specific methods from EntityImpl.
Time for action –
adding a script expression
Let
us work on the Script
expression validator
for the Job attribute to understand the full
advantages
of Groovy expressions. Follow these steps:
1. Select
the Job attribute in the EmpEO
entity object from the Attributes list.
2. Click
on the + icon to add a new validator.
3. Select
the Script Expression validator for the Rule Type option. This will open
an
Expression editor section to write the
script.
4. Enter
the following code in this editor section:
String value
= newValue;
String trim =
value.trim();
if(trim.equals('MANAGER')){
adf.error.warn('NO_VACANCY');
return false;
}
return true;
5. You
can click on the Text Syntax button to check if the syntax
is correct.
6. Click
on the OK button to add the script
expression.
What just
happened?
We
have added a script validation for the Job
attribute. The script is
written to do the
following:
1.
Assign the current value to the variable called value.
2.
The trimmed value is saved in a variable called trim.
3.
We are checking if the value of trim is equal to MANAGER.
4.
If the trimmed value is equal to MANAGER, then raise a warning from
the
property
file for the resource bundle that says "No Position available to
add
more Managers".
To
add the warning message, you will have to select the Failure Handling tab and
click
on the magnifying glass icon.
5.
The ADF warning is displayed from the resource bundle, and in this case, there
is
no
need to add a failure-handling message as we are already displaying a warning
to
the user.
6.
The return statement true or false signifies
whether the result for the expression
has
passed or failed.
Have a go hero –
try more features of Groovy expressions
You
should try out more features of Groovy expressions to increase your proficiency
in
writing
efficient scripting code and add declarative validation without having a
separate
class
for the Java API.
You
may try the following exercise:
1.
Try adding an attribute called DeptName to the EmpEO entity
object and provide
the
default value as DepName- along with the Deptno entity
added at the end.
For
example, if an employee belongs to department number 50, the DeptName
attribute
should default to DepName-50.
2.
List down all the common methods between Java and Groovy expressions,
and
note down how these methods differ.
Learning about
APIs
Until
now, we have seen the declarative power of ADF business components. Now we will
see
its programming capabilities and how ADF can leverage complex business
scenarios
using
the Java API.
From
all of the ADF components available, only the entity object, view object, and
application
module will allow the user to generate and extend the Java API. Every
class
created for the business components will extend the parent class, which will
take
care of the logic of an entire complex framework.
Generating an
entity implementation class
Generating
a Java API for a business component is a straightforward task. Most of the
time,
the
user is given an option to generate the Java API while creating the entity
object, view
object,
or an application module. If the user skips this step, we can add the API for
the
business
components from the Java tab.
Java classes in
entity objects
An
entity object will allow you to generate three types of Java classes. Each of
these APIs
is
separated to handle and maintain different sections of the entity object within
the
framework.
The three classes are as follows:
Entity object: This class will have all the methods that represent the
database rows.
The
attributes in this class represent columns in the database table.
Entity collection: This class will be used to cache the queried rows for
the
EntityImpl class.
Entity definition: This class will have the metadata definition of an
entity object class.
Time for action –
generating a Java API for DeptEO
In
our previous exercise, we did not select the options to generate the Java API
in Create
Component
Wizard. The
following steps will show how to generate a Java API for the
EmpEO.xml file:
1. Select
the EmpEO.xml file from the Model project
in the Projects pane.
Validating and Using the Model Data
2. Click
on the Java tab and then click on the
pencil icon. This will open the option
to
select the Java class files:
3. Check the Generate Entity
Object Class EmpEOImpl checkbox. This will create the EmpEOImpl class that will extend the EntityImpl class.
4. Select the Accessors option
to generate the attribute's getter and setter methods; Create Method will generate the create() method; Data Manipulation Methods will create the lock() and doDML() methods and Remove Method will
create the remove() method.
5. Checking the Generate
Entity Collection Class EmpEOCollImpl checkbox will create the EmpEOCollImpl class that will cache the queried entity row. This class
will extend the EntityCache class to store the rows
queried in the cache.
6. Checking the Generate
Entity Definition Class EmpEODefImpl option will create the EmpEODefImpl class where you can store the metadata information for the
entity object class.
7. Click on the OK button
to create the classes. The getDefinitionObject()
method in the EntityImpl class will help in retrieving the definition object for
the entity. The definition object is used to retrieve the definitions of the
entity attributes, display name, UI hints, and so on.
Let
us see some of the useful entity methods that can be overridden from the base
class to perform various operations on entity objects:
Operation
|
Explanation
|
setAttribute(): For example, if the
attribute is Empno, the setter will be setEmpno().
|
This method is used to set the attribute information for an
entity object.
|
getAttribute(): For example, if the
attribute is Empno, the setter will be getEmpno().
|
This method is used to get the attribute value of an entity
object.
|
create()
|
This is used to create a new entity object.
|
initDefaults()
|
The defaulting logic for an entity object can be added to this
method.
|
validateEntity()
|
This method is used to validate an entity.
|
beforeCommit()
|
Logic that has to be applied before committing the record is
added in this method.
|
afterCommit()
|
Logic that has to be applied after committing the record is
added in this method.
|
remove()
|
This method is used to remove an entity object.
|
doDML()
|
This method is used to perform operations based on the DML
operations INSERT, UPDATE, and DELETE.
|
Classes for view objects
A view
object also has three classes that are used to represent the view object and
its
metadata
information. A view object's classes are also generated in the same way as
that of an
entity object. The three classes are as follows:
View object: This
class will represent the view object itself. All operations related
to the view
object can be performed using this class.
View row: This
class will represent and provide access to the row of a view object.
This class
is similar to the entity object class.
View definition: This class will hold references to the metadata information of the
view
object. We can usually access the definition object by using the getDef()
method from
the ViewObjectImpl class.
Most of the
time, we will be working with the view object class to perform tasks
programmatically.
There are some operations that are used quite often in a view
object
implementation class; they are described in the following table:
Operation
Explanation
setWhereClause() This method is used to set the Where clause for
a view
object.
createViewCriteria() This method is used to create view
criteria
programmatically.
setOrderByClause() This method is used to set the Order by clause
for the
current view object.
applyViewCriteria() This method is used to apply an already
created
view
criteria to the view object to add dynamic
query
parameters.
clearCache() This method clears the cached row
information
in the view
object.
Operation
|
Explanation
|
remove()
|
This method is used to remove the current view object.
|
setMaxFetchSize()
|
This method is used to set the maximum fetch size for a view
object programmatically.
|
executeQuery()
|
This method is used to execute the view object's query.
|
No comments:
Post a Comment