Tuesday, November 8, 2011

Hibernate by Example - Part 2 (DetachedCriteria)

So last time we helped out justice league to effectively manage their super heroes. Today we focus on how The Avengers will be using Hibernate's Detached Criteria to find out their enemies with respect to each superhero so as to protect their super heroes. You can download the working example from here.

In this example we take only two entities into consideration. The Avenger & The Villain. We build a relationship between the two using a join table. Let us have a look at the domain mappings used in this example.




package com.avengers.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Type;

/**
 * The domain class representing each member of the avengers
 * 
 * @author Dinuka.Arseculeratne
 * 
 */
@Entity
@Table(name = "Avengers")
public class Avenger implements Serializable {

 /**
  * The primary key of the Avenger table
  */
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(name = "avenger_id")
 private Long avengerId;

 /**
  * The name of the avenger member
  */
 @Column(name = "avenger_name")
 private String avengerName;

 /**
  * A flag which holds whether the avenger's powers are awesome
  */
 @Type(type = "yes_no")
 @Column(name = "is_awesome")
 private boolean isAwesome;

 /**
  * The list of enemies the avenger has
  */
 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
 @JoinTable(name = "AVENGERS_AND_VILLAINS", joinColumns = { @JoinColumn(name = "avenger_id") }, inverseJoinColumns = { @JoinColumn(name = "villain_id") })
 private List<Villain> enemyList = new ArrayList<Villain>();

 public Long getAvengerId() {
  return avengerId;
 }

 public void setAvengerId(Long avengerId) {
  this.avengerId = avengerId;
 }

 public String getAvengerName() {
  return avengerName;
 }

 public void setAvengerName(String avengerName) {
  this.avengerName = avengerName;
 }

 public boolean isAwesome() {
  return isAwesome;
 }

 public void setAwesome(boolean isAwesome) {
  this.isAwesome = isAwesome;
 }

 public List<Villain> getEnemyList() {
  return enemyList;
 }

 public void addEnemy(Villain enemy) {
  enemyList.add(enemy);
 }

 @Override
 public String toString() {
  return "Avenger [avengerId=" + avengerId + ", avengerName="
    + avengerName + ", isAwesome=" + isAwesome + ", enemyList="
    + enemyList + "]";
 }

 
}

This class maps an avenger. I have used minimal fields in order to keep this example as simple and short as possible. And the Villain domain looks as follows;
package com.avengers.domain;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Type;

/**
 * This class represents the Villain forces against the avengers
 * 
 * @author Dinuka.Arseculeratne
 * 
 */
@Entity
@Table(name = "Villains")
public class Villain implements Serializable {

 /**
  * The primary key of the Enemy table
  */
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(name = "villain_id")
 private Long villaiId;

 /**
  * The name of the enemy
  */
 @Column(name = "villain_name")
 private String villainName;

 /**
  * A flag which checks whether the villain is super awesome
  */
 @Type(type = "yes_no")
 @Column(name = "is_awesome")
 private boolean isAwesome;

 public Long getVillaidId() {
  return villaiId;
 }

 public void setVillaidId(Long villaidId) {
  this.villaiId = villaidId;
 }

 public String getVillainName() {
  return villainName;
 }

 public void setVillainName(String villainName) {
  this.villainName = villainName;
 }

 public boolean isAwesome() {
  return isAwesome;
 }

 public void setAwesome(boolean isAwesome) {
  this.isAwesome = isAwesome;
 }

 @Override
 public String toString() {
  return "Villain [villaiId=" + villaiId + ", villainName=" + villainName
    + ", isAwesome=" + isAwesome + "]";
 }

}

Ok now that we have defined our domains, let us see how data retrieval happens with DetachedCriteria. I have used DetachedCriteria here because The Avengers were very specific and said they do not want anything to do with the Hibernate session, so hence i used DetachedCriteria which does not require a hibernate session to be present.

Our primary objective is to retrieve The Avenger to whom a villain belongs to. Note that this assumes the same villain cannot be a villain to more than one superhero. So moving on i give below the method that retrieves an avenger based on the villain name passed.

public Avenger retrieveAvengerByVillainName(String villainName) {

  Avenger avenger = null;
  /**
   * Selected a detached criteria so we do not need a session to run it
   * within.
   */
  DetachedCriteria criteria = DetachedCriteria.forClass(Avenger.class);

  /**
   * Here we are doing an inner join with the Villain table in order to do
   * a name comparison with the villainName passed in as a method
   * parameter
   */
  DetachedCriteria villainCriteria = criteria.createCriteria("enemyList");

  villainCriteria.add(Restrictions.eq("villainName", villainName));

  villainCriteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

  @SuppressWarnings("unchecked")
  List<Avenger> avengerList = getHibernateTemplate().findByCriteria(
    criteria);

  if (!avengerList.isEmpty()) {
   avenger = avengerList.get(0);
   getHibernateTemplate().initialize(avenger.getEnemyList());
  }
  return avenger;

 }
In this method what we do is first we create a criteria for our master class which in this case is Avenger.class. Then we need to do a join with the Villain table and hence we create a sub criteria from our main criteria with the name of the list we defined within the Avenger domain class. Then it is a matter of equaling the property of the Villain domain to the villain name passed in.

The power of the Criteria API is such that you can create dynamic queries with ease which would be a hassle if we were to use pure HQL which would require substantial string concatenations in order to achieve the same.

A sample test class called AvengerTest.java is given with the attachment which you can find at the top of the most. Note that you need to remove the comment on avenger-context.xml in order to create the tables needed for this example. So that is about it.

The Avengers can be risk averse now that they have a system by which they can relate any super villain to a super hero within their league.

As always your comments and suggestions are always welcome and appreciated.

Thank you for taking the time to read!!!!

Tuesday, September 6, 2011

Hibernate by Example - Part 1 (Orphan removal)

So i thought to do a series of hibernate examples showing various features of hibernate. In the first part i wanted to show about the Delete Orphan feature and how it may be used with the use of a story line. So let us begin :)  

Prerequisites:
In order for you to try out the following example you will need the below mentioned JAR files:


  • org.springframework.aop-3.0.6.RELEASE.jar
  • org.springframework.asm-3.0.6.RELEASE.jar
  • org.springframework.aspects-3.0.6.RELEASE.jar
  • org.springframework.beans-3.0.6.RELEASE.jar
  • org.springframework.context.support-3.0.6.RELEASE.jar
  • org.springframework.context-3.0.6.RELEASE.jar
  • org.springframework.core-3.0.6.RELEASE.jar
  • org.springframework.jdbc-3.0.6.RELEASE.jar
  • org.springframework.orm-3.0.6.RELEASE.jar
  • org.springframework.transaction-3.0.6.RELEASE.jar.
  • org.springframework.expression-3.0.6.RELEASE.jar
  • commons-logging-1.0.4.jar
  • log4j.jar
  • aopalliance-1.0.jar
  • dom4j-1.1.jar
  • hibernate-commons-annotations-3.2.0.Final.jar
  • hibernate-core-3.6.4.Final.jar
  • hibernate-jpa-2.0-api-1.0.0.Final.jar
  • javax.persistence-2.0.0.jar
  • jta-1.1.jar
  • javassist-3.1.jar
  • slf4j-api-1.6.2.jar
  • mysql-connector-java-5.1.13-bin.jar
  • commons-collections-3.0.jar

For anyone who want the eclipse project to try this out, you can download it with the above mentioned JAR dependencies here.

Introduction:

Its year 2011. And The Justice League has grown out of proportion and are searching for a developer to help with creating a super hero registering system. A developer competent in Hibernate and ORM is ready to do the system and handle the persistence layer using Hibernate. For simplicity, He will be using a simple stand alone application to persist super heroes. This is how this example will layout:

  • Table design
  • Domain classes and Hibernate mappings
  • DAO & Service classes
  • Spring configuration for the application
  • A simple main class to show how it all works
Let the Journey Begin......................


Table Design:

The design consists of three simple tables as illustrated by the diagram below;





As you can see its a simple one-to-many relationship linked by a Join Table. The Join Table will be used by Hibernate to fill the Super hero list which is in the domain class which we will go on to see next.

Domain classes and Hibernate mappings:

There are mainly only two domain classes as the Join table in linked with the primary owning entity which is the Justice League entity. So let us go on to see how the domain classes are constructed with annotations;

 
package com.justice.league.domain;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

import org.hibernate.annotations.Type;

