Thursday, September 13, 2007

Invoke JS functions through J2SE6.0

The The Java SE 6 installation comes with sample applications to demonstrate many of the release's new features. One of these samples, ScriptPad, is a 99 percent JavaScript application that loads and executes other scripts through the Java scripting API. It uses Java to load the Rhino JavaScript engine and execute the five script files that are built into ScriptPad. Included in the sample/scripting/scriptpad folder within your Java SE 6 installation root folder, ScriptPad comes complete with a NetBeans 5.5 project file, which you can use to easily build and execute it.

You can also use the application (through the Java Scripting API) to run other scripts that you've written.For instance, the script shown within the ScriptPad window in Figure 1 accesses Java's static System object, invokes its method (getProperties), uses the resulting Properties object to get the name of the host operating system, and outputs the result in an alert window.

This is a sample code to combine the scripting and Java. It demonstrate how to integration really is.The following Java code loads the Rhino JavaScript engine, loads the script contained within the file browse.js, and executes the function named browse

Code:

import java.util.*;
import java.io.*;
import javax.script.*;

public class Main
{
public Main()
{
try {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine engine = m.getEngineByName("javascript");
if ( engine != null )
{
InputStream is = this.getClass().getResourceAsStream("browse.js");
Reader reader = new InputStreamReader(is);
engine.eval(reader);
Invocable invocableEngine = (Invocable)engine;
invocableEngine.invokeFunction("browse");
}
}
catch ( Exception e ) {
e.printStackTrace();
}
}

public static void main(String[] args)
{
Main m = new Main();
}
}

This browse.js functions uses new Swing Desktop API in JDK 6. To use this with scriptpad, open this in scriptpad and use "Tools->Run Script" menu.

browse.js

function browse() {
var guiPkgs = new JavaImporter(java.awt, java.awt.event,
javax.swing, javax.swing.undo,
javax.swing.event, javax.swing.text);
with (guiPkgs) {
var desktop = null;
// Before more Desktop API is used, first check
// whether the API is supported by this particular
// virtual machine (VM) on this particular host.
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
}
else
{
alert("no desktop support");
return;
}
if (desktop.isSupported(Desktop.Action.BROWSE)) {
desktop.browse(new java.net.URI("www.ericbruno.com"));
}
else
{
alert("no browser support");
}
}
}
if (this.application != undefined) {
// add "Browse" menu item under "Tools" menu
this.application.addTool("Browse", browse);
}

This paradoxical example where Java invokes a script that in turn invokes Java to load an HTML page demonstrates just how dynamic the scripting API can be.

Friday, September 7, 2007

Object Serialization with XMLEncoder

Java API provides XMLEncoder class as an alternative to the ObjectOutputStream and can used to generate a textual representation of a JavaBean in the same way that the ObjectOutputStream can be used to create binary representation of Serializable objects. For example, the following fragment can be used to create a textual representation the supplied JavaBean and all its properties.

XMLEncoder e = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("Test.xml")));
e.writeObject(new JButton("Hello, world"));
e.close();

The XMLEncoder class provides a default denotation for JavaBeans in which they are represented as XML documents complying with version 1.0 of the XML specification and the UTF-8 character encoding of the Unicode/ISO 10646 character set.

The XML syntax uses the following conventions:

  • Each element represents a method call.
  • The "object" tag denotes an expression whose value is to be used as the argument to the enclosing element.
  • The "void" tag denotes a statement which will be executed, but whose result will not be used as an argument to the enclosing method.
  • Elements which contain elements use those elements as arguments, unless they have the tag: "void".
  • The name of the method is denoted by the "method" attribute.
  • XML's standard "id" and "idref" attributes are used to make references to previous expressions - so as to deal with circularities in the object graph.
  • The "class" attribute is used to specify the target of a static method or constructor explicitly; its value being the fully qualified name of the class.
  • Elements with the "void" tag are executed using the outer context as the target if no target is defined by a "class" attribute.
  • Java's String class is treated specially and is written Hello, world where the characters of the string are converted to bytes using the UTF-8 character encoding.


The below code is a sample student bean class to demonstrate the Usage of XMLEncoder and XMLDecoder

Code:

import java.util.Date;

