About Me

My photo
Ernakulam, Kerala, India
I am Sajadh, author of this blog. I run this with loads of passion.
If you are into java, you may find lot of interesting things around ...
Advance thanks for your queries to sajadhaja90@gmail.com.

Thursday, 8 November 2012

ProgressBar for File Upload using the Dojo

This tutorial demonstrates how to use a DojoSW ProgressBar to display the progress of a file upload, utilizing JavaSW classes that we developed in other tutorials. An example of the Dojo ProgressBar is shown below:
Dojo ProgressBar Example
In another tutorial, we created a TestProgressListener class to allow us to monitor the progress of a file upload to a servletW. We utilized the ApacheSW Commons FileUploadS library to handle the file upload. The TestProgressListener class implements the ProgressListener interface from the FileUpload library. The file gets uploaded to the TestServlet class, which sticks a reference to the TestProgressListener in a session. The ProgressServlet reads the TestProgressListener object from the session and displays the status of the file upload. The upload form to upload files to the TestServlet is located on upload.jsp.
I downloaded the Dojo AjaxW library from http://dojotoolkit.org/. I unpacked the library and placed it in the web directory of my project. In a production system, I would place the library somewhere on a web server rather than actually packaging it into a project, but this is fine for demonstration purposes.
file-upload project I modified the upload.jsp file from the previous tutorial, to include the Dojo ProgressBar. I added a style section for CSSW formatting of the ProgressBar. The Dojo library is referenced via "dojo-release-1.0.2/dojo/dojo.js". The ProgressBar is included via the JavascriptW call to dojo.require("dijit.ProgressBar").

upload.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Upload Page</title>

<style type="text/css">
@import "dojo-release-1.0.2/dijit/themes/tundra/tundra.css";
@import "dojo-release-1.0.2/dojo/resources/dojo.css"
</style>

<script type="text/javascript" src="dojo-release-1.0.2/dojo/dojo.js" djConfig="parseOnLoad: true">
</script>

<script type="text/javascript">
dojo.require("dijit.ProgressBar");

function doProgress() {
 var button = window.document.getElementById("submitButton");
 button.disabled = true;
 var max = 100;
 var prog = 0;
 var counter = 0;
 getProgress();
 doProgressLoop(prog, max, counter);
}

function doProgressLoop(prog, max, counter) { 
    var x = dojo.byId('progress-content').innerHTML;
    var y = parseInt(x);
    if (!isNaN(y)) {
     prog = y;
    }
    jsProgress.update({ maximum: max, progress: prog });
 counter = counter + 1;
 dojo.byId('counter').innerHTML = counter;
    if (prog < 100) {
     setTimeout("getProgress()", 500);
     setTimeout("doProgressLoop(" + prog + "," + max + "," + counter + ")", 1000);
    }
}

function getProgress() {
    dojo.xhrGet({url: 'progress', // http://localhost:8080/file-upload/progress
                 load: function (data) { dojo.byId('progress-content').innerHTML = data; },
                 error: function (data) { dojo.byId('progress-content').innerHTML = "Error retrieving progress"; }
                });
}

</script>
</head>
<body>
<div>
 <form name="form1" id="form1" action="test" method="post" enctype="multipart/form-data">
 <input type="hidden" name="hiddenfield1" value="ok">
 Files to upload:
 <br/>
 <input type="file" size="50" name="file1">
 <br/>
 <input type="file" size="50" name="file2">
 <br/>
 <input type="file" size="50" name="file3">
 <br/>
 <input type="button" value="Upload" id="submitButton" onclick="form1.submit();doProgress();">
 </form>
</div> 
<div class="tundra">Progress: 
 <div dojoType="dijit.ProgressBar" style="width: 300px" jsId="jsProgress" id="downloadProgress">
 </div>
</div>

