Monday, December 24, 2012

Using Regular Expressions with Javascript

Regular expressions are very powerful when you need to search or replace a certain pattern in a String.
In javascript there are two ways to create a RegExp object.

1. Using RegExp constructor
var pattern = new RegExp(expression);
or
var pattern = new RegExp(expression, modifiers);

Example
var pattern = new RegExp("[a-z]+");//case insensitive search - No modifiers
var pattern = new RegExp("[a-z]+", "i");//case sensitive search - With modifier

2. More simple way
var pattern = /expression/modifiers;

Example
var pattern = /[a-z]+/;//case insensitive search - No modifiers
var pattern = /[a-z]+/i;//case sensitive search - With modifiers

✔  Using RegExp constructor or literal regular expression will give you the same result. But the advantage of using the constructor is you can pass a varible as the argument of the constructor. So you can change the RegExp at runtime.

var exp = "[a-z]+";
var pattern = new RegExp(exp);

✔  When it comes to performance the use of literal regular expression is little bit faster than the
use of RegExp constructor.

Followings are the methods that you can use with RegExp.

1. RegExp.test("text")
The RegExp.test() method searches for a given pattern and returns true if a match found and else false.

Example
var matched = new RegExp("[a-z]+").test("abcDefg"); //true
or
var matched = /[a-z]+/.test("abcDefg"); //true

2. "text".match(pattern)
Without the modifier "g" this method returns the first match.
var result = "abcDefg".match(new RegExp("[a-z]+"));  //abc
or
var result = "abcDefg".match(/[a-z]+/);  //abc

You may have noticed that the above method gives you only one result("abc") although there are
two matches("abc" and "efg").
In order to find all matches you should use the "group" modifier "g".

var result = "abcDefg".match(new RegExp("[a-z]+", "g"));//[abc, efg]
or
var result = "abcDefg".match(/[a-z]+/g);  //[abc, efg]

You can search for groups like this
var arr = "abcDDDefg".match(/[a-z](D+)/); //[cDDD,DDD] 
alert(arr[0]); //whole match - cDDD 
alert(arr[1]); //First group - DDD


3. "text".search(pattern)
This method returns the index of the first letter of the match and -1 if not found.
Example
var result = "123abcDe".search(/abc/); //3


4. "text".replace(pattern, "new text")
Find and replace the occurrences and returns the modified string.
Example
var result = "abcDefg".replace(/[a-z]/, "x"); //xbcDefg
If you want to replace all the matches use modifier "g"
var result = "abcDefg".replace(/[a-z]/g, "x"); //xxxDxxx


5. "text".split(pattern)
Split the given text at the places where the pattern matches and return an array which contains the pieces of the text.
Example
var arr = "regular expressions are smart".split(/\s/);//[regular,expressions,are,smart]


6. RegExp.exec("text")
The exec() method is little bit complicated than the others. That is why I am discussing it here after
the others.
If a match found, this method returns an array which has the matched text as the first item. The other elements of the array contains one item for each capturing group that matched. If no matches found it returns null.
Not only that, the exec() method updates the properties of the regular expression object when it is called.
Yes, I know this is little bit ambiguous. You will understand this properly after looking at following examples.

Example
var pattern = /a(b+)(c)/i;
var text = "aabBBcdeabcde";
var result1 = pattern.exec(text);
var result2 = pattern.exec(text);

alert(result1);//abBBc,bBB,c
alert(result2);//abBBc,bBB,c

Here I have called the exec() method twice on the same RegExp object. Both have given the same result.
Observe the array it has returned.

First element  : This is the first whole match it found.
Second element : This is the first match it found for the group "(b+)"
Third element  : This is the first match it found for the group "(c)"

Obviously there are more matches and they have been ignored.

In order to retrive the ignored matches, I add the modifier "g" to the RegExp.

var pattern = /a(b+)(c)/ig;
var text = "aabBBcdeabcde";
var result1 = pattern.exec(text);
var result2 = pattern.exec(text);

alert(result1);//abBBc,bBB,c
alert(result2);//abc,b,c

See the results. Now result1 and result2 are not the same. result1 has not changed. But result2 has
given a different result.
The elements of the array "result2" can be described as below.

First element  : This is the second whole match found.
Second element : This is the second match found for the group "(b+)"
Third element  : This is the second match found for the group "(c)"

Now you can understand something important about exec() method. When you call the same method twise,
it has given you two different results. When you call it first time it returns the first matches and at
your second call it returns second matches.
Yes, really...!!! The exec() method with the modifier "g" is ideal for iterations.

var pattern = /a(b+)(c)/ig;
var text = "aabBBcdeabcde";
while(result = pattern.exec(text)) {
   alert(result);
}

Those are the methods that you meet when working with regular expressions in javascript.

Another common requirement you meet when working with Strings and Regular expressions is to replace the matched groups with different texts.

For an example lets assume that you have the following text which contains the name and the age of
the student combined.

var text = "Tom15";
Assume you want to display this information like this.
    "The age of Tom is 15."

This is simple with regular expressions.

