Archive for 'Java & JavaEE5'

Java shrinker, optimizer, obfuscator, and preverifier Encrypt jar files

Posted on 28. Feb, 2008 by sabin.

1

http://proguard.sourceforge.net/

Some uses of ProGuard are:

  • Creating more compact code, for smaller code archives, faster transfer across networks, faster loading, and smaller memory footprints.
  • Making programs and libraries harder to reverse-engineer.
  • Listing dead code, so it can be removed from the source code.
  • Retargeting and preverifying existing class files for Java 6, to take full advantage of Java 6′s faster class loading.

ProGuard‘s main advantage compared to other Java obfuscators is probably its compact template-based configuration. A few intuitive command line options or a simple configuration file are usually sufficient. For instance, the following configuration option preserves all applets in a jar:

http://www.yworks.com/

http://www.yworks.com/products/yguard/yguard_ant_howto.html

Continue Reading

session handaling with Servlet

Posted on 25. Feb, 2008 by sabin.

0

Use URL rewrite to save session data

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

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

public class ShoppingCartViewerRewrite extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,
IOException {
res.setContentType(“text/html”);
PrintWriter out = res.getWriter();

out.println(“<HEAD><TITLE>Current Shopping Cart Items</TITLE></HEAD>”);
out.println(“<BODY>”);

// Get the current session ID, or generate one if necessary
String sessionid = req.getPathInfo();
if (sessionid == null) {
sessionid = generateSessionId();
}

// Cart items are associated with the session ID
String[] items = getItemsFromCart(sessionid);

// Print the current cart items.
out.println(“You currently have the following items in your cart:<BR>”);
if (items == null) {
out.println(“<B>None</B>”);
} else {
out.println(“<UL>”);
for (int i = 0; i < items.length; i++) {
out.println(“<LI>” + items[i]);
}
out.println(“</UL>”);
}

// Ask if the user wants to add more items or check out.
// Include the session ID in the action URL.
out.println(“<FORM ACTION=\”/servlet/ShoppingCart/” + sessionid + “\” METHOD=POST>”);
out.println(“Would you like to<BR>”);
out.println(“<INPUT TYPE=SUBMIT VALUE=\” Add More Items \”>”);
out.println(“<INPUT TYPE=SUBMIT VALUE=\” Check Out \”>”);
out.println(“</FORM>”);

// Offer a help page. Include the session ID in the URL.
out.println(“For help, click <A href=\”/servlet/Help/” + sessionid
+ “?topic=ShoppingCartViewerRewrite\”>here</A>”);

out.println(“</BODY></HTML>”);
}

private static String generateSessionId() throws UnsupportedEncodingException {
String uid = new java.rmi.server.UID().toString(); // guaranteed unique
return URLEncoder.encode(uid, “UTF-8″); // encode any special chars
}

private static String[] getItemsFromCart(String sessionid) {
return new String[] { “a”, “b” };
}
}
=============================

Using Sessions in Servlet

import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class UsingSessions extends HttpServlet
{

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType(“text/html”);
PrintWriter out = response.getWriter();

HttpSession session = request.getSession(true);

Integer counter = (Integer) session.getAttribute(“counter”);

if (counter == null) {
counter = new Integer(1);
} else {
counter = new Integer(counter.intValue() + 1);
}

session.setAttribute(“counter”, counter);

out.println(“<HTML>”);
out.println(“<HEAD>”);
out.println(“<TITLE>”);
out.println(“Using Sessions”);
out.println(“</TITLE>”);
out.println(“</HEAD>”);
out.println(“<BODY>”);
out.println(“<H1>Using Sessions</H1>”);

out.println(“Welcome! You have been here ” + counter + ” times.<BR>”);

if(session.isNew()){
out.println(“This is a new session.<BR>”);
} else {
out.println(“This is not a new session.<BR>”);
}

out.println(“The session ID: ” + session.getId() + “<BR>”);
out.println(“Last time accessed: ” + new Date(session.getLastAccessedTime()) + “<BR>”);
out.println(“Creation time: ” + new Date(session.getCreationTime()) + “<BR>”);
out.println(“Timeout length: ” + session.getMaxInactiveInterval() + ” seconds<BR>”);

out.println(“</BODY>”);
out.println(“</HTML>”);
}
}

====================================================================

Session Tracker

import java.io.PrintWriter;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionTracker extends HttpServlet
{
public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException
{
res.setContentType(“text/html”);
PrintWriter out = res.getWriter();

HttpSession session = req.getSession(true);

Integer count = (Integer) session.getAttribute(“count”);

if (count == null) {
count = new Integer(1);
} else {
count = new Integer(count.intValue() + 1);
}

session.setAttribute(“count”, count);
out.println(“<html><head><title>SessionSnoop</title></head>”);
out.println(“<body><h1>Session Details</h1>”);
out.println(“You’ve visited this page ” + count + ((count.intValue()== 1) ? ” time.” : ” times.”) + “<br/>”);
out.println(“<h3>Details of this session:</h3>”);
out.println(“Session id: ” + session.getId() + “<br/>”);
out.println(“New session: ” + session.isNew() + “<br/>”);
out.println(“Timeout: ” + session.getMaxInactiveInterval() + “<br/>”);
out.println(“Creation time: ” + new Date(session.getCreationTime()) + “<br/>”);
out.println(“Last access time: ” + new Date(session.getLastAccessedTime()) + “<br/>”);
out.println(“</body></html>”);
}
}
===========================

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

public class SimpleSession extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {

response.setContentType(“text/html”);
java.io.PrintWriter out = response.getWriter();
HttpSession session = request.getSession();

out.println(“<html>”);
out.println(“<head>”);
out.println(“<title>Simple Session Tracker</title>”);
out.println(“</head>”);
out.println(“<body>”);

out.println(“<h2>Session Info</h2>”);
out.println(“session Id: ” + session.getId() + “<br><br>”);
out.println(“The SESSION TIMEOUT period is ”
+ session.getMaxInactiveInterval() + ” seconds.<br><br>”);
out.println(“Now changing it to 20 minutes.<br><br>”);
session.setMaxInactiveInterval(20 * 60);
out.println(“The SESSION TIMEOUT period is now ”
+ session.getMaxInactiveInterval() + ” seconds.”);

out.println(“</body>”);
out.println(“</html>”);

}

/**
* Handles the HTTP <code>POST</code> method.
*
* @param request
*            servlet request
* @param response
*            servlet response
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
java.io.IOException {

doGet(request, response);
}

}
==============================================

session listener

import java.util.Date;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class SessionListen implements HttpSessionListener {

private int sessionCount;

public SessionListen() {
this.sessionCount = 0;
}

public void sessionCreated(HttpSessionEvent se) {
HttpSession session = se.getSession();
session.setMaxInactiveInterval(60);
synchronized (this) {
sessionCount++;
}
String id = session.getId();
Date now = new Date();
String message = new StringBuffer(“New Session created on “).append(
now.toString()).append(“\nID: “).append(id).append(“\n”)
.append(“There are now “).append(“” + sessionCount).append(
” live sessions in the application.”).toString();

System.out.println(message);
}

public void sessionDestroyed(HttpSessionEvent se) {

HttpSession session = se.getSession();
String id = session.getId();
synchronized (this) {
–sessionCount;
}
String message = new StringBuffer(“Session destroyed”
+ “\nValue of destroyed session ID is”).append(“” + id).append(
“\n”).append(“There are now “).append(“” + sessionCount)
.append(” live sessions in the application.”).toString();
System.out.println(message);
}
}
==============================================

session filter

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class SessionFilter implements Filter {

private FilterConfig config;

/** Creates new SessionFilter */
public SessionFilter() {
}

public void init(FilterConfig filterConfig) throws ServletException {

System.out.println(“Instance created of ” + getClass().getName());
this.config = filterConfig;
}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws java.io.IOException, ServletException {

HttpSession session = ((HttpServletRequest) request).getSession();
ServletContext context = config.getServletContext();
/*
* use the ServletContext.log method to log filter messages
*/
context.log(“doFilter called in: ” + config.getFilterName() + ” on ”
+ (new java.util.Date()));

// log the session ID
context.log(“session ID: ” + session.getId());

// Find out whether the logged-in session attribute is set
String logged = (String) session.getAttribute(“logged-in”);
if (logged == null)
session.setAttribute(“logged-in”, “no”);

//log a message about the log-in status
context.log(“log-in status: ”
+ (String) session.getAttribute(“logged-in”));
context.log(“”);
chain.doFilter(request, response);
}

public void destroy() {
/*
* called before the Filter instance is removed from service by the web
* container
*/
}
}

======================================

session bind listener

mport java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;

public class SessionBindListen implements HttpSessionBindingListener {

private Map info;

/** Creates new SessionBindListen */
public SessionBindListen() {

//zero-arg constructor
info = new HashMap();
}

public void valueBound(HttpSessionBindingEvent be) {

HttpSession session = be.getSession();
String id = session.getId();
String name = be.getName();
Object value = be.getValue();
String source = be.getSource().getClass().getName();
String message = new StringBuffer(“Attribute bound to session in “)
.append(source).append(“\nThe attribute name: “).append(name)
.append(“\n”).append(“The attribute value: “).append(value)
.append(“\n”).append(“The session id: “).append(id).toString();

System.out.println(message);
}

public void valueUnbound(HttpSessionBindingEvent be) {

HttpSession session = be.getSession();
String id = session.getId();
String name = be.getName();
if (name == null)
name = “Unknown”;
String source = be.getSource().getClass().getName();
String message = new StringBuffer(“Attribute unbound from session in “)
.append(source).append(“\nThe attribute name: “).append(name)
.append(“\n”).append(“The session id: “).append(id).toString();
//clear Map; send message
info.clear();
System.out.println(message + “\nThe size of the HashMap is: ”
+ info.size());
}

public void addInfo(String name, String email) {

info.put(email, name);

}

}
=======================================

use cookies to save session data

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ShoppingCartViewerCookie extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException,
IOException {
res.setContentType(“text/html”);
PrintWriter out = res.getWriter();

String sessionid = null;
Cookie[] cookies = req.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals(“sessionid”)) {
sessionid = cookies[i].getValue();
break;
}
}
}

// If the session ID wasn’t sent, generate one.
// Then be sure to send it to the client with the response.
if (sessionid == null) {
sessionid = generateSessionId();
Cookie c = new Cookie(“sessionid”, sessionid);
res.addCookie(c);
}

out.println(“<HEAD><TITLE>Current Shopping Cart Items</TITLE></HEAD>”);
out.println(“<BODY>”);

// Cart items are associated with the session ID
String[] items = getItemsFromCart(sessionid);

// Print the current cart items.
out.println(“You currently have the following items in your cart:<BR>”);
if (items == null) {
out.println(“<B>None</B>”);
} else {
out.println(“<UL>”);
for (int i = 0; i < items.length; i++) {
out.println(“<LI>” + items[i]);
}
out.println(“</UL>”);
}

// Ask if they want to add more items or check out.
out.println(“<FORM ACTION=\”/servlet/ShoppingCart\” METHOD=POST>”);
out.println(“Would you like to<BR>”);
out.println(“<INPUT TYPE=SUBMIT VALUE=\” Add More Items \”>”);
out.println(“<INPUT TYPE=SUBMIT VALUE=\” Check Out \”>”);
out.println(“</FORM>”);

// Offer a help page.
out.println(“For help, click <A href=\”/servlet/Help”
+ “?topic=ShoppingCartViewerCookie\”>here</A>”);

out.println(“</BODY></HTML>”);
}

private static String generateSessionId() throws UnsupportedEncodingException {
String uid = new java.rmi.server.UID().toString(); // guaranteed unique
return URLEncoder.encode(uid,”UTF-8″); // encode any special chars
}

private static String[] getItemsFromCart(String sessionid) {
return new String[]{“a”,”b”};
}
}

=============================

use hidden field to save data

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

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

public class ShoppingCartViewerHidden extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType(“text/html”);
PrintWriter out = res.getWriter();

out.println(“<HEAD><TITLE>Current Shopping Cart Items</TITLE></HEAD>”);
out.println(“<BODY>”);

// Cart items are passed in as the item parameter.
String[] items = req.getParameterValues(“item”);

// Print the current cart items.
out.println(“You currently have the following items in your cart:<BR>”);
if (items == null) {
out.println(“<B>None</B>”);
}
else {
out.println(“<UL>”);
for (int i = 0; i < items.length; i++) {
out.println(“<LI>” + items[i]);
}
out.println(“</UL>”);
}

// Ask if the user wants to add more items or check out.
// Include the current items as hidden fields so they’ll be passed on.
out.println(“<FORM ACTION=\”/servlet/ShoppingCart\” METHOD=POST>”);
if (items != null) {
for (int i = 0; i < items.length; i++) {
out.println(“<INPUT TYPE=HIDDEN NAME=\”item\” VALUE=\”" +
items[i] + “\”>”);
}
}
out.println(“Would you like to<BR>”);
out.println(“<INPUT TYPE=SUBMIT VALUE=\” Add More Items \”>”);
out.println(“<INPUT TYPE=SUBMIT VALUE=\” Check Out \”>”);
out.println(“</FORM>”);

out.println(“</BODY></HTML>”);
}
}

=========================

session display

import java.text.DateFormat;
import java.util.Date;

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

public class SessionDisplay extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {

response.setContentType("text/html");
java.io.PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
Date creationTime = new Date(session.getCreationTime());
Date lastAccessed = new Date(session.getLastAccessedTime());
Date now = new Date();
DateFormat formatter = DateFormat.getDateTimeInstance(
DateFormat.MEDIUM, DateFormat.MEDIUM);

out.println("<html>");
out.println("<head>");
out.println("<title>Displaying the Session Creation and Last-Accessed Time</title>");
out.println("</head>");
out.println("<body>");
out.println("<h2>Session Creation and Last-Accessed Time</h2>");
out.println("The time and date now is: " + formatter.format(now)
+ "<br><br>");
out.println("The session creation time: HttpSession.getCreationTime( ): "
+ formatter.format(creationTime) + "<br><br>");
out.println("The last time the session was accessed: HttpSession.getLastAccessedTime( ): "
+ formatter.format(lastAccessed));
out.println("</body>");
out.println("</html>");

}
}

Continue Reading

Java Compress data communication Object To BytesArray

Posted on 24. Feb, 2008 by sabin.

0

http://www.unix.org.ua/orelly/java-ent/servlet/ch10_01.htm

http://www.unix.org.ua/orelly/java-ent/servlet/ch10_02.htm

http://www.oracle.com/technology/sample_code/tech/java/servlets/htdocs/basic.htm

import java.io.*;
import java.util.zip.*;

public class CompressUtils
{

public CompressUtils()
{
}

public static byte[] compressObjectToBytesArray(Object obj)
throws IOException
{
byte abyte0[] = null;
ByteArrayOutputStream bytearrayoutputstream = new ByteArrayOutputStream();
ObjectOutputStream objectoutputstream = new ObjectOutputStream(bytearrayoutputstream);
objectoutputstream.writeObject(obj);
objectoutputstream.close();
Deflater deflater = new Deflater(9);
byte abyte1[] = bytearrayoutputstream.toByteArray();
deflater.setInput(abyte1);
deflater.finish();
byte abyte2[] = new byte[abyte1.length];
int j = abyte2.length;
int k = 0;
int i;
while((i = deflater.deflate(abyte2, k, j)) == j)
{
byte abyte3[] = new byte[abyte2.length + j];
for(int i1 = 0; i1 != abyte2.length; i1++)
abyte3[i1] = abyte2[i1];

k = abyte2.length;
abyte2 = abyte3;
}
int l = (abyte2.length – j) + i;
abyte0 = new byte[l];
for(int j1 = 0; j1 != l; j1++)
abyte0[j1] = abyte2[j1];

return abyte0;
}

public static Object decompressObjectFromBytesArray(byte abyte0[])
throws DataFormatException, IOException, ClassNotFoundException
{
byte abyte1[] = null;
Inflater inflater = new Inflater();
inflater.setInput(abyte0);
byte abyte2[] = new byte[abyte0.length * 3];
int j = abyte2.length;
int k = 0;
int i;
while((i = inflater.inflate(abyte2, k, j)) == j)
{
byte abyte3[] = new byte[abyte2.length + j];
for(int i1 = 0; i1 != abyte2.length; i1++)
abyte3[i1] = abyte2[i1];

k = abyte2.length;
abyte2 = abyte3;
}
int l = (abyte2.length – j) + i;
abyte1 = new byte[l];
for(int j1 = 0; j1 != l; j1++)
abyte1[j1] = abyte2[j1];

ObjectInputStream objectinputstream = new ObjectInputStream(new ByteArrayInputStream(abyte1));
return objectinputstream.readObject();
}
}

============================================================

// Source File Name: TableRow.java

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

public class TableRow implements Serializable
{
Map row;

public TableRow()
{
row = new HashMap();
}

public TableRow(TableRow tablerow)
{
row = new HashMap();
if(tablerow != null)
row = new HashMap(tablerow.getInternalStruct());
else
row = new HashMap();
}

public int size()
{
return row.size();
}

public void add(int i, Object obj)
{
row.put(new Integer(i), obj);
}

public void add(String s, Object obj)
{
row.put(s, obj);
}

public Object get(int i)
{
return row.get(new Integer(i));
}

public Map getInternalStruct()
{
return row;
}

public Object get(String s)
{
return row.get(s);
}

public void copy(TableRow tablerow)
{
row.putAll(tablerow.getInternalStruct());
}

}
============================
// Source File Name: Table.java

import TableRow;
import java.util.List;

