Tuesday, April 28, 2009

Java regex tip

While working on a message parser based on java regex i had the need of breaking down messages and being able to ignore certain results from the group because i did not want those values to be considered. Searching on the net did not yield any results hence i went to one of my superiors at work and got to know the answer to this and hence wanted to share it with all of you so that the next time any one does search for a similar problem they might stumble upon this blog ;) ... So the solution is as follows;
 
String simplReg = ([A-B]{4} (?:(0-9){2}));
 
The '?:' operators are used in the second group to specify to java regex that the second group should be ignored from the final result. Thats it guys... Until my next post its adios from my side :D

Friday, April 17, 2009

Parsing with JavaCC

Currently i am working on deciphering a message with a certain format and filling in some DTOs(Data transfer objects) which were then sent to be stored in the database. First i looked at using java regex to do the task but found it was getting way too complicated and the code was not much readable which would result in maintenance problems in the future. After searching around on the net for a few minutes i stumbled upon a library which was originally developed by Sun called JavaCC which is basically a lexical analyser and parser generator. After going through some samples i was able to figure out the expressions used and was able to decipher the message and store releavant data in respective DTO attributes to be sent to the DB.
 
Following i have given a sample code which i used in the early stages to try out a HelloWorld kind of scenario.
 

options{

STATIC=false;

}

PARSER_BEGIN(FLW)

import java.io.*;

public class FLW{

public static void main(String ar[]){

CustomerDTO dtos = getDTO("xxxx 40,dddddddddd eeeeeeeeeer");

System.out.println("First Name: "+dtos.getFName());

System.out.println("Last Name: "+dtos.getLName());

System.out.println("Address : "+dtos.getAddress());

}

static CustomerDTO getDTO(String inString){

Reader reader = new StringReader(inString);

FLW parser = new FLW(reader);

StringBuffer buf = new StringBuffer();

try{

return parser.parse();

}

catch(Exception e){

System.out.println("exception");

e.printStackTrace();

}

return null;

}

}

PARSER_END(FLW)

TOKEN:{<SPACE:" ">}