public class Student
{
private String name;
private int age;
private int [] marks_M_P_C;
private String fatherName;
private int rollNumber;
private Date joinDate;

public Date getJoinDate() {
return joinDate;
}
public void setJoinDate(Date joinDate) {
this.joinDate = joinDate;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getFatherName() {
return fatherName;
}
public void setFatherName(String fatherName) {
this.fatherName = fatherName;
}
public int [] getMarks_M_P_C() {
return marks_M_P_C;
}
public void setMarks_M_P_C(int[] marks_M_P_C) {
this.marks_M_P_C = marks_M_P_C;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRollNumber() {
return rollNumber;
}
public void setRollNumber(int rollNumber) {
this.rollNumber = rollNumber;
}

public double getAvg(){
return (double)(this.getTotal()/3.0);
}

public double getTotal(){
return (double)(this.marks_M_P_C[0]+this.marks_M_P_C[1]+this.marks_M_P_C[2]);
}

public String toString() {
return getClass().getName() +
"[Marks=" + asString(marks_M_P_C) +
",avg=" + getAvg() +
",name=" + name +
",fatherName=" + fatherName +
"rollNumber" + rollNumber +
"age" + age + "]";
}

private String asString(int[] array) {
StringBuffer buffer = new StringBuffer("[");
for (int i=0, n=array.length; i < n; i++) {
if (i != 0) {
buffer.append(",");
}
buffer.append(array[i]);
}
buffer.append("]");
return buffer.toString();
}
}

The below code demonstrate the usage of XmlEncoder to store the object as well as XMLDecoder to Retrieve the object
Code:

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Date;

public class XmlObjTest {
public static void main (String args[]) throws Exception {
Student student = new Student();
student.setMarks_M_P_C(new int[] {146, 52, 53});
student.setName("Hari");
student.setJoinDate(new Date());
student.setRollNumber(1219);
student.setFatherName("Rao");
student.setAge(19);
XMLEncoder encoder = new XMLEncoder(new BufferedOutputStream(new FileOutputStream("student.xml")));
encoder.writeObject(student);
encoder.close();

System.out.println(student);

XMLDecoder decoder = new XMLDecoder(new BufferedInputStream(new FileInputStream("student.xml")));
Student studentR = (Student)decoder.readObject();
decoder.close();
System.out.println(studentR);

}
}

The below show how an Object will be stored

Code: (student.xml)

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0_08" class="java.beans.XMLDecoder">
<object class="temp.Student">
<void property="age">
<int>19</int>
</void>
<void property="fatherName">
<string>Rao</string>
</void>
<void property="joinDate">
<object class="java.util.Date">
<long>1189158030890</long>
</object>
</void>
<void property="marks_M_P_C">
<array class="int" length="3">
<void index="0">
<int>146</int>
</void>
<void index="1">
<int>52</int>
</void>
<void index="2">
<int>53</int>
</void>
</array>
</void>
<void
property="name">
<string>Hari</string>
</void>
<void
property="rollNumber">
<int>
1219</int>
</void>
</object>
</java>

Thursday, September 6, 2007

Cookies Handling through Java

What are cookies?
Technically, cookies are arbitrary pieces of data chosen by the Web server and sent to the browser. The browser returns them unchanged to the server, introducing a state (memory of previous events) into otherwise stateless HTTP transactions.

The below code explain how to handle cookies while working with java.net.URL and java.net.URLConnection objects

Code:

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;


public class CookieHandler {

private Map repository;

private static final String SET_COOKIE = "Set-Cookie";
private static final String COOKIE_VALUE_DELIMITER = ";";
private static final String PATH = "path";
private static final String EXPIRES = "expires";
private static final String DATE_FORMAT = "EEE, dd-MMM-yyyy hh:mm:ss z";
private static final String SET_COOKIE_SEPARATOR="; ";
private static final String COOKIE = "Cookie";

private static final char NAME_VALUE_SEPARATOR = '=';
private static final char DOT = '.';

private DateFormat dateFormat;

public CookieHandler() {
repository = new HashMap();
dateFormat = new SimpleDateFormat(DATE_FORMAT);
}

/**
* Retrieves and cookies stored in repository
* @param conn a opend URLConnection
* @throws java.io.IOException Thrown if conn is not open.
*/
public void storeCookies(URLConnection conn) throws IOException {
String domain = getDomainFromHost(conn.getURL().getHost());
Map domainStore;
if (repository.containsKey(domain)) {
domainStore = (Map)repository.get(domain);
} else {
domainStore = new HashMap();
repository.put(domain, domainStore);
}

String headerName=null;
for (int i=1; (headerName = conn.getHeaderFieldKey(i)) != null; i++) {
if (headerName.equalsIgnoreCase(SET_COOKIE)) {
Map cookie = new HashMap();
StringTokenizer st = new StringTokenizer(conn.getHeaderField(i), COOKIE_VALUE_DELIMITER);

if (st.hasMoreTokens()) {
String token = st.nextToken();
String name = token.substring(0, token.indexOf(NAME_VALUE_SEPARATOR));
String value = token.substring(token.indexOf(NAME_VALUE_SEPARATOR) + 1, token.length());
domainStore.put(name, cookie);
cookie.put(name, value);
}

while (st.hasMoreTokens()) {
String token = st.nextToken();
cookie.put(token.substring(0, token.indexOf(NAME_VALUE_SEPARATOR)).toLowerCase(), token.substring(token.indexOf(NAME_VALUE_SEPARATOR) + 1, token.length()));
}
}
}
}
/**
* Prior to opening a URLConnection, calling this method will set all
* unexpired cookies that match the path or subpaths for thi underlying URL
*
* The connection MUST NOT have been opened
* method or an IOException will be thrown.
*
* @param conn a java.net.URLConnection - must NOT be open, or IOException will be thrown
* @throws java.io.IOException Thrown if conn has already been opened.
*/
public void setCookies(URLConnection conn) throws IOException {
URL url = conn.getURL();
String domain = getDomainFromHost(url.getHost());
String path = url.getPath();

Map domainStore = (Map)repository.get(domain);
if (domainStore == null) return;
StringBuffer cookieStringBuffer = new StringBuffer();

Iterator cookieNames = domainStore.keySet().iterator();
while(cookieNames.hasNext()) {
String cookieName = (String)cookieNames.next();
Map cookie = (Map)domainStore.get(cookieName);
if (comparePaths((String)cookie.get(PATH), path) && isNotExpired((String)cookie.get(EXPIRES))) {
cookieStringBuffer.append(cookieName);
cookieStringBuffer.append("=");
cookieStringBuffer.append((String)cookie.get(cookieName));
if (cookieNames.hasNext()) cookieStringBuffer.append(SET_COOKIE_SEPARATOR);
}
}
try {
conn.setRequestProperty(COOKIE, cookieStringBuffer.toString());
} catch (java.lang.IllegalStateException ise) {
IOException ioe = new IOException("Illegal State! Cookies cannot be set on a URLConnection that is already connected. Only call setCookies(java.net.URLConnection) AFTER calling java.net.URLConnection.connect().");
throw ioe;
}
}

private String getDomainFromHost(String host) {
if (host.indexOf(DOT) != host.lastIndexOf(DOT)) {
return host.substring(host.indexOf(DOT) + 1);
} else {
return host;
}
}

private boolean isNotExpired(String cookieExpires) {
if (cookieExpires == null)
return true;
Date now = new Date();
try {
return (now.compareTo(dateFormat.parse(cookieExpires))) <= 0; } catch (java.text.ParseException pe) {
pe.printStackTrace(); return false;
}
}

private boolean comparePaths(String cookiePath, String targetPath) {
if (cookiePath == null) {
return true;
}
else if (cookiePath.equals("/")) {
return true;
}
else if
(targetPath.regionMatches(0, cookiePath, 0, cookiePath.length())) {
return true;
}
else {
return false;
}
}
}

Code: (To test)

public static void main(String[] args) {
CookieHandler cookieHandler = new CookieHandler();
try {
URL url = new URL("http://localhost:8080/test/mycookies.jsp");
URLConnection conn = url.openConnection();
conn.connect();
cookieHandler.storeCookies(conn);
System.out.println(cm);
cookieHandler.setCookies(url.openConnection());
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}

The below Code explains how to set and Retrive the cookies

Code: (mycookies.jsp)

<%@ page import="java.util.*"%>
<%
Cookie myCookie = new Cookie("LoginId", "100");
myCookie.setMaxAge(1234);
response.addCookie(myCookie);
out.println("cookies:<br>");
Cookie[] cookies = request.getCookies();
for (int i = 0; i < style="color: rgb(51, 51, 255);">" " + cookies[i].getValue() + "<br>");
}
out.println("<br/><br/>");
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerNameStr = (String)headerNames.nextElement();
Enumeration headerValues = request.getHeaders(headerNameStr);
while(headerValues.hasMoreElements()) {
out.println(headerNameStr + ": " + headerValues.nextElement() + "<br>");
}
}
%>

Wednesday, September 5, 2007

Launch Web Browser through Java

Some Times Java applications need to present the user with an online resource such as a help tutorial or an interactive web site. web browsers such as Netscape or Internet Explorer have additional advanced capabilities such as supporting HTML scripting languages and various multimedia formats. This tutorial describes how to launch the user's default browser from your Java application.

Code:

import java.lang.reflect.Method;

public class BrowserControl{
/**
* Method to Open the Broser with Given URL
* @param url
*/
public static void openUrl(String url){
String os = System.getProperty("os.name");
Runtime runtime=Runtime.getRuntime();
try{
// Block for Windows Platform
if (os.startsWith("Windows")){
String cmd = "rundll32 url.dll,FileProtocolHandler "+ url;
Process p = runtime.exec(cmd);
}
//Block for Mac OS
else if(os.startsWith("Mac OS")){
Class fileMgr = Class.forName("com.apple.eio.FileManager");
Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] {String.class});
openURL.invoke(null, new Object[] {url});
}
//Block for UNIX Platform
else {
String[] browsers = {"firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };
String browser = null;
for (int count = 0; count < style="color: rgb(153, 0, 0);">length && browser == null; count++)
if (runtime.exec(new String[] {"which", browsers[count]}).waitFor() == 0)
browser = browsers[count];
if (browser == null)
throw new Exception("Could not find web browser");
else
runtime.exec(new String[] {browser, url});
}
}catch(Exception x){
System.err.println("Exception occurd while invoking Browser!");
x.printStackTrace();
}
}
}

