Friday, July 31, 2009

EJB3.0

A nice place to start a bit about EJB

jboss.org/ejb3/docs
Enjoy learning!!!!
Sumit

Friday, July 10, 2009

writing a comparator

Sort a list based on some sort criteria,
List<_bean_name_for_which_comparator_made> _LIST_OBJECT_WHICH_IS_TO_SORTED = new ArrayList<_bean_name_for_which_comparator_made>();
Collections.sort(_LIST_OBJECT_WHICH_IS_TO_SORTED, new _COMPARATOR_CLASS_NAME());

Create a comparator class. We can make it generic by adding the bean class name for which we want to have the comparator.
Always the comparator is used to compare between same type of object. We cant compare an object of classA with an object of classB.

/**
* This class will do the sorting based on the Contact Format
*
*/
private static class _COMPARATOR_CLASS_NAME implements Comparator<_bean_name_for_which_comparator_made> {
public int compare(_BEAN_NAME_FOR_WHICH_COMPARATOR_MADE bean, _BEAN_NAME_FOR_WHICH_COMPARATOR_MADE beanToCompare) {
return doCompare(, );
}
}

/**
* method to do comparison
* @param toCompare
* @param toCompareWith
* @return int
*/
private static int doCompare(String toCompare, String toCompareWith) {
int i = 0;
if (toCompare == "" && toCompareWith != "") {
i = -1;
} else if (toCompare != "" && toCompareWith == "") {
i = 1;
} else if (toCompare == "" && toCompareWith == "") {
i = 0;
} else {
i = (toCompare).compareToIgnoreCase(toCompareWith);
}
return i;
}

Monday, July 6, 2009

Generation of PDF in internationaLangauge using FOP


Background Of FOP and related terms

What is FOP?
FOP is an acronym for Formatting Object Processor. Its a project developed by Apache.
FOP is a print formatter for XSL formatting objects.
It can be used to render an XML file containing XSL formatting objects into a page layout. The FOP command line application can be directly used to transform XML into PDF, PostScript, PCL and other formats.The library can be used in servlets and other Java applications.

What is XSL?
XSL is a W3C standard concerned with publishing XML documents. It consists of two parts: XSLT and XSL-FO. The acronym expands to eXtensible Stylesheet Language.

What is XSL-FO?
XSLFO (aka XSL-FO) is an XML vocabulary that is used to specify a pagination and other styling for page layout output. The acronym “FO” stands for Formatting Objects. XSLFO can be used in conjunction with XSLT to convert from any XML format into a paginated layout ready for printing or displaying.

XSLFO defines a set of elements in XML that describes the way pages are set up. The contents of the pages are filled from flows. There can be static flows that appear on every page (for headers and footers) and the main flow which fills the body of the page.

Synonyms: XSL FO, XSL (FO), XSL:FO, XSL-FO, Formatting Objects

What is XSLT?
XSLT describes the transformation of arbitrary XML input into other XML (like XSLFO), HTML or plain text. The “T” comes from Transformation. For historical reasons, a transformation is often also called a “style sheet”.
Synonyms: XSL transformation, XSL:T, XSL style sheet.

Problem Description:
In my web application we use FOP to generate a pdf document. This rendering is done from a DOM object and using a XSLT file.
When the application was made originally there were less number of user and no Asian user. But now the Chinese , Japanes and other Asian users got added and they wanted to generate the pdf in there langauge. This was not suppported by our application.. So I was suppose to make the required changes to support the Asian users.

Analysis:
Asian characters are double byte character and hance are not supported properly by the normal fonts like Arial etc. To support these character we need to have unicode fonts. As a part of my search result i got to know that the ArialUni.ttf font is the best supported font for the Asian languages and most of the other international languages.
If the font is not supporting a language then we will see a # in pdf which is the glypgh for unknown character.
Now we should take FOP as black box. We need to provide to the FOP the DOM object , template for pdf(i.e our XSLT file) and the desired font for render. If no font is specified then it maps to "any" which is nothing but the Arial font.
So to narrow down the scenario we need to do a configuration to provide the appropriate font family which will have support for international languages.

Solution:
Step 1: First of all download the FOP source. You can download the binary source also but it may have some problem related to class loading. So better download the latest FOP source. The source is available at http://xmlgraphics.apache.org/fop/0.95/index.html#download
It is is SVF form. I coudnt make out how to download the full project from here. So i made a google search and got a site from where i downlaoded the zip file of FOP .95 source.
So you can follow the same if are not able to download from the link.