@Entity
@Table(name = "SuperHero")
public class SuperHero implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -6712720661371583351L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "super_hero_id")
	private Long superHeroId;

	@Column(name = "super_hero_name")
	private String name;

	@Column(name = "power_description")
	private String powerDescription;

	@Type(type = "yes_no")
	@Column(name = "isAwesome")
	private boolean isAwesome;

	public Long getSuperHeroId() {
		return superHeroId;
	}

	public void setSuperHeroId(Long superHeroId) {
		this.superHeroId = superHeroId;
	}

	public String getName() {
		return name;
	}

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

	public String getPowerDescription() {
		return powerDescription;
	}

	public void setPowerDescription(String powerDescription) {
		this.powerDescription = powerDescription;
	}

	public boolean isAwesome() {
		return isAwesome;
	}

	public void setAwesome(boolean isAwesome) {
		this.isAwesome = isAwesome;
	}

}

As i am using MySQL as the primary database, i have used the GeneratedValue strategy as GenerationType.AUTO which will do the auto incrementing whenever a new super hero is created. All other mappings are familiar to everyone with the exception of the last variable where we map a boolean to a Char field in the database.

We use Hibernate's @Type annotation to represent true & false as Y & N within the database field. Hibernate has many @Type implementations which you can read about here. In this instance we have used this type.

Ok now that we have our class to represent the Super Heroes, lets go on to see how our Justice League domain class looks like which keeps tab of all super heroes who have pledged allegiance to the League.

package com.justice.league.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "JusticeLeague")
public class JusticeLeague implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 763500275393020111L;

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "justice_league_id")
	private Long justiceLeagueId;

	@Column(name = "justice_league_moto")
	private String justiceLeagueMoto;

	@Column(name = "number_of_members")
	private Integer numberOfMembers;

	@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true)
	@JoinTable(name = "JUSTICE_LEAGUE_SUPER_HERO", joinColumns = { @JoinColumn(name = "justice_league_id") }, inverseJoinColumns = { @JoinColumn(name = "super_hero_id") })
	private List<SuperHero> superHeroList = new ArrayList<SuperHero>(0);

	public Long getJusticeLeagueId() {
		return justiceLeagueId;
	}

	public void setJusticeLeagueId(Long justiceLeagueId) {
		this.justiceLeagueId = justiceLeagueId;
	}

	public String getJusticeLeagueMoto() {
		return justiceLeagueMoto;
	}

	public void setJusticeLeagueMoto(String justiceLeagueMoto) {
		this.justiceLeagueMoto = justiceLeagueMoto;
	}

	public Integer getNumberOfMembers() {
		return numberOfMembers;
	}

	public void setNumberOfMembers(Integer numberOfMembers) {
		this.numberOfMembers = numberOfMembers;
	}

	public List<SuperHero> getSuperHeroList() {
		return superHeroList;
	}

	public void setSuperHeroList(List<SuperHero> superHeroList) {
		this.superHeroList = superHeroList;
	}

}


The important fact to note here is the annotation @OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER, orphanRemoval = true). Here we have set orphanRemoval = true.

So what does that do exactly? Ok so say that you have a group of Super Heroes in your League. And say one Super Hero goes haywire. So we need to remove Him/Her from the League. With JPA cascade this is not possible as it does not detect Orphan records and you will wind up with the database having the deleted Super Hero(s) whereas your collection still has a reference to it.

Prior to JPA 2.0 you did not have the orphanRemoval support and the only way to delete orphan records was to use the following Hibernate specific(or ORM specific) annotation which is now deprecated;

@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)

But with the introduction of the attribute orphanRemoval, we are now able to handle the deletion of orphan records through JPA. Now that we have our Domain classes

DAO & Service classes:
To keep with good design standards i have separated the DAO(Data access object) layer and the service layer. So let us see the DAO interface and implementation. Note that i have used HibernateTemplate through HibernateDAOSupport so as to keep away any Hibernate specific detail out and access everything in a unified manner using Spring.
package com.justice.league.dao;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.justice.league.domain.JusticeLeague;

@Transactional(propagation = Propagation.REQUIRED, readOnly = false)  
public interface JusticeLeagueDAO {

	
	public void createOrUpdateJuticeLeagure(JusticeLeague league);
	
	public JusticeLeague retrieveJusticeLeagueById(Long id);
}


In the interface layer i have defined the Transaction handling as Required. This is done so that whenever you do not need a transaction you can define that at the method level of that specific method and in more situations you will need a transaction with the exception of data retrieval methods. 

According to the JPA spec you need a valid transaction for insert/delete/update functions.

So lets take a look at the DAO implementation;


package com.justice.league.dao.hibernate;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.justice.league.dao.JusticeLeagueDAO;
import com.justice.league.domain.JusticeLeague;

@Qualifier(value="justiceLeagueHibernateDAO")
public class JusticeLeagueHibernateDAOImpl extends HibernateDaoSupport
		implements JusticeLeagueDAO {

	@Override
	public void createOrUpdateJuticeLeagure(JusticeLeague league) {

		if (league.getJusticeLeagueId() == null) {
			getHibernateTemplate().persist(league);
		} else {
			getHibernateTemplate().update(league);
		}

	}
	
	@Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = false)  
	public JusticeLeague retrieveJusticeLeagueById(Long id){
		return getHibernateTemplate().get(JusticeLeague.class, id);
	}

}


Here i have defined an @Qualifier to let Spring know that this is the Hibernate implementation of the DAO class. Note the package name which ends with hibernate. This as i see is a good design concept to follow where you separate your implementation(s) into separate packages to keep the design clean.

Ok lets move on to the service layer implementation. The service layer in this instance is just acting as a mediation layer to call the DAO methods. But in a real world application you will probably have other validations, security related procedures etc handled within the service layer.


package com.justice.league.service;

import com.justice.league.domain.JusticeLeague;

public interface JusticeLeagureService {

	public void handleJusticeLeagureCreateUpdate(JusticeLeague justiceLeague);

	public JusticeLeague retrieveJusticeLeagueById(Long id);
}


package com.justice.league.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.justice.league.dao.JusticeLeagueDAO;
import com.justice.league.domain.JusticeLeague;
import com.justice.league.service.JusticeLeagureService;

@Component("justiceLeagueService")
public class JusticeLeagureServiceImpl implements JusticeLeagureService {

	@Autowired
	@Qualifier(value = "justiceLeagueHibernateDAO")
	private JusticeLeagueDAO justiceLeagueDAO;

	@Override
	public void handleJusticeLeagureCreateUpdate(JusticeLeague justiceLeague) {
		justiceLeagueDAO.createOrUpdateJuticeLeagure(justiceLeague);
	}

	public JusticeLeague retrieveJusticeLeagueById(Long id){
		return justiceLeagueDAO.retrieveJusticeLeagueById(id);
	}
}

Few things to note here. First of all the @Component binds this service implementation with the name justiceLeagueService within the spring context so that we can refer to the bean as a bean with an id of name justiceLeagueService.

And we have auto wired the JusticeLeagueDAO and defined an @Qualifier so that it will be bound to the Hibernate implementation.

The value of the Qualifier should be the same name we gave the class level Qualifier within the DAO Implementation class. And Lastly let us look at the Spring configuration which wires up all these together;


Spring configuration for the application:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="  
          http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd  
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">


	<context:component-scan base-package="com.justice.league" />
	<context:annotation-config />

	<tx:annotation-driven />

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="packagesToScan">
			<list>
				<value>com.justice.league.**.*</value>
			</list>
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop>
				<prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/my_test</prop>
				<prop key="hibernate.connection.username">root</prop>
				<prop key="hibernate.connection.password">password</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				
			</props>
		</property>
	</bean>

	<bean id="justiceLeageDAO"
		class="com.justice.league.dao.hibernate.JusticeLeagueHibernateDAOImpl">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

</beans>
Note that i have used the HibernateTransactionManager in this instance as i am running it stand alone. If you are running it within an application server you will almost always use a JTA Transaction manager.

I have also used auto creation of tables by hibernate for simplicity purposes. The packagesToScan property instructs to scan through all sub packages(including nested packaged within them) under the root package com.justice.league.**.* to be scanned for @Entity annotated classes.

We have also bounded the session factory to the justiceLeagueDAO so that we can work with the Hibernate Template. For testing purposes you can have the tag <prop key="hibernate.hbm2ddl.auto">create</prop> initially if you want, and let hibernate create the tables for you. Ok so now that we have seen the building blocks of the application, lets see how this all works by first creating some super heroes within the Justice League

A simple main class to show how it all works:

As the first example lets see how we are going to persist the Justice League with a couple of Super Heroes;
package com.test;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.justice.league.domain.JusticeLeague;
import com.justice.league.domain.SuperHero;
import com.justice.league.service.JusticeLeagureService;

