Wednesday, February 2, 2011

Behavioral Design Pattern: State

State Design Pattern:

State pattern is to alter an object behavior when its state changes.

It is behavioral software design pattern.

Classic real time example of state pattern is ToggleButton which when press first becomes on and when press again becomes off.

So if you want to implement that toggle button you can use the state pattern so that its state change at runtime.

Following is the class diagram for the same.




(Click to Enlarge)

Code :
State

package com.milind.design.pattern.gof.behavioral;

/**
* This is the abstract state
* @author milind
*/
public interface ButtonState {

public void pressButton(ToggleButton btn);

}

Context

package com.milind.design.pattern.gof.behavioral;
/**
* This is the context which will be called by the client.
* @author milind
*
*/

public class ToggleButton {

private ButtonState state;

public ToggleButton() {
// Making the on state in begining
this.state = new OnState();
}

public ButtonState getState() {
return state;
}

public void setState(ButtonState state) {
this.state = state;
}

public void pressButton() {
this.state.pressButton(this);
}
}

Concrete On State:
package com.milind.design.pattern.gof.behavioral;

/**
* Concrete State
* @author milind
*/
public class OnState implements ButtonState{

public void pressButton(ToggleButton btn) {

System.out.println("Light Is Switched On ...");
btn.setState(new OffState());
}
}

Concrete Off State
package com.milind.design.pattern.gof.behavioral;

/**
* Concrete State
* @author milindaol
*/
public class OffState implements ButtonState{

public void pressButton(ToggleButton btn) {
System.out.println("Light Is Switched Off ...");
btn.setState(new OnState());
}

}

Client
package com.milind.design.pattern.gof.behavioral;
/**
*
* @author milindaol
*/
public class Client {

public static void main(String[] args) {

//Creating the Context
ToggleButton btn = new ToggleButton();
//Swithchin on the light.
btn.pressButton();
//Swithchin off the light.
btn.pressButton();
//Testing for three times
for(int i=0;i<3;>
btn.pressButton();
}
}
}





Monday, January 31, 2011

Callback in Java

Recently I was approached by my friend to explain him how callback can be achieved in Java. I told him to Google it and find out the stuff, but to my surprise there is no concrete use case available on net and this thought me of creating a blog on callback.


What is callback ?
Callback is typically delegating part of its execution to more appropriate owner rather than doing on its own. Just like SoC (Separation of Concern).

It is also useful in notifying other when something happens.

In C++ callback can be easily achieved by function pointer but it Java as there is no function pointer we need to achieve it through interface.

It is like listener which when register will invoke a particular method.

Use Case:

We will take use case of Bank which is one of my favorite also.

Lets say Bank as an entity want to concentrate on the clearing part debit/credit and what to separate out the transaction logging (Separation of Concern) to some one else.

So here the transaction logging system will be notified when any debit or credit happens.

Lets start with BankAccount entity.

This is just a plain POJO to hold the bank account data.

package com.milind.callback.Bank;

/**
*
* @author milind
*/
public class BankAccount {

private int balance;
private int accountNumber;

public int getAccNumber() {
return accountNumber;
}

public BankAccount(int accountNumber, int balance) {
this.accountNumber = accountNumber;
this.balance = balance;
System.out.println("Initial Balance: " + balance);
}

public int getBalance() {
return balance;
}

public void setBalance(int balance) {
this.balance = balance;
}
}

Now lets defined the event which we need to capture.

package com.milind.callback.Bank;

/**
*
* @author milind
*/
public interface BankAccountEvent {


public void creditEvent(BankAccount acc, int amt);
public void debitEvent(BankAccount acc, int amt);
}


Now lets have the Bank entity which will also be EventNotifier.
When ever any deposit or withdrawal happens it will notify the BankTransactionLogging System.