Step 2: Extract the zip file in your directory and you have the full FOP project. Since you have downlaoded the Source you need to build the jar file on your own.
For this go to the cmd prompt and go to the fop directory. type ant all and press enter.
Doing this the project will genrate the fop jar and other related jars.
Take this FOP jar from the build folder of FOP project and put it in your application lib folder. I also copied the other jar files which got genrated as part of this command. Still i have to figure out if i can go ahead with out them.

Step 3: The success of step 2 is followed with step 3. Here we will see how to generate a Font -metric file.
As told earlier i will be using ArialUni.ttf font here. Download the font from net. The one i got was some 22mb size. We will have to use a TTFReader.java class of FOP to create a Font metric for the ArialUni font.
In the FOP Folder copy the jars from lib folder and the newly genrated jars from build folder and put them in one folder outside the project.
We will use an ant build script to generate the font metric file from TTFReader.java class



You will have to adjust the path accordingly and on running this command you will get a arialuni.xml which is nothing but our font-metric file.
Always Remeber for each font version you use it is required that you generate a new font metric file.This XML is specific to a particular font.
This close are Step 2. In Step 3 we will configure this metric file with your application.

Step 4: Now integrating the Web application.
Please ensure the following : 1) You have copied the fop.jar and other jars which got generted from FOP project. Also you need to update the jars you got from the FOP>lib folder in your web application. These are required by fop for their fucntioning.
2) Ensure these jars are now availble in the build path of project also.
3) Copy the fop.xconf file from FOP>config folder and the metric file generated. Copy them and keep them in the folder where you have also kept your web.xml file.
Its not a compulsion.
4) Edit the fop.xconf file as shown in the below image


5) Edit your xslt file to include the default font to be used for rendering. This can be easily done by giving the Font-family name in the fo:root tag of xslt file.

6) Ensure that the arialuni.ttf font is installed in your system.(Not sure if this step is really needed. need to identify this.)

7) The below java code will do the rest of the work:

FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent userAgent = fopFactory.newFOUserAgent();
File userConfigXml = new File("D:/HEAD/applications/proj/config/fop.xconf");

fopFactory.setUserConfig(userConfigXml);

TransformerFactory transformerFactory = TransformerFactory.newInstance();
File copyrightFile = new File(fileUpLoadTempDir + copyrightPdfFileName); //this is the output file name
outputStream = new FileOutputStream(copyrightFile);
outputStream = new BufferedOutputStream(outputStream);
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, outputStream);
Transformer transformer = transformerFactory.newTransformer(new StreamSource(xslSource)); //this is the xslt file passes to transformer
Source src = new DOMSource(copyrightDom);
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(src, res);


Step 5 : Build and deploy your application.

Problem faced:

1) From where to get latest FOP: download the source and build the jar file.
2) Class not found: Check if the correct version of supporting jars are used and that the jars are present in the build path.
3) "arialuni,normal,700" not found. Susbtituting with"any, normal,400". This may come coz of many reason. Its a configuration mistake. Check that the triplet name provided is correct. In my case i kept the triplet name same as the Font-family name i.e Arial Unicode MS.


Future:
1) I need to work on the relative paths been used.
2) The Applicaition is running in unix environment so need to make configuration for the unix system. So have to find which font will work in UNIX supporting most international language.
3) clarify few dowubts like installation of font is nessary or not.

Tuesday, June 30, 2009

Generating a listbox containg TimeZone values through properties file

I once had to populate a list box with timeZone from properties file. The requirement was the timezone shud come as its shown in Windows. The concept is easy but when it comes to timezone it becomes a a bit tricky as to how u handle it. REason been u need toshow the list in certain orde. But when u read it from properties file the order is maintained. So the properties file is designed in a specific way,

This is how it went

Step i:
Create a properties file (timeZone.properties)containing the select list item: here the timezone value
Keep this properties file in the applicaiton\config folder