public interface Table
{

public abstract void addRow(TableRow tablerow);

public abstract void addObject(Object obj);

public abstract Object getObject(int i);

public abstract void copy(Table table);

public abstract void copyByVal(Table table);

public abstract TableRow getRow(int i);

public abstract Object getValueAt(int i, int j);

public abstract int getRowCount();

public abstract void removeRow(int i);

public abstract void removeAllRows();

public abstract List getInternDataStructure();

public abstract void merge(Table table);

public abstract boolean isContained(int i, String s);

public abstract TableRow retrieveRow(String s, int i);
}
========================

// Source File Name: TableImpl.java

import TableRow;
import java.io.Serializable;
import java.util.*;

public class TableImpl implements Table, Serializable
{
private List list;
static final long serialVersionUID = 0xc106e9c97c4f9cdaL;

public TableImpl()
{
list = new ArrayList();
}

public TableImpl(Table table)
{
list = new ArrayList();
copyByVal(table);
}

public void copy(Table table)
{
list.addAll(table.getInternDataStructure());
}

public void copyByVal(Table table)
{
ListIterator listiterator = table.getInternDataStructure().listIterator();
Object obj = null;
TableRow tablerow;
for(; listiterator.hasNext(); list.add(tablerow))
tablerow = new TableRow((TableRow)listiterator.next());

}

public List getInternDataStructure()
{
return list;
}

public void removeAllRows()
{
list.clear();
}

public void addRow(TableRow tablerow)
{
list.add(tablerow);
}

public void addObject(Object obj)
{
list.add(obj);
}

public Object getObject(int i)
{
return list.get(i);
}

public void removeRow(int i)
{
list.remove(i);
}

public int getRowCount()
{
return list.size();
}

public TableRow getRow(int i)
{
return (TableRow)list.get(i);
}

public TableRow retrieveRow(String s, int i)
{
ListIterator listiterator = list.listIterator();
TableRow tablerow = null;
while(listiterator.hasNext())
{
tablerow = (TableRow)listiterator.next();
if(tablerow.get(i).equals(s))
return tablerow;
}
return tablerow;
}

public Object getValueAt(int i, int j)
{
TableRow tablerow = getRow(i);
if(tablerow != null)
{
Object obj = tablerow.get(j);
if(obj != null)
return obj;
}
return new String(“”);
}

public boolean isContained(int i, String s)
{
ListIterator listiterator = list.listIterator();
Object obj = null;
Object obj1 = null;
while(listiterator.hasNext())
{
TableRow tablerow = (TableRow)listiterator.next();
if(tablerow != null)
{
String s1 = (String)tablerow.get(i);
if(s1 != null && s.equals(s1.trim()))
return true;
}
}
return false;
}

public void merge(Table table)
{
if(table == null)
{
return;
} else
{
list.addAll(table.getInternDataStructure());
return;
}
}

}
========================
==================================================

// Source File Name: TableRowUtils.java

import Table;
import TableRow;
import java.io.PrintStream;
import java.util.*;

public class TableRowUtils
{

public TableRowUtils()
{
}

public static void printTable(Table table)
{
try
{
printTable(table, “”, 0);
}
catch(Exception exception) { }
}

public static void printTable(Table table, String s)
{
try
{
printTable(table, s, 0);
}
catch(Exception exception) { }
}

public static void printRow(TableRow tablerow)
{
try
{
printRow(tablerow, 0);
}
catch(Exception exception) { }
}

private static void printTable(Table table, String s, int i)
{
printLevel(i);
System.out.print(“{TABLE@” + s + “}:\n”);
for(int j = 0; table != null && j < table.getRowCount(); j++)
{
TableRow tablerow = table.getRow(j);
printRow(tablerow, j, i + 1);
}

}

private static void printRow(TableRow tablerow, int i)
{
printRow(tablerow, 0, 0);
}

private static void printRow(TableRow tablerow, int i, int j)
{
printLevel(j);
System.out.print(“{ROW@” + i + “L}:\n”);
Map map = tablerow.getInternalStruct();
java.util.Set set = map.keySet();
TreeSet treeset = new TreeSet(set);
for(Iterator iterator = treeset.iterator(); iterator.hasNext();)
{
Object obj = iterator.next();
Object obj1 = map.get(obj);
if(obj1 instanceof Table)
printTable((Table)obj1, obj.toString(), j + 1);
else
if(obj1 instanceof TableRow)
{
printRow((TableRow)obj1, j + 1);
} else
{
printLevel(j + 1);
System.out.print(” “);
System.out.print(“[" + obj + ":" + obj1 + "]\n”);
}
}

}

private static void printLevel(int i)
{
for(int j = 0; j < i; j++)
System.out.print(” “);

}
}
===========================================
// Source File Name: LocationInfo.java

import java.io.*;