<br/><br/><br/>
<div style="visibility: visible">
Content from Progress Servlet: <span id="progress-content">---</span><br/>
Counter: <span id="counter">---</span><br/>
</div> 
</body>
</html>
Clicking the Upload button submits the form and calls the doProgress() function which disables the Upload button and initializes the max, prog, and counter variables. The max variable is the maximum progress, which is 100 (100%). The prog variable is the upload progress, which starts at 0 (0%). The counter variable is a simple counter variable. The getProgress() function is called and then the doProgressLoop() function is called.
The getProgress() function contacts the ProgressServlet (via the 'progress' URL) and puts the results in the 'progress-content' span element.
The doProgressLoop() is a recursive function that calls itself until the file upload is complete. It reads the 'progress-content' span element, which gets its innerHTML value from the ProgressServlet via the getProgress() call. If the 'progress-content' value is an integer, the prog (progress) variable is updated with this value. The ProgressBar (jsProgress) is updated with the current progress via the jsProgress.update call. The counter is incremented and its value is placed in the 'counter' span element. If the prog (progress) variable is less than 100, meaning that the file upload hasn't completed yet, then getProgress() is called in 500 milliseconds, and doProgressLoop() is called in 1000 milliseconds (1 second) with the current prog, max, and counter values.
The doProgressLoop() will continue to call itself until the progress is 100%, meaning that the file upload has completed. At this point, the TestServlet will display another page, since the upload will be complete.



The project's web.xmlW file is shown here. We have a TestServlet mapped to '/test' and a ProgressServlet mapped to '/progress'.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="file-upload" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <servlet>
  <servlet-name>TestServlet</servlet-name>
  <servlet-class>test.TestServlet</servlet-class>
 </servlet>
 <servlet>
  <servlet-name>ProgressServlet</servlet-name>
  <servlet-class>test.ProgressServlet</servlet-class>
 </servlet>
 <servlet-mapping>
  <servlet-name>TestServlet</servlet-name>
  <url-pattern>/test</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>ProgressServlet</servlet-name>
  <url-pattern>/progress</url-pattern>
 </servlet-mapping>
</web-app>
The TestServlet class is shown here. This is the class that handles the file upload. It creates a TestProgressListener to monitor the file upload and sticks this in the session.

TestServlet.java

package test;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class TestServlet extends HttpServlet {

 private static final long serialVersionUID = 1L;
// public static final long MAX_UPLOAD_IN_MEGS = 50;

 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
  doPost(request, response);
 }

 public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
  response.setContentType("text/html");
  PrintWriter out = response.getWriter();
  
  out.println("Hello<br/>");

  boolean isMultipartContent = ServletFileUpload.isMultipartContent(request);
  if (!isMultipartContent) {
   out.println("You are not trying to upload<br/>");
   return;
  }
  out.println("You are trying to upload<br/>");

  FileItemFactory factory = new DiskFileItemFactory();
  ServletFileUpload upload = new ServletFileUpload(factory);
//  upload.setSizeMax(MAX_UPLOAD_IN_MEGS * 1024 * 1024);
  
  TestProgressListener testProgressListener = new TestProgressListener();
  upload.setProgressListener(testProgressListener);

  HttpSession session = request.getSession();
  session.setAttribute("testProgressListener", testProgressListener);
  
  try {
   List<FileItem> fields = upload.parseRequest(request);
   out.println("Number of fields: " + fields.size() + "<br/><br/>");
   Iterator<FileItem> it = fields.iterator();
   if (!it.hasNext()) {
    out.println("No fields found");
    return;
   }
   out.println("<table border=\"1\">");
   while (it.hasNext()) {
    out.println("<tr>");
    FileItem fileItem = it.next();
    boolean isFormField = fileItem.isFormField();
    if (isFormField) {
     out.println("<td>regular form field</td><td>FIELD NAME: " + fileItem.getFieldName() + 
       "<br/>STRING: " + fileItem.getString()
       );
     out.println("</td>");
    } else {
     out.println("<td>file form field</td><td>FIELD NAME: " + fileItem.getFieldName() +
//       "<br/>STRING: " + fileItem.getString() +
       "<br/>NAME: " + fileItem.getName() +
       "<br/>CONTENT TYPE: " + fileItem.getContentType() +
       "<br/>SIZE (BYTES): " + fileItem.getSize() +
       "<br/>TO STRING: " + fileItem.toString()
       );
     out.println("</td>");
    }
    out.println("</tr>");
   }
   out.println("</table>");
  } catch (FileUploadException e) {
   out.println("Error: " + e.getMessage());
   e.printStackTrace();
  }
 }
}
The TestProgressListener class allows us to monitor the progress of the file upload.