##
## The Format of this file is kept like this as all the content need to be loaded
## But whta is happening is that the order is not getting maintained. So to populate the
## timezone in specific time order we have to add any further timezone in format of
## serial_number=_TimeZoneValue;_TimeZoneDisplayNameInSelectListDropDown
## Also While inserting please check the order is maintained.
## Please be specific about the exact point of insertion for the new timezone
## Do not add blindly any timeZone to the end of the properties files.
##
1=US/Pacific;(GMT-08:00) Pacific Time (US and Canada)
2=US/Mountain;(GMT-07:00) Mountain Time (US and Canada)
3=US/Central;(GMT-06:00) Central Time (US and Canada)
4=US/Eastern;(GMT-05:00) Eastern Time (US and Canada)
5=Europe/Dublin;(GMT) Greenwich Mean Time :Dublin, Edinburgh, Lisbon, London
6=Europe/Amsterdam;(GMT+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm
7=Asia/Shanghai;(GMT+08:00) China, Hong Kong, Malaysia, Singapore, Taiwan
8=Japan;(GMT+09:00) Osaka, Sapporo, Tokyo
9=Australia/Brisbane;(GMT+10:00) Canberra, Melbourne, Sydney, Brisbane
10=Pacific/Auckland;(GMT+12:00) Auckland, Wellington

Step 2:
Now we require a class to load this properties file.

Create a java class name PropertyUtil.java.
This is the utility class for the Property related functionalities. It provides helper methods for loading Properties files.


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Properties;

public class PropertyUtil {

/**
* This method returns the Properties object from the given file name.
*
* @param propertiesFileName File name of the properties file to load
* @return The properties specified in the given file
* @throws IOException If file not found, cant load or read properties file
* @throws IllegalArgumentException if any
*/
public static Properties getProperties(String propertiesFileName) throws IOException {

// if specified properties file name is invalid throw exception
if (propertiesFileName == null || propertiesFileName.trim().length() == 0) {
throw new IllegalArgumentException("Property file name not specified: " + propertiesFileName);
}

//load the properties file from classes folder
File propertiesFile = new File(propertiesFileName);
if (!propertiesFile.exists()) {
ClassLoader tcl = Thread.currentThread().getContextClassLoader();
URL url = tcl.getResource(propertiesFileName);
if (url == null) {
throw new FileNotFoundException(propertiesFileName);
} else {
return getProperties(url.openStream());
}
} else {
return getProperties(propertiesFile);
}
}

/**
* This method returns the Properties object from the given File object.
*
* @param propertyFile the properties file to load
* @return The properties specified in the given file
* @throws IOException If file not found, cant load or read properties file
* @throws IllegalArgumentException if any
*/
public static Properties getProperties(File propertiesFile) throws IOException {

if (propertiesFile == null) {
throw new IllegalArgumentException("Property File cannot be null");
}

propertiesFile = new File(propertiesFile.getCanonicalPath());

if (propertiesFile.isDirectory()) { // if the specified file is folder
throw new IllegalArgumentException("Property file is a directory: " + propertiesFile.getPath());
}
if (!propertiesFile.exists()) { //if the specified file does not exists
throw new FileNotFoundException("Cannot find properties file: " + propertiesFile.getPath());
}
return getProperties(new FileInputStream(propertiesFile));
}

/**
* This method returns the Properties object from the given InputStream object.
*
* @param stream the InputStream object
* @return Properties object
* @throws IOException if any
*/
private static Properties getProperties(InputStream stream) throws IOException {

try {
Properties properties = new Properties();
properties.load(stream);
return properties;
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException ex) {
throw new IOException("IOException thrown while closing the stream: " + ex.getMessage());
}
}
}
}
}



Step 3:
Create a util class where the loading will be done for this proeprties file using the Static method of PropertyUtil.getProperties(String).
In the util class place the below method. let the util class name be MyUtil.java

/**
* This method will populate the TimeZone select list drop down.
*
* @return Map
*/
public static Map readTimeZoneProperty() {
//Linked hashmap is used so that the order in which timezone will be displayed can be maitained
Map timeZoneMap = new LinkedHashMap();
try {
//properties file has entry in the form of
//serial_number=_TimeZoneValue;_TimeZoneDisplayNameInSelectListDropDown
Properties properties = PropertyUtil.getProperties("timeZone.properties");
Set keyset = properties.keySet();//keys are of form: 1,2,3,4,5,6,7,8,9,10
List keyList = new ArrayList();
Iterator iter = keyset.iterator();
while (iter.hasNext()) {
keyList.add(Long.valueOf(String.valueOf(iter.next())));
}
Collections.sort(keyList);//Sort it in order of 1,2,3,4 etc
for (Long key : keyList) {
//value will be of Form: _TimeZoneValue;_TimeZoneDisplayNameInSelectListDropDown
String value = properties.getProperty(String.valueOf(key));
StringTokenizer token = new StringTokenizer(value, ";");
while (token.hasMoreTokens()) {
String timeZoneKey = (token.nextToken().trim());//First token is timeZoneKey
String timeZoneValue = (token.nextToken().trim());//2nd token is timeZoneValue
timeZoneMap.put(timeZoneKey, timeZoneValue);
}
}
} catch (IOException ie) {
log.error("timeZone.properties File does not exist. ");
}
return timeZoneMap;
}