public class TestSpring {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"spring-context.xml");
		JusticeLeagureService service = (JusticeLeagureService) ctx
				.getBean("justiceLeagueService");

		JusticeLeague league = new JusticeLeague();
		List<SuperHero> superHeroList = getSuperHeroList();

		league.setSuperHeroList(superHeroList);
		league.setJusticeLeagueMoto("Guardians of the Galaxy");
		league.setNumberOfMembers(superHeroList.size());

		service.handleJusticeLeagureCreateUpdate(league);

	}

	private static List<SuperHero> getSuperHeroList() {

		List<SuperHero> superHeroList = new ArrayList<SuperHero>();

		SuperHero superMan = new SuperHero();
		superMan.setAwesome(true);
		superMan.setName("Clark Kent");
		superMan.setPowerDescription("Faster than a speeding bullet");

		superHeroList.add(superMan);

		SuperHero batMan = new SuperHero();
		batMan.setAwesome(true);
		batMan.setName("Bruce Wayne");
		batMan.setPowerDescription("I just have some cool gadgets");
		superHeroList.add(batMan);

		return superHeroList;
	}

}

And if we go to the database and check this we will see the following output;
mysql> select * from superhero;
+---------------+-----------+-----------------+-------------------------------+
| super_hero_id | isAwesome | super_hero_name | power_description             |
+---------------+-----------+-----------------+-------------------------------+
|             1 | Y         | Clark Kent      | Faster than a speeding bullet |
|             2 | Y         | Bruce Wayne     | I just have some cool gadgets |
+---------------+-----------+-----------------+-------------------------------+

mysql> select * from justiceleague;
+-------------------+-------------------------+-------------------+
| justice_league_id | justice_league_moto     | number_of_members |
+-------------------+-------------------------+-------------------+
|                 1 | Guardians of the Galaxy |                 2 |
+-------------------+-------------------------+-------------------+
So as you can see we have persisted two super heroes and linked them up with the Justice League. Now let us see how that delete orphan works with the below example;
package com.test;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.justice.league.domain.JusticeLeague;
import com.justice.league.domain.SuperHero;
import com.justice.league.service.JusticeLeagureService;

public class TestSpring {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		ApplicationContext ctx = new ClassPathXmlApplicationContext(
				"spring-context.xml");
		JusticeLeagureService service = (JusticeLeagureService) ctx
				.getBean("justiceLeagueService");

		JusticeLeague league = service.retrieveJusticeLeagueById(1l);
		List<SuperHero> superHeroList = league.getSuperHeroList();
		/**
		 * Here we remove Batman(a.k.a Bruce Wayne) out of the Justice League
		 * cos he aint cool no more
		 */
		for (int i = 0; i < superHeroList.size(); i++) {
			SuperHero superHero = superHeroList.get(i);
			if (superHero.getName().equalsIgnoreCase("Bruce Wayne")) {
				superHeroList.remove(i);
				break;
			}

		}

		service.handleJusticeLeagureCreateUpdate(league);

	}

}

Here we first retrieve the Justice League record by its primary key. Then we loop through and remove Batman off the League and again call the createOrUpdate method. As we have the remove orphan defined, any Super Hero not in the list which is in the database will be deleted.
Again if we query the database we will see that batman has been removed now as per the following;
mysql> select * from superhero;
+---------------+-----------+-----------------+-------------------------------+
| super_hero_id | isAwesome | super_hero_name | power_description             |
+---------------+-----------+-----------------+-------------------------------+
|             1 | Y         | Clark Kent      | Faster than a speeding bullet |
+---------------+-----------+-----------------+-------------------------------+

So that's it. The story of how Justice League used Hibernate to remove Batman automatically without being bothered to do it themselves.

Next up look forward to how Captain America used Hibernate Criteria to build flexible queries in order to locate possible enemies. Watch out!!!!

Have a great day people and thank you for reading!!!!

If you have any suggestions or comments pls do leave them by.

Saturday, August 13, 2011

Lessons i learnt playing Angry Birds



So i finally saved up and bought my first smart phone a few weeks back(A samsung galaxy s i9000 to be specific). I heard about the game Angry Birds even before i had a smart phone but never got a chance to play it. The hype about it was very true. The game is addictive :D. Anyhow my objective of this article is not to disseminate news how awesome Angry Birds is, which is quite obvious with the plethora of download rates it is getting, but to write about a few things that crossed my mind whilst playing it.

  • Plan before execute
       When you first start off a chapter, you are shown a glimpse of what obstacles lie ahead. You can then scroll back and forth looking at where the stinky(ok im exaggerating a bit here, but im on the bird's side after all) pigs are situated and how they are protected by the obstacles. So you plan the attack beforehand and launch it. 
          As a developer this is a very interesting point. Sometimes i rush into writing a piece of code. But if i had looked at a few possible obstacles, other possible solutions, i believe most of the time i could have come up with a much better design. 

  • Efficiency in resource utilization
           In some instances you get birds with different abilities. Some blow up, speed through, drop bombs, replicate etc. Each has their strengths and weaknesses. Before we launch an attack we see how best to use them and at which point.
           As a developer, i should know my strengths and weaknesses and apply them accordingly when given a particular task, and look at what i lack and gain knowledge in areas where i lack in order to fill the gap.
          As a project manager you should know the skills of your resources and utilize them to the tasks at hand efficiently in order to achieve the end goal of delivering a stable product to the customer. Not everyone is good at everything, so identifying your resource pool enables you to make better decisions and improve and refine your resources' knowledge base as you go on.

  • How to handle the task with minimum effort
           When you blow up all the pigs around with a few birds left up you get bonus points.
           As a developer, when given a task i must strive to see ways in which i could achieve it with minimum effort. This does not mean your a lazy bum, but that you opt to work smarter than harder. You can thereby save up time to do other things like gain knowledge on other new technologies, contribute to some open source project you love etc. In the birds example, you are left with a few birds because you used your targets efficiently. In the same way, if you apply the solution you devised in the correct manner, you will be left with some time to spare(this might depend on your supervisor ofcourse :)  )

  • Go ahead with what works for you
           In any level, you have multiple ways of approaching the obstacles. You may try a few options, but in the end you have to go with what works for you in order to send those pigs flying(again exaggeration).
           As a developer, when designing a particular module/project, there always are many ways in which that can be achieved. But in the end you have to decide on what will work for you and go ahead with it. When presented with many solutions you have to decide on what will work for you and stick to the plan to achieve the end goal. Again as the birds example sometimes the one you chose might not work, so you refine your solution and come up with a successful one in the end.

  • Perseverance

        When you embark on a mission, sometimes you cannot complete it in one shot. You need to keep on trying and eventually you will get there and make the pigs pay.
           As a developer sometimes i might not be able to come up with a viable solution for the problem at hand. But you should not be discouraged and give up. Breaking the problem into smaller understandable components might let you see things in a new perspective. So keep on trying and eventually you will get there.  

Thats it for now guys. Ofcourse im still on level 2-17 at the time of writing this post, so i might learn a few more things as i go on :)... 

Thank you for reading and please do leave by your thoughts if you have the time. Have a great day guys!!! 

   

Saturday, August 6, 2011

What i love about PHP



 First of all i must say im relatively new to the whole PHP scene. Coming from an OOP background with mostly Java/C++ experience i must say the transition was not rough as i expected it to be. Unfortunately i have not been able to code in PHP at an industrial level but use it for many of my freelance projects which has been very productive up to now. So i would love to highlight why i love PHP and why i think others who aren't using it yet, should give it a try.

  • WAMP
                WAMP is one of the best bundled package i have seen. Right out of the box you got yourself an Apache server, mysql database and PHP core. So within a matter of minutes you are ready to write some productive code without having to deal with environment setup issues. And you have a wide variety of bundled packages to chose from which fits you needs. Need a mysql client to go through the database? No need of installing another sql client. Just type http://localhost/phpmyadmin/ and your ready to create your database schemas.

  • Its Interpreted
               All java folks know how much of a pain it is to compile your project if you are working on a large scale application. You just do a small change and stare at your command line as Maven or Ant destroys 2-5 minutes on average of your precious time. Im not emphasizing on build related problems here but the truth of the fact is there is no matter what, you do waste a portion of your time compiling code. Whats great about PHP is the fact that it is interpreted.  You just do a change, go to your browser and refresh. Thats it. Saved me a ton of time in many of my freelance projects.

              Ofcourse there are PHP compilers if anyone ever needs it. Some say it increases the performance but i have personally not been able to try it. Facebook has written a nice tool that converts PHP code to C code called HipHop.

             The information presented in this site is just out of this world. Anything and everything you will ever need when working with PHP is here so there is no hassle what so ever. When i need a function i just search it up here and the community has been very active with various people suggesting better ways of calling various functions which has been very helpful to me.

  • No need of a special IDE
             Myself and many i know just use Notepad++ for our coding with PHP.  Its just easy to use and switch between different source files. I dont think anyone ever needs an IDE when coding in PHP though there are some very useful IDEs out there as listed here.

            From PHP 5 they supported classes, object creation, constructors and the whole deal. This feature made it very easy for me in the transition phase from java to php. It was more or less a seamless transition.

  • Plethora of frameworks to choose 
           You got Zend, cake php, symphony and so many more frameworks. Its just amazing. If one does not fit your need you just move to the next one and try it out. The learning curve is also not that steep as well. The MVC architecture introduced by these frameworks make you feel at home when coming from a struts background as myself. And the DAO layer separation introduced in some frameworks is also a huge plus point for me.