Test the Code:

public static void main(String[] args){
openUrl("http://javaxden.blogspot.com");
}

Tuesday, September 4, 2007

Mapping XML- JavaBean

XML makes data portable. The Java platform makes code portable. The Java APIs for XML make it easy to use XML. Put these together, and you have the perfect combination: portability of data, portability of code, and ease of use. In fact, with the Java APIs for XML, you can get the benefits of XML with little or no direct use of XML.The portability and extensibility of both Java and XML make them ideal choices for the flexibility and wide availability requirements of Web applications and services.

The BeanXMLMapping component converts a JavaBean to an XML document and vice versa. By using JavaBean introspection, XML parsers, and DOM APIs, you can develop this component with a bean2Xml() method to represent the received bean as an XML document and a xml2Bean() method to instantiate and populate the proper bean according to the XML document received.

The below code shows a possible implementation for the BeanXMLMapping component. This particular implementation usesthe JOX (Java Objects in XML) library.

Download Dependencies:

jox116.jar
dtdparser121.jar

Code:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import com.wutka.jox.JOXBeanInputStream;
import com.wutka.jox.JOXBeanOutputStream;

public class BeanXMLMapping {

/**
* Method to generate the Bean object for the given xml String
*/
public static Object xml2Bean(String xml, Class className)
{
ByteArrayInputStream xmlData = new ByteArrayInputStream(xml.getBytes());
JOXBeanInputStream joxIn = new JOXBeanInputStream(xmlData);

try{
return (Object) joxIn.readObject(className);
} catch (IOException exc)
{
exc.printStackTrace();
return null;
}
finally{
try{
xmlData.close();
joxIn.close();
} catch (Exception e){
e.printStackTrace();
}
}

}


/**
* Method to generate the XML document String for the received bean
*/
public static String bean2Xml(Object bean)
{
ByteArrayOutputStream xmlData = new ByteArrayOutputStream();
JOXBeanOutputStream joxOut = new JOXBeanOutputStream(xmlData);
try{
joxOut.writeObject(beanName(bean), bean);
return xmlData.toString();
}
catch
(IOException exc){
exc.printStackTrace();
return null;
}
finally{
try{
xmlData.close();
joxOut.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}

/**
* Method to retrieve the Class name for the given bean object
*/
private static String beanName(Object bean){
String fullClassName = bean.getClass().getName();
String classNameTemp = fullClassName.substring(fullClassName.lastIndexOf(".") + 1, fullClassName.length());
return classNameTemp.substring(0, 1)+ classNameTemp.substring(1);
}
}


The BeanXMLMapping class converts a JavaBean to and from an XML document and provides two methods:

bean2Xml(): generates the respective XML document String for the bean instance
xml2Bean(): creates a bean instance for the XML document String


The below Code shows How to use the BeanXMLMapping class to map the bean to xml and vice varsa.

Code:

public class PersonBean {
private String name;
private Integer age;
private Double salary;
private Integer exp;

public PersonBean(){
this.name="test";
this.age=24;
this.salary=5000.0;
this.exp=2;
}

public PersonBean(String name,Integer age,Double salary,Integer exp){
this.name=name;
this.age=age;
this.salary=salary;
this.exp=exp;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getExp() {
return exp;
}
public void setExp(Integer exp) {
this.exp = exp;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public String toXML(){
return BeanXMLMapping.bean2Xml(this);
}
public static Object fromXML(String xml){
return (PersonBean) BeanXMLMapping.xml2Bean(xml,PersonBean.class);
}
}


Test Code:

public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
PersonBean bean=new PersonBean();
String xmlStr=bean.toXML();
System.out.println(xmlStr);
}
}


The Above Test Code Generates the Output As:

<?xml version="1.0" encoding="ISO-8859-1"?>
<PersonBean>
<age>24</age>
<exp>2</exp>
<name>test</name>
<salary>5000.0</salary>
</PersonBean>

Thursday, August 30, 2007

Evaluating XML's XPath Expressions

javax.xml.xpath package provides support for executing XPath expressions against a given XML document. The XPath expressions can be compiled for performance reasons, if it is to be reused.

By the way, the XPath APIs in JAXP are designed to be stateless, which means every time you want to evaluate an XPath expression, you also need to pass in the XML document. Often, many XPath expressions are evaluated against a single XML document. In such a case, it would have been better if the XPath APIs in JAXP were made stateful by passing the XML document once. The underlying implementation would then have had a choice of storing the XML source in an optimized fashion (say, a DTM) for faster evaluation of XPath expressions.


Sample XML to evaluate the XPath expressions :

<?xml version="1.0"?>
<employees>
<employee>
<name>e1</name>
</employee>
<employee>
<name>e2</name>
</employee>
</employees>

Code to evaluate the xml:

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XpathTest
{
public void parseXml()throws Exception{
//parse an XML to get a DOM to query
DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
dbfactory.setNamespaceAware(true);
dbfactory.setXIncludeAware(true);

DocumentBuilder parser = dbfactory.newDocumentBuilder();
Document doc = parser.parse(new File("data.xml"));

//get an XPath processor
XPathFactory xpfactory = XPathFactory.newInstance();
XPath xpathprocessor = xpfactory.newXPath();

//set the namespace context for resolving prefixes of the Qnames
//to NS URI, if the xpath expresion uses Qnames. XPath expression
//would use Qnames if the XML document uses namespaces.
//xpathprocessor.setNamespaceContext(NamespaceContext nsContext);

//create XPath expressions
String xpath1 = "/employees/employee";
XPathExpression employeesXPath = xpathprocessor.compile(xpath1);

String xpath2 = "/employees/employee[1]";
XPathExpression employeeXPath = xpathprocessor.compile(xpath2);

String xpath3 = "/employees/employee[1]/name";
XPathExpression empnameXPath = xpathprocessor.compile(xpath3);

//execute the XPath expressions
System.out.println("XPath1="+xpath1);
NodeList employees = (NodeList)employeesXPath.evaluate(doc, XPathConstants.NODESET);
for (int i=0; i<employees.getLength(); i++) {
System.out.println(employees.item(i).getTextContent());
}

System.out.println("XPath2="+xpath2);
Node employee = (Node)employeeXPath.evaluate(doc, XPathConstants.NODE);
System.out.println(employee.getTextContent());

System..out..println("XPath3="+xpath3);
String empname = empnameXPath.evaluate(doc);
System.out.println(empname);
}
}

Caching static and semi-static data in JSP

A JSP is a combination of different sections. For example, the basic sections that a JSP contains are header, footer, navigation and body sections. These sections are generally independent of each other and most of these sections are either static or semi-static. For example, product categories in navigation bar do not change frequently. When you call a JSP, it process all data (static, semi-static and dynamic content) on every request but what we actually require to process is just the dynamic content.

So how can we avoid unnecessary static or semi-static data processing in JSP on every user request?

The recipe for this problem is to identify and cache static and semi-static sections in JSP. Cache should be refreshed at certain times depending up on data refreshing policy. If the data is fully static, you don't have to refresh it but it is a good practice to refresh after every day or week to make sure that any changes are reflected in JSP. A typical example of fully static data section is footer section in your JSP. If the data is semi-static, you should refresh the cache often depending upon its state change policy. An example for semi-static data sections in JSP is header or navigation sections. And some of the body sections also may be semi-static. You can identify and cache them accordingly to improve performance.

we have used free and well-implemented caching code oscache from opensymphony.com in this sample. You can see information on this at www.opensymphony.com/oscache. The below code shows the usage of caching in JSP subsections using oscache.

Code:

<%@ page import="com.cookbook.servlet.helper.*" %>
<%@ taglib uri="oscache" prefix="cache" %>
<cache:cache time="7200">
<%= getItems() %>
<cache:cache>
<%! public String getItems(){
ItemsHelper helper = new ItemsHelper();
List list = helper.getAllItems();
StringBuffer body = new StringBuffer();
if(list != null && list.size()>0){
ListIterator iter = list.listIterator();
body.append("<TABLE border=\"1\"><TBODY>");
while (iter.hasNext()) {
Item item = (Item) iter.next();
body.append("<TR>");
body.append("<TD>");
body.append(item.getName());
body.append("</TD>");
body.append("<TD>");
body.append(item.getDesc());
body.append("</TD>");
body.append("</TR>");
}
body.append("</TBODY></TABLE>");
}
return body.toString();
}
%>

Discussion:

You can cache any section of your JSP as shown in the above code. You can also give the location of cache store as application or session scope parameter in the oscache tag. The default is application scope. You should be careful when you use session scope in a clustered environment where the session data could be stored as persistent sessions depending upon configuration. There will be overhead involved in persistent sessions if the session data is huge.

In order to utilize oscache, all you need to do is just download the zip file from opensymphony.com/oscache, unzip it and place oscache.jar in /web-inf/lib directory, place oscache.properties and taglib.tld files in web-inf directory and configure web.xml file for this tag library as follows.

<taglib>
<taglib-uri>oscache</taglib-uri>
<taglib-location>/WEB-INF/oscache.tld</taglib-location>
</taglib>

You can also configure other caching properties in oscache such as cache capacity and type of algorithm in oscache.properties file.

Wednesday, August 29, 2007

String replace in a File


This is the code to replace the existing String with the given String in a given file present in the given directory.

Code:

public void replaceStringInFile(File dir, String fileName, String match, String replacingString){
try {
File file = new File(fileName);
if(file.isDirectory()||!file.exists()){
//the fileName specified is not a file hence returning.
return;
}
file = new File(dir, fileName);
RandomAccessFile randomAccessFile =
new RandomAccessFile(file, "rw");
long fpointer = randomAccessFile.getFilePointer();
String lineData = "";
while((lineData =randomAccessFile.readLine()) != null){
fpointer = randomAccessFile.getFilePointer() - lineData.length()-2;
if(lineData.indexOf(match) > 0){
System.out.println("Changing string in file "+file.getName());
randomAccessFile.seek(fpointer);
randomAccessFile.writeBytes(replacingString);
// if the replacingString has less number of characters than the matching string line then enter blank spaces.
if(replacingString.length() < style="color: rgb(153, 0, 0);">int
difference = (lineData.length() - replacingString.length())+1;
for(int i=0; i < style="color: rgb(51, 51, 255);">" ");
}
}
}
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
catch (Exception ex){
ex.printStackTrace();
}
}

Friday, August 24, 2007

Time Scheduling in Java

Some Applications need to execute certain jobs and tasks at an exactly a perticular time or at regular time intervals. Let us see how to schedule the tasks to achieve that functionality, for this purpose java provides a standerd API Timer in java.util package, Now we will see how Java developers can implement such a requirement using the standard Java Timer API.

A Sample Code To use Timer:

import java.util.Timer;
import java.util.TimerTask;

public class Remainder {
Timer timer;

public Remainder ( int seconds ) {
timer = new Timer ( ) ;
timer.schedule ( new TimerTask(){
public void run ( ) {
System.out.println ( "Your scheduled Task Starts...." ) ;
timer.cancel ( ) ; //Terminate the Timer after task completion
}
} , seconds*1000 ) ;
}

public static void main (String args[]){
System.out.println ( "Before schedule task." ) ;
new Remainder ( 5 ) ;
System.out.println ( "Task scheduled." ) ;
}
}

Wednesday, August 22, 2007

Working with Online xml

Some times we required to access the xml files which are present at online or working with another site it is required to access the data through the xml.This artical deals how to work with online xml file.The below sample code parse the xml file throuth the given URL String and returns the DOM Document.Then we can access the xml file using that document.

Code:

import java.io.InputStream;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DOMProvider{
public Document getDocument(String strUrl)throws Exception{
URL url=new URL(strUrl);
InputStream in=url.openStream();
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse(in);
return document;
}
}

After getiing the document from getDocument() if you want to get retrive entire node list that can be done by
NodeList nodeList=document.getElementsByTagName("NameofTheNode");

By these all the node will come in that Node List.If you want to retrive the attributes with in that Node,that can be done by
Node node= nodeList.item(indx);
NamedNodeMap attrs=node.getAttributes();
String value=nnm.getNamedItem("AttributeNamewithinthatNode").getNodeValue();

Sample Work:

http://www.w3schools.com/xml/note.xml is in the form of










to work with the above xml as:


Code:

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Test{
public static void main(String[] args)throws Exception{
DOMProvider test=new DOMProvider();
Document doc=test.getDocument("http://www.w3schools.com/xml/note.xml");
Node node=doc.getDocumentElement();
System.out.println("Root Node: "+node.getNodeName());
NodeList list=node.getChildNodes();
int childsLen=list.getLength();
for(int index=0;index
Node tag=list.item(index);
if(tag.getNodeType()==Node.ELEMENT_NODE){
NodeList val=tag.getChildNodes();
int vallen=val.getLength();
System.out.println("Tag Name: "+tag.getNodeName());
for(int i=0;i
if(val.item(i)!=null)
System.out.println("Tag Value: "+val.item(i).getNodeValue());
}
System.out.println();
}
}
}

}

OutPut:

Root Node: note

Tag Name: to
Tag Value: Tove

Tag Name: from
Tag Value: Jani

Tag Name: heading
Tag Value: Reminder

Tag Name: body
Tag Value: Don't forget me this weekend!

ZIP Files in Java

The ZIP file format has become extremely popular for the distribution and storage of files. ZIP files allow for compression, making transporting a set of files from one location to another faster.Depending on the source file types being compressed, ZIP files can provide significant space savings. ZIP archives can also maintain the directory structure of files that are compressed, making the ZIP format a formidable file transport mechanism.

The java.util.zip package allows for the programmatic reading and writing of the ZIP and GZIP formats.Learning how to use the offerings of the java.util.zip package might best be facilitated via example.

The below example FileZip class has only one method makeZip(), takes two parameters,
String Array- Pass the files paths as strings which you want to Zip.
String - The target zip file name to save as.

Code:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipFiles {
public String makeZip(String[] filesToZip,String zipFileName){
byte[] buffer = new byte[18024];
if(!zipFileName.endsWith(".zip")){
zipFileName+=".zip";
}
try {
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFileName)));
// Set the compression ratio
out.setLevel(Deflater.DEFAULT_COMPRESSION);
// iterate through the array of files, adding each to the zip file
int filesSiz=filesToZip.length;
for (int i = 0; i < style="color: rgb(0, 153, 0);">// Associate a file input stream for the current file
File file2Zip=new File(filesToZip[i].toString());
InputStream in = new BufferedInputStream(new FileInputStream(file2Zip));
// Add ZIP entry to output stream.
String fileExctNm=filesToZip[i].substring(filesToZip[i].lastIndexOf("/")+1);
out.putNextEntry(new ZipEntry(fileExctNm));
// Transfer bytes from the current file to the ZIP file
int len;
while ((len = in.read(buffer)) > 0)
{
out.write(buffer, 0, len);
}
// Close the current entry
out.closeEntry();
// Close the current file input stream
in.close();
}
// Close the ZipOutPutStream
out.close();
}
catch (IllegalArgumentException iae) {
iae.printStackTrace();
}
catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
return new File(zipFileName).toString();
}
}

