Validation in JSF

Why is Data Validation required?

Computer application (Web based or otherwise) rely on correct and useful data and therefore data validation is built into systems to ensure that the business logic operates on clean, correct and useful data. Data validation is implemented using functions or routines that check for correctness, meaningfulness, and security of data that are input to the system.

Along with data validation, it is also equally important to look into "Usability" aspect of the validation i.e. how validation errors are handled and displayed back to the user(Usability is a vast topic and we are just talking about the error handling part of it here).

Validation in JSF

JSF lifecycle: 

As you are probably already aware that in JSF world everything is governed by JSF lifecycle, so it's important to understand where and how in the JSF lifecycle validation happens.
 jsf life cycle
<image courtesy www.developersbook.com>

Validation is 3rd phase in life cycle, i.e. after the component object model is built (or restored) and the submitted form fields values are updated in the corresponding components, validation routines (jsf in-built and custom both) are executed. Any validation error at this stage causes the control to jump directly to the "Render Response" phase i.e. processing of "Update Model Values" and "Invoke Application" is skipped.

Lets see how validation is done in JSF.

JSF supports both Declarative and Imperative means of validations

      1.  Declarative

             *  Using JSF standard validators
             *  Using Bean validation -- JSR 303

      2.  Imperative

             *  Validation Method in backing bean
             *  Custom validator by implementing javax.faces.validator.Validator and annotating the class with @FacesValidator

Declarative Validation using JSF tags 

Validator Class Tag Function
BeanValidator validateBean Registers a bean validator for the component.
DoubleRangeValidator validateDoubleRange Checks whether the local value of a component is within a certain range. The value must be floating-point or convertible to floating-point.
LengthValidator validateLength Checks whether the length of a component’s local value is within a certain range. The value must be a java.lang.String.
LongRangeValidator validateLongRange Checks whether the local value of a component is within a certain range. The value must be any numeric type or String that can be converted to a long.
RegexValidator validateRegEx Checks whether the local value of a component is a match against a regular expression from the java.util.regex package.
RequiredValidator validateRequired Ensures that the local value is not empty on an javax.faces.component.EditableValueHolder component.
 
Each of the above validator implementations have a corresponding tag available in JSF base reference implementation. Apart from above tags, the most commonly used form validation "Required" i.e. the form field cannot be empty, user must provide some information, is implemented in JSF as an attribute "Required". This attribute is available in all tags that extend EditableValueHolder namely inputText,teaxtArea, Select, Menu etc.

Lets look at some examples of declarative validation using tags and for that refer to index.xhtml

1)  Required Field


<h:outputLabel for="fName" value="*Enter First Name: " title="First Name"/>
<h:inputText id="fName" value="#{personView.per.fName}" title="First Name" tabindex="1" required="true" 
requiredMessage="first name is required"/>
<h:message id="m1" for="fName" style="color:red"/> <p></p>
Setting attribute required="true" makes field mandatory, i.e. if user submits form without providing first name, a message as defined by attribute requiredMessage="first name is required" is displayed to the user.
Note: The default value of "required"this attribute is "false", so if this attribute is not present then the field in NOT mandatory.

 2) DoubleRangeValidator

This tag is used to validate a floating point range.
<h:outputLabel for="ustaRankingId" value="Enter USTA Ranking: " title="USTA Ranking"/>
<h:inputText id="ustaRankingId" value="#{personView.ustaRanking}" title="USTA Ranking" tabindex="8" 
   size="3" validatorMessage="Registration Open Only for Level 3.0 to 4.5">
  <f:validateDoubleRange minimum="3.0" maximum="4.5" for="ustaRankingId"/>
  <!--f:validateRegex pattern="[3-4]\.?[05]" for="ustaRankingId"/-->
</h:inputText>
<h:message id="m6" for="ustaRankingId" style="color:red"/> <p></p>
Attributes minimum="3.0" maximum="4.5" validate that the value of this form field is between float 3.0 and 4.5. Now this filed is not designated as required="true", so its not mandatory for user to provide value, however, when a value is provided, the doubleRangeValidator ensures that the value is between 3.0 and 4.5, else a message as defined by attribute validatorMessage="Registration is Open....." is displayed to the user.

... other JSF validation tags follow/work on similar pattern and so lets move on to other types of validation supported in JSF.

Declarative Validation using Bean Validation -- JSR 303