public class LocationInfo
implements Serializable
{

public LocationInfo(Throwable throwable, String s)
{
if(throwable == null)
return;
String s1;
synchronized(sw)
{
throwable.printStackTrace(pw);
s1 = sw.toString();
sw.getBuffer().setLength(0);
}
int i = s1.lastIndexOf(s);
if(i == -1)
return;
i = s1.indexOf(LINE_SEP, i);
if(i == -1)
return;
i += LINE_SEP_LEN;
int j = s1.indexOf(LINE_SEP, i);
if(j == -1)
return;
if(!inVisualAge)
{
i = s1.lastIndexOf(“at “, j);
if(i == -1)
return;
i += 3;
}
fullInfo = s1.substring(i, j);
}

public String getClassName()
{
if(fullInfo == null)
return “?”;
if(className == null)
{
int i = fullInfo.lastIndexOf(‘(‘);
if(i == -1)
{
className = “?”;
} else
{
i = fullInfo.lastIndexOf(‘.’, i);
int j = 0;
if(inVisualAge)
j = fullInfo.lastIndexOf(‘ ‘, i) + 1;
if(i == -1)
className = “?”;
else
className = fullInfo.substring(j, i);
}
}
return className;
}

public String getFileName()
{
if(fullInfo == null)
return “?”;
if(fileName == null)
{
int i = fullInfo.lastIndexOf(‘:’);
if(i == -1)
{
fileName = “?”;
} else
{
int j = fullInfo.lastIndexOf(‘(‘, i – 1);
fileName = fullInfo.substring(j + 1, i);
}
}
return fileName;
}

public String getLineNumber()
{
if(fullInfo == null)
return “?”;
if(lineNumber == null)
{
int i = fullInfo.lastIndexOf(‘)’);
int j = fullInfo.lastIndexOf(‘:’, i – 1);
if(j == -1)
lineNumber = “?”;
else
lineNumber = fullInfo.substring(j + 1, i);
}
return lineNumber;
}

public String getMethodName()
{
if(fullInfo == null)
return “?”;
if(methodName == null)
{
int i = fullInfo.lastIndexOf(‘(‘);
int j = fullInfo.lastIndexOf(‘.’, i);
if(j == -1)
methodName = “?”;
else
methodName = fullInfo.substring(j + 1, i);
}
return methodName;
}

private static final String LINE_SEP = System.getProperty(“line.separator”);
private static final int LINE_SEP_LEN = LINE_SEP.length();
transient String lineNumber;
transient String fileName;
transient String className;
transient String methodName;
public String fullInfo;
private static StringWriter sw;
private static PrintWriter pw;
public static final String NA = “?”;
static final long serialVersionUID = 0xed99bbe14a91a57cL;
static boolean inVisualAge = false;

static
{
sw = new StringWriter();
pw = new PrintWriter(sw);
try
{
Class class1 = Class.forName(“com.ibm.uvm.tools.DebugSupport”);
inVisualAge = true;
}
catch(Throwable throwable) { }
}
}

==========================================
==========================================
==========================================
==========================================
//ServletConException.java
public class ServletConException extends Exception
{
public ServletConException() {
/* empty */
}

public ServletConException(String string) {
super(string);
}
}
================================
//ServletPack.java

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

import javax.rmi.PortableRemoteObject;

import TableRow;
import MonitorActivities;

public class ServletPack
{

public TableRow send(TableRow tablerow) {
MonitorActivities.resetStartMonitorTime();
TableRow tablerow_0_ = null;
Object object = null;
URLConnection urlconnection = null;
for (int i = 0; i < 3; i++) {
try {
if (urlconnection == null)
urlconnection = getConnection();
else
System.out.println(“connection is existing”);
byte[] is = compress(tablerow);
urlconnection.setRequestProperty(“Content-length”,
new Integer(is.length)
.toString());
setObjectOutStream(urlconnection, is);
tablerow_0_ = getObjectInStream(urlconnection);
} catch (MalformedURLException malformedurlexception) {
continue;
} catch (IOException ioexception) {
ioexception.printStackTrace();
System.out.println(“”);
System.out.println(“Retry Servlet = ” + i);
urlconnection = null;
continue;
} catch (Exception exception) {
exception.printStackTrace();
continue;
}
break;
}
return tablerow_0_;
}

public static byte[] compress(TableRow tablerow) throws Exception {
Object object = null;
ByteArrayOutputStream bytearrayoutputstream
= new ByteArrayOutputStream();
ObjectOutputStream objectoutputstream
= new ObjectOutputStream(bytearrayoutputstream);
objectoutputstream.writeObject(tablerow);
objectoutputstream.close();
Deflater deflater = new Deflater(9);
byte[] is = bytearrayoutputstream.toByteArray();
System.out.println(“uncompressed” + is.length);
deflater.setInput(is);
deflater.finish();
byte[] is_1_ = new byte[is.length];
int i = is_1_.length;
byte[] is_2_;
int i_3_;
for (int i_4_ = 0; (i_3_ = deflater.deflate(is_1_, i_4_, i)) == i;
is_1_ = is_2_) {
is_2_ = new byte[is_1_.length + i];
for (int i_5_ = 0; i_5_ != is_1_.length; i_5_++)
is_2_[i_5_] = is_1_[i_5_];
i_4_ = is_1_.length;
}
int i_6_ = is_1_.length – i + i_3_;
byte[] is_7_ = new byte[i_6_];
for (int i_8_ = 0; i_8_ != i_6_; i_8_++)
is_7_[i_8_] = is_1_[i_8_];
System.out.println(“compressed” + is_7_.length);
return is_7_;
}

public URLConnection getConnection() {
URL url = null;
try {
url = new URL(http://localhost:7001/RemoteServiceServlet);
System.out.println(“before getting connection —– url –>”
+ url);
} catch (MalformedURLException malformedurlexception) {
malformedurlexception.printStackTrace();
}
HttpURLConnection httpurlconnection = null;
try {
System.out.println(“trying to open url connection–”);
httpurlconnection = (HttpURLConnection) url.openConnection();
System.out.println(“after getting connection —–”);
} catch (IOException ioexception) {
ioexception.printStackTrace();
}
httpurlconnection.setRequestProperty(“Content-Type”,
“application/octet-stream”);
return httpurlconnection;
}

public static void setObjectOutStream
(URLConnection urlconnection, byte[] is) throws Exception {
urlconnection.setUseCaches(false);
urlconnection.setDoInput(true);
urlconnection.setDoOutput(true);
ObjectOutputStream objectoutputstream
= new ObjectOutputStream(urlconnection.getOutputStream());
objectoutputstream.writeObject(is);
objectoutputstream.flush();
objectoutputstream.close();
}

public static TableRow getObjectInStream(URLConnection urlconnection)
throws Exception {
Object object = null;
Object object_9_ = null;
TableRow tablerow = null;
ObjectInputStream objectinputstream
= new ObjectInputStream(urlconnection.getInputStream());
byte[] is = (byte[]) objectinputstream.readObject();
if (is != null)
tablerow = decompress(is);
else
System.out.println(“received is null”);
objectinputstream.close();
return tablerow;
}

public static TableRow decompress(byte[] is) throws Exception {
TableRow tablerow = null;
Object object = null;
System.out.println
(“size of the bytes before decompression in ClientSide::”
+ is.length);
Inflater inflater = new Inflater();
inflater.setInput(is);
byte[] is_10_ = new byte[is.length * 3];
int i = is_10_.length;
byte[] is_11_;
int i_12_;
for (int i_13_ = 0; (i_12_ = inflater.inflate(is_10_, i_13_, i)) == i;
is_10_ = is_11_) {
is_11_ = new byte[is_10_.length + i];
for (int i_14_ = 0; i_14_ != is_10_.length; i_14_++)
is_11_[i_14_] = is_10_[i_14_];
i_13_ = is_10_.length;
}
int i_15_ = is_10_.length – i + i_12_;
System.out.println(“totalLength ” + i_15_);
byte[] is_16_ = new byte[i_15_];
for (int i_17_ = 0; i_17_ != i_15_; i_17_++)
is_16_[i_17_] = is_10_[i_17_];
System.out.println
(“size of the bytes after decompression::Client Side”
+ is_16_.length);
ObjectInputStream objectinputstream
= new ObjectInputStream(new ByteArrayInputStream(is_16_));
Object object_18_ = objectinputstream.readObject();
if (object_18_ != null)
tablerow = (TableRow) (PortableRemoteObject.narrow
(object_18_,
(class$TableRow == null
? (class$TableRow
= class$(“TableRow”))
: class$TableRow)));
objectinputstream.close();
return tablerow;
}

static Class class$(String string) {
Class var_class;
try {
var_class = Class.forName(string);
} catch (ClassNotFoundException classnotfoundexception) {
throw new NoClassDefFoundError().initCause(classnotfoundexception);
}
return var_class;
}
}
=================================================

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import Session;

public class MonitorActivities implements Runnable
{
private static final int DELAY = 1000;
private static long startMonitorTime;
private JFrame frame;
private Session session;
private long timeOut;
private boolean stop = false;

public MonitorActivities(JFrame jframe) {
frame = jframe;
timeOut = 3600000L;
resetStartMonitorTime();
}

public void setSession(Session session) {
this.session = session;
}

public static void resetStartMonitorTime() {
startMonitorTime = System.currentTimeMillis();
}

public void run() {
while (!stop) {
if (System.currentTimeMillis() – startMonitorTime >= timeOut) {
if (((DesktopFrame) frame).getBusy())
resetStartMonitorTime();
else {
try {
session.getSessions()
.signOut();
} catch (Exception exception) {

}
if (frame != null && frame.isVisible()
&& session.isLogon())
JOptionPane.showMessageDialog
(frame,
“System Idle time expired. User has been logged out!”,
“Prog”, 1);
shutdown();
stop = true;
break;
}
} else {
try {
Thread.sleep(1000L);
} catch (InterruptedException interruptedexception) {
/* empty */
}
}
}
}

public void stop() {
stop = true;
}
}
================================
public interface Communicator
{
public void sendRequest(Object object);

public Object getResponse();
}

==========================================
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.BindException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.zip.DataFormatException;

import CompressUtils;

public class HttpObjectCommunicator implements Communicator
{
private final int MAX_ATTEMPTS = 10;
private String url = null;
private HttpURLConnection connection = null;
private byte[] responsebytes = null;

public HttpObjectCommunicator(String string) {
url = string;
}

protected void setConnection(HttpURLConnection httpurlconnection) {
connection = httpurlconnection;
}

protected HttpURLConnection getConnection() throws IOException {
if (connection == null) {
URL url = new URL(this.url);
connection = (HttpURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty(“Content-Type”,
“application/octet-stream”);
connection.setRequestMethod(“POST”);
}
return connection;
}

private void doConnect(HttpURLConnection httpurlconnection)
throws IOException {
int i = 10;
boolean bool;
do {
bool = false;
try {
httpurlconnection.connect();
} catch (IOException ioexception) {
if (ioexception instanceof BindException) {
String string = ioexception.getMessage().toLowerCase();
if (string.equals(“address in use”) && –i > 0)
bool = true;
}
if (!bool)
throw ioexception;
}
} while (bool);
}

private void doDisconnect(HttpURLConnection httpurlconnection) {
if (httpurlconnection != null)
httpurlconnection.disconnect();
}

public void sendRequest(Object object) {
HttpURLConnection httpurlconnection = null;
boolean bool = false;
for (int i = 0; i < 3; i++) {
try {
byte[] is = CompressUtils.compressObjectToBytesArray(object);
httpurlconnection = getConnection();
httpurlconnection.setRequestProperty(“Content-length”,
new Integer(is.length)
.toString());
doConnect(httpurlconnection);
ObjectOutputStream objectoutputstream
= new ObjectOutputStream(httpurlconnection
.getOutputStream());
objectoutputstream.writeObject(is);
objectoutputstream.flush();
objectoutputstream.close();
bool = true;
} catch (MalformedURLException malformedurlexception) {
System.out.println
(“MalformedURLException:- URL IS WRONG:” + url + “:”
+ malformedurlexception.toString());
return;
} catch (IOException ioexception) {
System.out.println(“Retry SendHttpObject = ” + i
+ “:”
+ ioexception.toString());
doDisconnect(httpurlconnection);
setConnection(null);
continue;
} catch (Exception exception) {
System.out.println(exception.toString());
continue;
}
break;
}
if (bool) {
try {
ObjectInputStream objectinputstream
= new ObjectInputStream(httpurlconnection
.getInputStream());
responsebytes = (byte[]) objectinputstream.readObject();
objectinputstream.close();
doDisconnect(httpurlconnection);
setConnection(null);
} catch (IOException ioexception) {
System.out.println(“receiveHttpResponse:”
+ ioexception.toString());
} catch (ClassNotFoundException classnotfoundexception) {
System.out.println(“receiveHttpResponse:”
+ classnotfoundexception
.toString());
}
}
}

public Object getResponse() {
do {
if (responsebytes != null) {
Object object;
try {
object
= CompressUtils
.decompressObjectFromBytesArray(responsebytes);
} catch (DataFormatException dataformatexception) {
System.out.println(dataformatexception
.toString());
break;
} catch (IOException ioexception) {
System.out.println(ioexception.toString());
break;
} catch (ClassNotFoundException classnotfoundexception) {
System.out.println(classnotfoundexception
.toString());
break;
}
return object;
}
} while (false);
System.out.println(“received is null”);
return null;
}
}

===========================
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import ServiceRequest;
import ServiceResponse;

import MonitorActivities;

public class ServiceProxy implements InvocationHandler
{
private String serviceName = null;
private static Map services = new HashMap();

public static Object newInstance(Class var_class) {
if (!services.containsKey(var_class.getName())) {
Class[] var_classes;
if (var_class.isInterface())
var_classes = new Class[] { var_class };
else
var_classes = var_class.getInterfaces();
ServiceProxy serviceproxy = new ServiceProxy(var_class.getName());
Object object
= Proxy.newProxyInstance(Thread.currentThread()
.getContextClassLoader(),
var_classes, serviceproxy);
services.put(var_class.getName(), object);
}
return services.get(var_class.getName());
}

private ServiceProxy(String string) {
serviceName = string;
}

public Object invoke(Object object, Method method, Object[] objects)
throws Throwable {
object_0_ = object_7_;
break while_2_;
}
}

==============================================
// Source File Name: ServiceRequest.java

import java.io.Serializable;
import java.util.Arrays;

public class ServiceRequest
implements Serializable
{

public ServiceRequest()
{
}

public String getService()
{
return service;
}

public void setService(String s)
{
service = s;
}

public String getMethod()
{
return method;
}

public void setMethod(String s)
{
method = s;
}

public Class[] getMethodParamTypes()
{
return methodParamTypes;
}

public void setMethodParamTypes(Class aclass[])
{
methodParamTypes = aclass;
}

public Object[] getArgs()
{
return args;
}

public void setArgs(Object aobj[])
{
args = aobj;
}

public boolean equals(Object obj)
{
if(this == obj)
return true;
if(!(obj instanceof ServiceRequest))
return false;
ServiceRequest servicerequest = (ServiceRequest)obj;
if(!Arrays.equals(args, servicerequest.args))
return false;
if(method == null ? servicerequest.method != null : !method.equals(servicerequest.method))
return false;
if(!Arrays.equals(methodParamTypes, servicerequest.methodParamTypes))
return false;
return service == null ? servicerequest.service == null : service.equals(servicerequest.service);
}

public int getRequestCode()
{
return requestCode;
}

public void setRequestCode(int i)
{
requestCode = i;
}

private String service;
private String method;
private Class methodParamTypes[];
private Object args[];
private int requestCode;
}
==========================================
// Source File Name: ServiceResponse.java
import java.io.Serializable;

public class ServiceResponse implements Serializable
{

public ServiceResponse()
{
}

public int getRequestCode()
{
return requestCode;
}

public void setRequestCode(int i)
{
requestCode = i;
}

public boolean isSuccess()
{
return success;
}

public void setSuccess(boolean flag)
{
success = flag;
}

public Object getResult()
{
return result;
}

public void setResult(Object obj)
{
result = obj;
}

public Throwable getError()
{
return error;
}

public void setError(Throwable throwable)
{
error = throwable;
}

private int requestCode;
private boolean success;
private Object result;
private Throwable error;
}
========================================

Continue Reading

Java Jnlp how to

Posted on 19. Feb, 2008 by sabin.

0

http://java.sun.com/j2se/1.5.0/docs/guide/javaws/developersguide/examples.html

http://java.sun.com/developer/technicalArticles/Programming/jnlp/

http://java.sun.com/products/javawebstart/1.2/docs/developersguide.html

* Introduction
* Using a BasicService Service
* Using a ClipboardService Service
* Using a DownloadService Service
* Using a FileOpenService Service
* Using a FileSaveService Service
* Using a PrintService Service
* Using a PersistenceService Service
* Using FileContents
* Using a JNLPRandomAccessFile
* Using a SingleInstanceService Service
* Using a ExtendedService Service

Introduction

The JNLP API is designed to provide additional information to the
application that would otherwise not be available using the standard Java
2 SE API. The following code examples show how the following services can
be used: BasicService, ClipboardService, DownloadService, FileOpenService,
FileSaveService, PrintService, and PersistenceService.

The public classes and interfaces in the JNLP API are included in the
jnlp.jar file. This JAR file must be included in the classpath when
compiling source files that use the JNLP API. For example on Windows:

javac -classpath .;jnlp.jar *.java

The jnlp.jar file is included in the JDK in the sample/jnlp/servlet/
directory.

Using a BasicService Service

The javax.jnlp.BasicService service provides a set of methods for querying
and interacting with the environment similar to what the AppletContext
provides for a Java Applet.

The showURL method uses the JNLP API to direct the default browser on the
platform to show the given URL. The method returns true if the request
succeeds, otherwise false.

import javax.jnlp.*;

// Method to show a URL
boolean showURL(URL url) {
try {
// Lookup the javax.jnlp.BasicService object
BasicService bs =
(BasicService)ServiceManager.lookup(“javax.jnlp.BasicService”);
// Invoke the showDocument method
return bs.showDocument(url);
} catch(UnavailableServiceException ue) {
// Service is not supported
return false;
}
}
Using a ClipboardService Service

The javax.jnlp.ClipboardService service provides methods for accessing the
shared system-wide clipboard, even for applications that are running in
the restricted execution environment.

Java Web Start will warn the user of the potential security risk of
letting an untrusted application access potentially confidential
information stored in the clipboard, or overwriting contents stored in the
clipboard.

import javax.jnlp;

private ClipboardService cs;

try {
cs = (ClipboardService)ServiceManager.lookup
(“javax.jnlp.ClipboardService”);
} catch (UnavailableServiceException e) {
cs = null;
}

if (cs != null) {
// set the system clipboard contents to a string selection
StringSelection ss = new StringSelection(“Java Web Start!”);
cs.setContents(ss);
// get the contents of the system clipboard and print them
Transferable tr = cs.getContents();
if (tr.isDataFlavorSupported(DataFlavor.stringFlavor)) {
try {
String s =
(String)tr.getTransferData(DataFlavor.stringFlavor);
System.out.println(“Clipboard contents: ” + s);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Using a DownloadService Service

The javax.jnlp.DownloadService service allows an application to control
how its own resources are cached.

The service allows an application to determine which of its resources are
cached, to force resources to be cached, and to remove resources from the
cache.

import javax.jnlp.*;

DownloadService ds;

try {
ds =
(DownloadService)ServiceManager.lookup(“javax.jnlp.DownloadService”);
} catch (UnavailableServiceException e) {
ds = null;
}

if (ds != null) {

try {
// determine if a particular resource is cached
URL url =
new
URL(“http://java.sun.com/products/javawebstart/lib/draw.jar”);
boolean cached = ds.isResourceCached(url, “1.0″);
// remove the resource from the cache
if (cached) {
ds.removeResource(url, “1.0″);
}
// reload the resource into the cache
DownloadServiceListener dsl = ds.getDefaultProgressWindow();
ds.loadResource(url, “1.0″, dsl);
} catch (Exception e) {
e.printStackTrace();
}
}

Using a FileOpenService Service

The javax.jnlp.FileOpenService service provides methods for importing
files from the local disk, even for applications that are running in the
restricted execution environment.

This interface is designed to provide the same kind of of disk access to
potentially untrusted Web-deployed applications that a Web developer has
when using HTML.  HTML forms support the inclusion of files by displaying
a file open dialog.

import javax.jnlp.*;

FileOpenService fos;

try {
fos =
(FileOpenService)ServiceManager.lookup(“javax.jnlp.FileOpenService”);
} catch (UnavailableServiceException e) {
fos = null;
}

if (fos != null) {
try {
// ask user to select a file through this service
FileContents fc = fos.openFileDialog(null, null);
// ask user to select multiple files through this service
FileContents[] fcs = fos.openMultiFileDialog(null, null);
} catch (Exception e) {
e.printStackTrace();
}
}

Using a FileSaveService Service

The javax.jnlp.FileSaveService service provides methods for exporting
files to the local disk, even for applications that are running in the
restricted execution environment.

This interface is designed to provide the same level of disk access to
potentially untrusted Web-deployed applications that a Web browser
provides for contents that it is displaying.  Most browsers provide a Save
As… dialog as part of their user interface.

import javax.jnlp.*;

FileSaveService fss;
FileOpenService fos;

try {
fos =
(FileOpenService)ServiceManager.lookup(“javax.jnlp.FileOpenService”);
fss = (FileSaveService)ServiceManager.lookup
(“javax.jnlp.FileSaveService”);
} catch (UnavailableServiceException e) {
fss = null;
fos = null;
}

if (fss != null && fos != null) {
try {
// get a file with FileOpenService
FileContents fc = fos.openFileDialog(null, null);
// one way to save a file
FileContents newfc = fss.saveFileDialog(null, null,
fc.getInputStream(), “newFileName.txt”);
// another way to save a file
FileContents newfc2 = fss.saveAsFileDialog(null, null, fc);

} catch (Exception e) {
e.printStackTrace();
}
}

Also see Using FileContents.
Using a PrintService Service

The javax.jnlp.PrintService service provides methods for access to
printing, even for applications that are running in the restricted
execution environment.

Using this service, an application can submit a print job. Java Web Start
will then show this request to the user and, if accepted, queue the
request to the printer.

In Java Web Start 5.0, you can now directly use the Java Printing APIs,
and Java Web Start will pop up a security dialog asking the user to grant
PrintPermission if the application is running in a sandbox. There is no
need to use the JNLP Printing APIs anymore. You can have full access to
the Java Printing APIs in any JNLP application.

import javax.jnlp.*;

PrintService ps;

try {
ps = (PrintService)ServiceManager.lookup(“javax.jnlp.PrintService”);
} catch (UnavailableServiceException e) {
ps = null;
}

if (ps != null) {
try {

// get the default PageFormat
PageFormat pf = ps.getDefaultPage();

// ask the user to customize the PageFormat
PageFormat newPf = ps.showPageFormatDialog(pf);

// print the document with the PageFormat above
ps.print(new DocToPrint());

} catch (Exception e) {
e.printStackTrace();
}
}

// Code to construct the Printable Document
class DocToPrint implements Printable {
public int print(Graphics g, PageFormat pageformat, int PageIndex){
// code to generate what you want to print
}
}

Using a PersistenceService Service

The  javax.jnlp.PersistenceService service provides methods for storing
data locally on the client system, even for applications that are running
in the restricted execution environment.

The service is designed to be somewhat similar to that which the cookie
mechanism provides to HTML-based applications.  Cookies allow a small
amount of data to be stored locally on the client system.  That data can
be securely managed by the browser and can only be retrieved by HTML pages
which originate from the same URL as the page that stored the data.

import javax.jnlp.*;

PersistenceService ps;
BasicService bs;

try {
ps =
(PersistenceService)ServiceManager.lookup(“javax.jnlp.PersistenceService”);
bs = (BasicService)ServiceManager.lookup(“javax.jnlp.BasicService”);
} catch (UnavailableServiceException e) {
ps = null;
bs = null;
}

if (ps != null && bs != null) {

try {
// find all the muffins for our URL
URL codebase = bs.getCodeBase();
String [] muffins = ps.getNames(url);

// get the attributes (tags) for each of these muffins.
// update the server’s copy of the data if any muffins
// are dirty
int [] tags = new int[muffins.length];
URL [] muffinURLs = new URL[muffins.length];
for (int i = 0; i < muffins.length; i++) {
muffinURLs[i] = new URL(codebase.toString() + muffins[i]);
tags[i] = ps.getTag(muffinURLs[i]);
// update the server if anything is tagged DIRTY
if (tags[i] == PersistenceService.DIRTY) {
doUpdateServer(muffinURLs[i]);
}
}

// read in the contents of a muffin and then delete it
FileContents fc = ps.get(muffinURLs[0]);
long maxsize = fc.getMaxLength();
byte [] buf = new byte[fc.getLength()];
InputStream is = fc.getInputStream();
long pos = 0;
while((pos = is.read(buf, pos, buf.length – pos)) > 0) {
// just loop
}
is.close();

ps.delete(muffinURLs[0]);

// re-create the muffin and repopulate its data
ps.create(muffinURLs[0], maxsize);
fc = ps.get(muffinURLs[0]);
// don’t append
OutputStream os = fc.getOutputStream(false);
os.write(buf);
os.close();

} catch (Exception e) {
e.printStackTrace();
}
}

void doUpdateServer(URL url) {
// update the server’s copy of the persistent data
// represented by the given URL

ps.setTag(url, PersistenceService.CACHED);
}

Using FileContents

javax.jnlp.FileContents objects encapsulate the name and contents of a
file.  An object of this class is used by the FileOpenService,
FileSaveService and PersistenceService. Here is an example of how an
instance of a FileContents can be used to read from and write to a file:

import javax.jnlp.*;

FileOpenService fos;

//Initialize fos (see Using a FileOpenService Service example)

if (fos != null) {

try {

// get a FileContents object to work with from the
// FileOpenService
FileContents fc = fos.openFileDialog(null, null);

// get the InputStream from the file and read a few bytes
byte [] buf = new byte[fc.getLength()];
InputStream is = fc.getInputStream();
int pos = 0;
while ((pos = is.read(buf, pos, buf.length – pos)) > 0) {
// just loop
}
is.close();

// get the OutputStream and write the file back out
if (fc.canWrite()) {
// don’t append
OutputStream os = fc.getOutputStream(false);
os.write(buf);
}

} catch (Exception e) {
e.printStackTrace();
}
}

Using a JNLPRandomAccessFile

Instances of javax.jnlp.JNLPRandomAccessFile support both reading and
writing to a random access file.  A random access file behaves like a
large array of bytes stored in the file system.  Here is an example of how
an instance of a JNLPRandomAccessFile can be used to write to a random
access file:

import javax.jnlp.*;

FileOpenService fos;

//Initialize fos (see Using a FileOpenService Service example)

if (fos != null) {
try {
// ask the user to choose a file to open
FileContents fc = fos.openFileDialog(null, null);

// attempt to increase the maximum file length
long grantedLength = fc.getLength();
if (grantedLength + 1024 > fc.getMaxLength()) {
// attempt to increase the maximum file size defined by
// the client
grantedLength = fc.setMaxLength(grantedLength + 1024);
}

// if we were able to increase the maximum allowable file size,
// get a JNLPRandomAccessFile representation of the file, and
// write to it
if (fc.getMaxSize() > fc.getLength() && fc.canWrite()) {
JNLPRandomAccessFile raf = fc.getRandomAccessFile(“rw”);
raf.seek(raf.length() – 1);
raf.writeUTF(“Java Web Start!”);
raf.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}

Using a SingleInstanceService Service

The javax.jnlp.SingleInstanceService provides a set of methods for
applications to register themselves as singletons, and to register
listener(s) for handling arguments passed in from different instances of
applications.

import javax.jnlp.*;

SingleInstanceService sis;

try {
sis =
(SingleInstanceService)ServiceManager.lookup(“javax.jnlp.SingleInstanceService”);
} catch (UnavailableServiceException e) { sis=null; }

// Register the single instance listener at the start of your application

SISListener sisL = new SISListener();
sis.addSingleInstanceListener(sisL);

// Remember to remove the listener before your application exits

sis.removeSingleInstanceListener(sisL);
System.exit(0);

// Implement the SingleInstanceListener for your application

class SISListener implements SingleInstanceListener {
public void newActivation(String[] params) {

// your code to handle the new arguments here


}
}

Using an ExtendedService Service

The javax.jnlp.ExtendedService provides additional support to the current
JNLP API. It allows applications to open specific file(s) in the client’s
file system.

import javax.jnlp.*;

ExtendedService es;

try {
es =
(ExtendedService)ServiceManager.lookup(“javax.jnlp.ExtendedService”);
} catch (UnavailableServiceException e) { es=null; }

// Open a specific file in the local machine

File a = new File(“c:\somefile.txt”);

// Java Web Start will pop up a dialog asking the user to grant
permission
// to read/write the file c:\somefile.txt

FileContents fc_a = es.openFile(a);

// You can now use the FileContents object to read/write the file

// Open a specific set of files in the local machine

File[2] fArray = new File[2];

fArray[0] = a;
fArray[1] = new File(“c:\anotherFile.txt”);

// Java Web Start will pop up a dialog asking the user to grant
permission
// to read/write files in fArray

FileContents[] fc_Array = es.OpenFiles(fArray);

// You can now read/write the set of files in fc_Array using the
// FileContents objects

}

For detailed information on using javaws, see the javaws Command Line
Interface.

Continue Reading

Cascading Style Sheet(Css)

Posted on 19. Feb, 2008 by sabin.

0

plz download the tutor from here css

Continue Reading

Java Scripts Tutor

Posted on 19. Feb, 2008 by sabin.

0

Continue Reading

java Awt Notes

Posted on 19. Feb, 2008 by sabin.

0

Download small Media library Project in java

Media library Project

User Interface Componect Classes
A awt package contains a number of component classes that are typical elements of any
interactive user interface.it is also called UI componect classes.

Methods
setSize(Dimension d) Resizes the corresponding component so that it has width d.width
and height d.height
setSize(int width,int height) Resizes the corresponding component so that it has widht and height
setFont(font f) sets the font of allcorresponding component
setenabled(boolean b) Sets the font of the corresponding component
setEnabled(boolean b) Enables or disables the corresponding component depending on the value of the parameter b
setVisible(boolean b) Shows or hides the corresponding component depending on the values of parameter b
setForeground(Color c) Sets the foreground color of the corresponding component
setBounds(int x,int y, int width,int height) Moves and resizes the corresponding component
setBounds(int Rectangle) Moves and resizes the corresponding component to conform to the new bounding rectangle r
setBackground(Color c) Sets the background color of the corresponding component
getBackground() Gets the background color of the corresponding component
getBounds() Gets teh bounds of the corresponding component in the form of Recatangle Object
getFont() Gets the font of the corresponding component
getForeground() Gets the foreground color of the corresponding component
getSize() Returns the size of the corresponding component in the form of Dimension object.

To use the UI component following steps should be followed
1) First the user interface component has to be created using the constructor of the corresponding class
eg Button mybutton=new button(“Ok”);

2) Teh component created is added to container using add() method of the container class For eg
add(mybotton)

3)Depending on the user interface component it is necessary to handle the events grenerated by it
there are 2 ways of handaling events the beast one is listner

To determine the component in which an even has occured it is necessary to use inner classes.
each object has an inner class defined for it implements their respective event listners.

UI component
Label
Button
Checkbox
TextComponent
TextArea & TextField
Choice
List
Scrollbars

1)Buttons
Constructors
Button() Construsts a button with no label
Button(String label) Construct a button with the label

Methods
addActionListner(ActionListener l) Adds the specified actoion listner to receive action events
from the corresponding button
getActionCommand() Returns teh command name from the action event fired by the corresponding button
getLabel() Retruns teh label of the corresponding button
paramString() Returns the parameter string representing the state of the corresponding button
setLabel(String label) sets the label of the button to the value specified

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class buttontest extends Applet
{
Label lb1=new Label(“Button1″);
Button b1=new Button(“OK”);
Label lb2=new Label(“Button2″);
Button b2=new Button(“CANCEL”);

public void init()
{
setLayout(new FlowLayout());
b1.addActionListener(new b1());
b2.addActionListener(new b2());
add(lb1);
add(b1);
add(lb2);
add(b2);
}
class b1 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
getAppletContext().showStatus(“button1 click”);
}
}

class b2 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
getAppletContext().showStatus(“button2 click”);
}
}

}

2)ChecBox
Constructor
CheckBox() Creates a checkbox with no label
CheckBox(String label) Creates a checkbox with the specified label
Checkbox(String label,boolean state) Creates a checkbox with the specified label and set the specifies state
Checkbox(String label,boolean state,CheckboxGroup group) Creates a checkbox with the specified label and sets the
Specified label and sets the specified state and places it in the specified group