Im just starting out with PHP and i believe more will be added to this list as time goes on. If any PHP pros can share their opinion on why you love the language it is highly appreciated.

Cheers Guys!!!!


Saturday, July 23, 2011

The story of the ArrayList imposter

Each and everyone of us, undoubtedly has had used Array lists in our lives as programmers. This story is about an imposter who lives among us, unnoticed, undetected until WHAM you are presented with a bug that makes no sense. Let me give you an example to reveal this imposter :). I have a hypothetical system that stores information on games and their ratings. A glimpse of the DTO i would use is as follow;


/**
 * A class to hold basic data about game titles
 * @author dinuka
 *
 */
public class Game  {

	/**
	 * The name of the game
	 */
	private String title;
	/**
	 * The rating users have given the game
	 */
	private int rating;
	
	public Game(String title,int rating){
		this.title = title;
		this.rating = rating;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public int getRating() {
		return rating;
	}

	public void setRating(int rating) {
		this.rating = rating;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + rating;
		result = prime * result + ((title == null) ? 0 : title.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Game other = (Game) obj;
		if (rating != other.rating)
			return false;
		if (title == null) {
			if (other.title != null)
				return false;
		} else if (!title.equals(other.title))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Game [title=" + title + ", rating=" + rating + "]";
	}
	
	
}

Nothing fancy. Just a plain old data holder value object with customary getter/setter methods. I have overriden equals,hashcode and tostring methods because i usually do that as a principal :). Ok moving on to reveal the culprit i will present you with a sample code and run the code and show you the problem at hand;


import java.util.Arrays;
import java.util.List;


public class Test {

	
	public static void main(String[] args) {

		Game[]gameArr = new Game[3];
		
		gameArr[0] = new Game("Metal gear solid 4",8);
		
		gameArr[1] = new Game("Unchartered 2",6);
		
		gameArr[2] = new Game("NFS Underground",2);
		
		Game[]newGameList = manipulateGames(gameArr);
		
		
	}
	
	/**
	 * Here we delete low rating games
	 * and add new game titles in place of those games
	 * @param gameArr
	 */
	private static Game[] manipulateGames(Game[]gameArr){
		List&lt;Game&gt;gameList = Arrays.asList(gameArr);
		
		for(int i=0;i&lt;gameList.size();i++){
			Game game = gameList.get(i);
			if(game.getRating()&lt;5){
				gameList.remove(game);
				Game newGame = new Game("NFS Hot pursuit 2",7);
				gameList.add(newGame);
			}
		}
		Game[]newArr = new Game[gameList.size()];
		return gameList.toArray(newArr);
	}
}


Ok these are my personal ratings i have given for the few of the games i love. Hopefully no one will take them personally because i do not want you to get off the topic here ;). So what we are doing here is, we have an array of games which we pass into a method which looks at the games with ratings lower than 5 and removes them and adds new games as substitutes. Do not consider implementation details as that is not my intention. My intention is to show you the problem at hand. So lets run this code and see what we get.

Ok what just happened? We get this really awkward error saying Unsupported exception. When i first got this i was thinking that maybe a previous version of java did not support removing from list given the object because i was at work using JDK 1.4 for work related things. But jdeclipse came to my help. If anyone has not used it, i can guarantee that it is one of the most useful plugins and a faithful companion in my eclipse workbench. Its a java decompiler which can decompile class files. Its much easier than downloading the JDK source and linking it.

I wanted to see the implementation of the Arrays.asList() method. This is where i found our little ArrayList imposter.....


public static <T> List<T> asList(T[] paramArrayOfT)
  {
    return new ArrayList(paramArrayOfT);
  }


By the looks of it, there is nothing implicitly wrong with this implementation. So most probably it should be a problem with the ArrayList. Lets see whats happening there;


private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, Serializable
  {
    private static final long serialVersionUID = -2764017481108945198L;
    private final E[] a;

    ArrayList(E[] paramArrayOfE)
    {
      if (paramArrayOfE == null)
        throw new NullPointerException();
      this.a = paramArrayOfE;
    }

    public int size()
    {
      return this.a.length;
    }

    public Object[] toArray()
    {
      return ((Object[])this.a.clone());
    }

    public <T> T[] toArray(T[] paramArrayOfT)
    {
      int i = size();
      if (paramArrayOfT.length < i)
        return Arrays.copyOf(this.a, i, paramArrayOfT.getClass());
      System.arraycopy(this.a, 0, paramArrayOfT, 0, i);
      if (paramArrayOfT.length > i)
        paramArrayOfT[i] = null;
      return paramArrayOfT;
    }

    public E get(int paramInt)
    {
      return this.a[paramInt];
    }

    public E set(int paramInt, E paramE)
    {
      Object localObject = this.a[paramInt];
      this.a[paramInt] = paramE;
      return localObject;
    }

    public int indexOf(Object paramObject)
    {
      int i;
      if (paramObject == null)
        for (i = 0; i < this.a.length; ++i)
          if (this.a[i] == null)
            return i;
      else
        for (i = 0; i < this.a.length; ++i)
          if (paramObject.equals(this.a[i]))
            return i;
      return -1;
    }

    public boolean contains(Object paramObject)
    {
      return (indexOf(paramObject) != -1);
    }
  }

Huh what is that?? Its an inner class extending the AbtractList class,residing within the Arrays class baring the name ArrayList. The problem here is that it does not override all methods available within AbtractList thus throwing the UnsupportedException as defined within the class AbtractList .

Why they have done this im not really sure. It maybe because they are syncing the Array you passed initially and what ever update you do, is done to the original Array you passed in. But why chose such an implementation is a question mark for me.

So if you ever want to remove elements when using an ArrayList composed using Arrays.asList make sure to wrap it with a call such as newArrayList(Array.asList(myArr)); This will guarantee that you will use the concrete ArrayList implementation and not our imposter we just discovered.


So that ends the story of the ArrayList imposter that bothered me last week at work :)


Thank you for reading and hope you guys have a peaceful day of coding!!!


Wednesday, July 6, 2011

The MBA Riddle



So its been a while since i started working. 4 years to be exact. And i decided it is time i pondered on what kind of higher studies i should pursue. For me learning is not about having a piece of paper nicely laminated,framed and hanged in your house. Its about the learning outcome and the value i get from it. You feel this more when you have to self sponsor your studies and not depend on your parents to fund you. After all i believe they spent more than enough for my undergraduate studies and i do not want to burden them again.

Most people have the propensity to think that your post graduate studies should be inline with your undergraduate studies. Whilst there is some truth to this belief let me say that it shouldnt be a one to one match of your undergraduate studies. At least that is the case with my choice. I had two choices. MSc vs MBA.


I read for my BSc in  Computing and Information Systems as my undergraduate studies, as computers were my passion from younger days. Most people will and actually did suggest that i should read for an MSc in Computer Science saying it will propel my career to new heights. I never disregard anyone's thoughts as a principal so i thought about it long and hard. Here is my analysis on it.

If i were to do an MSc i first would see the available options for me. Coming from an average family the financial feasibility of funding for a foreign education was not realistic. I sure do wish i could have done a degree at MIT. But hey that is life, we do not always get what we want, but i believe God guides us through various paths so that we realize our true potential in ways we could not comprehend at first.

So anyhow moving on, i looked at a few opportunities locally. I must say in Sri Lanka there are quite a few reputed local universities offering recognized post graduate degrees in Computer Science. So my next step was to see what areas are covered within those courses.


Going along each, some were more inclined towards Software Architecture whilst others were more into artificial intelligence, Data mining etc. My passion was Software Architecture so i looked at the course content of those post graduate degrees. Going through it in detail i was amazed to see that most of what it covers had already been covered within my work experience. So i was left with the question as to what possible advantage this will give me. If i were to do a SWOT analysis i would come up with a negative response for sure.


As i stated before i am not a person to do degree just to get the mental satisfaction that i have achieved something great. I would actually want something that would enable me to challenge my self and help to me reach new heights.


An MBA has always been my choice of post graduate studies. I did my research on MSc because various people suggested that option to me and i really wanted to assess that option. So why an MBA you might ask. I am not going to give you obvious answers many people give such as;


  1. I want to start my own business someday
  2. I want to be a manager in my work place
and many more.

For me the world of entrepreneurship has been an interesting phenomena. From my younger days i have been a fan of The Apprentice, following most seasons up-to-date. Some may not like the way Mr. Trump handles business, but i can see his point of view in most cases.Though some may seem harsh, at the end of the day as he says its business and nothing personal.