JSR 303 is implemented by JSF framework (and other like Spring and Hibernate) and supports validation using annotations in the bean. A good reason to use this feature is that it is "display framework/ technology" agnostic and provides a centralized location for bean constraints and validation as compared to being scattered across front-end and app-tier.
Lets look at some examples of JSR 303 validation and for that refer to index.xhtml and Person.java.

In index.xhtml, there is a field for "Sex" options - Male or Female and we want to make this field required, i.e. user should select one of the two option (when the form is first displayed, neither option is selected); the JSF code is very straight forward, there is NO validation/checks done.
<h:outputLabel for="sexId" value="*Sex:" title="Sex"/>
<h:selectOneRadio id="sexId" value="#{personView.per.sex}" title="Sex" tabindex="5">
  <f:selectItem itemLabel="M" itemValue="M" />
  <f:selectItem itemLabel="F" itemValue="F" />
  <f:validateBean disabled="false"/>
</h:selectOneRadio>
<h:message id="m3" for="sexId" style="color:red"/> <p></p>
The "Required" constraint is added declaratively in Person.java using annotation @NotNull corresponding to property sex, as follows:
  @NotNull(message = "Please select Sex Type, (M) for Male or (F) for Female")
  String sex;
@NotNull makes field mandatory, i.e. if user submits form without selecting radio button corresponding to either of the (M) or (F) option then a message as defined by attribute message="Please select....." is displayed to the user.. 


Imperative Validation

The simple declarative validation discussed so far is a good first step but is rarely sufficient. Most enterprise applications require more complex validation logic that can span multiple properties, multiple entities, security-roles and hence require custom code. Imperative validations is also called as application level validation.
In JSF world application level validation can be done either by
1) Implementing interface javax.faces.validator.Validator and annotating that class with @FacesValidator 
2) Implementing validation in a backing bean method.
    or
3) Using Custom Component

In this article, we will focus on the first two ways of validation.

Custom Validator

A java class as validator needs to 
  1. be annotated with @FacesValidator.The presence of this annotation on a class automatically registers the class with the runtime as a Validator.
  2. implement javax.faces.validator.Validator
for example refer to EmailValidator.java in attached source.

@FacesValidator("emailValidator")
public class EmailValidator implements Validator

The implementation is very straight forward; Validator interface has a method
validate(FacesContext context, UIComponent component, java.lang.Object value)
This method needs to be implemented by the validator class. All the validation logic goes in this method (or say its the entry point).
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    log("Validating submitted email -- " + value.toString());
    matcher = pattern.matcher(value.toString());
    
    if (!matcher.matches()) {
      FacesMessage msg =
              new FacesMessage(" E-mail validation failed.",
              "Please provide E-mail address in this format: abcd@abc.com");
      msg.setSeverity(FacesMessage.SEVERITY_ERROR);
    
      throw new ValidatorException(msg);
    }
  }
JSF framework automatically calls this method at appropriate time in the life-cycle. If the custom validation logic fails, then this method exits by throwing a ValidatorException(msg) where "msg" is an instance of javax.faces.application.FacesMessage, which is queued in the messages list and displayed to the user; else If the logic succeeds then the code exits normally.

Custom validator is integrated/used in the xhtml by using <f:validator> jsf tag.(refer to index.xhtml)
<h:outputLabel for="email" value="*Enter Email: " title="Primary Email"/>
<h:inputText id="email" value="#{personView.per.email}" required="true" requiredMessage="email is required"  
title="Primary Email" tabindex="3"> 
  <f:validator validatorId="emailValidator" />
</h:inputText>
<h:message id="m2a" for="email" style="color:red"/> <p></p>
Note that the value of the attribute validatorId is the bind id of the custom validator class.(refer to EmailValidator.java)
@FacesValidator("emailValidator")

Validation using a Method in Backing Bean

A method in the backing bean can serve as a validation method if it confirms to the following signature:
public void someMethod(FacesContext context, UIComponent component, java.lang.Object value){ .. }
if you notice, the method signature is same as that of "validate" method of custom Validator, except that the method name is NOT confined to "validate", it can be any valid java method name.(refer to PersonView.java)
Note: this example refers to multiple bean properties for validation
/**
 *
 * Validation method 3
 */