Method
getCheckboxGroup() Determines the group of the corresponding checkbox
getLabel() Gets the name of the corresponding checkbox
getSelectedObjects() Returns an aray(lengths 1) containing the checkbox label or null if the check box is not selected
getState() Determines if the checkbox is in the on or off state
setCheckboxGroup(CheckboxGroup g) sets the corresponding checkbox’s group to the specified one
setLabel(String label) Sets the label of the corresponding checkbox to the value specified
setState(boolean state) sets the state of the corresponding checkbox to the value specified

3)Choice
Constructior
Choice() Creates a new choice menu

Methods
add(String item) Adds an item to the corresponding choice menu
addItem(String item) Adds an item to the corresponding choice
getItem(int index) Gets the string at the specified index of the corresponding choice menu
getItemCount() Returns the number of items in the corresponding choice menu
getSelectedIndex() Returns the index of the currently select item
getSelectedItem() Gets a representation of the current selected item
getSelectedObjects() Returns an array(length 1) containing the currently selected item
insert(String item, int index) Inserts the item into the corresponding chice at the specified position)
remove(int position) Removes an item from the corresponding choice menu at the specified position
remove(Stirng item) remove the first occurence of item from the corresponding choice menu
removeAll() removes the first occurence of item from the corresponding choice menu
select(int pos) sets the selectd item in the corresponding choice menu to be the item at the specified position
select(String str) Sets the selected item in the corresponding choice menu to be the item whose name is equal to the specified string

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
public class radiotest extends Applet
{
public void init()
{
CheckboxGroup c=new CheckboxGroup();
Checkbox c1=new Checkbox(“black and white”,c,true);
Checkbox c2=new Checkbox(“Color”,c,false);
c1.addMouseListener(new check1());
c2.addMouseListener(new check2());
add(c1);
add(c2);
Choice abc=new Choice();
abc.add(“Onida”);
abc.add(“BPL”);
abc.add(“Samsung”);
abc.add(“Philips”);
abc.add(“Videcon”);
abc.addItemListener(new ch());
add(abc);
}
class check1 extends MouseAdapter
{
public void mouseClicked(MouseEvent e)
{
showStatus(“you have selectd:black and white”);
}
}
class check2 extends MouseAdapter
{
public void mouseClicked(MouseEvent e)
{
showStatus(“you have selected color tv”);
}
}

class ch implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{
String s=(String)e.getItem();
showStatus(“you have selecte “+s+” brand”);
}
}
}

4)Label
Construstor
Label() Construct an empty label
Label(String text) Construct a string with the corresponding text
Label(String text,int alignment) Construct a string with the text with the specified aligiment CENTER,LEFT,RIGHT

Method
getText() gets the text of the corresponding label
paramString() returns the parameter string representing the state of the corresponding label
setText(String text) Sets the text for the corresponding label to the specified text

5)List
List() creates a new scrolling list of items
List(int rows) creates a new scrolling list of items with the specified number of visible lines
List(int rows,boolean multiplemode) Creates a new scrolling list of items to display the specified number of rows

Method
add(string item) Adds the specified item at the end of the scrolling list
add(String item,index) adds the specified item at the position specified
deselect(int index) deselects the item at the specified index
getItem(int index) gets the item at the specified index
getItemCount() Gets the number of items in the list
getItems() gets the item in the list
getMinimumSize() Determines the minimum size of the scrolling list
getMinimumSize(int rows) gets teh minimun dimensions for a list with specified number of rows
getPreferredSize() Gets the preferred size of the corresponding scrolling list
getPreferredSize(int rows) Gets the minimum dimension for a list with the specified number of rows
getRows() gets the number of visible lines in hte corresponding list
getSelectedIndex() gets the index of the selected item in hte list
getSelectItem() gets the selected item in the corresponding list
select(int index ) selects the item at the specified index in the corresponding list
setMultipleMode(boolean b) Sets the flag that allows multiple selection in the corresponding list

6)Scrollbar
constructor
Scrollbar() constructs a vertical scroll bar
Scrollbar(int orientation) Construct a new scrollbar with the specified orientation
Scrollbar(int orientation,int maxvalue,int visible,int minimum,int maximum)
constructs a new scroll bar with the specified orientation initial value page size,minimum and maximum values

Method
getBlockIncrement() gets teh block increment of the corresponding scroll bar
getMaximum() gets the maximum value of the corresponding scroll bar
getMinimum() gets the minimum value of the corresponding scroll bar
getOrientation() determines the orientation of the corresponding scroll bar
getValue() gets teh current value of the corresponding scroll bar
setBlockIncrement(int v) sets the block increment for the corresponding scroll bar
setMaximum(int newMaximum) sets the maximum value for the corresponding scroll bar
setMinimum(int newminimum) sets the minimum value for the corresponding scroll bar
setVale(int newvalue) sets the value of the corresponding scroll bar to the specified value

7)TextField
Constructor
TextField() constructs a new text field
TextField(int columns) creates a new text field with the specified number of columns
TextField(String text) Constructs a new text field initialized with the specified text
TextField (String text,int columns) Constructs a new text field initialized with the specified text with the specified number of columns

Methods
getColumns() gets the number of columns in the corresponding text field
getEchoChat() get the character that is to be used for echoing
setColumns(int columns) sets the number of columns in the text field
setEchoChar(char c) sets the echo character for the text field
setText(String t) sets the test that is presented by hte corresponding text component to be the specified text

8)TextArea
constructors
TextArea() Constructs a new text area
TextArea(int rows, int columns) Constructs a text area with the specified number of rows and columns
TextAra(String text) Constructs a new new text area with the specified text
TextArea(String text int rows,int columns) constructs a new text area with the specified text, and specified number of row and columns
TextArea(String text int rows int cols, int scrollbar) Constructs a new text area with the specified text and specified text and specified number of rows and columns and visibility of the scrollbar

Methods
append(string str) appends the given text to the xtext area’s contents
getColumns() gets the number of the text area
getMinimumSize() determines the minimum area of the text area
getRows() gets the number of rows in the text area
insert(String str, int pos) inserts the specified string at the specified position
setColumns(int columns) set the number of columns for the text area
setRows(int rows) sets the number of rows for the text area

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class listtext extends Applet
{
List acts=new List();
TextField tx=new TextField(10);
Button add=new Button(“add”);
String stringlist[]={“one”,”two”,”three”};
public void start()
{
add(new Label(“text”));
add(tx);
for(int i=0;i<stringlist.length;i++)
acts.addItem(stringlist[i]);
add(acts);
add.addActionListener(new Add());
add(add);
}
class Add implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
acts.addItem(tx.getText());
}
}
}

===============================================================================================
Panel
The panel object can contain other ui components is unvisible window in applet
Panel p1=new Panel();
setLayout(p1);
p1.add()

================================================================================================
Container
the Component(UI) is drawn inside the Container. A container represents the positioning the ui

1)Canvas
A canvas component represents a blank rectangular area of the scren onto which the application
can draw or from whickh the application can trap input events from the user
canvas are good for paintaing a graphics.

Constructor
Canva() Constructs a new canvas
Methods
addNotify() Creates a peer of the canvas
paint(Graphics g) this method is called to repaint the corresponding canvas

2) Window
Window is displayed in desktop to to draw the sub window you have to draw Frames or dialog

1) Frames
it is same like window

Constructor
Frame()
Frames(String title)

Methods
dispose() To close frame window
getTitle(0 to get the title of the frame window
isResizeable() it takes a boolean value
resize(horizontal size,vertical size) it sets a new dimension to the frame according to the pixcel
setTitle(String str) to set the title of frame window
show() to show the frame
setVisible(boolean) makes the frame or window visible
setSize(Dimension d) set the size
setLocation(int,int) set the location of window
getLocation() returs the point objects of window

import java.awt.*;
import java.awt.events.*;
class frameapp extens Frames
{
boolean a;
frameapp()
{
a=false;
setTitle(“stand-alone application”);
addWindowListener(new w());
}
class w extends wWindowAdapter
{
public void windowClosing(WindowEvent e)
{
if(a)
dispose();
else
System.exit(0);
}
}

public static void main(String args[])
{
frameapp fn=new frameapp();
fn.setSize(300,300);
fn.setVisible(true);
}
}

2) FileDialog
Constructor
FileDialog(Frame parent) creates file dialog for loading a file
FileDialog(Frame parent),string title) creates a file fialog window with the specified title for loading a file
FileDialog(Frame parent, String title,int mode) Creates a file dialog window with the specified title for loading or saving file.

Methods
getDirectory() gets the directory of the corresponding file dialog
getFile() gets the file of the corresponding file dialog
getFilenameFilter() Determines the file dialog’s filename filter
getMode() Indicates whether the file dialog is in the save mode or open mode
setDirectory(string str) sets the directory of the file dialog window to the one specified
setFile(String file) set the selected file for the corresponding fiel dialog window to the one specified
setFilenameFilter(filenamefilter filter) set the filename filter for the specified dialog window to the specified value
setMode(int Mode) set the mode of the file dialog .

3)ScrollPane
is container class with implements auomatic horizontal ad or vertical scrolling for a single
child component.

Constructor
ScrollPane() Create a new scroll pane container with the scroll bar policy of “as needed”
ScrollPane(int Scrollbardisplaypolicy) creates a new scrolpane container
getScrollbarDisplayPolicy() returns teh display policy for the corresponding scroll bars
setScrollPositionint x,int y) Scrolls to the specified position within the child component

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Layout Manager
1) Flow layout
2)BorderLayout
3) gridlayout

1) like word processor. the flow layout lays out components linewise from left to right when the line of
components is filled , flow layout creates a new line and continues laying out components on the next line

constructor
FlowLayout() Constructs a new flow layout with centered alignment leaving a vertical and horizontal gap of 5 pixels
FlowLayout(int align) Constructs a new flow layout with the alignment specified leaving a vertical and horizontal gap of 5 pixels
FlowLayout(int align,int vgap,int hgap) constructs a new flow layout with the alignment specified leaving a vertical and horizontal pag as specified

methods
getAlignment() gets the alignment for the layout
getHgap() get the horizontal gap between components
getVgap(0 gets the vertical gap between components
setAlignment(int align) set the alignment for the specified layout
setHgap(int hgap) set the horizontal gap for the specified layout
setVgap(int vgap) set the vertical gap for the specified layout

2)Grid Layout
The gridlayout class is like spreadsheet int rows and columns. specifying number of row and columns
in the grid creates the gridlayout.the components in a grid are resized to fit their cell. all the
components in a grid are the same size.

Constructor
GridLayout() creates a gridlayout with a default of one column per component in single row
GridLayout(int rows,int cols) Creates a grid layout with the specified rows and columns
GridLayout(int rows,int cols,int hgap,int vgap) Creates a grid layout with the specified row and columns
and specified horizontal and vertical gap

Methods
getColumns() gets the number of columns in coresponding layout
getRows() gets the number of rows in the corresponding layout
getHgap(0 get s the horizontal gap for the corresponding layout
setColumns(int cols) set the number of columns to the specified number in the corresponding layout
setHgap(int hgap) sets the horizontal gap to the value specified in the corresponding layout
stVgap(int vgap) sets the vertical gap to the value specified in the corresponding layout
setRows(int rows) sets the number of rows in the corresponding layout to the specified value

3)Border layout
with border layout the placement the component is specified as being north south east and west the boreer
alyout resizes the crenter component to fill the remaining center spaces

BorderLayout() creates a new border layout with no gap between the components
BorderLayout(int hgap,int vgap) creates a border layout with the specified horizontal and vertical gap
between components

Methods
getHgap() returns teh horizontal gap between components
getVgap() returns teh vertical gap between components
setHgap() sets teh horizontal gap between components to the value specified
setVgap(int vgap) sets the vertical gap between components to the value specified

add(“East”,mybutton);

import java.awt.*;
public class bordertest extends java.applet.Applet
{
public void init()
{
setLayout(new BorderLayout(5,5));
ad(“South”,new Button(“Buttom of the applet”));
add(“North”,new Button(“Top of the applet”));
add(“East”,new Button(“Right “));
add(“West”,new Button(“Left”));
add(“Center”,new TextArea(“Appears at the center”));
}
public Insets getInsets()
{
return new(Insets(20,20,10,10);
}
}

==============================================================================================
Menus
Menubar class
is the top most element displayed along the top of the window to which it belongs
Menubar mb=new Menubar();
myframe.setMenubar(mb);

Menu class
the menu class is used to implement a pull down menu that provides a number of items to select from.
Menu m=new Menu(“File”);
m.add(“open”);
m.add(“close”);
m.add(“exit”);

mb.add(m);

methods of menu
add(MenuItem) Adds the specified Menu item to the menu
add(String) Adds the specified string to menu.
addSeparator() adds a separator to the menu
getItem(int) returns teh item at the specified index as a Stirng
remove() deletes the item index from menu

MenuItem class
Teh menu Item class encapsulates the functionallity of the lower most components of the menu system
MenuItem mitem1=new MenuItem(“open”);
m.add(mitem);

Methods
getLabel() returns the label of the menuItem as a string
setLabel(String) change teh label of the menuitem to specified string
setEnabled(boolean) makes the menu item selectable /deselectable depending on whether the parameter is true or false

The ChecboxMenuItem classs
the CheckboxMenuItem creates a dual state menu item. it can be toggles on and off by clicking it

CheckboxMenuItem(string)
CheckboxMenuItem cmi=new CheckboxMenuItem(“view text”)

methods
getState() returns the state of the menu item as boolean value a value of true implies that the checkbox
menu item is selected
setState(boolean) Sets teh state of the menuitem if the value passed is true the menu item is set to selected state

import java.awt.*;
import java.awt.event.*;
public class MenuApplication extends Frame implements ActionListener,ItemListener
{
boolean inAnApplet=true;
TextArea output;
PopupMenu popup;
String newline;
public MenuApplication()
{
MenuBar mb;
Menu m1,m2,m3,m4,m4_1,m5;
MenuItem m1_1,m1_2,m3_1,m3_2,m3_3,m3_4,m4_1_1,m5_1,m5_2,pm1,pm2,m5_1_duplicate;
CheckboxMenuItem m2_1;
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
if(inAnApplet)
{
dispose();
}
else
{
System.exit(0);
}
}
});
newline=System.getProperty(“line.separator”);
setLayout(new BorderLayout());
output=new TextArea(5,30);
output.setEditable(false);
add(“Center”,output);
Label label=new Label(“Try bringing up”+” a popup menu!”);
add(“North”,label);
mb=new MenuBar();
setMenuBar(mb);

m1=new Menu(“Menu1″,true);
mb.add(m1);
m1_1=new MenuItem(“Menu item 1_1″);
m1.add(m1_1);
m1_2=new MenuItem(“Menu item 1_2″);
m1.add(m1_2);

m5=new Menu(“Help”);
mb.setHelpMenu(m5);
m5_1=new MenuItem(“menu item 5_1″);
m5_1.setShortcut(new MenuShortcut(KeyEvent.VK_5));
m5.add(m5_1);
m5_2=new MenuItem(“Menu item 5_2″);
m5.add(m5_2);
popup=new PopupMenu(“A popup menu”);
add(popup);
pm1=new MenuItem(“a popup menu item”);
popup.add(pm1);
m5_1_duplicate=new MenuItem(“Duplicate the menu item 5_1″,new MenuShortcut(KeyEvent.VK_5));
popup.add(m5_1_duplicate);
pm2=new MenuItem(“An item with a shortcust”,new MenuShortcut(KeyEvent.VK_6));
popup.add(pm2);
m2=new Menu(“Menu 2″);
mb.add(m2);
m2_1=new CheckboxMenuItem(“Menu item 2_1″);
m2.add(m2_1);