An MBA for me is a source which will enable me to view the world in a different perspective and to think differently. Take for example what happened with Coca Cola and Pepsi. They were rivals going head on against each other. Though the rivalry exist still, its not as much as before. Its because they identified their true foe which is WATER. So they came up with various stalls on the road to promote the idea that if your thirsty you should drink Coca cola/Pepsi. This is a concept called Game Theory. For me this is a great idea. In the world of business so many interesting cases exists. That thinking pattern amazes me. Though an MBA will not directly provide me the ability to come up with amazing ideas as such, it will surely change my thinking pattern to see things differently at to let go of the limited scope thinking pattern.

Being able to grab hold of all aspects of the business world is very important as i see with the increased propelling of the economies of countries. So rather than limiting my knowledge to one particular field i would like to have the option of widening my knowledge in the business world. Of course one might say that you can learn all that is taught in MBA schools by reading a few books. Of course the theoretical knowledge you can acquire my reading a few good books, but the practical experience that you are taught my visiting lecturers and the various experiences you obtain with outbound training, team work activities etc those you cannot gain by your own as those are experiences you have to live out.

Im not stating that everyone in the field of IT should do an MBA after the undergraduate studies. For me its a passion driven by various aspects as i highlighted above. An MSc will stand you in good stead too given that the course content fits what you are looking for.

And that is how i solved my MBA riddle :) ... I know many will have alot of different views on the same. So pls leave by your view which is highly appreciated.

And to others who are contemplating on their higher studies i hope i shed some light on the subject and i wish each and everyone of you the best in everything.

God Bless....

Sunday, July 3, 2011

My two cents on Scrum

Scrum is an agile methodology which helps companies iterate through a product/project development to successful completion. Back in the days we all know that we were limited to the water fall model which was later extended to be known as the V-Model. Gantt charts and the like were included with these methodologies.

The practices defined within these traditional methods were concise and precise. We start off with gathering of requirements from the client, document it which usually goes as the Software Requirement Document (Known as SRS), which is later signed off by the client after user acceptance testing is done. Afterwards we have the design phase where all our class diagrams come into play as well as use case diagrams, ER diagrams and the like. Then it’s time to implement this well designed product with technologies that fit the choice. Testing and product release follows the implementation phase.

Though there were no intrinsic problems with this methodology, the problem lied in the fact that we humans are involved in every phase. In a perfect world (such as what skynet once planned) this methodology would work seamlessly and we would have picture perfect product releases. But alas, with us humans nothing is guaranteed. We all know how hard it is for us to make a decision on something at certain times. In terms of a company, when they approach a software company to build a piece of software for them, they might not know what they exactly want early on. As time goes on as they see the product they might and most usually do want something radically different to what they wanted earlier.

The problem posed by the traditional methodologies as everyone knows is that it’s very hard to go back from once phase to a previous phase as the cost and time involved in the process is of great monetary value to the company. We can’t coerce the customer to agree on our basis as client’s request are always dynamic and we as a company should have the processes in place to adapt to such changes.
This is where Scrum shines as I see. I’m quite new to the scrum process. In scrum what is usually done is that we start off with a base Product backlog which has feature tasks that the client requested. There are a few entities that are involved within the process of Scrum such as;

The Product Owner(PO) – The product owner is the one who gathers requirements from the client and creates and maintains the product backlog. Also he/she is responsible in assigning a priority to each task defined within the product backlog.
The Scrum Master(SM) – The scrum master does not involve with anything specific to the project, but acts as a supervisor helping the team and the product owner to adhere to scrum practices whenever he/she sees that they are deviating from proper processes.
The Team  – is that development team involved in the development as well as the testing of the project features.

Ok now that we have met the people involved in the Scrum, let’s see why it is so awesome. One of the eye catching points of Scrum is the fact that the team decides on the time lines rather than your project manager deciding it for you. I have been any many meetings where the developers stand there like deaf or dumb people and watch as their Project manger do the estimation giving unrealistic deadlines. In scrum the practice is that the team decides along with the PO which tasks they can take on. Usually in Scrum features are taken to fit into one sprint which is more less a month of time. This is the most efficient time as proposed by Scrum. So the team decides what they can achieve within the month and take on the tasks that fit the timeline.

The key feature to note is that they do not make the estimation based on the high level task defined within the Product backlog. They break it down to meaningful development tasks and estimate based on that. If a feature has work for more than one sprint, some features are pushed to the next release. This is a very efficient way of estimating as I see because you do not leave anything out in your estimate and are able to give credible estimates to your Product owner.

Also Scrum is dynamic in which if a customer wants a new feature added on whilst a spring is going on, though they can’t achieve it within this sprint they can always push it to the next sprint  and the wait time of the customer is minimized to just a month.

Also usually whilst a Sprint is coming to an end, the team gets together with the PO to estimate on the upcoming spring to. In scrum momentum is key, which allows teams and companies achieve its development goals in a timely manner without pressurizing the developers with unrealistic deadlines. So the team is aware of upcoming work load as well whilst within the current spring. This is a great feature of scrum the scrum practice. Planning ahead, but not too far ahead.

And also if for any reason they are unable to deliver a feature within the current Sprint they can always push it to the next Sprint and finish off.

As a couple or so Sprints go on, the team gets the feeling of the kind of work it can achieve within a particular sprint which allows them to make timely, accurate estimates on future tasks.
All in all, I believe these agile practices is the way ahead for all companies big or small as the benefits it brings along supersedes the switching costs involved with moving away from your current practices.
What are your thoughts on Scrum? Pls do leave a comment with your own thoughts on the same.

God Bless 

Font resizing and IE

Font Size mishaps

When it comes to declaring font size we know we have a variety of methods in order to achieve it. Few of them are as below;

1.    px – the size in number of pixels
2.    em – the size relative to the parent element
3.    in – the size in inches
4.    cm – the size in centi-meters
And a few others are there as well. On top of these there are a few keywords available to define text size such as;
1.    xx-small
2.    x-small
3.    small
4.    medium
5.    large
6.    x-large
7.    xx-large
In general I have seen many people using px(pixel) definition to markup your text size. Of course this works well out of the box but one caveat it brings along with it is a small scalability issue that I am going to touch upon this article.
To start off lets vamp up a test html plus a css file to go along with it.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
   
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" id="vista"> 
 
 <head>
 <title>Test my font size</title>
 <link rel="stylesheet" href="style.css" type="text/css" media="screen" />
</head>

<body>
<h1>My Awesome Article</h1>
	<p>
		Though i started the heading as my awesome article i do not actually know
		what to write about that simply could be awesome.
	</p>
</body>

</html>

body{
font-size:15px;
font-family:"Times New Roman",Georgia,Serif;
}
h1{
font-size:20px;
}
p{
font-size:18px;
}

Nothing special as you can see. It’s just a simple definition of a header and a paragraph element. And within our style sheet we have defined a font-size attribute specifying it to by 15px which will be the default size on which elements will base on. Now let’s run this and see how this looks like;






Ok looks fine to me. How about you guys? So what is the problem you might ask? You probably must be thinking I’m nuts to assume something was going to be wrong.  Though there is nothing wrong implicitly in this markup it fails in one area where if for an instance a person with bad eye sight wants to increase the default text size through the browser by going to View->Text size in Internet explorer and selecting a text size, the text in our site won’t budge. It will always stay on the default 15px size we defined.

Not what you want for your site right? A website should be accessible, readable no matter if you have a disability or not. So in this instance how are we going to fix this problem with our sites text? We want it to scale according to the user preference.

In order to do that we first need to specify the size in any one of the keywords I mentioned earlier. Afterwards any subsequent element you want to increase/decrease the size, we use percentages to define the size based on the base keyword size we defined. Ok enough words; let’s put this into action shall we?


body{
font-size:small;
font-family:"Times New Roman",Georgia,Serif;
}
h1{
font-size:180%;
}
p{
font-size:90%;
}


So now if we try to resize again we will see this time our text within the page will scale according to the user’s need. Following is a screen shot of the same;


One thing before i forget, for this to work in IE 5 you need to apply something called the Box model hack which was developed by Tantek Celik. . You need this hack because in IE 5 it displays the text one step larger than the font size keyword we define.This is the short version of the same hack defined in the site;

* html body{
font-size:x-small;/* for IE5*/
f\ont-size:small;/* for all other IE versions*/
}

That’s it guys. Most of you might already know this. So for you guys this is just a revision, for all others I hope this helped you in anyway. Comments are as usual always welcome.

God Bless


Wednesday, June 22, 2011

Local time of any country based on GMT with Java

In a recent change request for one application i was working on, it was requested to update the time stamp a certain task was done based on the location of the user. We have a separate Country table stored which has the GMT action and the GMT off set defined in minutes.

I was searching for a way to get the local time of a certain country using the Calendar object. There were many sites that gave various information which led to me finding a work around by testing with various parameters. This is what i came up with in the end.