Step 4:

In the Action class directly set a parameter in the request attribute as below

req.setAttribute("timeZoneMap", MyUtil.readTimeZoneProperty());

Step 5:

In the JSP the below code will iterate through the request attribute timeZoneMap to get all the value and populate it in
the list item






Thats it the job is done!!!!!!!

Phone Number validation revisited

The earlier date valdation i did was taking care that atleast a number is enetered.
Now we got a hit back that ()+-23 is also taken as a phonenumber.
So had to write a regex altogether to take care of all possible pattern

So the fucntion below is capable of handling the below format validaiton
Invalid Formats
+()-
(+)-,.
493 -- 3227341
240/752-5009
(+91)(240)(876867) 652-5009
+974-5dadad32d84-5656
++44 07222 555555
0-234.567/8912
0212\345/6789
652-5009.
652-5009-
652-5009,
.652-5009
-652-5009
,652-5009
1-800-ALPHNUM
a-12-3
(658 154 1122
658 154 1122)

Valid Formats
201-654-5932
201 654 5932
(201)-654-5932
201.654.5932
X201.654.5932
+1 201.654.5932
1.123.123.123
020 1234 5678
02-9323-1234
(02) 9323 1234
1-561-555-1212
12345-1234
(913) 451-6461
(+447222)555555
+44 7222 555 555
+91-98-44111112
+91-9844111112
+44(7222)555555
1(240) 652-5009
(0833)1234567-8888
+974-584-5656
+44 07222 555555
1.2123644567
1-(212)-123 4567
1212-364,4321
0-212364345
(658)154-1122
123131312312
875 (489 1568)
(+91)(240) 652-5009


function ValidatePhoneNumber(phoneNumber){
var phoneNo = phoneNumber.value;
//Regular expression used for the Phone validation
var isBracketClose = true;
var firstIndex = phoneNo.indexOf("(");
var lastIndex = phoneNo.lastIndexOf(")");
if((firstIndex == -1 && lastIndex != -1) ||(firstIndex != -1 && lastIndex == -1) ) {
isBracketClose = false;
}
var phonePattern = /^(([^\.\-\,a-wy-z]([\(]?(\+|[x])?\d+[\)]?)?[\s\.\-\,]?([\(]?\d+[\)]?)?[\s\.\-\,]?(\d+[\s\.\-\,]?)+[^\.\-\,a-z])|((\+|[x])?\d+))$/i;
if((trim(phoneNo) == '' || (!phonePattern.test(trim(phoneNo)))) || !isBracketClose ){
alert("Please enter a valid phone number. Phone number must be numeric and can only contain the following characters: '.', '-', '+', ',' . ");
phoneNumber.value = "";
phoneNumber.focus();
return false;
}
return true;
}



uuuufffff one full day went in writng & testing this regex expression. But thank god i finally learned to write a regex on my own...
Even i posted this regex in regexlib.com with my copyright name :)
Atleast now i can contribute something to Java community...

Monday, June 29, 2009

Disabling enter key through javascript

copy paste this code for disabling enter key

function disableEnterKey(e)
{
var key;
var sourceType;
if(window.event){
key = window.event.keyCode; //IE
sourceType=window.event.srcElement.type;
}
else{
key = e.which; //firefox
sourceType=e.target.type;
}
//give style id name here for ur case. like in my case i had image and textarea as name
if(sourceType!="textarea" && sourceType!="image"){
return (key != 13);
}else{
return true;
}
}

generating a pop upd window in the center of a screen

Copy paste this code. it will generate a popup in the centre of the user screen.