m3=new Menu(“Menu3″);
mb.add(m3);
m3_1=new MenuItem(“menu item 3_1″);
m3.add(m3_1);
m3_2=new MenuItem(“menu item 3_2″);
m3.add(m3_2);
m3.addSeparator();
m3_3=new MenuItem(“menu item 3_3″);
m3.add(m3_3);
m3_4=new MenuItem(“menu item 3_4″);
m3_4.setEnabled(false);
m3.add(m3_4);

m4=new Menu(“Menu4″);
mb.add(m4);

m4_1=new Menu(“Sub Menu 4_1″);
m4.add(m4_1);
m4_1_1=new MenuItem(“Menu item 4_1_1″);
m4_1.add(m4_1_1);

m1.addActionListener(this);
m2.addActionListener(this);
m3.addActionListener(this);
m4.addActionListener(this);
m4_1_1.addActionListener(this);
m5.addActionListener(this);
popup.addActionListener(this);
m1_1.setActionCommand(“1_1″);
m1_2.setActionCommand(“1_2″);
m5_1.setActionCommand(“5_1″);
m5_2.setActionCommand(“5_2″);
pm1.setActionCommand(“Pop item #1″);
m5_1_duplicate.setActionCommand(“5_1″);
pm2.setActionCommand(“popup item #2″);

m2_1.addItemListener(this);

MouseListener listener=new PopupListener();
addMouseListener(listener);
output.addMouseListener(listener);
label.addMouseListener(listener);
}

class PopupListener extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e)
{
maybeShowPopup(e);
}

private void maybeShowPopup(MouseEvent e)
{
if(e.isPopupTrigger())
{
popup.show(e.getComponent(),e.getX(),e.getY());
}
}
}

public void actionPerformed(ActionEvent e)
{
output.append(“\”"+e.getActionCommand()+”\” action detected in menu labeled \”"+((MenuItem)(e.getSource())).getLabel()+”\”.”+newline);
}

public void itemStateChanged(ItemEvent e)
{
output.append(“Item state change detected on item \”"+e.getItem()+”\”(state is “+((e.getStateChange()==ItemEvent.SELECTED)?”selected).”:”deselected).”)+newline);
}
public static void main(String arg[])
{
MenuApplication m=new MenuApplication();
m.inAnApplet=false;
m.setTitle(“Menu Application”);
m.setSize(450,200);
m.setVisible(true);
}
}

==============================================================================================

Continue Reading

Using Global/Distributed Transactions in Java/JDBC with Oracle Real Application Clusters

Posted on 18. Feb, 2008 by sabin.

0

This document describes some of the ways to leverage the high availability features of Oracle Real Application Cluster (RAC) databases by moving the load balancing functionality from the Oracle server/Oracle driver to your application. In this article, I discuss the ways to achieve load balancing of connections across RAC nodes and yet maintain the sticky nature to the same RAC node for the all of the participants of a single global transaction. I have used Java examples wherever possible, but most of the programming constructs can be mapped to other sufficiently advanced programming languages.

An Oracle Real Application Cluster database is a clustered database. A cluster is a group of independent servers that cooperate as a single system. Clusters provide improved fault resilience and modular incremental system growth over single, symmetrical multiprocessor systems. Oracle’s RAC page has more information on RAC technology.

A global transaction is a mechanism that allows a set of programming tasks, potentially using more than one resource manager and potentially executing on multiple servers, to be treated as one logical unit. Once a process is in transaction mode, any service requests made to servers may be processed on behalf of the current transaction. The services that are called and join the transaction are referred to as transaction participants. The value returned by a participant may affect the outcome of the transaction. A global transaction may be composed of several local transactions, each accessing the same resource manager. The resource manager is responsible for performing concurrency control and atomicity of updates.

Problems with Global Transactions and Oracle RAC

Problems occur when connections participating in a distributed transaction are routed to different instances of an RAC cluster. A split transaction is a distributed transaction that spans more than one instance of an RAC database. This implies that different branches of the same distributed transaction are located on different instances of an RAC database. This could result in erroneous situations, as follows:

  • During normal operation: Neither branch can see changes made by the other branch. This can cause row-level lock conflicts amongst these branches, leading to ORA-2049 errors (timeout waiting for distributed lock).
  • During recovery operation: Failures can occur during two-phase commit (2PC). Sometimes 2PC requires its own connection to the database (e.g., an abort). In such cases, a 2PC operation may be attempted on a transaction branch at an instance where that branch does not exist, causing missing transaction errors (ORA-24756). This in turn leaves the branch hanging as an active branch to be cleaned up by the Process Monitor daemon (PMON). While the branch is active, it still holds row-level locks on all rows that it modified. Similarly, if the 2PC operation that failed is a commit, then in-doubt transactions can remain in the database. This can cause ORA-1591 errors when another transaction attempts to access data that has been modified by the in-doubt transaction. You can find more detailed explanation of this problem in Oracle’s “Best Practices for using XA with RAC” (PDF, 219 KB).

Recommended Approach

The following design forms the foundation of the recommended approach:

  • Create multiple pools, one for each RAC node in the cluster. I call each pool a node pool. For example, if you have three RAC nodes, create three node pools. All popular pooling components and application servers support creating multiple pools.
  • Disable server-side load balancing for each of the pools. Setting the INSTANCE_NAME attribute in your JDBC connect descriptor aliases will disable server-side load balancing. For example:
      jdbc:oracle:thin:@(DESCRIPTION=
        (ADDRESS_LIST=
          (ADDRESS=(PROTOCOL=tcp)(HOST=MYDBHOST1)(PORT=1522))
        )
        (CONNECT_DATA=
          (SERVICE_NAME=MYDB)(INSTANCE_NAME=MYDB1)
        )
      )

    If you miss the INSTANCE_NAME attribute in your JDBC connect descriptor, the Oracle TNS Listener could still redirect the connection request to some other instance, depending on the load on the instance in question.

  • Write a connection factory that does the following when a connection is requested:
    • Checks if a node pool is already associated with the thread.
    • If a node pool is not associated with the thread, randomly picks a pool from the available pools and associates the node pool with the thread.
    • If a pool is associated with the thread, just reuses the pool.
    • Depending on your application behavior (discussed later), disassociates the pool from the thread.

Multithreaded Application

In a multithreaded application, multiple threads are spawned to perform concurrent tasks. Usually global transactions have thread affinity; i.e., they are identified and associated by the threads in which they run. All connections participating in the same global transaction must be drawn from the pool or a data source in the same thread. You can maintain affinity to a node pool by associating the thread with the node pool. The connection factory responsible for providing the connection should then inspect the thread and reuse the node pool referenced in the thread space. The connection factory is allowed to randomly pick a pool only if there is no node pool associated with the thread. You can implement this in Java using the ThreadLocal class. When the connection factory requests a connection, it inspects the thread space to check if a node pool is associated with the thread; if there is, it reuses it. Otherwise, it randomly picks one.

/*
 * Method ConnectionFactory.getConnection
 */
Connection getConnection() {

  // nodePoolTracker is a ThreadLocal object
  // defined in the class definition
  NodePoolIndentifier poolId =
    (NodePoolIndentifier) nodePoolTracker.get();
  if (poolId == null) {
    // There is no node pool associated with
    // this thread, randomly pick
    // one and store it in the thread
    NodePool pool = getLeastLoadedInstacePool();
    nodePoolTracker.set(
      new NodePoolIdentifier(pool.getId());
    return pool.getConnection();
  }
  else {
    // get a reference to the pool
    NodePool pool = getPoolById(poolId);
    return pool.getConnection();
  }

}

The above method creates an affinity between the thread and the node pool. If your application spawns a new thread for every new task, you don’t need to manually clean up the thread space. However, for applications that have thread pools or reuse threads (like web servers, app servers, etc.), you need to manually clean up the thread space after each global transaction or task completion. This entirely depends on how you manage threads in your application. If you don’t clean up the thread space, the node pool will get associated with the thread for the complete lifespan of the thread, which may result in suboptimal load balancing across RAC instances.

Web Application

Modern web applications have a distinct advantage over standalone applications. They run in a managed environment which delegates most of the dirty work to the underlying application/web server. Here you can leverage an approach similar to standalone applications–using a thread pool–but by using HTTP filters, you can eliminate the problem with reusable threads by resetting the state of the thread in the HTTP filters.

You can do this using Java servlets as follows:

  • Configure custom servlet filters to intercept requests and responses from your applications.
  • Pick a node pool and set it in the ThreadLocal object in the in-filter before the request is sent to the actual request handler.
  • After the request handler processes the request (in the out filter), reset the thread state.

All of the connections for a particular request are directed to a single RAC instance. Alternatively, you can also use the request object to store the reference of the node pool rather then the ThreadLocal object. The downside of this approach is that you need to pass the request object to all of the components that draw a connection to the database.

Known Issues

This approach assumes a specific pattern in the life span of global transactions that happens to work with most popular applications. Some places where this would not work include:

  • Global transactions spanning multiple threads.
  • Multithreaded application reusing threads: this is kind of tricky, though not very dangerous. In this case, the node pool (RAC node) gets tightly coupled to the thread for the complete lifespan of the thread. You can still work around this problem depending on your application. For example, in a web server, you can have the request filters reset the thread state after each request. You will have to figure out your application-specific logic to reset the thread state after the thread has processed each request.
  • What happens if an RAC node goes down while the corresponding node pool is being used by some threads? I would still prefer to let the complete global transaction roll back and report the operation as a failed operation.

http://www.oracle.com/technology/products/database/clustering/pdf/TWP_RAC10gR2.pdf

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ThreadLocal.html

http://www.oracle.com/technology/products/database/clustering/pdf/bestpracticesforxaandrac.pdf

http://www.oracle.com/database/rac_home.html

http://smartpool.sourceforge.net/

package pooling;

import java.sql.*;
import java.util.HashMap;

/**
 * This class demonstrates the use of ThreadLocal to pin a particular connection to a RAC node.
 *
 */
public class RACConnectionFactory {

    /**
     * Instance connect descriptors to the database
     */
    private static final String url1 = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=MYHOST1)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=DEV)(INSTANCE_NAME=DEV1)))";
    private static final String url2 = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=tcp)(HOST=MYHOST2)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=DEV)(INSTANCE_NAME=DEV2)))";

    /**
     * Store the list of connections, ideally should store references to node pools
     */
    private HashMap poolMap = new HashMap();

    /**
     * Simple algo to keep track of which node is least used
     */
    private String lastNodePoolUsed = null;

    /**
     * Singleton pattern
     */
    private static RACConnectionFactory singletonFactory = null;

    private static boolean isDebug = true;

    /*
     *  Our Golden Horse, Thread local.
     */

    private static ThreadLocal nodePoolTracker = new ThreadLocal();

    /**
     * Easy method for logging
     */
    private static void log(String log) {
        if (isDebug) {
            System.out.println(log);
            System.out.flush();
        }
    }

    /**
     * Gets the instance name from the V$instance view, the connected user should have the required prevelige
     * @param conn
     * @return
     * @throws Exception
     */
    private String getInstanceName(Connection conn) throws Exception {
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            stmt  = conn.prepareStatement("select instance_name from v$instance");
            rs = stmt.executeQuery();
            if (rs.next()) {
                return rs.getString(1);
            }
            else {
                throw new Exception("No Rows found, should never happen");
            }
        }
        finally {
            stmt.close();
            rs.close();
        }
    }

    /**
     * Gets a connection from the database
     * @param url
     * @return
     * @throws Exception
     */

    private Connection getRawConnection(String url) throws Exception {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        return DriverManager.getConnection(url, "sachin", "sachin");
    }

    /**
     * Just returns the last not used pool
     * @return
     */
    private String getLeastLoadedPool() {
        if (lastNodePoolUsed == null) {
            lastNodePoolUsed = "1";
            return "1";
        }
        if (lastNodePoolUsed.equals("1")) {
            lastNodePoolUsed = "2";
            return "2";
        }
        else {
            lastNodePoolUsed = "1";
            return "1";
        }
    }

    private Connection getConnection(String poolId) {
        return (Connection)poolMap.get(poolId);
    }

    private RACConnectionFactory() throws Exception {

        Connection conn = getRawConnection(url1);
        // Validate that this connection is indeed gone to DEV1
        if (!(getInstanceName(conn).equalsIgnoreCase("DEV1"))) {
            throw new Exception("This was supposed to hit DEV1, actual: " + getInstanceName(conn));
        }

        // Not creating any pools, assume pools are of size 1 ;)
        poolMap.put("1", conn);

        conn = getRawConnection(url2);
        // Validate that this connection is indeed gone to DEV2
        if (!(getInstanceName(conn).equalsIgnoreCase("DEV2"))) {
            throw new Exception("This was supposed to hit DEV2, actual: " + getInstanceName(conn));
        }
        poolMap.put("2", conn);

    }

    /**
     * This method does all the work of getting the connection, sticking the poolid in to the thread ....
     * @return
     * @throws Exception
     */

    public synchronized static Connection getConnection() throws Exception {

        if (singletonFactory == null)
            singletonFactory = new RACConnectionFactory();

        String poolId = (String) nodePoolTracker.get();
        if (poolId == null) {
        // one and store it in the thread
            poolId = singletonFactory.getLeastLoadedPool();
            nodePoolTracker.set(poolId);
            log("No Pool Associated:" + Thread.currentThread().getId() + ", adding: " + poolId);
            return singletonFactory.getConnection(poolId);
        }
        else {
            log("Pool Associated:" + Thread.currentThread().getId() + ", " + poolId);
            return singletonFactory.getConnection(poolId);
        }

    }

    public static void main (String args[] ) throws Exception {

        log("main thread is: " +  Thread.currentThread().getId());
        TaskProcessor taskProcessor[] = new TaskProcessor[5];
        Thread threads[] = new Thread[taskProcessor.length];
        for (int i=0; i<taskProcessor.length; i++) {
            taskProcessor[i] = new TaskProcessor(i);
            threads[i] = new Thread(taskProcessor[i]);
            threads[i].start();
        }
        for (int i=0; i<taskProcessor.length; i++) {
            if (threads[i].isAlive()) {
                threads[i].join();
            }
        }

    }

    /**
     * Thread to run many concurrent connections
     */
    private static class TaskProcessor implements Runnable {

        private int number = 0;

        public TaskProcessor(int number) {
            this.number = number;
        }

        public void run() {

            try {

                log("Thread started: " + Thread.currentThread().getId());

                // Get a connection
                Connection conn = RACConnectionFactory.getConnection();

                // Sleep and yield so that other threads can run
                Thread.yield();
                //Thread.sleep(1000);
                Thread.yield();

                Connection conn1 = RACConnectionFactory.getConnection();

                log("Thread " + Thread.currentThread().getId() + ": First Con: " +  conn);
                log("Thread " + Thread.currentThread().getId() + ": Second Con: " +  conn1);

                //ideally we should be checking if both the connections have come from the same pool, but since this
                // is just a mockup and we are running a single connection pool, we will directly check if the connections are same references.
                if (conn1 != conn)
                    throw new Exception("Connections dont match: " + conn + ": " + conn1);

                log("Thread " + Thread.currentThread().getId() + " over");

            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }

    }

}

Assuming a 2 node Oracle RAC cluster , Give the connect url as

jdbc:oracle:thin:@
(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = host1-vip)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = host2-vip)(PORT = 1521))
(LOAD_BALANCE = yes)
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = db-service)
(FAILOVER_MODE =(TYPE = SELECT)(METHOD = BASIC)(RETRIES = 180)(DELAY = 5))
)
)

where host1-vip is virtual IP of node1
host2-vip is virtual IP of node2
db_service is the Service name of the database

Oracle Database Programming using Java and Web Services

http://db360.blogspot.com/2007/01/is-your-java-application-failoverproof.html

http://www.oracle.com/technology/tech/java/sqlj_jdbc/index.html

Continue Reading

Java data compression

Posted on 18. Feb, 2008 by sabin.

0

introductionDo you need the ability to add data compression to your enterprise application? Well, look no further because Java 1.1 provides a package for zip-compatible data compression. The new package, java.util.zip, allows software developers to read, create, modify and write PKZIP and GZIP compatible files.

This article will provide step-by-step examples for reading data from a ZIP file and writing data to a ZIP file. Also, the article will discuss the methods available for accessing property information for the compressed entries in a ZIP file.

The Benefits of Data Compression

By using the java.util.zip package, you will be able to incorporate sophisticated compression technology into your Java applications with minimal work. The package not only provides single file compression but you can also create multi-file archives. Since the ZIP files created by the package adhere to the ZIP standard, you will be able to use these files with the PKZIP utility.

Sample Application Using Data Compression

Smart E-mailer

You can use ZIP data compression to create a smart e-mail program. The e-mail program can be developed to have the following features:

  • automatic compression of outgoing attachments
  • automatic uncompression of incoming attachments
  • compress old e-mail messages

Normally, users attach very large word-processing or spreadsheet files to e-mail message. The e-mail program assists the user with compressing the file. Before sending out the message the e-mail program checks to see if the attached files are in a compressed format. If not, then the e-mail program automatically compresses the file in ZIP format.

The e-mail program also automatically unzips incoming attachments. The user simply sets a program option for unzipping files in a specific directory. Also, in order to conserve disk space, an archive feature is available to compress old e-mail messages. This will allow the user to conserve valuable disk space.

The user will benefit because the e-mail program has ZIP data compression built-in. Also, the user no longer has to fumble with an external ZIP utiliy.

The Components of a ZIP file

Before we get into the nuts-and-bolts of compressing and uncompressing data, we will discuss the components of a ZIP file. A ZIP file is composed of one or more compressed files. Refer to figure 1 for the ZIP file structure.