TestProgressListener.java

package test;

import org.apache.commons.fileupload.ProgressListener;

public class TestProgressListener implements ProgressListener {

 private long num100Ks = 0;

 private long theBytesRead = 0;
 private long theContentLength = -1;
 private int whichItem = 0;
 private int percentDone = 0;
 private boolean contentLengthKnown = false;

 public void update(long bytesRead, long contentLength, int items) {

  if (contentLength > -1) {
   contentLengthKnown = true;
  }
  theBytesRead = bytesRead;
  theContentLength = contentLength;
  whichItem = items;

  long nowNum100Ks = bytesRead / 100000;
  // Only run this code once every 100K
  if (nowNum100Ks > num100Ks) {
   num100Ks = nowNum100Ks;
   if (contentLengthKnown) {
    percentDone = (int) Math.round(100.00 * bytesRead / contentLength);
   }
   System.out.println(getMessage());
  }
 }

 public String getMessage() {
  if (theContentLength == -1) {
   return "" + theBytesRead + " of Unknown-Total bytes have been read.";
  } else {
   return "" + theBytesRead + " of " + theContentLength + " bytes have been read (" + percentDone + "% done).";
  }

 }

 public long getNum100Ks() {
  return num100Ks;
 }

 public void setNum100Ks(long num100Ks) {
  this.num100Ks = num100Ks;
 }

 public long getTheBytesRead() {
  return theBytesRead;
 }

 public void setTheBytesRead(long theBytesRead) {
  this.theBytesRead = theBytesRead;
 }

 public long getTheContentLength() {
  return theContentLength;
 }

 public void setTheContentLength(long theContentLength) {
  this.theContentLength = theContentLength;
 }

 public int getWhichItem() {
  return whichItem;
 }

 public void setWhichItem(int whichItem) {
  this.whichItem = whichItem;
 }

 public int getPercentDone() {
  return percentDone;
 }

 public void setPercentDone(int percentDone) {
  this.percentDone = percentDone;
 }

 public boolean isContentLengthKnown() {
  return contentLengthKnown;
 }

 public void setContentLengthKnown(boolean contentLengthKnown) {
  this.contentLengthKnown = contentLengthKnown;
 }

}
The ProgressServlet class gets the TestProgressListener reference from the session. In our earlier tutorial, we displayed a friendly status message using testProgressListener.getMessage(). Since now we just want to know the percentage done, we instead call testProgressListener.getPercentDone() and output this to the response.

ProgressServlet.java

package test;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class ProgressServlet extends HttpServlet {

 private static final long serialVersionUID = 1L;

 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
  doPost(request, response);
 }

 public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
  response.setContentType("text/html");
  response.setHeader("Cache-Control", "no-cache");
  
  PrintWriter out = response.getWriter();

  HttpSession session = request.getSession(true);
  if (session == null) {
   out.println("Sorry, session is null"); // just to be safe
   return;
  }

  TestProgressListener testProgressListener = (TestProgressListener) session.getAttribute("testProgressListener");
  if (testProgressListener == null) {
   out.println("Progress listener is null");
   return;
  }

//  out.println(testProgressListener.getMessage());
  out.println(testProgressListener.getPercentDone());

 }
}
 
Now, let's see the ProgressBar in action. I started up the project. I browsed to the BigFile.mp3 and set this as the file to upload. I then clicked the Upload button.
File Upload Start As you can see, when the upload starts, the Upload button gets disabled. The progress is displayed on the DojoSW ProgressBar. Here, the upload is 22% complete. We can also see that this screen capture was taken after about 6 seconds.
File Upload Progress When the file upload is done, the TestServlet class displays some information about the upload.
File Upload Finished The Dojo ProgressBar is a very visually appealing way to display the status of a task. In this tutorial, we've seen how we can use it to display the status of a file upload.
 

Wednesday, 10 October 2012

Regular Expressions in Java

Java and Regular Expressions
This article gives an overview of the usage of regular expressions in general and describes the usage of regular expressions with Java. It also provides several Java regular expression examples.

1. Regular Expressions

1.1. Overview