package com.milind.callback.Bank;
/**
*
* @author milind
*/
public class Bank {

private BankAccountEvent events;
public Bank(BankAccountEvent events) {
this.events = events;
}

/**
* Depositing in any account
* @param acc
* @param amount
*/
public void deposit(BankAccount acc, int amount) {
System.out.println("Depositing : "+amount + " in account No: "+acc.getAccNumber());
acc.setBalance(acc.getBalance()+amount);
events.creditEvent(acc, amount);
}

/**
* Crediting in any account
* @param acc
* @param amount
*/
public void withdraw(BankAccount acc, int amount) {
System.out.println("Withdrawing : " + amount + " from account No: " + acc.getAccNumber());
acc.setBalance(acc.getBalance() - amount);
events.debitEvent(acc, amount);
}
}

Finally BankTransactionLogging which will act as CallMe.

package com.milind.callback.Bank;
/**
*
* @author milind
*/
public class BankTransactionLogging implements BankAccountEvent{

private Bank bank;

public BankTransactionLogging() {

this.bank = new Bank(this);
}

/**
* This will be callback when any credit happens in Bank
* @param acc
* @param amt
*/
public void creditEvent(BankAccount acc, int amt) {

System.out.println("Credit Logging for Bank Account No: "+acc.getAccNumber()+" amount: "+amt);
}

/**
* This will be callback when any debit happens in Bank
* @param acc
* @param amt
*/
public void debitEvent(BankAccount acc, int amt) {
System.out.println("Debit Logging for Bank Account No: "+acc.getAccNumber()+" amount: "+amt);
}

}


Testing:
package com.milind.callback.Bank;

/**
*
* @author milind
*/
public class Main {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {

// Creating the Bank Account
BankAccount account = new BankAccount(501, 10000);
// Creating the transaction logging object
BankTransactionLogging log = new BankTransactionLogging();
// Creating the Bank
Bank bank = new Bank(log);
// Depositing the amount 300
bank.deposit(account, 300);
// Withdrawing the amount 700
bank.withdraw(account,700);

// Doing for another account
BankAccount account2 = new BankAccount(999, 4000);
bank.deposit(account2, 100);
bank.withdraw(account2, 50);

//Final Balance
System.out.println("Final Balance in accout "+account.getAccNumber() +": "+account.getBalance());
System.out.println("Final Balance in accout "+account2.getAccNumber() +": "+account2.getBalance());

}
}

Out Come:
Initial Balance: 10000
Depositing : 300 in account No: 501
Credit Logging for Bank Account No: 501 amount: 300
Withdrawing : 700 from account No: 501
Debit Logging for Bank Account No: 501 amount: 700
Initial Balance: 4000
Depositing : 100 in account No: 999
Credit Logging for Bank Account No: 999 amount: 100
Withdrawing : 50 from account No: 999
Debit Logging for Bank Account No: 999 amount: 50
Final Balance in accout 501: 9600
Final Balance in accout 999: 4050



So you can see how the bank had delegate the transaction logging and how the Logging system is getting notified as and when an event occur.


Thursday, February 18, 2010

Compiling JavaScript using Java SE 5

This blogs talks about how to compile JavaScript from Java

Requirement:

1) Java SE 5
2) jsr223-1.0.jar (http://jcp.org/en/jsr/detail?id=223)
3) js-14.jar (http://www.mozilla.org/rhino/)
4) js.jar (http://www.mozilla.org/rhino/)

Note if you are using Java SE 6 then none of the above jar are needed as it is part of jdk.

Writing a test class:

import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

/**
*
* @author milind
*/
public class JavaScriptCompileTest {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByExtension("js");
if (engine instanceof Compilable) {
Compilable compEngine = (Compilable) engine;
try {
CompiledScript script = compEngine.compile("function count(){ var count; function myName() { document};");
} catch (ScriptException e) {
System.out.println("Message : " + e.getCause().getMessage() );
}
} else {
System.err.println("Engine can't compile code the code Scripting Engine Missing");
}
}
}

It will print following on console:
Message : missing } after function body along with stack trace.

Tuesday, January 19, 2010

Attaching New Object Dynamically To Spring Context