A compressed file is described by a zip entry. The zip entry contains information for the compressed file such as the file name, original size, compressed size and additional file details. In a later section, we will see how to access this information.

Uncompressing a ZIP file

Uncompressing a ZIP file is simply a matter of reading data from an input stream. In this example, we will write the code fragments to unzip the contents of a file secrets.zip. The five step process follows:

Step 1: Get the ZIP input stream

The java.util.zip package provides a class ZipInputStream for sequentially reading ZIP files. The constructor for this class accepts an InputStream object. As you can see, a ZipInputStream is created similar to other input streams.

fis = new FileInputStream(“secrets.zip”);

source = new ZipInputStream(fis);

Step 2: Get the zipped entries

Once the ZIP input stream is opened, then you can get each zip entry one at time. The getNextEntry() method returns a ZipEntry() object. If the end-of-file is reached then getNextEntry() will return null.

        while ( (theEntry = source.getNextEntry()) != null )
{
	// read the data
	//
	// more code to come
}

After the getNextEntry() method is called, then you can begin reading the data associated with this ZipEntry.

Step 3: Prepare the uncompressed output stream

Now is a good time to setup the uncompressed output stream. This code is placed inside of the while-loop from step 2.

fos = new FileOutputStream(theEntry.getName());

targetStream = new BufferedOutputStream(fos, DATA_BLOCK_SIZE);

A file output stream is created using the entry’s name. The method Entry.getName() will return the name of the entry which is the file name of the compressed file.

Step 4: Inside of the main while-loop, you can read source zipped data and write it to the uncompressed stream.

        while ((byteCount = source.read(data, 0, DATA_BLOCK_SIZE)) != -1)
{
	targetStream.write(data, 0, byteCount);
}

The read() method retrieves data from the source zipped input stream. This method will return the number of bytes read in. If end-of-file is reached, then the read() method will return a -1. For each block of data that is read in, it is then written to the uncompressed target stream.

Step 5: Close the input/output streams

After processing the data for each entry (ie reading and writing), the target stream is flushed and closed.

targetStream.flush();

targetStream.close();

Finally, after all entries are processed, the source input stream is also closed.

source.close();

Complete code example: JKUNZIP

Listing 1 contains a complete code example. The file jkunzip.java incorporates the above steps and works as a command-line decompression utility. You can compile the program by typing:

javac jkunzip.java

To test the jkunzip utility, you can enter the command below. You must provide a zip file name.

java jkunzip zipfile

Compressing data to a ZIP file

In order to compress data to a ZIP file, you can use the ZipOutputStream class. This class provides the functionality of writing the data in a compressed format. There is only a small amount of work required by the developer to create a ZIP file. The simple six step process is outlined below.

Step 1: Create the zip output stream

The java.util.zip package provides the class ZipOutputStream for writing ZIP files. The constructor for this class accepts an OutputStream object. Basically, you can pass the output stream of the file you are writing to. Here is an example of creating a ZIP file titled “modules.zip“:

fos = new FileOutputStream(“modules.zip”);
targetStream = new ZipOutputStream(fos);
targetStream.setMethod(ZipOutputStream.DEFLATED);

Notice the call to setMethod(). By passing the value of DEFLATED, the ZipOutputStream object will store the files in a compressed manner. By default, the compression method is set to ZipOutputStream.DEFLATED.

You also have the option of just storing the files in an uncompressed format. To accomplish this, you pass the value of ZipOutputStream.STORED to the setMethod() routine. However, when storing files in an uncompressed format, you must specify the CRC-32 checksum and the file size. Please reference the JDK 1.1 API for details on the CRC32 class.

You can also set the level of compression by calling the setLevel(int aLevel) method. The compression levels range from 1-9 with 1 being the weakest and 9 being the fastest level of compression.

Step 2: Open the source data file

Now that the target zip output stream is created, you can open the source data file. In this code example, the file “java_intro.ppt” is the source data file:

String dataFileName = “java_intro.ppt”;
fis = new FileInputStream(dataFileName);
sourceStream = new BufferedInputStream(fis);

Step 3: Create the zip entry

You will need to create a zip entry for each data file that is read. Recall from an earlier section that a zip entry contains file information such as the file name, original size, compressed size and additional details. Most of the zip entry information will be updated once the data is written to the zip output stream. Here is the code for creating a ZipEntry object:

    theEntry = new ZipEntry(dataFileName);

Step 4: Put the zip entry into the archive

Before you can write information to the zip output stream, you must first put the zip entry object that was created in Step 3.

    targetStream.putNextEntry(theEntry);

Step 5: Read source and write the data to the zip output stream

Finally, the coast is clear for you to read the source file and write the data. Since you are writing to a zip output stream, the data will be written in a compressed format without any additional work by you.

data = new byte[DATA_BLOCK_SIZE];
while ((bCnt = sourceStream.read(data, 0, DATA_BLOCK_SIZE)) != -1)
{
targetStream.write(data, 0, bCnt);
}

          targetStream.flush();

Step 6: Close the zip entry and other open streams.

You can close the zip entry when you are finished writing the data. By closing the zip entry, the ZipEntry object is updated with the compressed file size, uncompressed file size and other file related information. It is also a good idea to close any open streams.

targetStream.closeEntry();
targetStream.close();
sourceStream.close();

Complete code example: JKZIP

Listing 2 contains a complete code example. The file jkzip.java incorporates the above steps and works as a command-line compression utility. You can compile the program by typing:

javac jkzip.java

To test the jkzip utility, you can enter the command below. You must provide a zip file name and an optional list of files to compress.

java jkzip zipfile [files…]

Checking ZIP file properties

At any time, you can find out the properties of a given ZIP file. Recall that the ZIP file is composed of zip entries for each compressed file. The ZipEntry class has a number of useful methods for accessing compressed file details (see figure 2).


Here is a description of the popular methods available in the ZipEntry class:

Method Signature Description
public String getComments() Returns any additional comments that given for this zip entry
public long getCompressedSize() Returns the compressed size of the file in bytes.
public int getMethod() Returns the compression method: DEFLATED (for compressed files), STORED (for uncompressed files).
public String getName() Returns the name associated with the entry. This is usually the file name.
public long getSize() Returns the original file size in bytes. You can use this method in conjunction with getCompressedSize() to find out compression percentage.
public long getTime() Returns the date / time stamp of the file.

Here is a code sample that uses some of the above methods to display information for a given ZipEntry

System.out.print(theEntry.getSize() + “\t\t”);
System.out.print(theEntry.getCompressedSize() + “\t\t”);
System.out.println(theEntry.getName());

Complete code example: JKUNZIP

In the jkunzip program, functionality was added to display the contents of a given zip file. Refer to Listing 1 and view the listContents() method. You can use the “-v” option on the jkunzip program to list the zip file contents.

Compatibility Issues

The java.util.zip package is compatible with PKZIP version 2.04G. However, I encountered problems when using other zip utilities. For example, earlier versions of WinZip could not extract ZIP files created with java.util.zip. This problem was solved when I downloaded the latest version of WinZip, version 6.3. If you are going to share your ZIP files with others then be sure to test for compatibility with the various zip utilities.

Conclusion

As you can see, the java.util.zip package is easy to use. By following a simple six-step process, you can create, read and write ZIP files. You can easily tune the compression level of files to favor speed or size. The package allows you to take advantage of the many benefits of reading and writing ZIP files. Currently software companies are selling ZIP controls for Visual Basic and Delphi. I wonder who will ship the first JavaBean with ZIP functionality? Well, armed with the information in this article…it could easily be you!

import java.util.zip.*;
import java.io.*;
import java.util.*;

//  File:  jkunzip.java
//
/**
 *
 *  This class will allow you to perform basic pkzip compatible
 *  data uncompression. <p>
 *
 *  <p>
 *  The basic steps are: <br>
 *    1. get the zipped input stream <br>
 *    2. get the zipped entries <br>
 *    3. prepare the uncompressed output stream <br>
 *    4. read source zipped data and write to uncompressed stream <br>
 *    5. close the source and target stream <br>
 *
 *  <p>
 *  Command syntax <br>
 *  <pre>
 *  Usage: java jkunzip [-v] zipfile <br>
 *  where option includes: <br>
 *  -v List zip file contents <br>
 *  </pre>
 *
 *  <p>
 *  NOTE:  This version expands entries w/ directory structures.
 *
 *  @author Chad (shod) Darby,  darby@j-nine.com
 *  @version 3.13, 16 Sep 1999
 *
 */
public class jkunzip
{

  //-------------------------------------------------
  // DATA MEMBERS
  //
  protected String zipFileName;
  protected boolean showListingFlag = false;

  protected final int DATA_BLOCK_SIZE = 2048;

  //-------------------------------------------------
  //  CONSTRUCTORS
  //
  /**
   *
   *  The constructor is used to create a new jkunzip object based
   *  on the command line arguments. <br>
   *
   *  <p>
   *  Command syntax <br>
   *  <pre>
   *    Usage: java jkunzip [-v] zipfile <br>
   *      where option includes: <br>
   *        -v List zip file contents <br>
   *  </pre>
   *
   *  @param args a string array of command line arguments.
   *
   */
  public jkunzip(String args[])
  {

    parseCommandLineArgs(args);

    if (zipFileName == null)
    {
      System.out.println(getUsageString());
      System.exit(1);
    }
  }

  //-------------------------------------------------
  //  METHODS
  //
  /**
   *  Parses the command line arguments. <br>
   *
   *  @param args command line args as an array of strings.
   *
   */
  protected void parseCommandLineArgs(String args[])
  {
    String name;
    int length = args.length;

    // check if empty arguments
    if (length == 0)
    {
      System.out.println(getUsageString());
      System.exit(1);
    }

    if (length == 1)
    {
      if ( ! (args[0].equals("-v")) )
      {
        zipFileName = args[0];
        return;
      }
      else
      {
        System.out.println(getUsageString());
        System.exit(1);
      }
    }
    else
    {
      zipFileName = args[1];
      showListingFlag  = true;
    }

  }

  /**
   *
   *  Returns the usage string for this class.
   *
   *  @return Returns the usage string.
   *
   */
  protected String getUsageString()
  {
    String temp = null;

    temp =  "\nJKUNZIP ver 1.13\n\n";
    temp += "Usage: java jkunzip [-v] zipfile\n\n";
    temp += "where option includes:\n";
    temp += "-v\tList zip file contents\n";

    return temp;
  }

  /**
   *
   *  Lists the contents of the zipped file. <br>
   *
   *  @param zipFileName name of the zipped file.
   *
   */
  protected void listContents(String zipFileName)
  {
    ZipFile zf;
    ZipEntry theEntry;

    try
    {
      zf = new ZipFile(zipFileName);

      Enumeration entries = zf.entries();

      // display the listing header
      System.out.println("Length\t\tSize\t\tName");
      System.out.println("------\t\t----\t\t----");

      // list the contents of each zipped entry
      while (entries.hasMoreElements())
      {
        theEntry = (ZipEntry) entries.nextElement();
        System.out.print(theEntry.getSize() + "\t\t");
        System.out.print(theEntry.getCompressedSize() + "\t\t");
        System.out.println(theEntry.getName());
      }

    }
    catch (IOException exc)
    {
      exc.printStackTrace();
    }
  }

  /**
   *
   *  Performs the different switches for the jkunzip object. <br>
   *
   *  Determines if it should list contents or extract files. <br>
   *
   */
  public void unzipIt()
  {
    System.out.println("Searching ZIP: " + zipFileName + "\n");

    if (showListingFlag)
    {
      listContents(zipFileName);
    }
    else
    {
      extractFiles(zipFileName);
    }
  }

  /**
   *
   *  Extracts the files contained in the zipped file. <br>
   *
   *  <p>
   *  The basic steps are: <br>
   *    1. get the zipped input stream <br>
   *    2. get the zipped entries <br>
   *    3. prepare the uncompressed output stream <br>
   *    4. read source zipped data and write to uncompressed stream <br>
   *    5. close the source and target stream <br>
   *
   *  @param theZipFleName name of the zipped archive
   *
   */
  protected void extractFiles(String theZipFileName)
  {
    FileInputStream fis = null;
    ZipInputStream sourceZipStream;

	FileOutputStream fos = null;
	BufferedOutputStream targetStream;

	ZipEntry theEntry = null;
	String entryName = null;

    try
    {
      //  1. get the zipped input stream
      fis = new FileInputStream(theZipFileName);
      sourceZipStream = new ZipInputStream(fis);

	  //  2. get the zipped entries
	  while ( (theEntry = sourceZipStream.getNextEntry()) != null )
	  {

		entryName = theEntry.getName();

		//  3. prepare the uncompressed output stream
		try {
			fos = new FileOutputStream(entryName);
		}
		catch (FileNotFoundException exc) {
			// the directory is not created...so let's build it!
			buildDirectory(entryName);
			fos = new FileOutputStream(entryName);
		}

		targetStream = new BufferedOutputStream(fos, DATA_BLOCK_SIZE);

		System.out.println("\tUnzipping: " + theEntry);

		int byteCount;
		byte data[] = new byte[DATA_BLOCK_SIZE];

		//  4. read source zipped data and write to uncompressed stream
		while ( (byteCount = sourceZipStream.read(data, 0, DATA_BLOCK_SIZE)) != -1)
		{
		  targetStream.write(data, 0, byteCount);
		}

		//  5. close the target stream
		targetStream.flush();
		targetStream.close();
	  }

      //  close the source stream
      sourceZipStream.close();

    }

    catch (IOException exc)
    {
      exc.printStackTrace();
    }

  }

  /**
   *  Creates the directory structure
   */
  protected void buildDirectory(String entryName) throws IOException
  {
    StringTokenizer st = new StringTokenizer(entryName, "/");

    int levels = st.countTokens() - 1;
	StringBuffer directory = new StringBuffer();
	File newDir;

    for (int i=0; i < levels; i++) {
		directory.append(st.nextToken() + "/");
	}

	newDir = new File(directory.toString());
	newDir.mkdirs();

  }

  /**
   *  The main driver routine!
   */
  public static void main(String args[])
  {
    jkunzip myApp = new jkunzip(args);

    myApp.unzipIt();
  }
}
=================================================

 import java.util.zip.*;
import java.io.*;

//  File:  jkzip.java
//
/**
 *
 *  This class will allow you to perform basic pkzip compatible
 *  data compression. <p>
 *
 *  The basic steps are: <br>
 *    1.  Create the zip output stream  <br>
 *    2.  Open source data file  <br>
 *    3.  Create the zip entry  <br>
 *    4.  Put the entry  <br>
 *    5.  Read source and write the data to the zip output stream  <br>
 *    6.  Close the zip entry and other open streams  <br>
 *
 *  <p>
 *  Command syntax <br>
 *  <pre> Usage: java jkzip zipfile [files] </pre> <br>
 *
 *  <p>
 *  NOTE:  This version does not recurse sub-directories.
 *
 *  @author Chad (shod) Darby,  darby@j-nine.com
 *  @version 1.13, 27 Sep 97
 *
 *
 */
public class jkzip
{

  //-------------------------------------------------
  // DATA MEMBERS
  //
  String archiveFileName;
  String fileNamesArray[];

  //-------------------------------------------------
  //  CONSTRUCTORS
  //
  /**
   *
   *  The constructor is used to create a new jkzip object based
   *  on the command line arguments. <br>
   *  Usage: <pre>  java jkzip zipfile [files] </pre> </b> <br>
   *
   *  @param args - a string array of command line arguments.
   *
   */
  public jkzip(String args[])
  {
    if (args.length == 0)
    {
      System.out.println(getUsageString());
      System.exit(1);
    }

    archiveFileName = args[0];

    // create the fileNames array
    //
    // if user supplied list of file(s) then args.length
    // will be greater than 1.
    //
    if (args.length > 1)
    {
      fileNamesArray = new String[args.length - 1];

      for (int j=0; j < fileNamesArray.length; j++)
      {
        fileNamesArray[j] = args[j+1];
      }
    }

    // if user didn't supply files then zip the entire directory
    //
    else if (args.length == 1)
    {
      File currentDirectory = new File(".");
      fileNamesArray = currentDirectory.list();
    }

  }

  //-------------------------------------------------
  //  METHODS
  //
  /**
   *  Reads the data source and writes the compressed file. <br>
   *
   *  <p>
   *  The basic steps are: <br>
   *    1.  Create the zip output stream  <br>
   *    2.  Open source data file  <br>
   *    3.  Create the zip entry  <br>
   *    4.  Put the entry  <br>
   *    5.  Read source and write the data to the zip output stream  <br>
   *    6.  Close the zip entry and other open streams  <br>
   */
  public void zipIt()
  {

    BufferedInputStream sourceStream;
    File theFile;
    FileInputStream fis;

    ZipOutputStream targetStream;
    FileOutputStream fos;
    ZipEntry theEntry;

    final int DATA_BLOCK_SIZE = 2048;
    int byteCount;
    byte data[];

    try
    {

      // 1.  create the ZipOutputStream
      //
      System.out.println("Creating ZIP: " + archiveFileName);
      fos = new FileOutputStream(archiveFileName);
      targetStream = new ZipOutputStream(fos);
      targetStream.setMethod(ZipOutputStream.DEFLATED);

      // loop thru the array
      for (int i=0; i < fileNamesArray.length; i++)
      {

        theFile = new File(fileNamesArray[i]);

        //  check if file is a directory, if so then skip
        if (theFile.isDirectory())
        {
          // i won't recurse directories so let's skip
          System.out.println("\tSkipping directory: " + theFile);
          continue;
        }

        // 2.  open source file
        //
        fis = new FileInputStream(fileNamesArray[i]);
        sourceStream = new BufferedInputStream(fis);

        // 3.  create the ZipEntry
        //
        theEntry = new ZipEntry(fileNamesArray[i]);
        System.out.print("\tAdding: " + theEntry.getName());

        // 4.  put the entry
        //
        targetStream.putNextEntry(theEntry);

        // 5.  read source data and write target data
        //     to compressed output stream
        //
        data = new byte[DATA_BLOCK_SIZE];

        while ( (byteCount = sourceStream.read(data, 0, DATA_BLOCK_SIZE)) != -1)
        {
          targetStream.write(data, 0, byteCount);
        }

        targetStream.flush();

        // 6.  close the entry
        //
        System.out.println(", done.");
        targetStream.closeEntry();

        sourceStream.close();

      } // end for loop

      targetStream.close();

    }

    catch (IOException e)
    {
      e.printStackTrace();
    }

  }