A regular expression defines a search pattern for strings. This pattern may match one or several times or not at all for a given string. The abbreviation for regular expression is regex.
A simple example for a regular expression is a (literal) string. For example the Hello World regex will match the "Hello World" string.
.. (dot) is another example for an regular expression. .. matches any single character; it would match for example "a" or "z" or "1".

1.2. Usage

Regular expressions can be used to search, edit and manipulate text.
Regular expressions are supported by most programming languages, e.g. Java, Perl, Groovy, etc.
Unfortunately each language supports regular expressions slightly different.
If a regular expression is used to analyse or modify a text, this process is called The regular expression is applied to the text.
The pattern defined by the regular expression is applied on the string from left to right. Once a source character has been used in a match, it cannot be reused. For example the regex "aba" will match "ababababa" only two times (aba_aba__).

2. Prerequisites

Some of the following examples use JUnit to validate the result. You should be able to adjust them in case if you do not want to use JUnit.

3. Regular Expressions

The following is an overview of regular expressions. This chapter is supposed to be a references for the different regex elements.

3.1. Common matching symbols



Table 1. 
Regular Expression Description
. Matches any sign
^regex regex must match at the beginning of the line
regex$ Finds regex must match at the end of the line
[abc] Set definition, can match the letter a or b or c
[abc][vz] Set definition, can match a or b or c followed by either v or z
[^abc] When a "^" appears as the first character inside [] when it negates the pattern. This can match any character except a or b or c
[a-d1-7] Ranges, letter between a and d and figures from 1 to 7, will not match d1
X|Z Finds X or Z
XZ Finds X directly followed by Z
$ Checks if a line end follows


3.2. Metacharacters

The following metacharacters have a pre-defined meaning and make certain common pattern easier to use, e.g. \d instead of [0..9].


Table 2. 
Regular Expression Description
\d Any digit, short for [0-9]
\D A non-digit, short for [^0-9]
\s A whitespace character, short for [ \t\n\x0b\r\f]
\S A non-whitespace character, for short for [^\s]
\w A word character, short for [a-zA-Z_0-9]
\W A non-word character [^\w]
\S+ Several non-whitespace characters
\b Matches a word boundary. A word character is [a-zA-Z0-9_] and \b matches its bounderies.


3.3. Quantifier

A quantifier defines how often an element can occur. The symbols ?, *, + and {} define the quantity of the regular expressions


Table 3. 
Regular Expression Description Examples
* Occurs zero or more times, is short for {0,} X* - Finds no or several letter X, .* - any character sequence
+ Occurs one or more times, is short for {1,} X+ - Finds one or several letter X
? Occurs no or one times, ? is short for {0,1} X? -Finds no or exactly one letter X
{X} Occurs X number of times, {} describes the order of the preceding liberal \d{3} - Three digits, .{10} - any character sequence of length 10
{X,Y} Occurs between X and Y times, \d{1,4}- \d must occur at least once and at a maximum of four
*? ? after a qualifier makes it a "reluctant quantifier", it tries to find the smallest match.


3.4. Grouping and Backreference

You can group parts of your regular expression. In your pattern you group elements via round brackets, e.g. "()". This allows you to assign a repetition operator the a complete group.
In addition these groups also create a backreference to the part of the regular expression. This captures the group. A backreference stores the part of the String which matched the group. This allows you to use this part in the replacement.
Via the $ you can refer to a group. $1 is the first group, $2 the second, etc.
Lets for example assume you want to replace all whitespace between a letter followed by a point or a comma. This would involve that the point or the comma is part of the pattern. Still it should be included in the result

// Removes whitespace between a word character and . or ,
String pattern = "(\\w)(\\s+)([\\.,])";
System.out.println(EXAMPLE_TEST.replaceAll(pattern, "</code>$3")); 

This example extracts the text between a title tag.

// Extract the text between the two title elements
pattern = "(?i)(<title.*?>)(.+?)(</title>)";
String updated = EXAMPLE_TEST.replaceAll(pattern, "$2"); 

3.5. Negative Lookahead

Negative Lookahead provide the possibility to exclude a pattern. With this you can say that a string should not be followed by another string.
Negative Lookaheads are defined via (?!pattern). For example the following will match a if a is not followed by b.