Tuesday, August 21, 2007

Receive Application Errors via Yahoo Messenger

Logging application events is a central part of many applications. Most of our applications do some sort of logging, using a variety of mechanisms. When things go wrong, the first course of action is usually to get hold of the application log file and go through its contents.

Someone supporting live, deployed applications would probably appreciate the importance of getting notified of application errors as early as possible. It is much better to be proactive dealing with errors, rather than waiting to hear from the customer that something seems to have gone wrong.

How about getting notified immediately, by utilizing an instant messenger client like Yahoo Messenger? (Read More..)


Monday, August 20, 2007

RSS feed of your application logs.

How about getting RSS updates of your application logs?

Heres a sample and simple Log4J RSS appender.
The RSS Appender binary can be download here.

1. to log4j.appender.rss=org.lorecraft.rssappender.RSSAppender
2. log4j.appender.rss.port=1234
3. log4j.appender.rss.maxSize=10
4. log4j.appender.rss.layout=org.apache.log4j.PatternLayout
5. log4j.appender.rss.layout.ConversionPattern=%d {ABSOLUTE} %5p %c {1}: %L - %m%n
6. log4j.rootLogger=info, rss

Screen Capture

The java.awt.Robot class provides several opportunities for fun. One opportunity involves building a screen-capture utility. This Java code uses Robot to capture the contents of the primary screen device.