Following i have encapsulated the final outcome into a method so it would be easier to understand and use if anyone ever needs it;

 public static final String GMT_STR = "GMT";
	public static final String COLON_STR = ":";
	public static final String ZERO = "0";
	
	/**
	 * This method will take as parameters the GMT off set in minutes
	 * as well as the GMT actions i.e + or - and based on that will
	 * output the calendar object representing that specific time in that
	 * location. The GMT is defined in minutes so that the calculation is
	 * simplified.
	 * @param gmtOffSetMins 
	 * @param gmtAction
	 * @return
	 */
	public static Calendar getLocalTime(int gmtOffSetMins,
			String gmtAction) {

		// This will get the quotient part of the division
		int gmtHours = (gmtOffSetMins / 60);
		// This will get the remainder of the division which will give us the
		// minutes portion
		Integer gmtMins = Integer.valueOf((gmtOffSetMins % 60));
		if (gmtMins < 10) {
			gmtMins = Integer.valueOf("0"+gmtMins);
		}
		
		/**
		 * This will produce a String in the format of GMT+5:30
		 */
		String gmtString = null;
		if (gmtMins == 0) {
			gmtString = GMT_STR + gmtAction + gmtHours + COLON_STR + gmtMins+ ZERO;
		} else {
			gmtString = GMT_STR + gmtAction + gmtHours + COLON_STR + gmtMins;
		}

		/**
		 * This calendar object will give you the local time of the specific country
		 * based on the gmt offset hours and the action passed. 
		 */
		return Calendar.getInstance(TimeZone.getTimeZone(TimeZone.getTimeZone(
				gmtString.trim()).getID()));

	}

Thats all you need. The returned calendar will have the local time of that specific country depending on the GMT minutes and action you passed. Note that i have given the GMT in minutes to ease the calculation. Normally you will get the GMT in hours so you will need to convert that to minutes.

Ofcourse when daylight savings come into play you will need to change this accordingly. For our application this was not needed so we didnt do that change. To handle daylight savings we will have to keep the day light saving changes somewhere and deduct or add appropriately to the base GMT.

If you guys know anyway of doing this in a much simpler way or you have any suggestions for improvements pls do leave by a comment which is as always much appreciated.

Cheers Guys!!!!

Thursday, May 5, 2011

Struts 2 and Annotations

Googling around i saw there wasnt any concise article explaining how to integrate Struts 2 with annotations. I will keep this as simple as possible because,well the struts developers have done some awesome work to make it as simple as they can. I will create a sample maven project showing you how to integrate struts 2.

Ok first off lets go ahead and create our maven project.Im going with a maven project because its just easier to create a war and dependencies required for struts as well. So below is my project root pom;

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">



 <modelVersion>4.0.0</modelVersion>

 <groupId>com.myexamples</groupId>

 <artifactId>my-struts-sample</artifactId>

 <packaging>war</packaging>

 <version>1.0-SNAPSHOT</version>

 <name>My Struts Example</name>

 <dependencies>



  





  <dependency>

   <groupId>javax</groupId>

   <artifactId>javaee-api</artifactId>

   <version>6.0</version>

   <scope>provided</scope>

  </dependency>





  



  <dependency>

   <groupId>commons-collections</groupId>

   <artifactId>commons-collections</artifactId>

   <version>3.2.1</version>

  </dependency>



  <dependency>

   <groupId>commons-logging</groupId>

   <artifactId>commons-logging</artifactId>

   <version>1.1.1</version>

  </dependency>



  <dependency>

   <groupId>commons-configuration</groupId>

   <artifactId>commons-configuration</artifactId>

   <version>1.6</version>

  </dependency>



  <dependency>

   <groupId>commons-lang</groupId>

   <artifactId>commons-lang</artifactId>

   <version>2.5</version>

  </dependency>









  <dependency>

   <groupId>org.slf4j</groupId>

   <artifactId>slf4j-log4j12</artifactId>

   <version>1.5.2</version>

   <scope>provided</scope>

  </dependency>

  <dependency>

   <groupId>log4j</groupId>

   <artifactId>log4j</artifactId>

   <version>1.2.16</version>

   <scope>provided</scope>

  </dependency>



  

  <dependency>

   <groupId>junit</groupId>

   <artifactId>junit</artifactId>

   <version>4.8.1</version>

   <scope>test</scope>

  </dependency>

  







  <dependency>

   <groupId>com.sun</groupId>

   <artifactId>tools</artifactId>

   <version>1.4.2</version>

   <scope>system</scope>

   <systemPath>${java.home}/../lib/tools.jar

   </systemPath>

  </dependency>



  <dependency>

   <groupId>org.apache.struts</groupId>

   <artifactId>struts2-core</artifactId>

   <version>2.0.6</version>

  </dependency>





  



  

  <!-- standard.jar -->

  <dependency>

   <groupId>taglibs</groupId>

   <artifactId>standard</artifactId>

   <version>1.1.2</version>

  </dependency>



  <!-- JSTL -->

  <dependency>

   <groupId>javax.servlet</groupId>

   <artifactId>jstl</artifactId>

   <version>1.1.2</version>

  </dependency>

  

 



 </dependencies>



 <build>

  <plugins>

   <plugin>

    <groupId>org.apache.maven.plugins</groupId>

    <artifactId>maven-war-plugin</artifactId>

    <version>2.0</version>

    <configuration>



     <archive>

      <manifest>

       <addClasspath>true</addClasspath>

       <classpathPrefix>lib/</classpathPrefix>

      </manifest>

     </archive>

     <webResources>

      <resource>

       <!-- this is relative to the pom.xml directory -->

       <directory>${project.basedir}/resources

       </directory>



      </resource>

     </webResources>

     <outputDirectory>${env.JBOSS_HOME}/server/default/deploy</outputDirectory>

     <warName>my-struts-sample</warName>

    </configuration>

   </plugin>

  </plugins>

 </build>



</project>


The structure of the project will be as follows;

    my-struts-sample
            |
            |
            --------->pom.xml
            |
            |
            ----->resources
            |        |
            |        |
            |        ----->js
            |
            ----->src
                   |
                   |
                   ------->main
                             |
                             |
                             ----->webapp
                                     |
                                     |
                                     ------->index.html
                                     |
                                     |
                                     ------->WEB-INF
                                                |
                                                |
                                                ------>web.xml
                                                |
                                                |
                                                ------>jsp
                                                        |
                                                        |
                                                        ------>test
                                                                |
                                                                |
                                                                ---->test.html

That is the normal structure of any maven project. This will create the war file and deploy it within your jboss as i have mentioned to get it from JBOSS_HOME in my pom.xml. You can change it as you need depending on your server.

Afterwards lets create our first action class given below;

package com.test..myexample;
import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.config.Result;
import org.apache.struts2.config.Results;
import org.apache.struts2.interceptor.ServletRequestAware;

@Results({
    @Result(name="success", value="/public/showTest")
})

public class ShowTestAction implements ServletRequestAware{
 
 private HttpServletRequest request;
 
 public void setServletRequest(HttpServletRequest request) {
  this.request = request;
 }
 
 public String  execute(){
  return "success";
 }
}


This is a simple action class. Few things to note here. Always your Action class name should end with the name Action, else it wont get recognized as an action class during package scan phase which i will explain later. For now i am only returning success. You can add more Results as you deem appropriate to handle error situations and others. I have injected the HttpServletRequest instance here as well because almost always you will require this to read your parameters or attributes. Now that you have your action class lets see how we can map out our web.xml and configure struts 2.



<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

 


 <filter>
  <filter-name>struts2</filter-name>
  <filter-class>
   org.apache.struts2.dispatcher.FilterDispatcher
  </filter-class>
  <init-param>
   <param-name>actionPackages</param-name>
   <param-value>
      com.test..myexample
          </param-value>
  </init-param>
 </filter>

 

 <filter-mapping>
  <filter-name>struts2</filter-name>
  <url-pattern>*.action</url-pattern>
 </filter-mapping>

 <servlet>
  <servlet-name>mytest</servlet-name>
  <jsp-file>/WEB-INF/jsp/test/test.html</jsp-file>
 </servlet>

 <servlet-mapping>
  <servlet-name>mytest</servlet-name>
  <url-pattern>/public/showTest</url-pattern>
 </servlet-mapping>

</web-app>

There are a few things to note here. One is that we have defined a filter called struts 2. Within that we have specified an attribute called actionPackages. This is the place where we define the package name in which our action classes reside in. If you have many packages then you can have comma separated package names specified within the param-value attribute.

Next we have specified a filter-mapping attribute. This says that all urls ending with .action should go through the org.apache.struts2.dispatcher.FilterDispatcher which in turn will search in all packages defined to see which action should be called. Hope that is clear to you guys. The rest is just normal servlet mapping which all of you should be familiar with.

Now i will show you the index.html which just does a simple redirect calling our action class which in turn will display our test.html according the success mapping name defined within the action class.


<html>
<head>My Home Page</head>
<body>