a(?!b) 

3.6. Backslashes in Java

The backslash is an escape character in Java Strings. e.g. backslash has a predefined meaning in Java. You have to use "\\" to define a single backslash. If you want to define "\w" then you must be using "\\w" in your regex. If you want to use backslash you as a literal you have to type \\\\ as \ is also a escape character in regular expressions.

4. Using Regular Expressions with String.matches()

4.1. Overview

Strings in Java have build in support for regular expressions. Strings have three build in methods for regular expressions, e.g. matches(), split()), replace(). .
These methods are not optimized for performance. We will later use classes which are optimized for performance.


Table 4. 
Method Description
s.matches("regex") Evaluates if "regex" matches s. Returns only true if the WHOLE string can be matched
s.split("regex") Creates array with substrings of s divided at occurance of "regex". "regex" is not included in the result.
s.replace("regex"), "replacement" Replaces "regex" with "replacement


Create for the following example the Java project de.vogella.regex.test.

package com.sajadhaja.test;

public class RegexTestStrings {
  public static final String EXAMPLE_TEST = "This is my small example "
      + "string which I'm going to " + "use for pattern matching.";

  public static void main(String[] args) {
    System.out.println(EXAMPLE_TEST.matches("\\w.*"));
    String[] splitString = (EXAMPLE_TEST.split("\\s+"));
    System.out.println(splitString.length);// Should be 14
    for (String string : splitString) {
      System.out.println(string);
    }
    // Replace all whitespace with tabs
    System.out.println(EXAMPLE_TEST.replaceAll("\\s+", "\t"));
  }
} 

4.2. Examples

The following class gives several examples for the usage of regular expressions with strings. See the comment for the purpose.
If you want to test these examples, create for the Java project de.vogella.regex.string.

package com.sajadhaja.string;

public class StringMatcher {
  // Returns true if the string matches exactly "true"
  public boolean isTrue(String s){
    return s.matches("true");
  }
  // Returns true if the string matches exactly "true" or "True"
  public boolean isTrueVersion2(String s){
    return s.matches("[tT]rue");
  }
  
  // Returns true if the string matches exactly "true" or "True"
  // or "yes" or "Yes"
  public boolean isTrueOrYes(String s){
    return s.matches("[tT]rue|[yY]es");
  }
  
  // Returns true if the string contains exactly "true"
  public boolean containsTrue(String s){
    return s.matches(".*true.*");
  }
  

  // Returns true if the string contains of three letters
  public boolean isThreeLetters(String s){
    return s.matches("[a-zA-Z]{3}");
    // Simpler from for
//    return s.matches("[a-Z][a-Z][a-Z]");
  }
  


  // Returns true if the string does not have a number at the beginning
  public boolean isNoNumberAtBeginning(String s){
    return s.matches("^[^\\d].*");
  }
  // Returns true if the string contains a arbitrary number of characters except b
  public boolean isIntersection(String s){
    return s.matches("([\\w&&[^b]])*");
  }
  // Returns true if the string contains a number less then 300
  public boolean isLessThenThreeHundret(String s){
    return s.matches("[^0-9]*[12]?[0-9]{1,2}[^0-9]*");
  }
  
} 

And a small JUnit Test to validates the examples.