var text = "Tom15";
var pattern = /([a-z]+)(\d+)/ig;
var sentence = "The age of $1 is $2.";
var result = text.replace(pattern, sentence);
alert(result);//The age of Tom is 15.

Yes, it is such simple.
Note that $1 and $2 represents the group1 and group2 respectively.

Saturday, December 1, 2012

How to use rich:beanValidator together with Hibernate annotations to validate input components

<rich:beanValidator/> component from Richfaces is very useful because it lets us validate input components by using Hibernate annotations. This highly reduces our need of writing validator classes.

This tutorial will show you how to use this component with @NotNull annotation to avoid NULL inputs and to display a custom message.

Create a JSF managed bean or a SEAM component as below.
public class MyBean {
  Integer number;
  
  @NotNull(message = "Please enter a value")
  public Integer getNumber() {
    return number;
  }

  public void setNumber(Integer number) {
    this.number = number;
  }
}

You need to add this import.
import org.hibernate.validator.NotNull;

This is your xhtml page.
<h:form>
  <h:inputText value="#{myBean.number}" id="txtNumber">
    <rich:beanValidator/>
  </h:inputText>
  <rich:message for="txtNumber"/>
  <a4j:commandButton value="Submit"/>
</h:form>

In this page we have a <h:inputText>  component. inside it we have a <rich:beanValidator/> component. What that component does is when the user enters a value and click the button that value is validated according to the hibernate annotations in the bean class. In this example since we have used the @NotNull annotation, the value is checked for null. If the value is null then our message "Please enter a value" is displayed in the <rich:message> component.

Similarly toy can use <rich:beanValidator/> component with other Hibernate validator annotations.

✔  You can find a list of validator annotations here

    If your page contains lot of input components you would have to put <rich:beanValidator/>s inside each of them. But it could be painful. So Richfaces introduces another component for this. It is <rich:graphValidator/> component. Instead of using <rich:beanValidator/>s inside each element, you can get the same result by wrapping all the input elements with only one <rich:graphValidator/> as below.


<h:form>
  
  <rich:graphValidator>
    <h:inputText value="#{myBean.number}" id="num" />
    <rich:message for="num" /><br />

    <rich:calendar value="#{myBean.date}" id="dte" />
    <rich:message for="dte" /><br/>
     </rich:graphValidator>

  <a4j:commandButton value="Save" />
</h:form>

Internationalize your seam application

► What is Internationalization?
  In computing, Internationalization (or i18n) can be described as "making your application to be easily adapted to more than one locale".

How to implement Internationalization in your SEAM project 
   This is not very much difficult. This tutorial will guide you through the steps.

If you open the faces-config.xml file in your WEB-INF folder you will see there are several locales already defined in it as below.
<application>
........
    <locale-config>
      <default-locale>en</default-locale>
      <supported-locale>bg</supported-locale>
      <supported-locale>de</supported-locale>
      <supported-locale>en</supported-locale>
      <supported-locale>fr</supported-locale>
      <supported-locale>tr</supported-locale>
    </locale-config>
</application>

You can add or remove <supported-locale> tags as necessary.

    Now open the resource directory of your web project and you will see the file messages_en.properties. Note the name of the file. Similarly you can create multiple files by naming like messages_<locale>.properties.
These files store texts in various languages, so that when you change the locale, the text is displayed in relevant language.
In this example we are going to show the welcome message in japanese when the user select the Japanese locale.

Let's start...
First add a <supported-locale> tag to the faces-config.xml file which includes japanese locale.
The locale code for Japanese is "ja".  So add
<supported-locale>ja</supported-locale>

Then create the file messages_ja.properties in your resource directory.
Add this line to messages_en.properties file.
welcome_msg=Welcome

Add this line to messages_ja.properties file.
welcome_msg=歓迎


Now what we want is to display the welcome message in English if the locale is en and to display the welcome message in Japanese if the locale is ja.

We are going to use the built-in seam component localeSelector.
Add this code in to your page.
<h:form>
  <h:selectOneMenu value="#{localeSelector.localeString}">
    <f:selectItems value="#{localeSelector.supportedLocales}"/>
    <a4j:support event="onchange" reRender="txtMsg"/>
  </h:selectOneMenu>
  <h:outputText id="txtMsg" value="#{messages.welcome_msg}!"/>
</h:form>

I think it is not necessary to explain what above code does.
Yes, when you select a locale from the combo box it displays the welcome message from the selected language.
Note: You can use #{messages['helloWorld']} instead of #{messages.welcome_msg}. Both give the same result.

See the result...
Save and deploy your application. Open the browser, type the url and go to the page.
Open the combo box and you will see something like this.










Now select the Japanese locale and it should display the message in Japanese language.

Problem....?
Unfortunately you may not get the expected result. You may see something weird like this.




Don't worry. The reason is this.
In .properties  files ISO 8859-1 character encoding is used to encode the input/output stream. Characters which can't be directly represented in this encoding have to be written using Unicode escapes.
So edit your messages_ja.properties file as below.
welcome_msg=\u6B53\u8FCE

Wow... Now you get the desired result.




Note: There are lot of online Unicode escape applications.This is one