public void validatePlayer3(FacesContext context, UIComponent component, Object value) throws ValidatorException {
  String selectedRadio = (String) value;
  String msg = "V3-- Since you indicated that you play Tennis, Please enter Club Name.";
  String clubNameFromComp = (String) clubNameBind.getSubmittedValue();
  log("\n\t ##clubName=" + clubNameFromComp + ",##selectedRadio=" + selectedRadio + "##\n\t");
  if ((clubNameFromComp == null || "".equalsIgnoreCase(clubNameFromComp)) && "Y".equalsIgnoreCase(selectedRadio)) {
    throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg));
  }
}
JSF framework automatically calls this method at appropriate time in the life-cycle. If the custom validation logic fails, then this method exits by throwing a ValidatorException(msg) where "msg" is an instance of javax.faces.application.FacesMessage, which is queued in the messages list and displayed to the user; else If the logic succeeds then the code exits normally.
Custom validator is integrated/used in the xhtml by using validator attribute; the value of this attribute is EL expression corresponding to the backing bean method which implements the validation logic.(refer to index.xhtml)
<h:outputLabel for="sportsPer" value="Do You Play Tennis?" title="Play tennis"/>
  <h:selectOneRadio id="sportsPer" value="#{personView.per.likesTennis}" 
     validator="#{personView.validatePlayer3}" title="Play tennis" tabindex="6">
    <f:selectItem itemLabel="Yes" itemValue="Y" />
    <f:selectItem itemLabel="No" itemValue="N" />
    <!--f:attribute name="clubNameAttr" value="# {clubNameBind.submittedValue}" /-->
  </h:selectOneRadio>
<h:message id="m4" for="sportsPer" style="color:red"/> <p></p>
There are 3 variants of validation methods in PersonView.java, each has a different approach (in conjunction with index.xhtml) for getting data to validate.

This completes our Section on what and how to validate, now moving on to how validation messages are displayed to user.
JSF provides two tags for displaying messages (which are queued  either by jsf validation tags or custom validators)
1.  h:message, contains message specific to a component.It is a good practice to have <h:message> right after the component tag for which the message is queued.
2.  h:messages, messages from all components and all other messages queued in by the system.

see index.xhtml,for how the above tags are used.

Form Validation and Usability

As I mentioned earlier in the blog that along with form validation, it is equally important to display correct message as well. There is also an increased awareness in the technology world about developing application that are accessible to people with visual and other disabilities. One of the major stumbling block in usability is form validation and how to recover from it. User's with disability quite often use some sort of tool like JAWS, to read/interpret a web page. The application we code should take into account how, these tools read/interpret our pages and what best we can do to accommodate ADA needs.Here are some suggestion which I consider are good practices and we developers should at the minimum include in our application:

  1. If form validation fails, tell user that the form validation failed and list all the instructions/errors at the top of form.
  2. Repeat the instructions in front/after the field.
  3. If possible set focus on the "top" error message or on the field corresponding to the first error message.
  4. Use correct font color and size for displaying error.
  5. The error message should tell the user what needs to be done and NOT what is wrong.
  6. Use correct tab index or make sure that form fields are in a logical tab order
  7. When form controls are text input fields use the LABEL element.
  8. Check to make sure the page does not contain a strobe effect
  9. Make sure the page does not contain repeatedly flashing images
JSF and Accessibility support is evolving and some vendors provide some support. Refer to index.xhtml for how message display can be done (although is far from accessibility compliant, its a start)
<ui:param name="errorMessages" value="#{facesContext.getMessageList()}" />
  <h:panelGroup rendered="#{not empty errorMessages}" styleClass="errorMsg">
  <h:outputText value="Form Submission was not successful; Please review and correct listed errors and then resubmit " 
      escape="false"/>
  <br />
  <h:messages style="color: red" globalOnly="false"/>
</h:panelGroup>

you can download the source from here

Hope this blog helped you in gaining understanding of the validation in JSF. If you have any question orsuggestion, please post your comment.

Prasanna Bhale