<script type="text/javascript">
location.replace('showTest.action');
</script>
</body>
</html>

Here we are saying to redirect to showTest.action. Note that your action name was ShowTestAction. But when you call it you should always make sure the name starts with a simple letter and ends with .action or else it would not be recognized by the struts Filter Dispatcher.

Thats about it guys. I did not give the implementation of the test.html because that can be anything you want. Please feel free to leave a comment if you have any doubts or clarification regarding the tutorial provided. mvn clean install and your good to go with struts 2 with annotations :)

Cheers guys

Thursday, April 28, 2011

Secure your webservices with JBoss

WS-SEC is a vast area in it self and trying to cover the whole topic in one blog post is just not possible. So ill be touching on a glimpse of it by showing you how to achieve ws-sec with Jboss with the least amount of effort.

In simplest terms WS-SEC is more or less the same as what you do when you log into a website by providing your user name and password. Only difference is in this case you provide your credentials to gain access to the web service you are trying to access.

People use WS-SEC in order to protect their web service from being used by unknown third parties. There always might be instances in which you would want to restrict access to certain web services as they process and handle confidential data. For this situation WS-SEC is a must. Adding HTTPS would guarantee transport leve security for your Web service as well. But in this article i will only focus on securing your web service through WS-SEC as there are many articles explaining how to expose it on HTTPS.

Note that i will be creating the web service using the @Webservice annotation(a.k.a code first approach). Following i have given the web service we are going to use for our example;

package com.myservices;
@WebService(serviceName = "MyService", portName = "MyServicePort", targetNamespace = "personlaservices")
@Stateless
@HandlerChain(file = "myconfigs/webservices/security_handler.xml")
public class MySecurityService {

 @WebMethod
 public String sayMyName(){
  return "Iron Man!!!";
 }

}

Note that i have just a simple method with a string output. The important thing to note here is the @HandlerChain attribute. This refers to an XML we define which i will show below which defines the class which will handle the authentication by reading the user name and password which comes in the header part of the soap message enclosed within the ws-sec tag. Note that the xml file path is relative to the classpath. I have placed the folder myconfigs within the conf directory of jboss.

The Configuration XML security_handler.xml is as follows;

<?xml version="1.0" encoding="UTF-8"?>



<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">



 <!-- Note:  The '*" denotes a wildcard. -->



 <handler-chain>

  <handler>

   <handler-name>com.myservice.security.AuthenticateHandler</handler-name>

   <handler-class>com.myservice.security.AuthenticateHandler

   </handler-class>

  </handler>

 </handler-chain>

</handler-chains>


This defines a class called AuthenticationHandler which will retrieve the user name and password contained within the soap message and do the authentication using the JBoss login module with the security realm defined which i will not go into detail as we all know how to handle security within JBoss. but you can use any authentication mechanism you want here.

/**
 * 
 */
package com.myservice.security;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.Name;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.apache.log4j.Logger;



/**
 * Handler to authenticate the requests send in by the user from information provided through soap-headers.
 */
public class AuthenticateHandler implements SOAPHandler<SOAPMessageContext> {

    /** The Constant logger. */
    private static final Logger logger = Logger.getLogger(AuthenticateHandler.class);

    /** The Constant USERNAME_TOKEN_STRING. */
    private static final String USERNAME_TOKEN_STRING = "UsernameToken";

    /** The Constant USERNAME_STRING. */
    private static final String USERNAME_STRING = "Username";

    /** The Constant ARG_0_STRING. */
    private static final String ARG_0_STRING = "arg0";

    /** The Constant PASSWORD_STRING. */
    private static final String PASSWORD_STRING = "Password";


    private static final String HIGHPHEN = "-";

    /*
     * (non-Javadoc)
     * @see javax.xml.ws.handler.Handler#handleFault(javax.xml.ws.handler.MessageContext)
     */
    public boolean handleFault(SOAPMessageContext context) {
        // throw new UnsupportedOperationException("Not supported yet.");
        logger.debug("handleFault() is called");
        return true;
    }

    /*
     * (non-Javadoc)
     * @see javax.xml.ws.handler.Handler#handleMessage(javax.xml.ws.handler.MessageContext)
     */
    public boolean handleMessage(SOAPMessageContext smc) {

        SOAPMessage message = smc.getMessage();
        Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        boolean authenticated = false;

        try {

            // Let's extract information and try to log XML.
            SOAPPart sp = message.getSOAPPart();
            SOAPEnvelope envelope = sp.getEnvelope();

           
            if (!outboundProperty) {

                SOAPHeader header = envelope.getHeader();

                if (header != null) {
                    authenticated = processSOAPHeader(header);
                }

            }

        } catch (SOAPException se) {
            logger.error("SOAPException occured while processing the message", se);

        }
        return authenticated;
    }

    /**
     * Gets the sOAP message as string.
     * 
     * @param msg the msg
     * @return the sOAP message as string
     */
    private String getSOAPMessageAsString(SOAPMessage msg) {

        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            msg.writeTo(baos);
            return baos.toString();

        } catch (IOException ioe) {
            logger.warn("Could not extract XML from soap message", ioe);
            return null;
        } catch (SOAPException se) {
            logger.warn("Could not extract XML from soap message", se);
            return null;
        }
    }

    /**
     * Process soap header. This method is called by handleRequest method It retrieves the SOAP headers in the message
     * and authenticates the client.
     * 
     * @param sh the soap header
     * @return true, if successful
     */
    private boolean processSOAPHeader(SOAPHeader sh) {
        boolean authenticated = false;

        // look for authentication header element inside the HEADER block
        Iterator childElems = sh.getChildElements();

        SOAPElement child = extractUserNameInfo(childElems);

        if (child != null) {

            // call method to perform authentication
            authenticated = authenticateRequest(child);
        }
        return authenticated;
    }

    /**
     * Extract user name info.
     * 
     * @param childElems the child elems
     * @return the sOAP element
     */
    private SOAPElement extractUserNameInfo(Iterator childElems) {

        logger.debug("extractUserNameInfo called.");

        SOAPElement child = null;
        Name sName;

        // iterate through child elements
        while (childElems.hasNext()) {
            Object elem = childElems.next();

            if (elem instanceof SOAPElement) {

                // Get child element and its name
                child = (SOAPElement) elem;
                sName = child.getElementName();

                // Check whether there is a UserNameToken element
                if (!USERNAME_TOKEN_STRING.equalsIgnoreCase(sName.getLocalName())) {

                    if (child.getChildElements().hasNext()) { // TODO check logic
                        return extractUserNameInfo(child.getChildElements());
                    }
                }
            }
        }

        return child;
    }

    /**
     * Authenticate request. This method retrieves the authentication information for the request header and validates
     * it.
     * 
     * @param element the element
     * @return true, if successful
     */
    private boolean authenticateRequest(SOAPElement element) {

        logger.debug("authenticateRequest called");
        boolean authenticated = false;

        // variable for user name and password
        String userName = null;
        String password = null;
        Name sName;

        // get an iterator on child elements of SOAP element
        Iterator childElems = element.getChildElements();

        SOAPElement child;
        // loop through child elements

        while (childElems.hasNext()) {
            // get next child element
            Object elem = childElems.next();

            if (elem instanceof SOAPElement) {
                child = (SOAPElement) elem;

                // get the name of SOAP element
                sName = child.getElementName();

                // get the value of username element
                if (USERNAME_STRING.equalsIgnoreCase(sName.getLocalName())) {
                    logger.debug("---UserName =" + child.getValue());
                    userName = child.getValue();
                } else if (PASSWORD_STRING.equalsIgnoreCase(sName.getLocalName())) {
                    // get the value of password element
                    password = child.getValue();
                }

                if (userName != null && password != null) {

                   
   /**
       Note that in this instance i have used my custom used class
       called ClientLoginModule whic wraps a JBossLoginModule instance.
         You can use your own authentication mechanism as you have the user name
        and password at this point.
   **/
                        ClientLoginModule.login("WEBSERVICE" + "^" + userName, password);
                        return true;
                  

                    break;
                }

            }
        }

        if (userName == null || password == null) {
            logger.warn("Username or password is empty. userName : [" + userName + "], password : [" + password + "]");
        }

        return authenticated;

    }

    

    /**
     * Extract TCI info.
     * 
     * @param childElems the child elems
     * @return the sOAP element
     */
    private SOAPElement extractTCIInfo(Iterator childElems) {

        logger.debug("extractTCIInfo called.");

        SOAPElement child = null;
        Name sName;

        // iterate through child elements
        while (childElems.hasNext()) {
            Object elem = childElems.next();

            if (elem instanceof SOAPElement) {

                // Get child element and its name
                child = (SOAPElement) elem;
                sName = child.getElementName();

                // Check whether there is a UserNameToken element
                if (!ARG_0_STRING.equalsIgnoreCase(sName.getLocalName())) {

                    if (child.getChildElements().hasNext()) {
                        return extractTCIInfo(child.getChildElements());
                    }
                }
            }
        }

        return child;
    }

    /*
     * (non-Javadoc)
     * @see javax.xml.ws.handler.soap.SOAPHandler#getHeaders()
     */
    public Set<QName> getHeaders() {
        logger.debug("--- In AuthenticateHandler.getHeaders ()");
        // return headers;
        return null;
    }

    /*
     * (non-Javadoc)
     * @see javax.xml.ws.handler.Handler#close(javax.xml.ws.handler.MessageContext)
     */
    public void close(MessageContext context) {
        logger.debug("close() is called");
        // throw new UnsupportedOperationException("Not supported yet.");
    }

}