package com.sajadhaja.string;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class StringMatcherTest {
  private StringMatcher m;

  @Before
  public void setup(){
    m = new StringMatcher();
  }

  @Test
  public void testIsTrue() {
    assertTrue(m.isTrue("true"));
    assertFalse(m.isTrue("true2"));
    assertFalse(m.isTrue("True"));
  }

  @Test
  public void testIsTrueVersion2() {
    assertTrue(m.isTrueVersion2("true"));
    assertFalse(m.isTrueVersion2("true2"));
    assertTrue(m.isTrueVersion2("True"));;
  }

  @Test
  public void testIsTrueOrYes() {
    assertTrue(m.isTrueOrYes("true"));
    assertTrue(m.isTrueOrYes("yes"));
    assertTrue(m.isTrueOrYes("Yes"));
    assertFalse(m.isTrueOrYes("no"));
  }

  @Test
  public void testContainsTrue() {
    assertTrue(m.containsTrue("thetruewithin"));
  }

  @Test
  public void testIsThreeLetters() {
    assertTrue(m.isThreeLetters("abc"));
    assertFalse(m.isThreeLetters("abcd"));
  }
  
  @Test
  public void testisNoNumberAtBeginning() {
    assertTrue(m.isNoNumberAtBeginning("abc"));
    assertFalse(m.isNoNumberAtBeginning("1abcd"));
    assertTrue(m.isNoNumberAtBeginning("a1bcd"));
    assertTrue(m.isNoNumberAtBeginning("asdfdsf"));
  }
  
  @Test
  public void testisIntersection() {
    assertTrue(m.isIntersection("1"));
    assertFalse(m.isIntersection("abcksdfkdskfsdfdsf"));
    assertTrue(m.isIntersection("skdskfjsmcnxmvjwque484242"));
  }
  

  @Test
  public void testLessThenThreeHundret() {
    assertTrue(m.isLessThenThreeHundret("288"));
    assertFalse(m.isLessThenThreeHundret("3288"));
    assertFalse(m.isLessThenThreeHundret("328 8"));
    assertTrue(m.isLessThenThreeHundret("1"));
    assertTrue(m.isLessThenThreeHundret("99"));
    assertFalse(m.isLessThenThreeHundret("300"));
  }

} 

5. Pattern and Matcher

For advanced regular expressions the java.util.regex.Pattern and java.util.regex.Matcher classes are used.
You first create a Pattern object which defines the regular expression. This Pattern object allows you to create a Matcher object for a given string. This Matcher object then allows you to do regex operations on a String.

package com.sajadhaja.test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTestPatternMatcher {
  public static final String EXAMPLE_TEST = "This is my small example string which I'm going to use for pattern matching.";

  public static void main(String[] args) {
    Pattern pattern = Pattern.compile("\\w+");
    // In case you would like to ignore case sensitivity you could use this
    // statement
    // Pattern pattern = Pattern.compile("\\s+", Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(EXAMPLE_TEST);
    // Check all occurance
    while (matcher.find()) {
      System.out.print("Start index: " + matcher.start());
      System.out.print(" End index: " + matcher.end() + " ");
      System.out.println(matcher.group());
    }
    // Now create a new pattern and matcher to replace whitespace with tabs
    Pattern replace = Pattern.compile("\\s+");
    Matcher matcher2 = replace.matcher(EXAMPLE_TEST);
    System.out.println(matcher2.replaceAll("\t"));
  }
} 

6. Java Regex Examples

The following lists typical examples for the usage of regular expressions. I hope you find similarities to your examples.

6.1. Or

Task: Write a regular expression which matches a text line if this text line contains either the word "Joe" or the word "Jim" or both.
Create a project de.vogella.regex.eitheror and the following class.

package com.sajadhaja.eitheror;

import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class EitherOrCheck {
  @Test
  public void testSimpleTrue() {
    String s = "humbapumpa jim";
    assertTrue(s.matches(".*(jim|joe).*"));
    s = "humbapumpa jom";
    assertFalse(s.matches(".*(jim|joe).*"));
    s = "humbaPumpa joe";
    assertTrue(s.matches(".*(jim|joe).*"));
    s = "humbapumpa joe jim";
    assertTrue(s.matches(".*(jim|joe).*"));
  }
} 

6.2. Phone number

Task: Write a regular expression which matches any phone number.
A phone number in this example consists either out of 7 numbers in a row or out of 3 number a (white)space or a dash and then 4 numbers.

package com.sajadhaja.phonenumber;

import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;


public class CheckPhone {
  
  @Test
  public void testSimpleTrue() {
    String pattern = "\\d\\d\\d([,\\s])?\\d\\d\\d\\d";
    String s= "1233323322";
    assertFalse(s.matches(pattern));
    s = "1233323";
    assertTrue(s.matches(pattern));
    s = "123 3323";
    assertTrue(s.matches(pattern));
  }
} 

6.3. Check for a certain number range

The following example will check if a text contains a number with 3 digits.
Create the Java project "de.vogella.regex.numbermatch" and the following class.