function popUp(url,width, height) {
width += 32;
height += 96;
wleft = (screen.width - width) / 2;
wtop = (screen.height - height) / 2;
if (wleft < 0) {
width = screen.width;
wleft = 0;
}
if (wtop < 0) {
height = screen.height;
wtop = 0;
}
var win = window.open(url,
'popup_window_name',
'width=' + width + ', height=' + height + ', ' +
'left=' + wleft + ', top=' + wtop + ', ' +
'location=no, menubar=no, ' +
'status=yes, toolbar=no, scrollbars=yes, resizable=no');
win.resizeTo(width, height);
win.moveTo(wleft, wtop);
win.focus();
}

Date validation in javascript

The method below will valdiate a date.
This will not take care for 29 Feb or 30 Feb or 31 Feb
It is a basic date valdiation

function checkDate(input) {
var validformat = /^(0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])[-](19|20)\d\d+$/;
var returnval = true;
if (!validformat.test(input)) {
alert("The specified delivery date is invalid. Please specify the date in the proper format(MM-DD-YYYY) to continue.");
returnval = false;
}
return returnval;
}

REgex for valdiaitong email address

var validEmailFormat = /^[A-Za-z]([A-Za-z0-9_\.]*)@([A-Za-z0-9_\.]+)([.][A-Za-z0-9]+)$/;

Trim function in Javascript

The method can be used to trim a string for empty spaces

function trim(x) {
x = (x.replace(/^\s*/, "").replace(/\s*$/, ""));
return x;
}

Add/Remove element from List box by Javascript

I have 2 list boxes. name selected List and unselected list.

To move an element from one to another we have a javascript. This will remain a commn function. So if u have a remove button and add button then u jsut have to provide the location namei.e. from which lsit box to which list box.

function optionMove(source, destination) {
var fromSource = document.forms['ur_form_name'].elements[source];
toDestination = document.forms['ur_form_name'].elements[destination];

for (var i = (fromSource.options.length-1); i >= 0 ; i--) {
if(i != 0 ) {
if (fromSource.options[i].selected) { toDestination.appendChild(fromSource.options.item(i));
}
}
}
selectNone(toDestination,fromSource);
setSize(toDestination,fromSource);
}


//here we have fixed the lsit box size. so even if there are no element then also we //have a fixed ssoze for list box
function setSize(list1,list2){
list1.size = 15;
list2.size = 15;
}

function selectNone(list1,list2) {
list1.selectedIndex = -1;
list2.selectedIndex = -1;
addIndex = -1;
selIndex = -1;
}

Generic way to validate Phone number

If we have to do phone valdiation where a phone number can have +, ., - and [0-9] and no specific format is given. Then we can use a approach where we check if the input sptring when replace with all the valdi character contains only numbers then we can conclude a basic check for phone number

for this we can call a js method:

function ValidatePhoneNumber(phoneNumber){
var phoneNo = phoneNumber.value;
//Regular expression used for the Phone validation
var stripped = phoneNo.replace(/[\(\)\.\-\+\ ]/g, '');
var isNumber = /(^\d+$)/ ;
if((trim(stripped) == '' || !(isNumber.test(trim(stripped))))){
alert("Please enter a valid phone number. Phone number must be numeric and can only contain the following characters: '.', '-', '+' . ");
phoneNumber.value = "";
phoneNumber.focus();
return false;
}
return true;
}


Other regex availabe for Phoe number valdaition are

var regPhone = /^(\+\d)*\s*(\(\d{3}\)\s*)*\d{3}(-{0,1}|\s{0,1})\d{2}(-{0,1}|\s{0,1})\d{2}$/;
var regPhone =/^((\+\d{1,3}(-| )?\(?\d\)?(-| )?\d{1,5})|(\(?\d{2,6}\)?))(-| )?(\d{3,4})(-| )?(\d{4})(( x| ext)\d{1,5}){0,1}$/

var regPhone = (/^\d{3}-\d{3}-\d{4}$/) US

var regPhone = /^\(?[2-9]\d{2}[\)\.-]?\s?\d{3}[\s\.-]?\d{4}$/ US
var re = /^\(?[2-9]\d{2}[\)\.-]?\s?\d{3}[\s\.-]?\d{4}$/

var regPhone = /^\({0,1}[0-9]{3}\){0,1}[\-\.]{0,1}[0-9]{3}[\-\.]{0,1}[0-9]{4}$/


The above regex i searched from net.

Monday, November 17, 2008

Welcome!!!

I thought of starting up another blog..This time to document the Work i do and the technical stuff i learn !!!

Will start blogging soon at this site

Best Wishes
Sumit