Many times it is required to attach new custom object dynamically to a Spring Context.

Here are the steps to do that:

1) First Step is to create a new custom object which will be dynamically attached to the Spring Context.


package com.milind.BeanAttach;

/**
*
* @author milind
*/
public class TestBean {

private String name;

public TestBean() {
}

private int age;

public TestBean(String name, int age) {
this.name = name;
this.age = age;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Name: "+this.name+ " Age: "+ this.age;
}

}

2) Now we need to create our own custom BeanFactory by implementing the FactoryBean interface.
package com.milind.BeanAttach;

import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;

/**
*
* @author milind
*/
public class AttachBean implements BeanNameAware, FactoryBean {

public static Map beanMap = new HashMap();

public static Map getBeanMap() {
return beanMap;
}

public static void setBeanMap(Map beanMap) {
AttachBean.beanMap = beanMap;
}

private String beanName;

public void setBeanName(String arg0) {

System.out.println("In Set Bean Name .....");
this.beanName= arg0;
}

public Object getObject() throws Exception {
System.out.println("In get Object .....");
return beanMap.get(this.beanName);
}

public Class getObjectType() {
return beanMap.get(this.beanName).getClass();
}

public boolean isSingleton() {
return false;
}
}

3) Creating the applicationContext.xml

Here is the how the applicationContext.xml will look like:


4) Creating the Client to test

package com.milind.BeanAttach;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
*
* @author milind
*/
public class BeanTest {

public static void main(String[] args) {

TestBean obj = new TestBean("Tanmay", 4);
AttachBean.beanMap.put("attach_object", obj);
ApplicationContext ctx = new ClassPathXmlApplicationContext("com/milind/BeanAttach/applicationContext.xml");
TestBean gotObj = (TestBean)ctx.getBean("attach_object");
print(gotObj.toString());

print("Assigning new Object .........................................");
AttachBean.beanMap.put("attach_object", new TestBean("Guest", 99));
gotObj = (TestBean)ctx.getBean("attach_object");
print(gotObj.toString());
}

private static void print(String s) {
System.out.println(s);
}

}


Now you can attach object of any type to the same bean id. Only you had to cast it appropriately when you get the object from context.








Wednesday, October 14, 2009

Varargs in Java

What is varargs ?

varargs - Variable arguments supported in Java from JDK1.5 and higher.
For example you want to specify variable argument in constructor or method you can do it in following ways:

1) Constructor:
public Employee(String firstName, String lastName, String... address);
Note String... is vairable argument.

2) Method:
public int maximum(int first, int... rest);
So variable argument can be of any type.

How JVM interprets ?

When you specify a variable-length argument list, the Java compiler
essentially reads that as “create an array of type ”.
So if you typed:

public Employee(String firstName, String lastName, String... address);

However, the compiler interprets this as:

public Employee(String firstName, String lastName, String[] address);

How to read varargs?

So you can read it as a array directly.
public int maximum(int first, int... rest) {
int max = first;
for (int i : rest) {
if (i > max)
max = i;
}
return max;
}

How to call Varargs method:

If the method is:
public int maximum(int first, int... rest);

It can be called in following ways:
int max = maximum(9, 4);
int max = maximum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int max = maximum(18, 8, 78, 29, 19889, -908);

Classic example of varargs is System.out.printf(String... String);

Varargs Limitations:

1) There can be only one varargs as parameter.
2) varargs should be the last parameter in the list.

Thursday, August 27, 2009

Distributed Transaction in Java

What is Distributed Transaction ?

Transaction that access and update two or more resources across network.
Example: Different database(s) (MySQL, Oracle, Sybase etc) located on single server or single instance of the database(s) located on different servers (Server1, Server2 ...) or combination of above.


How we can achieve distributed transaction in java ?

We can achieve distributed transaction using the XA datasource and JTA.

Important Interfaces:

There are three important interfaces:

1) UserTransaction - (javax.transaction.UserTransaction)
It provides application the ability to controls the trasaction boundary programatically. It starts the global transaction and associates that transaction to the calling thread.