To capture the screen with the Robot class, Capture must first create a Robot object. ScreenCapture class's printScreen()method attempts to create this object by invoking Robot's public Robot() constructor. If successful, a reference to a Robot configured to the primary screen device's coordinate system returns. If the platform does not support low-level control , a java.awt.AWTException is thrown. A java.lang.SecurityException is thrown if the platform doesn't grant permission to create a Robot. Hopefully, you will not encounter either exception.

Assuming a Robot object is created, createScreenCapture() invokes the Capture class's constructor .Capture obtains the dimensions of the primary screen device by invoking Toolkit.getDefaultToolkit ().getScreenSize ();. Because Robot's public BufferedImage createScreenCapture(Rectangle screenRect) method, which is used to perform a screen capture, requires a java.awt.Rectangle argument, the constructor converts the java.awt.Dimension object to a Rectangle object via rectScreenSize = new Rectangle(dimScreenSize);. The screen capture is done with java.awt.Robot.

Then call createScreenCapture() by passing required parameters through the reference of ScreenCapture Class where your application needs to capture the screen, or from public static void main(String[] a).

Code:
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;

class ScreenCapture {
public void printScreen() throws AWTException, IOException {
// capture the whole screen
BufferedImage screencapture = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()) );
// Save as JPEG
File file = new File("screencapture.jpg");
ImageIO.write(screencapture, "jpg", file);