  /**
   *
   *  Returns the usage string for this class.
   *
   *  @return Returns the usage string.
   *
   */
  public String getUsageString()
  {
    String temp = null;

    temp  =  "\nJKZIP ver 1.13\n\n";
    temp +=  "Usage: java jkzip zipfile [files]\n";

    return temp;
  }

  public static void main(String args[])
  {
    jkzip myApp = new jkzip(args);

    myApp.zipIt();
  }

}

							
                            

Continue Reading

Servlet Applet Communication

Posted on 18. Feb, 2008 by sabin.

0

Introduction Java servlets provide a new and exciting method of developing server-side solutions. Servlets provide the features of traditional CGI scripts with the added benefits of efficiency and portability. Currently, major corporations are making the migration from CGI scripts to Java servlets. As a result, the demand for applet and servlet communication is on the rise.

This article is the third in a three-part series on Java servlets. In the Feb 98 issue of JDJ, I presented you with a 3-tier database application that used Java servlets. In this article, you will learn how to build a 3-tier database application that allows a Java applet to perform two-way communication with a Java servlet. I will focus on the concepts and techniques of applets communicating with servlets. The article will build on the 3-tier application presented in the previous article. However, if you are a newcomer and missed the previous article, don’t worry because I’ll give a review of the application.

Reviewing our Student Tracker Application

Our previous article presented a 3-tier database application that used Java servlets and the Java Database Connection (JDBC). The application allows a public speaker to keep track of students who attends her seminars. Students interact with the application by entering their contact information into an HTML form. Once the form is submitted then the Java servlet uses JDBC to store the student information in a database. Afterwards, an updated student list is generated by the servlet and returned as an HTML page to the user.

The application is partitioned into three tiers: user interface layer, the business rules layer and the data store layer. Figure 1 illustrates the three-tier design.

The first tier is a web browser, which serves as our universal client. In the first phase of the application, an HTML front-end was used for user-input and displaying the database query results. The HTML approach was taken because it lowered the requirements of the client’s web browser version. By taking this low-tech approach, the application was accessible to users who had browsers that were not Java 1.1 enabled.

The second tier of the application is implemented with a Web server capable of executing Java servlets. The Java servlet harnesses the power of JDBC to access the database to store/retrieve information as needed. A dynamic HTML page is generated by the servlet based on the database results.

The third tier is composed of our back-end database server. The database server stores the information that is used by the application. Thanks to the JDBC API, the servlet can access the database in a portable fashion by using the SQL call-level interface.

Developing an Applet Front-end

In order to enhance the student tracking system, we will develop an applet front-end. The students can now enter their contact information into a Java dialog box. Also, an updated student list is displayed in a Java list component. Figure 2 below shows the new applet front-end.


Applet-Servlet Communication with HTTP GET and POST

In the previous version, the HTML form was used to submit the student’s data to the servlet. Accessing the form data on the server side was simple and straightforward. This was accomplished by calling the method HttpRequest.getParameter( “<form field name>”) which is available in the Java Servlet API.

However, we are now using an applet front-end and we need a mechanism for the applet to communicate with the servlet. We need to capture the information a student enters and somehow pass this information to the servlet. Since servlets support the HTTP/CGI interface, we can communicate with the servlet over HTTP socket connections. The applet simply has to open a connection to the specified servlet URL. Once this connection is made, then the applet can get an output stream or input stream on the servlet.

The applet can send data to the applet by sending a GET or a POST method. If a GET method is used, then the applet must URL encode the name/value pair parameters into the actual URL string. For example, if we wanted to send the name/value pair of LastName=Jones, then our servlet URL would resemble:

http://www.foo.com/servlet/TestServlet?LastName=Jones

If you have additional name/value pairs, then they are separated by an ampersand (&). So, adding an additional name/value pair of FirstName=Joe, then our revised servlet URL would resemble:

http://www.foo.com/servlet/TestServlet?LastName=Jones&FirstName=Joe

In our application, we would have to URL encode each name/value pair for the student’s contact information. To send a GET method to a servlet, the applet can use the java.net.URLConnection class. The code fragment below shows you how.

String location = “http://www.foo.com/servlet/TestServlet?LastName=Jones”;
URL testServlet = new URL( location );
URLConnection servletConnection = testServlet.openConnection();
inputStreamFromServlet = servletConnection.getInputStream();

// Read the input from the servlet.
. . .

Once the applet has opened a connection to the URL, then the input stream from the servlet is accessed. The applet can read this input stream and process the data accordingly. The type and format of the data returned depends on the servlet. If the servlet is returning custom information, then the creation of a custom messaging protocol is needed for the applet and servlet to communicate. However, I will not get into the details of a custom protocol because I’ll present an elegant solution later in the article.

To POST data to a servlet, the java.net.URLConnection class is used again. However, this time, we must inform the URL connection that we will send data over the output stream. The POST method is powerful because you can send any form of data (plain text, binary, etc). All you have to do is set the content type in the HTTP request header. However, the servlet must be able to handle the type of data that the applet sends.

The code fragment below shows how to send a POST method to a servlet URL. The details of transmitting the data are discussed later in the article.

// connect to the servlet
String location = “http://www.foo.com/servlet/TestServlet”;
URL testServlet = new URL( servletLocation );
URLConnection servletConnection = testServlet.openConnection();

// inform the connection that we will send output and accept input
servletConnection.setDoInput(true);
servletConnection.setDoOutput(true);

// Don’t use a cached version of URL connection.
servletConnection.setUseCaches (false);
servletConnection.setDefaultUseCaches (false);

// Specify the content type that we will send binary data
servletConnection.setRequestProperty
(“Content-Type”, “<insert favorite mime type>”);

// get input and output streams on servlet
. . .

// send your data to the servlet
. . .

As you can see, applets can communicate with servlets using the GET and POST method. However, when the applet sends data using a GET method, then it must URL encode each name/value pair.

Communicating w/ Object Serialization

In our application, we would like to provide a higher level of abstraction. Instead of passing each parameter of student information (i.e. last name, first name) as name value pairs, we would like to send it as a true Java object. Our Java application already has a Student class that encapsulates all of the information about a student (see Listing 1). This information is gathered from the New Student dialog box and a Student object is created. When we register a new student, we would like to simply send the Student object to the servlet. Upon receipt of the Student object, the servlet would add the new student to the database. Also, it is our desire for the servlet to send the applet an updated student list as a vector of student objects. This will allow the applet to quickly and easily display the student list.

How can we accomplish this you ask? Easy, thanks to Java’s object serialization. Java 1.1 introduced object serialization, which allows an object to be flattened and saved as a binary file. The values of the data members are saved so in fact, the state of the object is persisted or serialized. At a later time, the object can be loaded or deserialized from the binary file with the values of its data members intact. Object serialization is fascinating in that it frees the developer from low-level details of saving and restoring the object.

You may wonder how does this relate to applet-servlet communication? Well, object serialization is not limited to binary disk files. Objects can also be serialized to any output stream. This even includes an output stream based on a socket connection. So, you can serialize an object over a socket output stream! As you’ve probably guessed by now, a Java object can also be deserialized or loaded from a socket input stream.

In order for a Java object to be serializable, its class must implement the java.io.Serializable interface. However, you will not have to actually implement any methods for this interface because the interface is empty. The java.io.Serializable interface is simply a tag for the Java Virtual Machine. We can create a custom class as follows:

class Foo implements java.io.Serializable
{
// normal declaration of data members,
// constructors and methods
}

The code fragment below shows you how to serialize an object to an output stream. In this example, we already have a socket connection to a host machine and we are simply serializing the object, myFoo.

outputToHost = new ObjectOutputStream(hostConnection.getOutputStream());

// serialize the object
Foo myFoo = new Foo();
outputToHost.writeObject(myFoo);
outputToHost.flush();
outputToHost.close();

Notice in the example that an ObjectOutputStream is created. This class is responsible for serializing an object. The object is actually serialized when the writeObject() method is called with the target object as its parameter. At this time, a binary image of the object is written to the output stream. In this case, the output stream is based on a socket connection.

However, this example would not be complete without code on the host machine to read the serialized object. The code fragment below shows you how to deserialize an object from an input stream.

inputFromClient = new ObjectInputStream(clientConnection.getInputStream());

// deserialize the object, note the cast
Foo theData = (Foo) inputFromClient.readObject();
inputFromClient.close();

An ObjectInputStream is created based on the client’s socket connection. The object is deserialized by simply calling the readObject() method. However, we must cast the object to its appropriate class, in this case, the class Foo. At this point, the object is available for normal use.

As you can see, object serialization is very straightforward and easy. Now, we’ll use this technology to pass objects back and forth between our applet and servlet.

Sending Objects from an Applet to a Servlet

With the information presented so far, we can send a Java object to a servlet. In our Student Tracking application, the applet sends a Student object to the servlet when a new student is registered. Figure 3 displays the object interaction between the servlet and the applet.


The code fragment shown in Listing 2 is used by the applet to send the Student object to the servlet. The applet is actually sending a POST method to the servlet. This client-side code fragment opens a URL connection to the servlet URL. We inform the servlet connection that we are sending output data over the connection and receiving input. Methods are also called such that the connection will not use cached versions of the URL. An important call in this code fragment is setRequestProperty(…). This method sets the content-type in the HTTP request header to the MIME-type application/octet-stream. The application/octet-stream MIME-type allows us to send binary data. In our case, the binary data is our serialized Student object. The next couple of statements creates an ObjectOutputStream and actually writes the object to the connection stream.

However, we are not yet finished. Recall that our application is in the process of registering a new student. The servlet must read this student object and update the database accordingly. Thus, we need code on the server side to receive a serialized Student object.

The code fragment in Listing 3 displays the servlet code for reading a Student object from an applet. The servlet handles POST methods by implementing the doPost() method. The servlet acquires an ObjectInputStream from the requesting applet. From there, it is simply a matter of reading the Student object from the stream. At this point, the Student object is loaded and available for registration in the database. Please make note of the small number of statements on the server-side for reading in a serialized object. You must agree that it is quite simple and straightforward.

Sending Objects from a Servlet to an Applet

In our Student Tracking application, the servlet is now capable of receiving a student object and registering them in the database. Now, the servlet must return an updated list of registered students. The updated student list is returned as a vector of student objects. This interaction is also illustrated in Figure 3.

When the servlet returns the vector of student objects, there is no need to iterate through the vector and serialize each Student object individually. The servlet can simply serialize the entire vector in one step, since the class java.util.Vector also implements the java.io.Serializable interface.

The code fragment shown in Listing 4 is used by the servlet to send a vector of Student objects to the applet. The sendStudentList() method is passed an HttpResponse parameter and a vector of Student objects. Since the applet initiated the HttpRequest, the servlet can respond to the applet by using the HttpResponse parameter. Thus, an ObjectOutputStream to the applet is created based on the HttpResponse object. The student vector is actually serialized and sent to the vector with a call to outputToApplet.writeObject(studentVector).

As we’ve seen before, code is needed by the applet to handle the data being sent from the servlet. The code fragment shown in Listing 5 is used by the applet to read in a vector the Student objects from the servlet. The applet opens a URL connection to the servlet’s location. The necessary methods are called to ensure that the applet doesn’t use cached versions of the URL connection. Next, an ObjectInputStream is created based on the servlet’s input stream socket connection. Now, all of switches have been flipped and we can easily read in our vector of Student objects. Again, remember we have to cast the object to the appropriate type. Congratulations, you have successfully read in a vector of student objects. This vector is now available for refreshing the AWT List component.

Conclusion

This article went beyond the normal method of sending name/value pairs over the HTTP/CGI protocol. The techniques presented leveraged the features of Java object serialization. As you can see, this provided an elegant way of transmitting serialized Java objects over network connections.

However, I must inform you, this article only discussed communication using the HTTP/CGI protocol. There are a number of other mechanisms for applets to communicate with server-side processes. The first one that comes to mind is Java’s Remote Method Invocation (RMI).

RMI allows a client application to call methods on a remote object as if the object was local. In fact, RMI uses object serialization to pass objects back and forth between the client application and the remote object. All of the low-level details of network connections and serialization are hidden from the developer when using RMI. If your project requires a large amount of applet-servlet communication, I’d recommend that you take a close look at RMI and the features it has to offer.

The second mechanism of communicating with server-side process is CORBA (Common Object Request Broker Architecture). Like RMI, CORBA allows you to make method calls on remote objects. If you have legacy server-side code written in a different language, then you can wrap it as a CORBA object and expose its functionality. CORBA provides a rich framework of services and facilities for distributing objects on the network.

If you’d like to get further information on distributed computing with RMI and CORBA visit the web-sites listed at the end of this article.

By now, you should understand the concepts and techniques for communication between applets and servlets. In this article, I demonstrated how an applet uses a POST method to send a serialized object to a servlet. The appropriate server-side code for the servlet was provided for reading in a serialized object. Our Student Tracking applet used this communication method to send a true Java object to a servlet. The servlet was also enhanced to return a vector of student objects to the applet. Likewise, the appropriate applet code was provided for reading in a vector of student objects.

As you can see, applet and servlet communication is straightforward with the techniques presented in this article. You can now add an applet front-end to your servlet-based application.

URL References:
//  File:  Student.java
//  Listing 1
//

import java.sql.*;
import javax.servlet.http.*;

/**
 *  The Student class has data members to describe
 *  a student.  String methods are available to
 *  display the data members to the console or web page.
 *
 *  @author Chad (shod) Darby,  darby@j-nine.com
 *  @version 0.6, 5 Jan 1998
 *
 */
public class Student implements java.io.Serializable
{
    // data members
    protected String lastName;
    protected String firstName;
    protected String company;
    protected String email;
    protected String courseTitle;
    protected String courseLocation;
    protected String expectations;
    protected java.sql.Date courseDate;

    protected final String CR = "\n";     // carriage return

    // constructors
    public Student()
    {
    }

    public Student(String aLastName, String aFirstName, String aEmail,
                   String aCompany, String aDate, String aCourseTitle,
                   String aCourseLocation, String aExpectation)
    {
        lastName = aLastName;
        firstName = aFirstName;
        email = aEmail;
        company = aCompany;

        courseDate = java.sql.Date.valueOf(aDate);
        courseTitle = aCourseTitle;
        courseLocation = aCourseLocation;
        expectations = aExpectation;
    }

    public Student(HttpServletRequest request)
    {
        lastName = request.getParameter("LastName");
        firstName = request.getParameter("FirstName");
        email = request.getParameter("Email");
        company = request.getParameter("Company");

        String dateString = request.getParameter("CourseStartDate");
        courseDate = java.sql.Date.valueOf(dateString);

        courseTitle = request.getParameter("CourseTitle");
        courseLocation = request.getParameter("CourseLocation");
        expectations = request.getParameter("Expectations");
    }