package com.sajadhaja.numbermatch;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class CheckNumber {

  
  @Test
  public void testSimpleTrue() {
    String s= "1233";
    assertTrue(test(s));
    s= "0";
    assertFalse(test(s));
    s = "29 Kasdkf 2300 Kdsdf";
    assertTrue(test(s));
    s = "99900234";
    assertTrue(test(s));
  }
  

  
  
  public static boolean test (String s){
    Pattern pattern = Pattern.compile("\\d{3}");
    Matcher matcher = pattern.matcher(s);
    if (matcher.find()){
      return true; 
    } 
    return false; 
  }

} 

6.4. Building a link checker

The following example allows you to extract all valid links from a webpage. It does not consider links with start with "javascript:" or "mailto:".
Create the Java project de.vogella.regex.weblinks and the following class:

package com.sajadhaja.weblinks;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LinkGetter {
  private Pattern htmltag;
  private Pattern link;
  private final String root;

  public LinkGetter(String root) {
    this.root = root;
    htmltag = Pattern.compile("<a\\b[^>]*href=\"[^>]*>(.*?)</a>");
    link = Pattern.compile("href=\"[^>]*\">");
  }

  public List<String> getLinks(String url) {
    List<String> links = new ArrayList<String>();
    try {
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new URL(url).openStream()));
      String s;
      StringBuilder builder = new StringBuilder();
      while ((s = bufferedReader.readLine()) != null) {
        builder.append(s);
      }

      Matcher tagmatch = htmltag.matcher(builder.toString());
      while (tagmatch.find()) {
        Matcher matcher = link.matcher(tagmatch.group());
        matcher.find();
        String link = matcher.group().replaceFirst("href=\"", "")
            .replaceFirst("\">", "");
        if (valid(link)) {
          links.add(makeAbsolute(url, link));
        }
      }
    } catch (MalformedURLException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return links;
  }

  private boolean valid(String s) {
    if (s.matches("javascript:.*|mailto:.*")) {
      return false;
    }
    return true;
  }

  private String makeAbsolute(String url, String link) {
    if (link.matches("http://.*")) {
      return link;
    }
    if (link.matches("/.*") && url.matches(".*$[^/]")) {
      return url + "/" + link;
    }
    if (link.matches("[^/].*") && url.matches(".*[^/]")) {
      return url + "/" + link;
    }
    if (link.matches("/.*") && url.matches(".*[/]")) {
      return url + link;
    }
    if (link.matches("/.*") && url.matches(".*[^/]")) {
      return url + link;
    }
    throw new RuntimeException("Cannot make the link absolute. Url: " + url
        + " Link " + link);
  }
} 

6.5. Finding duplicated words

The regular expression \b(\w+) \1\b matches duplicated words. The (?!-in)\b(\w+) \1\b finds duplicate words if they do not start with "-in".
 

6.6 MySQL Regexps

You have seen MySQL pattern matching with LIKE ...%. MySQL supports another type of pattern matching operation based on regular expressions and the REGEXP operator

ex:-Query to find all the names starting with 'st'

mysql> SELECT name FROM person_tbl WHERE name REGEXP '^st';
 
ex:-Query to find all the names ending with 'ok'
 
mysql> SELECT name FROM person_tbl WHERE name REGEXP 'ok$'; 


Thursday, 6 September 2012

Javascript Best Practices

I found two links that is really useful for javascript developers: http://www.javascripttoolbox.com/bestpractices/ and http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/e6ea1b73adfe8228.
These two links talk about best practices when developing javascript code.

1. Always Use 'var'
Variables in javascript either have global scope or function scope, and using the 'var' keyword is vital to keeping them straight. When declaring a variable for use either as a global variable or as a function-level variable, always prefix the declaration with the 'var' keyword.

2. Avoid 'with'

3. Use onclick In Anchors Instead Of javascript: Pseudo-Protocol

When you want to trigger javascript code from an anchor <A> tag, the onclick handler should be used rather than the javascript: pseudo-protocol. The javascript code that runs within the onclick handler must return true or false (or an expression than evalues to true or false) back to the tag itself - if it returns true, then the HREF of the anchor will be followed like a normal link. If it returns false, then the HREF will be ignored. This is why "return false;" is often included at the end of the code within an onclick handler.

Correct Syntax