2) Transaction Manager - (javax.transaction.TransactionManager)
This interface allows application server to controls the transaction boundary on behalf of application being managed. Transaction manager is responsible whether to commit or rollback any distributed transaction.

3) XAResource— (javax.transaction.xa.XAResource)
Is a Java mapping of the industry standard XA interface.

Note: JDBC driver should support XAResource portion of JTA.

How distributed transaction works?

Application send request to transaction manager to start the transaction via usertransaction object. Once the transaction is started it will associate itself to the current thread.

After that application can access different datasources belonging to different databases or same databases located on single or multiple servers.

Transaction manager treat the whole unit as one single logical unit irrespective of different database and will commit in case of sucess or rollback if any exception/s.

Implementation:

We implement in JBOSS and Tomcat Servers using mysql as database server.

Use Case:

User will enter id and name which will be stored into two different mysql databases. Table structure will be same in both database except one database will have primary key configured, so when user enters duplicate value it will throw sql exception.

SQL Script:

Database: DB1
CREATE TABLE `xadb`.`EmpTest` (
`id` int NOT NULL,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
)
ENGINE = InnoDB;

Database: DB2
CREATE TABLE `EmpTest` (
`id` int NOT NULL,
`name` varchar(50) NOT NULL

)
ENGINE = InnoDB;

Directory Structure of war file:

xadir
|------ input.jsp
|------ bl.jsp
|------ WEB-INF (Folder)
|---- web.xml
|---- lib (Folder)
|---- classes (Folder)
|---- foo (Folder)
|--- XATest.java

JSP Code:

input.jsp



bl.jsp



Java Code:
package foo;

import java.sql.PreparedStatement;
import java.sql.Connection;

import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;

public class XATest{


public String insertData(int id, String name) {
UserTransaction ut = null;
String returnStr = null;
Connection conn1 = null;
Connection conn2 = null;
PreparedStatement pstmt1 = null;
PreparedStatement pstmt2 = null;
try {

//Creating the context
Context ctx = new InitialContext();
//Getting datasource
DataSource ds1 = (DataSource)ctx.lookup("java:ds1");
DataSource ds2 = (DataSource)ctx.lookup("java:ds2");
//Getting the user transaction
ut = (UserTransaction)ctx.lookup("java:comp/UserTransaction");
//Starting the transaction
ut.begin();
printStr("Transaction Started .....................");
//Processing First Database
conn1 = ds1.getConnection();
pstmt1 = conn1.prepareStatement("insert into EmpTest values ( ?,?)");
pstmt1.setInt(1, id);
pstmt1.setString(2, name);
int exeVal = pstmt1.executeUpdate();
printStr("Statement Executed: "+exeVal);

//Processing Second Database
conn2 = ds2.getConnection();
pstmt2 = conn2.prepareStatement("insert into EmpTest values ( ?,?)");
pstmt2.setInt(1, id);
pstmt2.setString(2, name);
exeVal = pstmt2.executeUpdate();
printStr("Statement Executed: "+exeVal);

printStr("Committing the transaction ...... ");
ut.commit();
pstmt1.close();
pstmt2.close();
conn1.close();
conn2.close();
returnStr = "Transaction Successful";
}catch(Exception e) {

returnStr = "Transaction Failed";
e.printStackTrace();
try {
ut.rollback();
} catch (IllegalStateException ex) {
ex.printStackTrace();
} catch (SecurityException ex) {
ex.printStackTrace();
} catch (SystemException ex) {
ex.printStackTrace();
}

} finally {
try {
pstmt1.close();
pstmt2.close();
conn1.close();
conn2.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
return returnStr;
}

private void printStr(String s) {

System.out.println(s);
}
}
)


Implementing in JBOSS (jboss-4.2.2):
1) create the file mysql-xa-ds.xml under jboss_home/server/default/deploy folder.

2) Add the driver jar file (mysql-connector-java-5.0.8-bin.jar) in
jboss_home/server/default/lib folder.