    public Student(ResultSet dataResultSet)
    {

        try {
            // assign data members
            lastName = dataResultSet.getString("LastName");
            firstName = dataResultSet.getString("FirstName");
            email = dataResultSet.getString("Email");
            company = dataResultSet.getString("Company");
            expectations = dataResultSet.getString("CourseExpectations");
            courseTitle = dataResultSet.getString("CourseTitle");
            courseLocation = dataResultSet.getString("CourseLocation");
            courseDate = dataResultSet.getDate("CourseStartDate");
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
    }

    //  accessors
    public String getLastName()
    {
        return lastName;
    }

    public String getFirstName()
    {
        return firstName;
    }

    public String getEmail()
    {
        return email;
    }

    public String getCompany()
    {
        return company;
    }

    public String getExpectations()
    {
        return expectations;
    }

    public String getCourseTitle()
    {
        return courseTitle;
    }

    public String getCourseLocation()
    {
        return courseLocation;
    }

    public Date getCourseDate()
    {
        return courseDate;
    }

    //  methods
    //  normal text string representation
    public String toString()
    {
        String replyString = "";

        replyString += "Name: " + lastName + ", " + firstName + CR;
        replyString += "E-mail: " + email + CR;
        replyString += "Company: " + company  + CR;
        replyString += "Course Expectations: " + expectations + CR;
        replyString += "Course Title: " + courseTitle + CR;
        replyString += "Course Location: " + courseLocation + CR;
        replyString += "Course Start Date: " + courseDate + CR + CR;

        return replyString;
    }

    //  returns data as HTML formatted un-ordered list
    public String toWebString()
    {
        String replyString = "<ul>";

        replyString += "<li><B>Name:</B> " + lastName + ", " + firstName + CR;
        replyString += "<li><B>E-mail:</B> " + email + CR;
        replyString += "<li><B>Company:</B> " + company  + CR;
        replyString += "<li><B>Course Expectations:</B> " + expectations + CR;
        replyString += "<li><B>Course Title:</B> " + courseTitle + CR;
        replyString += "<li><B>Course Location:</B> " + courseLocation + CR;
        replyString += "<li><B>Course Start Date:</B> " + courseDate + CR;

        replyString += "</ul>" + CR;

        return replyString;
    }

    // returns data formatted for an HTML table row
    public String toTableString(int rowNumber)
    {
        String replyString = "";
        String tdBegin = "<td>";
        String tdEnd = "</td>" + CR;

        replyString += "<tr>" + CR;
        replyString += tdBegin + rowNumber + tdEnd;
        replyString += tdBegin + lastName + ", " + firstName + tdEnd;
        replyString += tdBegin + "<a href=mailto:" + email + "> "
                               + email + "</a>" + tdEnd;

        replyString += tdBegin + company + tdEnd;
        replyString += tdBegin + expectations + tdEnd;
        replyString += "</tr>" + CR;

        return replyString;
    }
}

Listing 2

//  Listing 2
//
//  Applet client-side code to send a student object
//  to a servlet in a serialized fashion.
//
//  A POST method is sent to the servlet.
//

URL studentDBservlet = new URL( webServerStr );
URLConnection servletConnection = studentDBservlet.openConnection();  

// inform the connection that we will send output and accept input
servletConnection.setDoInput(true);
servletConnection.setDoOutput(true);

// Don't use a cached version of URL connection.
servletConnection.setUseCaches (false);
servletConnection.setDefaultUseCaches (false);

// Specify the content type that we will send binary data
servletConnection.setRequestProperty ("Content-Type", "application/octet-stream");

// send the student object to the servlet using serialization
outputToServlet = new ObjectOutputStream(servletConnection.getOutputStream());

// serialize the object
outputToServlet.writeObject(theStudent);

outputToServlet.flush();
outputToServlet.close();

Listing 3

//  Listing 3
//
//  Servlet server-side code to read a serialized
//  student object from an applet.
//
//  The servlet code handles a POST method
//
public void doPost(HttpServletRequest request,
                   HttpServletResponse response)
           throws ServletException, IOException
{
    ObjectInputStream inputFromApplet = null;
    Student aStudent = null;
    PrintWriter out = null;
    BufferedReader inTest = null;

    try
    {
        // get an input stream from the applet
	inputFromApplet = new ObjectInputStream(request.getInputStream());

        // read the serialized student data from applet
        aStudent = (Student) inputFromApplet.readObject();

        inputFromApplet.close();

	// continue the process for registering the student object

    }
    catch(Exception e)
    {
        // handle exception
    }
}
//  Listing 4
//
//  Servlet server-side code to send a serialized
//  vector of student objects to an applet.
//
//

public void sendStudentList(HttpServletResponse response, Vector studentVector)
{
     ObjectOutputStream outputToApplet;

     try
     {
         outputToApplet = new ObjectOutputStream(response.getOutputStream());

         System.out.println("Sending student vector to applet...");
         outputToApplet.writeObject(studentVector);
         outputToApplet.flush();

         outputToApplet.close();
         System.out.println("Data transmission complete.");
     }
     catch (IOException e)
     {
       e.printStackTrace();
     }
}

//  Listing 5
//
//  Applet client-side code to read a serialized
//  vector of student objects from a servlet.
//
//

// connect to the servlet
URL studentDBservlet = new URL( servletLocation );
URLConnection servletConnection = studentDBservlet.openConnection();  

// Don't used a cached version of URL connection.
servletConnection.setUseCaches (false);
servletConnection.setDefaultUseCaches(false);

// Read the input from the servlet.
//
// The servlet will return a serialized vector containing
// student entries.
//
inputFromServlet = new ObjectInputStream(servletConnection.getInputStream());
studentVector = (Vector) inputFromServlet.readObject();

download source appletservlet communication    
3 TIER
 figure1figure2figure3


Introduction

Currently, Java developers are delivering enterprise database applications. By using the Java Database Connection (JDBC) developers are able to query and update enterprise information stored in databases. However, the issue that continues to surface with database applications is performance. Application performance is critical when developing an enterprise application because typically the application sends database queries to a remote database server.

In a quest to increase performance, this article will discuss the Java classes available in the JDBC Application Programming Interface (API) for optimizing database access. There are two methods available for optimization: prepared statements and stored procedures. This article examines the implementation of prepared statements and stored procedures by analyzing a sample application.

The Consultant Job Selector Application

A technical recruiter to fill contracting positions primarily uses this application. The recruiter has the option to search for consultants with a maximum hourly rate and job category. Also, the recruiter has the capability to update the hourly rate for consultants in a given field. Figure 1 provides a snapshot of the database:


Figure 2 is a screen shot of the sample application.


The sample application is used to illustrate the implementation of prepared statements and stored procedures. Listings 1 – 5 contain the full source code for the sample application. The full source code can also be found at www.j-nine.com/pubs/javareport.

Analyzing the SQL Execution Plan

A SQL statement is used to access and update information stored in a database. When you submit a SQL statement, the database engine performs a number of steps in order to build an execution plan as shown in figure 3.


For every SQL statement submitted to the database, the execution plan is followed. The complete process is also followed if you submit the same SQL statement to the database engine.

Now let’s take a look at the “Consultant Job Selector” application. If the recruiter is searching for consultants with a maximum hourly rate of $50.00 to fill a Windows NT contract position, the application submits the following SQL statement to the database engine:

SELECT LastName, FirstName, Email, HourlyRate FROM consultantsWHERE HourlyRate <= 50.00 AND JobCategory = ‘Windows NT’; The JDBC code for this SQL statement follows: Connection connection = DriverManager.getConnection(databaseURL, userid, passwd);Statement searchStatement = connection.createStatement();ResultSet myResultSet = searchStatement.executeQuery (“SELECT LastName, FirstName, Email, HourlyRate ” +“FROM consultants ” +“WHERE HourlyRate <= 50.0 and JobCategory = ‘Windows NT’ “); If the recruiter made multiple queries using this statement, the database engine parses, compiles, plans and executes the statement each time. As you can see, this process is inefficient for multiple transactions with the same SQL statement.You can optimize the execution plan by parsing, compiling and planning the SQL statement ahead of time. Then when you submit the SQL statement again, you only have to perform the “execute” step of the SQL execution plan.Prepared StatementsA prepared statement is a pre-compiled SQL statement. The application sends the prepared statement to the database engine before the query is executed. This process allows the database engine to parse, compile and plan the query. Figure 4 illustrates the optimization of prepared statements.


When the same query is submitted again, the database engine only has to perform the “execute” step of the SQL execution plan. This minimizes the overhead of repeating the entire process for building an execution plan.

CAUTION: JDBC does not guarantee that the database engine will take advantage of prepared statements and provide this optimization. You should consult the technical documentation provided by your database vendor. Creating and Executing Prepared StatementIn order to create a prepared statement, you must call the prepareStatement(String sqlString) method of your Connection object. Sample code for preparing a statement to find all Windows NT consultants with maximum hourly rate of $50.00 follows: Connection connection = DriverManager.getConnection(dbURL, userid, passwd); searchPreparedStatement = connection.prepareStatement ( “SELECT LastName, FirstName, Email, HourlyRate ” +“FROM consultants ” +“WHERE HourlyRate <= 50.0 and JobCategory = ‘Windows NT’ “); The above statement is prepared during your application startup. This normally occurs after you have received your database connection from the driver manager. Repeat submissions of this query can be executed using the following code: ResultSet rs = searchPrepStmt.executeQuery(); Multiple submissions of the prepared SQL statement results in processing the “execute” step of the SQL execution plan only. This execution process effectively giving you the desired optimization. This optimization is useful in the “Consultant Job Selector” application because the recruiter normally makes multiple queries during an application session.Prepared Statement Limitations By now, you may have noticed the constraints imposed on the prepared statement. The prepared statement in the previous example is inflexible because the values for the hourly rate and job category are predefined. If the recruiter wanted to search for Windows NT consultants with a maximum hourly rate of $75.00, the program submits the following query SELECT LastName, FirstName, Email, HourlyRate FROM consultantsWHERE HourlyRate <= 75.00 AND JobCategory = ‘Windows NT’; Also during the same session, the recruiter may want to search for lower-paid Windows NT consultants with an hourly rate of $50.00. The program then submits an entirely different query SELECT LastName, FirstName, Email, HourlyRate FROM consultantsWHERE HourlyRate <= 50.00 AND JobCategory = ‘Windows NT’; Please note that the SQL statements differ only in the hourly rate. There may be situations in which you would like to make small modifications to the SQL statement before re-executing.Parameterized Prepared StatementsThe real power of a prepared statement is realized when used with parameters. Parameterized prepared statements gives you the ability to create a pre-compiled SQL statement and bind new parameter values prior to execution.Creating Parameterized Prepared Statements Now, let’s take the previous example a step further. The recruiter needs to submit a query based on their input of hourly rate and job category. Here is the code for creating parameterized prepared statements: searchPreparedStatement = connection.prepareStatement (“SELECT LastName, FirstName, Email, HourlyRate ” +“FROM consultants ” +“WHERE HourlyRate <= ? and JobCategory = ?”); Please make note of the question marks (“?”). The question marks serve as parameters or placeholders.Setting Prepared Statement ParametersIn order to set the parameters, the PreparedStatement class provides a collection of setXXX methods for setting strings, ints, and floats and other Java data types. public void setInt(int parameterIndex, int anInt)public void setString(int parameterIndex, String aString)public void setFloat(int parameterIndex, float aFloat)… many others available When the prepared statement, searchPreparedStatement, was created, two parameters were given. The first parameter was for the hourly rate and the second parameter was for the job category as shown below: searchPreparedStatement = connection.prepareStatement (“SELECT LastName, FirstName, Email, HourlyRate ” +“FROM consultants ” +“WHERE HourlyRate <= ? and JobCategory = ?”); Setting the parameter values is accomplished by binding a value to the parameter position. Parameter positions are numbered from left to right starting at 1.Given this information, the parameters for the prepared statement are set using the following code: searchPreparedStatement.setInt(1, theRate); // theRate is an intsearchPreparedStatement.setString(2, theJobCategory);// theJobCategory is a String To execute this SQL statement, use the following code: ResultSet myResultSet = searchPreparedStatement.executeQuery(); Now the SQL statements can be built based on the user input. The “Consultant Job Selector” prompts the recruiter for the hourly rate and job category. Given that information, the application uses the pre-compiled prepared statement and bind the user supplied data to the statement parameters. Figure 5 shows the dialog box for user input.


The recruiter can now retrieve a list of all Macintosh consultants whose hourly rate is $50.00 maximum and analyze the results of the query. If the recruiter would like to view consultants with a lower hourly rate, then he simply provides new values and the application binds these new values to the statement parameters.

Benefits of Using Parameterized Prepared Statements

By using parameterized prepared statements, the application can efficiently submit multiple queries to the database. The end user of the application, which was the recruiter in this example, received a quicker response from the database engine. As you can see, prepared statements with parameters give you the ability to create efficient pre-compiled SQL statements.

Stored Procedures

A stored procedure is pre-compiled SQL code that resides on the database server. They take input parameters and return a result.

Stored procedures are compiled only once in their lifetime. As a result, they actually execute faster than prepared statements. Recall that prepared statements need to build an execution plan each time the application is run.

In addition to the speed advantage, a stored procedure gives you the ability to centralize business logic. This centralization of the business logic directly supports reuse. By using stored procedures, you actually move complex business logic onto the database server as opposed to including it in every application you develop.

In the sample application, “Consultant Job Selector”, a stored procedure is used to update the hourly rates for a given job category. For example, the recruiter can increase the hourly rate of all Macintosh consultants to $60.00.

Creating A Stored Procedure

The task at hand is to create the stored procedure on the database server. Depending on your database, there is a different syntax for creating stored procedures.

CAUTION: Not all databases support stored procedures, namely MS Access. You can query the database metadata and see if stored procedures are supported. For example, the following is SQL code for creating the stored procedure sp_updateHourlyRate on an Oracle database: CREATE OR REPLACE PROCEDURE sp_updateHourlyRate( rate IN INTEGER,theJobCategory IN VARCHAR ) ISBEGINUPDATE consultants SET HourlyRate = rateWHERE JobCategory = theJobCategoryEND;

Once the SQL code for the stored procedure is successfully compiled, then it is callable by outside applications. The challenge now is to call the stored procedure from the “Consultant Job Selector” application.Calling Stored Procedures From JDBCIn order to call the stored procedure, you must use the CallableStatement available in the JDBC API. The following code creates a CallableStatement to access the stored procedure sp_updateHourlyRate. CallableStatement updateHourlyStatement;updateHourlyStatement = connection.prepareCall(“{call sp_updateHourlyRate [(?, ?)]}”); Passing Parameters To Stored Procedures At this point, you have a callable statement. However, you are not finished because you must bind values to the parameters. This process is very similar to setting parameters for prepared statements.So, to set the parameters for updating the hourly rate of Macintosh consultants to $60.00, you use the following code: updateHourlyStatement.setInt(1, 60); // set the rateupdateHourlyStatement.setString(2, “Macintosh”); // set the job category Once the parameters are set, you execute the statement using the following code:updateHourlyStatement.executeUpdate(); Getting Results From Stored ProceduresYou may have noticed that the stored procedure sp_updateHourlyRate only takes input parameters. You can modify the stored procedure to also return information to the calling application. This is accomplished by declaring an out parameter in the SQL code of the stored procedure. The SQL code for the revised stored procedure follows: CREATE OR REPLACE PROCEDURE sp_updateHourlyRate( rate IN INTEGER,theJobCategory IN VARCHAR,recordsAffected OUT INTEGER ) ISBEGIN… perform the update… count the changes and store result in parameter recordsAffected

END;

This revised stored procedure makes the updates and stores the number of updates in the recordsAffected out parameter. One additional step is required before calling the revised stored procedure. You must register the out parameters. Sample code follows for registering out parameters: updateHourlyStatement = connection.prepareCall (“{call sp_updateHourlyRate [(?, ?, ?)]}”); updateHourlyStatement.setInt(1, 50); // set the rate updateHourlyStatement.setString(2, “Macintosh”); // set the job category updateHourlyStatement.registerOutParameter(3, java.sql.Types.INTEGER) // set out param Now you can execute the stored procedure and get the results of the out parameter using the following code: updateHourlyStmt.executeUpdate();int theRecordsChanged = updateHourlyStmt.getInt(3); The point of this example was to illustrate the basic steps for getting results from stored procedures.Benefits Of Stored ProceduresEarlier in the section, you learned how stored procedures are used to increase execution speed and centralize business logic. Stored procedures also reduce network traffic because multiple, complex transactions are grouped into a single stored procedure. By having the SQL code pre-compiled as a stored procedure you effectively hide sensitive transaction information. This also reduces the amount of SQL code that you have to embed in your actual Java program. As you can see, stored procedures provide a number of advantages.

Conclusion

The sample application, “Consultant Job Selector”, was a good example of using prepared statements and stored procedures. The prepared statements were used in conjunction with parameters to provide dynamic SQL statements to the database engine. Also, stored procedures were used to centralize the business logic on the database server. The challenge now is to integrate these techniques in your next enterprise application to optimize database performance. Are you ready for the challenge?

Jobselect download code

Servlet Applet Communication

http://www.unix.org.ua/orelly/java-ent/servlet/ch10_01.htm

http://www.theserverside.com/discussions/thread.tss?thread_id=514

============================================================

Applet to Servlet

protected Vector getEmployeeList() throws Exception {
// create a reference to ObjectInputStream object
ObjectInputStream inputFromServlet = null;

// create a reference to a Vector,
// this will be used to keep the details of all employees
Vector employeeList = null;

// reference to Object class
Object obj = null;

// get the URLConnection to the servlet
URLConnection servletConnection = this.getURLConnectionToServlet();

// get the Object input stream
inputFromServlet = new ObjectInputStream(servletConnection.getInputStream());

// read the serialized object from the input stream, it may be a Vector
// or an exception.
obj = inputFromServlet.readObject();

// close the objectInputStream
inputFromServlet.close();

if (obj instanceof Vector) { // if it is a Vector type
// type cast it to a Vector and assign it to employeeList
employeeList = (Vector) obj;
} else if (obj instanceof Exception) {
//otherwise type cast it to Exception and throw that exception.
throw (Exception) obj;
}

// return employee list
return employeeList;
}

private URLConnection getURLConnectionToServlet(String urlParam)
throws Exception {
// Create a url request string
String location = URLString + “servlet/MainServlet” + urlParam;

// Create reference to URLConnection class
URLConnection servletConnection = null;

// Create a URL object for the given url
URL mainServlet = new URL(location);

// Open the conection to the servlet
servletConnection = mainServlet.openConnection();

// Set the connection to send output and accept input
servletConnection.setDoInput(true);
servletConnection.setDoOutput(true);

// Don’t use a cached version of URL connection.
servletConnection.setUseCaches(false);
servletConnection.setDefaultUseCaches(false);

// return the URLConnection object
return servletConnection;
}

===============================================

Servlet to Applet

protected void sendResponseToApplet(HttpServletResponse response) {
// Create a reference to ObjectOutputStream class
ObjectOutputStream outputToApplet = null;

try {
// Create ObjectOutputStream object
outputToApplet = new ObjectOutputStream(response.getOutputStream());
// Make a call to getAllEmployee function
Vector empList = this.getAllEmployee();

System.out.println(“Sending employee vector to applet…”);

// Write empList to outputToApplet object
outputToApplet.writeObject(empList);
// Flush and close the ObjectOutputStream
outputToApplet.flush();
outputToApplet.close();

System.out.println(“Data transmission complete…”);
} catch (Exception e) {
try {
outputToApplet.writeObject(new Exception(
“SQL Exception while fetching the Employee Details”, e));
// close and flush the ObjectOutputStream
outputToApplet.flush();
outputToApplet.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

private Vector getAllEmployee() throws SQLException {
// Create a vector object
Vector empVector = new Vector();

// Make a call to populateDataFromTable function of DbInteraction class
empVector = dbInteraction.populateDataFromTable();

// Return the Vector of all the employees
return empVector;
}

Continue Reading