53 comments:

  1. Thanks you, Prasanna Bhale! The post helped me to understand a little more about JSF Validation. I have one question, if form validation have passed, but occurs business exception on action method of the ManagedBean, which is the practice used?
    Regards

    ReplyDelete
    Replies
    1. Considering that your backing bean is at least ViewScoped, so that submitted form data can be displayed back to user; I would create FacesMessage for the business exception and display it in < h:messages >
      public void formSub() {
      try {
      // ... business logic exception
      } catch(RegistrationFullException ex) {
      FacesMessage msg =
      new FacesMessage("Registration is full for now! Please check back later.");
      msg.setSeverity(FacesMessage.SEVERITY_ERROR);
      FacesContext.getCurrentInstance().addMessage("", msg);
      }
      }

      Delete
  2. It's an awesome explanation. I got a clear cut idea with this stuff. Thank you very much.

    ReplyDelete
  3. The source code is missing the index.xhtml. Can you please include it.

    ReplyDelete
  4. Excellent summary on different validation options within JSF. Thanks a lot for it!

    ReplyDelete
  5. Thanks for this amazing article. Things are very well explained :)

    ReplyDelete
  6. please follow your software :- The Validation Change Management for manufacture somewhere else the website manufacturing sprint is by method of the end of it be supposed to be Validation Software solution big quantity in prevalent way Validation Software the meaning of reformation which will produce put down the blame on new belongings. The Electronic Validation necessities in adding collectively to the possessions will pipe up lends a hand in the most new thing which has occurred.

    ReplyDelete
  7. The article was excellent, JSF, Data validation is implemented using functions or routines that check for correctness, meaningfulness, and security. For more information.
    Check this site tekslate for indepth Jsf-tutorials
    Go here if you’re looking for information on jsf-tutorials

    ReplyDelete
  8. The article was excellent, JSF, Data validation is implemented using functions or routines that check for correctness, meaningfulness, and security. For more information.
    Check this site tekslate for indepth Jsf-tutorials
    Go here if you’re looking for information on jsf-tutorials

    ReplyDelete
  9. Hey man, thx for your post, it helps me a lot.

    ReplyDelete
  10. I'd like too validate (with own validator) some fields that are not required (validation only if it is filled) but my validator is only called when required attribute is true, not else.

    ReplyDelete
  11. Hey thanks for this great article. For preparing JSF interview, here is an article on JSF Interview Questions with Answers

    ReplyDelete
  12. Thank you very much for the nice tutorial :) it tested the source code and worked like a charm. I just have to add the "@Model" annotation to the Person class after I got this error: "Exception while loading the app : CDI deployment failure:WELD-001408: Unsatisfied dependencies for type Person with qualifiers @Default". Thanks again!

    ReplyDelete
  13. Thanks for the very easy to understand tutorial!

    ReplyDelete
  14. Wow.... i'm very grateful to you for this tutorial.

    ReplyDelete
  15. "I like your post it is too good
    for more information visit Intellipaat"

    ReplyDelete
  16. Great site for these post and i am seeing the most of contents have useful for my Carrier.Thanks to such a useful information.Any information are commands like to share him.
    PEGA Training in Chennai

    ReplyDelete
  17. Very elaborated and useful information. JSF, Data validation is implemented using functions or routines that check for correctness, meaningfulness, and security
    Free Live Demos informatica mdm training online
    I have subscribed the RSS of the website
    to get regular updates.
    Thanks for sharing such a useful information.

    ReplyDelete
  18. Thanks for such a great website which is helping people who is new to oracle apps and professional also.Your site is very impressive and you are doing an amazing job.For more info visit our website.
    Oracle Fusion Cloud SCM Course Structure

    ReplyDelete
  19. The good thing I like about this website is Point to point you elaborate each term. Really nice work. Thanks for sharing.

    ReplyDelete
  20. Hiya,

    Thanks for the tip, appreciate it.
    Your article definitely helped
    me to understand the core concepts.
    I’m most excited about the details your article touch based! I assume it doesn’t come out of the box, it sounds like you are saying we’d need to write in the handlers ourselves.
    Is there any other articles you would recommend to understand this better?

    I am running a session to create a .tde file (Tableau data extract) from Informatica Power Center.
    I am able to create the .tde target and mapping as per the document.

    Now, while creating .tde file through the mapping, I am receiving error shown below.

    ERROR : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : GENERIC_WRITER_5 : [ERROR] Error while initializing the writer : [Plugin's .properties file : TableauPlugin not found.]
    2017-05-17 14:27:39 : ERROR : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : JAVA PLUGIN_1762 : [ERROR] com.informatica.powercenter.sdk.SDKException: com.informatica.powercenter.sdk.SDKException: Plugin's .properties file : TableauPlugin not found.


    at com.informatica.cloud.api.adapter.utils.Utils.getPluginInstance(Unknown Source)


    at com.informatica.cloud.api.adapter.writer.runtime.GenericWriterPartitionDriver.initializeWriter(Unknown Source)


    at com.informatica.cloud.api.adapter.writer.runtime.GenericWriterPartitionDriver.init(Unknown Source)
    2017-05-17 14:27:39 : ERROR : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : JAVA PLUGIN_1762 : [ERROR]
    2017-05-17 14:27:39 : ERROR : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : JAVA PLUGIN_1762 : [ERROR] at com.informatica.cloud.api.adapter.writer.runtime.GenericWriterPartitionDriver.init(Unknown Source)
    2017-05-17 14:27:39 : ERROR : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : SDKS_38502 : Plug-in #447100's target [TDE_OMHSAS_DAI_USED: Partition 1] failed in method [init].
    2017-05-17 14:27:39 : ERROR : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : WRT_8068 : Writer initialization failed. Writer terminating.
    2017-05-17 14:27:39 : ERROR : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : JAVA PLUGIN_1762 : [ERROR] java.lang.NullPointerException
    2017-05-17 14:27:39 : ERROR : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : JAVA PLUGIN_1762 : [ERROR] at com.informatica.cloud.api.adapter.writer.runtime.GenericWriterPartitionDriver.deinit(Unknown Source)
    2017-05-17 14:27:39 : ERROR : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : SDKS_38502 : Plug-in #447100's target [TDE_OMHSAS_DAI_USED: Partition 1] failed in method [deinit].
    2017-05-17 14:27:39 : INFO : (13196 | WRITER_1_*_1) : (IS | INTEGRATION_DEV_EDW) : node01 : WRT_8035 : Load complete time: Wed May 17 14:27:39 2017


    By the way do you have any YouTube videos, would love to watch it. I would like to connect you on LinkedIn, great to have experts like you in my connection (In case, if you don’t have any issues).
    Please keep providing such valuable information.
    Regards,
    Krishna

    ReplyDelete
  21. Hi There,

    Hip Hip Hooray! I was always told that slightly slow in the head, a slow learner. Not anymore! It’s like you have my back. I can’t tell you how much I’ve learnt here and how easily! Thank you for blessing me with this effortlessly ingestible digestible content.


    I'm new in Pega Robotics and starting to make a bot. I would like to ask some help. I'm creating a bot wherein in a web page there's a table. The number of rows is not fix and inside the row there's a link. I have an input data item wherein if the value of data item is equal to the text value of link then bot will click the link.

    Anyways great write up, your efforts are much appreciated.

    Gracias
    Irene Hynes

    ReplyDelete
  22. Hi Mate,


    Hip Hip Hooray! I was always told that slightly slow in the head, a slow learner. Not anymore! It’s like you have my back. I can’t tell you how much I’ve learnt here and how easily! Thank you for blessing me with this effortlessly ingestible digestible content.

    I have parent case PC-1 and I created mulitple child cases through page list CC-1 , CC-2. And I applied wait shape at PC-1 giving options - Wait type as "Case Dependecy" , Case Type as "Child Case Type" , To reach status as "Resolved-Completed" , Scope as "Parent" and advance wait option as "Some work basket". And when i resolved my child cases PC-1 is not moving further and appreciate the reason cause and how can we debug the issue.






    It was cool to see your article pop up in my google search for the process yesterday. Great Guide.
    Keep up the good work!


    Kind Regards,
    Anil

    ReplyDelete
  23. Hi There,

    Allow me to show my gratitude bloggers. You guys are like unicorns. Never seen but always spreading magic. Your content is yummy. So satisfied.

    Oracle OpenWorld combines product information and strategy with customer stories to help attendees discover and chart their journey to the cloud Driven by over 180 sessions led by independent user groups and Oracle, the theme will focus on customer choice and how customers can modernize and extend their on premise solutions through Oracle Cloud and community engagement with user groups. Below is a sampling of some of the content themes taking place on Sunday at OpenWorld.

    Follow my new blog if you interested in just tag along me in any social media platforms!


    Thank you,
    Rydan

    ReplyDelete
  24. Hello There,

    You make learning and reading addictive. All eyes fixed on you. Thank you being such a good and trust worthy guide
    I'm newbie in Pega 7.What is A Step? A task? They are rules, classes?
    How can I see their properties ?
    When I double click I can's what they are??Thanks in advance.
    Thanks a lot. This was a perfect step-by-step guide. Don’t think it could have been done better.


    Ciao,
    Franda

    ReplyDelete

  25. Hi, thanks for posting a tips-full article, I had learned more things on this blog, Keep on blogging, thanks .
    JAVA Training in chennai

    ReplyDelete
  26. Hiya,

    Thanks for the post, it’s a great piece of article. Really saved my day.

    Is it advisable to update a field directly into hub tables. For instance if a Name is being converted from UpperCase to TitleCase instead of processing all the updates through hub jobs, can we directly update the stage/ BO tables.
    If so, can you please share the list of tables that need to be updated.

    But nice Article Mate! Great Information! Keep up the good work!

    Obrigado,
    Irene Hynes

    ReplyDelete
  27. Hi There,

    Thanks for the tip, appreciate it. Your article definitely helped me to understand the core concepts.
    I’m most excited about the details your article touch based! Informatica MDM Training USA I assume it doesn’t come out of the box, it sounds like you are saying we’d need to write in the handlers ourselves.
    Is there any other articles you would recommend to understand this better?

    If I use the lookup transformation joining on key columns , Should i check the below one in the expression transformation

    CASE WHEN DEP.HIRED_DST BETWEEN HIST.HIRED_DST AND WHEN HIST.HIRED_EDT THEN 'OVERLAP'
    ELSE 'NEW'
    END FLAG

    Excellent tutorials - very easy to understand with all the details. I hope you will continue to provide more such tutorials.

    Best Regards,
    Irene Hynes

    ReplyDelete
  28. It's A Great Pleasure reading your Article Bala Guntipalli Thanks for posting.

    ReplyDelete
  29. I Just Love to read Your Articles Because they are very easy to understand Bala Guntipalli Thanks for posting.

    ReplyDelete
  30. Great Article its easy to understand Bala Guntipalli Thanks for posting.

    ReplyDelete
  31. Nice article. Really i enjoy to read this article. It will helpful and useful to all. Thanks for posting.
    tibco Training Online

    ReplyDelete
  32. Health Is God aims to deliver the best possible health reviews of the supplement collections and other wellness production that range from skincare to brain, muscle, male enhancement and brain health conditions. You, the user are of utmost importance to us, and we are committed to being the portal that sustains your healthy lifestyle. Visit for more- Health is God

    ReplyDelete
  33. I think this is a real great article post.Really looking forward to read more. Visit at
    Crazy Video Hub

    ReplyDelete
  34. This blog is really awesome Thanks for sharing most valuable information with us.

    Sitecore Online Training

    ReplyDelete
  35. Nutra Trials defines personal characteristics of different health products including skincare, weight loss, muscle and male enhancement. The study presented here is briefly described for reader convenience and to deliver them assurance with health standards. The best possible answers are given here regarding the selection of an ideal supplement or cream or serum that possibly remains to be safe for health and do not cause any side effects.

    ReplyDelete
  36. It is a great job, I like your posts and wish you all the best. and I hope you continue this job well.
    NutraT line

    ReplyDelete
  37. nyc coding and nyc writting it will definealtly help a java developer.
    techenoid providing quality courses through online.visit the site through this link: http://www.techenoid.com

    ReplyDelete
  38. Your blog is very useful for me, Thanks for your sharing.


    RPA Training in Hyderabad

    ReplyDelete
  39. Very useful post and I think it is rather easy to see from the other comments as well that this post is well written and useful. I bookmarked this blog a while ago because of the useful content and I am never being disappointed. Keep up the good work..
    kim kardashian sex tape
    porn sex video hd
    mia khalifa sex video
    sunny leone sexy movie

    ReplyDelete
  40. Your blog is very useful for me, Thanks for your sharing.


    MSBI Training in Hyderabad

    ReplyDelete
  41. Thank you for providing useful information and this is the best article blog for the students.learn Oracle Fusion Financials Online Training.

    Oracle Fusion Financials Online Training

    ReplyDelete
  42. Thank you for sharing such a valuable article with good information containing in this blog.learn Oracle Fusion Technical Online Training.

    Oracle Fusion Technical Online Training

    ReplyDelete
  43. Thanks for sharing valuable information in the article.students can make a good career by learning Oracle Fusion SCM Online Training.

    Oracle Fusion SCM Online Training

    ReplyDelete
  44. Thanks for providing such a great information in the blog and also very helpful to all.learn best Oracle Fusion HCM Online Training.

    Oracle Fusion HCM Online Training

    ReplyDelete