TOKEN:{<#COMMA:",">}

TOKEN:{<FIRST_NAME:(<LETTER>){4}>}

TOKEN:{<ADDRESS:(<NUMBER>){2}(<COMMA>){1}(<LETTER>){10}>}

TOKEN:{<LAST_NAME:(<LETTER>){11}>}

TOKEN:{<#LETTER:["a"-"z","A"-"Z"]>}

TOKEN:{<#NUMBER:["0"-"9"]>}

CustomerDTO parse():

{

Token fName;

Token lName;

Token address;

CustomerDTO cusDTO = new CustomerDTO();

}

{

(

((fName=<FIRST_NAME>

{cusDTO.setFName(fName.image);}))

<SPACE>

(address=<ADDRESS>)

{cusDTO.setAddress(address.image);}

<SPACE>

(lName=<LAST_NAME>)

{cusDTO.setLName(lName.image);}

)

{return cusDTO;}

}

 

Note that you have to first install JavaCC and also create the CustomerDTO which is in the default class path in the above example and store this in a file named xxx.jj. What the above code does is basically break down the string message passed in the main method and put the relevant data in the relvant attributes of the DTO. Note that JavaCC automatically hanldes EOF(End of file). Hope this helps anyone who is looking at how to use JavaCC for such scenario.


Wednesday, April 8, 2009

JFreeChart For The Web Cont.....

Ok my last post showed you guys as to how to display JFreeCharts in your web application. One issue with that code that i later realized that was it does not support concurrency due to the fact that it creates a temporary file with the same name and if two pepole requests for the same chart at the same time there might be unpredictable outputs and hence i went throught their API again and found a way to resolve this issue. Use the following code if you need to support concurrency when genearating reports and this method anyway is much better performance vice as it does not include any I/O operations which is always an overhead to the application.
 

JFreeChart chart = ChartFactory.createBarChart(chartTitle,

xAxisName, yAxisName, dataSet, PlotOrientation.VERTICAL,

false, true, false);

 

OutputStream outStream = response.getOutputStream();

ByteArrayOutputStream byteArray = new ByteArrayOutputStream();

ChartUtilities.writeChartAsPNG(byteArray, chart, 800, 500);

byte[] byteStream = null;

byteStream = byteArray.toByteArray();

response.setContentType("image/png");

response.setContentLength((int) byteStream.length);

response

.setHeader("Cache-Control",

"no-store, no-cache, must-revalidate, post-check=0, pre-check=0");

response.setHeader("Pragma", "no-cache");

outStream.write(byteStream);

outStream.flush();

outStream.close();


Tuesday, April 7, 2009

JFreeChart For The Web


Ever needed to create a JFreeChart and display it in your web application?Well people i was in need of the same and after searching in vain i finally was able to put together a solution and thought i should share it with you all which will save you a considerable amount of development time.

 

 

1. Create a jsp xxx.jsp and include the following line within the jsp;

 <img src="xxx.jsp" alt="Progress chart" />

 

2. Then you need to write your servlet code. Include the following code snippet in your servlet which will

    create a temp image file in your server and use that to stream it to your response. Note that i have created a

    simple bar chart in the following code snippet,but you can change it with what ever chart that you are

    working with.

 

public static void createBarChart(String chartTitle, String xAxisName,

String yAxisName, DefaultCategoryDataset dataSet,

HttpServletRequest request, HttpServletResponse response) {

try {

// NOTE : I have filled in the Dataset with a DefaultCategoryDataset

// data set

JFreeChart chart = ChartFactory.createBarChart(chartTitle,

xAxisName, yAxisName, dataSet, PlotOrientation.VERTICAL,

false, true, false);

File image = File.createTempFile("image", "tmp");

ChartUtilities.saveChartAsPNG(image, chart, 500, 300);

FileInputStream fileInStream = new FileInputStream(image);

OutputStream outStream = response.getOutputStream();

long fileLength;

byte[] byteStream;

fileLength = image.length();

byteStream = new byte[(int) fileLength];

fileInStream.read(byteStream, 0, (int) fileLength);

response.setContentType("image/png");

response.setContentLength((int) fileLength);

response

.setHeader("Cache-Control",

"no-store, no-cache, must-revalidate, post-check=0, pre-check=0");

response.setHeader("Pragma", "no-cache");

fileInStream.close();

outStream.write(byteStream);

outStream.flush();

outStream.close();

} catch (IOException e) {

}

}

 

 

Thats it guys. Include the following in your servlet code and your good to go with JFreeChartsin you web application. Hope this helps.

 


Friday, April 3, 2009

EJB 3 Slight Perfomance Increasing tips

Most of the people who code EJB 3 which i have seen so far are reluctant to override the defaults provided by the container. Specially when it comes to transactions handling. In EJB 3 a session bean's method's default transaction type is REQUIRED. So we keep this as it is in most cases and sometimes just use REQUIRES_NEW if we want to do a batch process withouth haulting the current transaction.
 
But what most of us forget is that methods such as find(),getReference() and flush() do not need a transaction in order to perform the required function. By keeping the container defaults you are unnecessarily burning the container by starting unwanted Transactions.
 
So next time when you are using these methods make sure to mark the transaction type as NOT_SUPPORTED an opposed to NEVER because NOT_SUPPORTED only blocks the current transaction until the end of the method where as NEVER throws a remote exception.


String builder/buffer performance

If you ever wanted to do string manipultion what you would turn to would be one of the following as opposed to using raw String objects which we know is not good for string manipulation due to the object construction on the heap. But the only issue with String builder/buffer is that even those it has append methods, it does not have a clear method which would clear out the buffer and enable the user to start fresh. There are two ways in which you can achieve this;
 
    StringBuilder str = new StringBuilder();
    str.delete(0,str.length);
 
    or
    str.setLength(0);
 
    From the above two methods it is said that performance vice it is always advisable to use the later method of setting the length to zero which will start appending strings from the zeroth position again rather than deleting the already existing strings within the buffer.


Hibernate load vs get


In my current project where we are using spring-hibernate we faced an issue where at certain times stale objects were being manipulated when tested on concurrent access. When doing throught the specs we were able to nail down the issue which was basically the way the methods load and get works in hibernate. According to the specs, the load method populated that respective entity object with cached results where as get method fetched it from the database.
 
So when ever you want to do a batch operation as i see it, its always better to use load method to achieve better performance where as you should use the get method if you are regularly updating and recovering data from a particular table.
 
If your a EJB 3 EntityManager fan then this same can be achieved through the getReference() method which is the same as the load method in hibernate.


Simple Select SQL Tips

Simple Select SQL Tips;
 
Recently i was trying to optimize my SQL statements to increase the overall performance of the application that im currently working on. I have a friend who is working as a DBA at a reputed company so i decided to get his assitence so that i can reduce some research time.
 
He was talking about alot of ways to increase performance databases but what i didnt know which he told me was about SQL joins. I always prefer writting joins using aliases rather than using the JOIN/OUTER JOIN keywords. But according what he said when you write join statements using aliases, it is in the end converted to JOIN/OUTER JOIN statement type by the database. So for example if you write an alias join statement as;
 
Select * from Customer a, Phone b where a.phone_id = b.id;
 
It is infact converted to the following query by the database;
 
Select * from Customer INNER JOIN Phone ON Customer.phone_id=Phone.id;
 
So you can get better performance by writting your queries in the latter order, yet i still prefer aliases as it is more readable. But then again, the Customer usually doesnt care about code readability but performance. So its a compromise between maintenance vs efficiancy.


Oracle Outer Join Simplified

If your using oracle, you do not need to use the OUTER JOIN keyword when you are joining tables as oracle has its own syntax. You can use the below comman to outer join tables in oracle;
 
select * from passenger a, reservation b where a.res_id(+) = b.id;


Google goes black

In the times of recession it seems that Google has stepped into make a mark by contributing to saving energy by providing users with a black screen Google which is said to lower energy consumption. IMHO it does have some kind of coolness added to it. Maybe black metal rock fans will kinda like googling on this ;) ....

Check it out @ www.blackle.com

Thursday, April 2, 2009

Continuous File Reading In Java

So i recently worked on a project and a requirement came up to be able to read a text file which was been written to at regular intervals to be read continuously. While searching on the web i did not find much help with this regard, hence i started my journey on finding a solution to this on my own and was in the end successful though i might have wasted a wee bit of my development time. But it was overall a really valuable learning experience and i thought of sharing it with you all so that if ever you do get the need for continuous file reading in java, you can find it right here.

private static void continuousFileReader(String fileName) {

String appFileName = fileName+"/fileName.txt";
File file = new File(appFileName);
if(!(file.exists())){
System.out.println("Relevant File Does Not Exist At " +fileName+" Hence Exiting System");
System.exit(1);
}

long lengthBefore = 0;
long length = 0;



while(true){
RandomAccessFile reader = null;
try {
if ((length = file.length()) > lengthBefore) {

try {

reader = new RandomAccessFile(file,"r");
reader.seek(lengthBefore);
lengthBefore = length;
String line = null;
while (!((line = reader.readLine()) == null)) {
// do whatever with contents
}

} catch (FileNotFoundException ex) {
//handle exception
}

catch (IOException ex) {
//handle exception
}

}

Thread.sleep(10000);
} catch (InterruptedException ex) {
try {
if(reader!=null){
reader.close();
}
} catch (IOException ex1) {
//handle exception
}
}
}


}

And one more thing to note is to remember to block the main thread using a while(true) condition because otherwise the continuous file reading will end if the main thread halts ;) .

This is my very first post and my first time blogging so if you guys see any mistakes, constructive criticisms or what ever you might call it please feel free to share your thoughts :D.

Until then, its Adieu from my side.