This class extracts the user name and password as you can see within the method authenticateRequest() and authenticates the user. If authentication fails it will return false from within handleMessage(). Note that i have used a class called ClientLoginModule. This is a class i have written which extends JBoss Login Module. I did not go into much detail with that due to the fact that it is already known to anyone who has dealt with jboss user security handling.

Now that we have these two methods you just need to bundle this up and run jboss which will expose the wsdl of this service. In jboss you can see what current web services are being hosted on your server by going to the URL http://localhost:8080/jbossws/services where 8080 is the port you expose your jboss on.

After you get your wsdl you need to generate the stubs by running any tool such as wsimport which does the wsdl to java transformation for you. Check here for more information.

Assuming you got your stubs generated and constructed a jar containing your code i will show you how to consume this ws-sec enabled webservice through a client.


try {
            URL wsdlLocation = new URL("http://localhost:8080/MyService");

            QName qName = new QName("personlaservices", "MyService");

            Service service = null;
            service = Service.create(wsdlLocation, qName);
            
     /**
  HeaderHandlerResolve will pass this information to a HeaderHandler implementation
  class which will embed the user name and password passed in to the ws-security
  header within the soap header element
     **/
            HeaderHandlerResolver handlerResolver = new HeaderHandlerResolver("myusername","mypassword");
            service.setHandlerResolver(handlerResolver);

            MySecurityService servicePort = service.getPort(MySecurityService.class);

     System.out.println(servicePort.sayMyName());
        } catch (MalformedURLException mue) {
            logger.warn("An error occurred while getting the wsdl location.", mue);
        }

Here i first create an instance of the javax.xml.ws.Service class using the URL, namespace and the service name we provided within our web service implementation we specified earlier. Next the important thing to note here is we define a custom HeaderHandlerResolver which we set to the service. I will show you the implementation of the HeaderhandlerResolver as well as the HeaderHandler which is used within the HeaderHandlerResolver class so that you can understand what happens.

/**
 * 
 */
package com.myservice.client;

import java.util.ArrayList;
import java.util.List;

import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;

/**
 * Taken from www.javadb.com and modified.
 * 
 * @author www.javadb.com
 */
public class HeaderHandlerResolver implements HandlerResolver {

    private String userName;

    private String password;

    public HeaderHandlerResolver() {
        super();

    }

    public HeaderHandlerResolver(String userName,String password) {
        super();
 this.userName = userName;
 this.password = password;
    }

    @SuppressWarnings("unchecked")
    public List<Handler> getHandlerChain(PortInfo portInfo) {
        List<Handler> handlerChain = new ArrayList<Handler>();

        HeaderHandler hh = new HeaderHandler(userName,password);

        handlerChain.add(hh);

        return handlerChain;
    }
}


The Header Handler implementation is the one which embeds the ws-security header to the soap header as you can see from the below code;


/**
 * 
 */
package com.myservice.client;

import java.io.ByteArrayOutputStream;
import java.util.Set;

import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

import org.apache.log4j.Logger;



/**
 * Taken from www.javadb.com and modified.
 * 
 * @author www.javadb.com
 */
public class HeaderHandler implements SOAPHandler<SOAPMessageContext> {

    /** The Constant logger. */
    private static final Logger logger = Logger.getLogger(HeaderHandler.class);

    /** The Constant WS_SECURITY_SECEXT_URI. */
    private static final String WS_SECURITY_SECEXT_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";

    /** The Constant WS_SECURITY_UTILITY_URI. */
    private static final String WS_SECURITY_UTILITY_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";

    /** The Constant WS_PASSWORD_TYPE_URI. */
    private static final String WS_PASSWORD_TYPE_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";

    /** The Constant WSSE_PREFIX. */
    private static final String WSSE_PREFIX = "wsse";

    /** The Constant SECURITY_LOCAL_NAME. */
    private static final String SECURITY_LOCAL_NAME = "Security";

    /** The Constant USERNAME_TOKEN_LOCAL_NAME. */
    private static final String USERNAME_TOKEN_LOCAL_NAME = "UsernameToken";

    /** The Constant LOCAL_PART_XMLNS_WSU. */
    private static final String LOCAL_PART_XMLNS_WSU = "wsu";

    /** The Constant USERNAME_LOCAL_NAME. */
    private static final String USERNAME_LOCAL_NAME = "Username";

    /** The Constant PASSWORD_LOCAL_NAME. */
    private static final String PASSWORD_LOCAL_NAME = "Password";

    /** The Constant PASSWORD_ATTRIBUTE_TYPE. */
    private static final String PASSWORD_ATTRIBUTE_TYPE = "Type";

    private static final String HIGHPHEN = "-";

    private String userName;

    private String password;

    public HeaderHandler(String userName,String password) {
        this.userName = userName;
 this.password = password;
    }

    /*
     * (non-Javadoc)
     * @see javax.xml.ws.handler.Handler#handleMessage(javax.xml.ws.handler.MessageContext)
     */
    public boolean handleMessage(SOAPMessageContext smc) {

        Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        SOAPMessage message = smc.getMessage();

        try {

            // Let's extract information and try to log XML.
            SOAPPart sp = message.getSOAPPart();
            SOAPEnvelope envelope = sp.getEnvelope();

         

            if (outboundProperty.booleanValue()) {

                SOAPHeader header = envelope.getHeader();

                if (header != null) {
                    header.detachNode();
                }

                header = envelope.addHeader();

                SOAPElement security = header.addChildElement(SECURITY_LOCAL_NAME, WSSE_PREFIX, WS_SECURITY_SECEXT_URI);

                SOAPElement usernameToken = security.addChildElement(USERNAME_TOKEN_LOCAL_NAME, WSSE_PREFIX);

                QName qName = new QName(XMLConstants.NULL_NS_URI, LOCAL_PART_XMLNS_WSU);
                usernameToken.addAttribute(qName, WS_SECURITY_UTILITY_URI);

                SOAPElement username = usernameToken.addChildElement(USERNAME_LOCAL_NAME, WSSE_PREFIX);

                username.addTextNode(userName);

                SOAPElement password = usernameToken.addChildElement(PASSWORD_LOCAL_NAME, WSSE_PREFIX);
                password.setAttribute(PASSWORD_ATTRIBUTE_TYPE, WS_PASSWORD_TYPE_URI);

                password.addTextNode(password);

            }

        } catch (SOAPException se) {
            logger.error("SOAPException occured while processing the message", se);

        }

        return outboundProperty;

    }

    /**
     * Gets the sOAP message as string.
     * 
     * @param msg the msg
     * @return the sOAP message as string
     */
    private String getSOAPMessageAsString(SOAPMessage msg) {

        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            msg.writeTo(baos);
            return baos.toString();

        } catch (Exception e) {
            logger.warn("Could not extract XML from soap message");
            return null;
        }
    }

    /*
     * (non-Javadoc)
     * @see javax.xml.ws.handler.soap.SOAPHandler#getHeaders()
     */
    public Set<QName> getHeaders() {
        // throw new UnsupportedOperationException("Not supported yet.");
        logger.info("getHeaders() is called");
        return null;
    }

    /*
     * (non-Javadoc)
     * @see javax.xml.ws.handler.Handler#handleFault(javax.xml.ws.handler.MessageContext)
     */
    public boolean handleFault(SOAPMessageContext context) {
        // throw new UnsupportedOperationException("Not supported yet.");
        logger.info("handleFault() is called");
        return true;
    }

    /*
     * (non-Javadoc)
     * @see javax.xml.ws.handler.Handler#close(javax.xml.ws.handler.MessageContext)
     */
    public void close(MessageContext context) {
        logger.info("close() is called");
        // throw new UnsupportedOperationException("Not supported yet.");
    }
}


Thats about it guys. Withing the handleMessage() method in the above class you can see we are embedding the user name and password to the ws-security header element which is part of the soap header. So now when you call your web service the message wil go through the HeaderHandlerResolver which will pass it on to the Header Handler which in turn will embed the ws-security header before passing on the soap request.

If you have any questions or if there are any areas of improvement you see please do leave a comment which is as always highly appreciated.


Cheers Guys!!!