3) Add the following to the file created in step-1


Note: When the JBOSS start make sure that JNDI are created properly.


4) create the war file and deploy the same in JBOSS.

5) Enter the test data.

a) Id= 1 Name = Milind
Result --
Trasaction Sucessful
b) Id= 2 Name = Guest
Result --
Trasaction Sucessful
c) Id= 1 Name = Guest1
Result --
Trasaction Failed Reason -- Primary Key violation.
Check the table in DB1 and DB2 database both should not have record of 1,Guest1





Wednesday, April 15, 2009

How to start existing windows xp from Ubuntu

How to start existing windows xp from Ubuntu

Step-1 Install Virtual Box

Open terminal (Alt-F2 Type terminal) and type

mkdir ~/virtualbox

cd ~/virtualbox

wget -c http://download.virtualbox.org/virtualbox/2.1.4/virtualbox-2.1_2.1.4-42893_Ubuntu_hardy_i386.deb

ls -ltr

You should able to see file virtualbox-2.1_2.1.4-42893_Ubuntu_hardy_i386.deb

If file is found with virtualbox-2.1_2.1.4-42893_Ubuntu_hardy_i386.deb?xxxxxx then type following command

mv virtualbox-2.1_2.1.4-42893_Ubuntu_hardy_i386.deb?xxxxxx virtualbox-2.1_2.1.4-42893_Ubuntu_hardy_i386.deb

dpkg -i virtualbox-2.1_2.1.4-42893_Ubuntu_hardy_i386.deb

Note: If following libraries are not found/compitable you need to download and install following files

libqt4-core_4.3.4-0ubuntu3_i386.deb
URL: http://packages.ubuntu.com/hardy/libqt4-core
libqt4-gui_4.3.4-0ubuntu3_i386.deb
URL : http://packages.ubuntu.com/hardy/i386/libqt4-gui/download
libaudio2_1.9.1-1_i386.deb
URL: http://packages.ubuntu.com/hardy/libaudio2

to install use the command
dpkg -i *.deb

Once it is done you should able to start the virtual box.

Open terminal (Alt-F2 Type terminal) and type
VirtualBox

alternative you can use menu Applications > System Tools > Virtual Box

Step - 2 Creating Master Boot Record

Type following in terminal

install-mbr --force myBootRecord.mbr

Step 3 Getting the partition details where window is installed

Type following in terminal

sudo fdisk -l /dev/sda

It will display
Device Boot Start End Blocks Id System
/dev/sda1 * 1 6374 51199123+ 7 HPFS/NTFS
/dev/sda2 6375 9729 26949037+ 5 Extended
/dev/sda5 6375 9585 25792326 83 Linux
/dev/sda6 9586 9729 1156648+ 82 Linux swap / Solaris

Step 4 Creating group permission

Type following in terminal

sudo usermod -a -G disk user_name

Log Out and Login again.

Step 5 Creating Virtual Disk and registering the same

VBoxManage internalcommands createrawvmdk -filename ./WinXP.vmdk -rawdisk /dev/sda -partitions 1 -mbr ./myBootRecord.mbr -relative -register

Note:
Change the following in above command:
-rawdisk /dev/sda to -rawdisk your_device
-partitions 1 to -partitions your_partion Number.

Step 6 Configuring Virtual Box

Open Virtual Box ( Refer Step 1)

Click Setting > General > Advance

Check all extended features.

Step 7 Finally Creating New Virtual Machine

Open Virtual Box ( Refer Step 1)

Click New -- Virtual Machine Wizard will come

Click Next

Enter your desire name

Select Operating System : Microsoft Windows
Version: Window XP
Click Next

Select Base Memory Size : 512 MB

Click Next

Click exsisting

Click Add

Browse your WinXP.vmdk file created in step 5

Click Finish

Your Virtual Box is ready select it and press start it will start your windows in Ubuntu

Note: To enter cltr+alt+delete use HOST (right control key) + Del