// Save as PNG
File file = new File("screencapture.png");
ImageIO.write(screencapture, "png", file);
}

//To capture a specific area
public void printScreen(int x, int y, int width, int height) throws AWTException, IOException {
// capture the whole screen
BufferedImage screencapture = new Robot().createScreenCapture( new Rectangle( x, y, width, height));
// Save as JPEG
File file = new File("screencapture.jpg");
ImageIO.write(screencapture, "jpg", file);

// Save as PNG
File file = new File("screencapture.png");
ImageIO.write(screencapture, "png", file);
}

//To capture a specific visual object
public void printScreen(JFrame myframe) throws AWTException, IOException {
// capture the whole screen
BufferedImage screencapture = new Robot().createScreenCapture(new Rectangle( myframe.getX(), myframe.getY(), myframe.getWidth(), myframe.getHeight() ) );
// Save as JPEG
File file = new File("screencapture.jpg");
ImageIO.write(screencapture, "jpg", file);

// Save as PNG
File file = new File("screencapture.png");
ImageIO.write(screencapture, "png", file);
}
}

Sunday, August 19, 2007

Parsing & Binding XML

XML has arrived. Configuration files, application file formats, even database access layers make use of XML-based documents.Here is an accessible introduction to the two most widely used APIs
Application XML:











XML Processing:

Three traditional techniques for processing XML files are:

* Using a programming language and the SAX API.
* Using a programming language and the DOM API.
* Using a transformation engine and a filter









Xerses:

The Xerces Java Parser 1.4.4 supports the XML 1.0 recommendation and contains advanced parser functionality, such as support for the W3C's XML Schema recommendation version 1.0, DOM Level 2 version 1.0, and SAX Version 2, in addition to supporting the industry-standard DOM Level 1 and SAX version 1 APIs and supports Xml-dtd validation. For
more Info http://xerces.apache.org/xerces-j/

DOM Vs SAX Parsing:

Dom create the dom tree by parsing the given xml where as SAX Creates the Event Structure as shown below














DOM Example:

// Create a Xerces DOM Parser
DOMParser parser = new DOMParser();
// Parse the Document and traverse the DOM
parser.parse(xmlFile);
Document document = parser.getDocument();
traverse (document);
// Traverse DOM Tree and print elements names
private void traverse (Node node) {
int type = node.getNodeType();
if (type == Node.ELEMENT_NODE)
System.out.println (node.getNodeName());
NodeList children = node.getChildNodes();
if (children != null) {
for (int i=0; i< color="#005e00">getLength
(); i++)
traverse (children.item(i));
}
}


SAX Example:

public class BasicSAX extends org.xml.sax.helpers.DefaultHandler {
public BasicSAX (String xmlFile) {
//Create a Xerces SAX Parser
SAXParser parser = new SAXParser();
//Set Content Handler
parser.setContentHandler (this);
//Parse the Document
parser.parse(xmlFile)
}

// Start Element Event Handler
public void startElement (String uri, String local, String qName, Attributes atts) {
System.out.println (local);

}

JAXP:

The Java API for XML Processing (JAXP) supports processing of XML documents using DOM, SAX, and XSLT. JAXP enables applications to parse and transform XML documents independent of a particular XML processing implementation.












SAX with JAXP:

import java.xml.parsers.*
import javax.xml.parsers.SAXParserFactory
import org.xml.sax.*
...
SAXParserFactory factory =SAXParserFactory.newInstance();
factory.setValidating(true);
SAXParser parser = factory.newSAXParser();
parser.parse("sample.xml", handler);
// can also parse InputStreams, Files, and
// SAX input sources.

DOM With JAXP:


import
java.xml.parsers.*
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.*
...
DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
factory.setValidating(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("sample.xml");
// can also parse InputStreams, Files, and
// SAX input sources.

XSLT with JAXP


import java.xml.transform.*;
import javax.xml.transform.TransformerFactory;
...
Transformer transformer;
TransformerFactory factory =TransformerFactory.newInstance();
// Create a transformer for a particular stylesheet.transformer = factory.newTransformer(new StreamSource(stylesheet));
// Transform the source xml to System.out.
transformer.transform(new StreamSource(sourceId),new StreamResult(System.out));