<a href="javascript_required.html" onclick="doSomething(); return false;">go</a>

What Not To Do

<a href="javascript:doSomething()">link</a>
<a href="#" onClick="doSomething()">link</a>
<a href="#" onClick="javascript:doSomething();">link&;lt;/a>
<a href="#" onClick="javascript:doSomething(); return false;">link</a>

4. Avoid document.all
Only Use document.all As A Last Resort
There is never a reason to use document.all in javascript except as a fall-back case when other methods are not supported and very early IE support (<5.0) is required.
if (document.getElementById) {
 var obj = document.getElementById("myId");
}
else if (document.all) {
 var obj = document.all("myId");
}

5. Use Correct <script> Tags
The LANGUAGE attribute is deprecated in the <script> tag. The proper way to create a javascript code block is:
<script type="text/javascript">
// code here
</script>

Tricks to use multiple group by within a single query

Here, I have 3 tables: users, photos, and friends. Each user has many photos and friends. I face one problem when I want to join to these two tables to get the total number of photos and friends of a specific user with a single query. Here is my first query I wrote that returns incorrect information:
SELECT
   u.id, COUNT(p.user_id) as total_photo, COUNT(f.user_id) as total_friend
FROM
 friends as f RIGHT JOIN (
 photos as p RIGHT JOIN users as u ON p.user_id = u.id)
 ON f.user_id = u.id
WHERE
  u.id = 1070
GROUP BY
   p.user_id

The reason would cause from GROUP BY. My friend, sophy, advised me to join users with photos first then make it as derived table. Last join it with friends, it works. Here is my query, but it is seems too complicated:
SELECT
     t_photo.*, COUNT(f.user_id) as total_friend
FROM (
     SELECT u.id as user_id, COUNT(p.user_id) as total_photo
     FROM
         users as u LEFT JOIN photos as p ON u.id = p.user_id
     WHERE
  u.id = 1070
     GROUP BY
         p.user_id
) AS t_photo
LEFT JOIN friends as f ON f.user_id = t_photo.user_id
GROUP BY t_photo.user_id

Double Request in RoR

Notice that when you have <img src="" /> in your view, it will double request to the server. Should be careful about this. Don't ever the src attribute of the img tag to blank.

Dynamic Height Code

Here is a css code called clearfix:
.clearfix:after {
 content: ".";
 display: block;
 height: 0px;
 clear: both;
 visibility: hidden;
}
.clearfix {display: inline-block;}

/* Hides from IE-mac \*/
* html .clearfix {height: 1%;}
.clearfix {display: block;}
/* End hide from IE-mac */


Use it when items in a container is longer than the outer container or is unpredictable. This css code will make the outer container have a fixed height. Then you could use Element.getDimensions() to get the computed css height of that container.

Browser Dimensions and Document Scroll Offsets

Determining browser dimensions


IE: document.body.clientWidth & document.body.clientHeight
Firefox: window.innerWidth & window.innerHeight
<script type="text/javascript">

document.write("Your browser\'s dimensions are: ")
if (window.innerWidth) //if browser supports window.innerWidth
document.write(window.innerWidth+" by "+window.innerHeight)
else if (document.all) //else if browser supports document.all (IE 4+)
document.write(document.body.clientWidth+" by "+document.body.clientHeight)

</script>

Determining document scroll offset coordinates


IE: document.body.scrollLeft & document.body.scrollTop
Firefox: window.pageXOffset & window.pageYOffset
There is a pitfall on IE when you uses a doctype at the top of the page. The way to accessing the DSOC properties in IE6 changes, namely, from document.body to document.documentElement.
var iebody=(document.compatMode && document.compatMode != "BackCompat")? document.documentElement : document.body

var dsocleft=document.all? iebody.scrollLeft : pageXOffset
var dsoctop=document.all? iebody.scrollTop : pageYOffset

http://www.javascriptkit.com/javatutors/static2.shtml

Fix PNG image in IE

Here are some links about this issue:
http://www.pcmag.com/article2/0,1759,1645331,00.asp
http://msdn2.microsoft.com/en-us/library/ms532969.aspx

Here is my function that I developed, it works when you use div for png image:
function fixPNG(element, src) {
 $(element).style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='scale')";
}