Apache Axis Web Service with Maven (modified)

I have modified the existing SOAP web service project here -> https://mattisee.wordpress.com/2013/10/04/creating-a-simple-web-service-using-apache-axis-1-4/ with some minor modifications to use Maven for deployment.The command line to generate the stubs is still the same, but with javax.mail.jre15_1.4.1 jar added:

new -> Maven project on Eclipse


set LIB_HOME=D:\GitWorkspace\packages\axis-bin-1_4\axis-1_4\lib

set SERVER_IMPL_HOME=D:\OxygenWorkspace2\githubws\axisExample\AxisServerExample

//Screenshot of the library below
//LIB_HOME is the lib folder of the axis installation with javax.mail.jre15_1.4.1 jar added to the axis library.

//SERVER_IMPL points to the project root created as a Maven project

axis_installation_lib
To create the wsdl file from java code ->

java -cp "%LIB_HOME%/axis-ant.jar;%LIB_HOME%/axis.jar;%LIB_HOME%/commons-discovery-0.2.jar;%LIB_HOME%/commons-logging-1.0.4.jar;%LIB_HOME%/jaxrpc.jar;%LIB_HOME%/log4j-1.2.8.jar;%LIB_HOME%/saaj.jar;%LIB_HOME%/wsdl4j-1.5.1.jar;%LIB_HOME%/javax.mail.jre15_1.4.1.jar;%SERVER_IMPL_HOME%\target\classes" org.apache.axis.wsdl.Java2WSDL -o %SERVER_IMPL_HOME%/src/main/resources/mattiz.wsdl -l "http://localhost:8080/axis/services/MattizAxisTest" -n urn:mattiz -p"mattiz" urn:mattiz com.mattiz.ws.axis.server.impl.MattizAxisServerImpl

To create the stubs from the generated wsdl->

java -cp "%LIB_HOME%/axis-ant.jar;%LIB_HOME%/axis.jar;%LIB_HOME%/commons-discovery-0.2.jar;%LIB_HOME%/commons-logging-1.0.4.jar;%LIB_HOME%/jaxrpc.jar;%LIB_HOME%/log4j-1.2.8.jar;%LIB_HOME%/saaj.jar;%LIB_HOME%/wsdl4j-1.5.1.jar;%LIB_HOME%/javax.mail.jre15_1.4.1.jar;" org.apache.axis.wsdl.WSDL2Java -o %SERVER_IMPL_HOME%/src/main/java -p com.mattiz.axis.request -s %SERVER_IMPL_HOME%/src/main/resources/mattiz.wsdl

Follow the remaining instructions without change, but leave out the build.xml.Instead use run as maven install on the pom.xml (uploaded to git)
To generate the server-config file (wsdd) in the Axis tomcat installation run this on command line

java -cp ""%LIB_HOME%/axis-ant.jar;"%LIB_HOME%/axis.jar;"%LIB_HOME%/commons-discovery-0.2.jar;"%LIB_HOME%/commons-logging-1.0.4.jar;"%LIB_HOME%/jaxrpc.jar;"%LIB_HOME%/log4j-1.2.8.jar;"%LIB_HOME%/saaj.jar;"%LIB_HOME%/wsdl4j-1.5.1.jar" org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService %SERVER_IMPL_HOME%/src/main/java/com/mattiz/axis/request/deploy.wsdd

There are no changes on the client side. And since this is a standalone application I have not created a Maven project for this. Neither is there a build.xml.
The maven pom.xml for the server project is here->

<project>
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.mattiz.axis</groupId>
	<artifactId>AxisServerExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>mattiz</name>
	<description>Axis Server Example</description>
	<properties>
		<mavenVersion>2.0</mavenVersion>
	</properties>
	<scm>
		<url>http://svn.apache.org/viewcvs/webservices/axis/trunk/java</url>
	</scm>
	<dependencies>
		<dependency>
			<groupId>org.apache.axis</groupId>
			<artifactId>axis</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency><!-- depends on nothing; I think -->
			<groupId>axis</groupId>
			<artifactId>axis-jaxrpc</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency><!-- depends on nothing; I think -->
			<groupId>axis</groupId>
			<artifactId>axis-saaj</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency><!-- depends on nothing; I think -->
			<groupId>axis</groupId>
			<artifactId>axis-wsdl4j</artifactId>
			<version>1.5.1</version><!-- version independent of axis -->
			<scope>runtime</scope>
			<!-- note: also at wsdl4j:wsdl4j (a sf.net project) -->
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.0.4</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>commons-discovery</groupId>
			<artifactId>commons-discovery</artifactId>
			<version>0.2</version>
			<scope>runtime</scope>
		</dependency>
		<!-- -->
		<dependency>
			<groupId>org.apache.axis2</groupId>
			<artifactId>axis2-java2wsdl</artifactId>
			<version>1.7.6</version>
		</dependency>
	</dependencies>
	<repositories>
		<repository>
			<id>axis</id>
			<name>Axis repo</name>
			<layout>default</layout>
			<url>https://mvnrepository.com/artifact/org.apache.axis/axis</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>axis2</id>
			<name>Axis2 repo</name>
			<layout>default</layout>
			<url>https://mvnrepository.com/artifact/axis/axis-jaxrpc</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>axis3</id>
			<name>Axis3 repo</name>
			<layout>default</layout>
			<url>https://mvnrepository.com/artifact/org.apache.axis2/axis2-java2wsdl</url>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>
	<pluginRepositories>
		<pluginRepository>
			<id>central</id>
			<name>Maven Plugin Repository</name>
			<url>http://repo1.maven.org/maven2</url>
			<layout>default</layout>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
			<releases>
				<updatePolicy>never</updatePolicy>
			</releases>
		</pluginRepository>
	</pluginRepositories>
	<build>
		<finalName>mattiz</finalName>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
			</resource>
		</resources>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>3.2.0</version>
				<configuration>
					<webappDirectory>/output/deploy/directory</webappDirectory>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

The source code has been uploaded to git here.
https://github.com/CuppajavaMattiz/mattiz/tree/master/new_mattiz
Cheers!

Cuppajava git hub site

Some of the code you see here on the blog has been uploaded to the git hub site at
https://github.com/CuppajavaMattiz/mattiz

Thanks,
Cuppajava Mattiz

PDF creation using iText – An example

The main class:

PdfGnerator.java

package com.matttiz.itext.pdf.generator;

import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.xml.parsers.ParserConfigurationException;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.Image;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;
import com.matttiz.itext.pdf.vo.AddressVO;
import com.matttiz.itext.pdf.vo.GoogleMapBean;

public class PdfGenerator {

	protected static Font smallfont = new Font(Font.HELVETICA, 8, Font.NORMAL);
	protected static Font middlefont = new Font(Font.HELVETICA, 8, Font.BOLD);
	protected static Font sealfont = new Font(Font.HELVETICA, 6, Font.NORMAL);
	protected static Font bigfont = new Font(Font.HELVETICA, 12, Font.BOLD);

	public byte[] createTable(Document document, AddressVO addressVO, List<GoogleMapBean> googleMapBeanList)
			throws IOException, DocumentException, ParserConfigurationException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		PdfWriter.getInstance(document, baos);
		document.open();
		try {
			HeaderFooter header = new HeaderFooter(new Paragraph("This is the Document Header", FontFactory.getFont("Arial", 7)),
					true);
			document.setHeader(header);
			PdfPCell headerDetail = new PdfPCell(headerSection());
			PdfPTable additionTable = new PdfPTable(1);
			headerDetail.setBorder(0);
			additionTable.addCell(new PdfPCell(headerDetail));

			PdfPCell addressDetailsSectionCell = new PdfPCell(addressDetailsSection(addressVO));
			addressDetailsSectionCell.setBorder(0);
			additionTable.addCell(new PdfPCell(addressDetailsSectionCell));

			PdfPCell googleBeanListCell = new PdfPCell(googleMapSection(googleMapBeanList));
			googleBeanListCell.setBorder(0);
			additionTable.addCell(new PdfPCell(googleBeanListCell));

			additionTable.setTotalWidth(1024);
			additionTable.setWidthPercentage(100);
			additionTable.completeRow();
			document.add(additionTable);
		} catch (BadElementException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		document.close();
		return baos.toByteArray();
	}

	private PdfPTable headerSection() throws IOException, BadElementException {
		PdfPTable additionTable = new PdfPTable(6);
		PdfPCell imageCell = new PdfPCell();
		imageCell.setBorder(0);
		InputStream inps = this.getClass().getClassLoader().getResourceAsStream("mattiz.properties");
		Properties cache = new Properties();
		cache.load(inps);
		String imageUrl = cache.getProperty("MattizLogoLocation");
		Image img = Image.getInstance(imageUrl);
		if (img.getScaledWidth() > 70 || img.getScaledHeight() > 70) {

			img.scaleToFit(50, 50);
		}
		imageCell = new PdfPCell(img);
		imageCell.setBorder(0);
		additionTable.addCell(imageCell);
		PdfPTable imageAndHeaderTable = new PdfPTable(1);
		Color darkCyan = new Color(0, 139, 139);
		Font fontColor = new Font(BaseFont.FONT_TYPE_T1, 12f, 1, darkCyan);
		PdfPCell header1Cell = new PdfPCell(new Paragraph("Example iText PDF With Logo, Array and Individual Cells", fontColor));
		header1Cell.setBorder(0);
		header1Cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER);
		imageAndHeaderTable.addCell(header1Cell);
		PdfPCell header2Cell = new PdfPCell(
				new Paragraph("Cuppajava Mattiz", middlefont));
		header2Cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER);
		header2Cell.setBorder(0);
		imageAndHeaderTable.addCell(header2Cell);
		PdfPCell header3Cell = new PdfPCell(new Paragraph("Tips from A Mentor to His Protege", smallfont));
		header3Cell.setBorder(0);
		header3Cell.setHorizontalAlignment(Rectangle.ALIGN_CENTER);
		imageAndHeaderTable.addCell(header3Cell);
		PdfPCell layoutCell = new PdfPCell(imageAndHeaderTable);
		layoutCell.setBorder(0);
		layoutCell.setColspan(5);
		additionTable.addCell(layoutCell);
		return additionTable;
	}

	private PdfPTable addressDetailsSection(AddressVO addressVO) throws IOException, BadElementException {
		PdfPTable additionTable = new PdfPTable(3);

		PdfPCell c001 = new PdfPCell(new Paragraph(" ", middlefont));
		c001.setColspan(3);
		c001.setHorizontalAlignment(Rectangle.ALIGN_LEFT);
		c001.setBorder(0);
		additionTable.addCell(c001);

		PdfPCell c01 = new PdfPCell(new Paragraph("Postal Address", middlefont));
		c01.setColspan(3);
		c01.setHorizontalAlignment(Rectangle.ALIGN_LEFT);
		c01.setBorder(0);
		additionTable.addCell(c01);

		PdfPCell c02 = new PdfPCell(new Paragraph("____________", middlefont));
		c02.setColspan(3);
		c02.setHorizontalAlignment(Rectangle.ALIGN_LEFT);
		c02.setBorder(0);
		additionTable.addCell(c02);

		PdfPCell c1 = new PdfPCell(getLabelAndDataParagraph("Address Line 1: ", addressVO.getAddressLine1()));
		c1.setBorder(0);
		additionTable.addCell(c1);
		PdfPCell c2 = new PdfPCell(getLabelAndDataParagraph("Address Line 2: ", addressVO.getAddressLine2()));
		c2.setBorder(0);
		additionTable.addCell(c2);
		PdfPCell c3 = new PdfPCell(getLabelAndDataParagraph("City: ", addressVO.getCity()));
		c3.setBorder(0);
		additionTable.addCell(c3);

		PdfPCell c4 = new PdfPCell(getLabelAndDataParagraph("State: ", addressVO.getState()));
		c4.setBorder(0);
		additionTable.addCell(c4);

		PdfPCell c5 = new PdfPCell(getLabelAndDataParagraph("State: ", addressVO.getState()));
		c5.setBorder(0);
		additionTable.addCell(c5);

		PdfPCell c6 = new PdfPCell(getLabelAndDataParagraph("Country: ", addressVO.getCountry()));
		c6.setBorder(0);
		additionTable.addCell(c6);

		PdfPCell c7 = new PdfPCell(getLabelAndDataParagraph("Pin Code: ", addressVO.getPinCode()));
		c7.setBorder(0);
		additionTable.addCell(c7);

		PdfPCell c8 = new PdfPCell(getLabelAndDataParagraph("Land Mark: ", addressVO.getLandMark()));
		c8.setBorder(0);
		additionTable.addCell(c8);
		return additionTable;
	}

	private PdfPTable googleMapSection(List<GoogleMapBean> googleMapBeanList) throws IOException, BadElementException {
		PdfPTable additionTable = new PdfPTable(3);
		PdfPCell titleCell = new PdfPCell(new Paragraph("Geographical Locations", middlefont));
		titleCell.setHorizontalAlignment(Rectangle.ALIGN_CENTER);
		titleCell.setColspan(3);
		titleCell.setBorder(0);
		additionTable.addCell(titleCell);
		PdfPTable subTable2 = null;
		PdfPCell headerCell1 = new PdfPCell(new Paragraph("Location", middlefont));
		headerCell1.setColspan(1);
		additionTable.addCell(headerCell1);
		PdfPCell headerCell2 = new PdfPCell(new Paragraph("Latitude", middlefont));
		headerCell2.setColspan(1);
		additionTable.addCell(headerCell2);
		PdfPCell headerCell3 = new PdfPCell(new Paragraph("Longitude", middlefont));
		headerCell3.setColspan(1);
		additionTable.addCell(headerCell3);
		if (googleMapBeanList.size() > 0) {
			subTable2 = new PdfPTable(3);
			for (GoogleMapBean googleMapBean : googleMapBeanList) {
				PdfPCell locationInnerCell = new PdfPCell(new Paragraph(googleMapBean.getLocation(), smallfont));
				locationInnerCell.setColspan(1);
				subTable2.addCell(locationInnerCell);
				PdfPCell latitudeInnerCell = new PdfPCell(new Paragraph(googleMapBean.getLatitude() + "", smallfont));
				latitudeInnerCell.setColspan(1);
				subTable2.addCell(latitudeInnerCell);
				PdfPCell longitudeInnerCell = new PdfPCell(new Paragraph(googleMapBean.getLongitude() + "", smallfont));
				longitudeInnerCell.setColspan(1);
				subTable2.addCell(longitudeInnerCell);
			}
		} else {
			subTable2 = new PdfPTable(3);
			PdfPCell blankCell = new PdfPCell(new Paragraph("No Records Found", smallfont));
			blankCell.setHorizontalAlignment(Rectangle.ALIGN_CENTER);
			blankCell.setBorder(0);
			blankCell.setColspan(3);
			subTable2.addCell(blankCell);
		}
		PdfPCell subTableCell = new PdfPCell(subTable2);
		subTableCell.setColspan(3);
		additionTable.addCell(subTableCell);
		return additionTable;
	}

	private Paragraph getLabelAndDataParagraph(String label, String data) {
		Chunk chunk1 = new Chunk(label, middlefont);
		Chunk chunk2 = new Chunk(data, smallfont);
		Paragraph merged = new Paragraph();
		merged.add(chunk1);
		merged.add(chunk2);
		return merged;
	}

	public static void main(String[] args) {
		try {
			Document document = new Document();
			PdfWriter.getInstance(document, new FileOutputStream(".\\output\\data.pdf")).setStrictImageSequence(true);
			AddressVO addressVO = new BeanPopulatorUtil().populateAddress();
			List<GoogleMapBean> googleMapBeanList = new BeanPopulatorUtil().populateGoogleMapLocations();//new ArrayList();
			new PdfGenerator().createTable(document, addressVO, googleMapBeanList);
			System.out.println("CREATING... ");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

BeanPopulatorUtil.java that creates the demo data

package com.matttiz.itext.pdf.generator;

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

import com.matttiz.itext.pdf.vo.AddressVO;
import com.matttiz.itext.pdf.vo.GoogleMapBean;

public class BeanPopulatorUtil {

	public List<GoogleMapBean> populateGoogleMapLocations() {
		List<GoogleMapBean> googleMapLocations = new ArrayList<GoogleMapBean>();
		GoogleMapBean googleMapBean1 = new GoogleMapBean();
		googleMapBean1.setLatitude(-33.890542);
		googleMapBean1.setLongitude(151.274856);
		googleMapBean1.setLocation("Bondi Beach");
		GoogleMapBean googleMapBean2 = new GoogleMapBean();
		googleMapBean2.setLatitude(-33.923036);
		googleMapBean2.setLongitude(151.259052);
		googleMapBean2.setLocation("Coogee Beach");
		GoogleMapBean googleMapBean3 = new GoogleMapBean();
		googleMapBean3.setLatitude(-34.028249);
		googleMapBean3.setLongitude(151.157507);
		googleMapBean3.setLocation("Cronulla Beach");
		GoogleMapBean googleMapBean4 = new GoogleMapBean();
		googleMapBean4.setLatitude(-33.80010128657071);
		googleMapBean4.setLongitude(151.28747820854187);
		googleMapBean4.setLocation("Manly Beach");
		GoogleMapBean googleMapBean5 = new GoogleMapBean();
		googleMapBean5.setLatitude(-33.950198);
		googleMapBean5.setLongitude(151.259302);
		googleMapBean5.setLocation("Maroubra Beach");
		googleMapLocations.add(googleMapBean1);
		googleMapLocations.add(googleMapBean2);
		googleMapLocations.add(googleMapBean3);
		googleMapLocations.add(googleMapBean4);
		googleMapLocations.add(googleMapBean5);
		return googleMapLocations;
	}

	public AddressVO populateAddress(){
		AddressVO addressVO = new AddressVO();
		addressVO.setAddressLine1("Park Lane");
		addressVO.setAddressLine2("May Fair");
		addressVO.setCity("London");
		addressVO.setCountry("U.K.");
		addressVO.setLandMark("Big Eye.");
		addressVO.setPinCode("689 585");
		addressVO.setState("England");
		return addressVO;
	}
}

GoogleMapBean.java

package com.matttiz.itext.pdf.vo;

public class GoogleMapBean {

	private double latitude;
	private double longitude;
	private String location;

	public double getLatitude() {
		return latitude;
	}

	public void setLatitude(double latitude) {
		this.latitude = latitude;
	}

	public double getLongitude() {
		return longitude;
	}

	public void setLongitude(double longitude) {
		this.longitude = longitude;
	}

	public String getLocation() {
		return location;
	}

	public void setLocation(String location) {
		this.location = location;
	}
}

AddressVO.java

package com.matttiz.itext.pdf.vo;

public class AddressVO {

	private String addressLine1;
	private String addressLine2;
	private String city;
	private String state;
	private String country;
	private String pinCode;
	private String landMark;

	public String getAddressLine1() {
		return addressLine1;
	}

	public void setAddressLine1(String addressLine1) {
		this.addressLine1 = addressLine1;
	}

	public String getAddressLine2() {
		return addressLine2;
	}

	public void setAddressLine2(String addressLine2) {
		this.addressLine2 = addressLine2;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getState() {
		return state;
	}

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

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

	public String getPinCode() {
		return pinCode;
	}

	public void setPinCode(String pinCode) {
		this.pinCode = pinCode;
	}

	public String getLandMark() {
		return landMark;
	}

	public void setLandMark(String landMark) {
		this.landMark = landMark;
	}

}

mattiz.properties

MattizLogoLocation=resources/cuppajavamattiz.gif

Many to Many mapping with Hibernate when the mapping table has extra fields

When you want some additional fields in the mapping table other than the mapping primary keys from the tables to be mapped, some extra work is involved.
Two additional domain classes have to be generated as compared to a normal many to many mapping scenario.

This is an example of the example here:
http://cuppajavamattiz.com/2014/05/17/many-to-many-hibernate-mapping-using-mapping-table/

Here goes.

The SQL DDL used:

drop database pubsTill12;
create database pubsTill12;
use pubsTill12;
drop table TB_AUTHORS;
CREATE TABLE TB_AUTHORS (AUTHOR_ID int(11) NOT NULL AUTO_INCREMENT ,AUTHOR_NAME varchar(30) 
default NULL,PRIMARY KEY (AUTHOR_ID)) ;
drop table TB_BOOKS;
CREATE TABLE TB_BOOKS (ISBN_CODE int(11) NOT NULL AUTO_INCREMENT, 
BOOK_TITLE varchar(30) default NULL,PRIMARY KEY (ISBN_CODE));
drop table TB_AUTHORS_BOOKS;
CREATE TABLE TB_AUTHORS_BOOKS (AUTHOR_ID int(11), ISBN_CODE int(11),
CREATED_BY varchar(30),
CREATED_AT timestamp
);

The hbm.xml hibernate mapping files that can automate the generation of domain classes.

Author.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <class name="com.mattiz.persistence.beans.Author" lazy="false" table="TB_AUTHORS" >
        <id name="authorId" column="AUTHOR_ID" length="11" type="int" >
        	<generator class="increment"></generator>
        </id>
        <set name="authorBookAssocs" table="TB_AUTHORS_BOOKS" lazy="false" cascade="save-update" >
			<key column="AUTHOR_ID"/>
			<one-to-many class="com.mattiz.persistence.beans.AuthorBookAssoc"/>
		</set>
        <property name="name" type="java.lang.String" column="AUTHOR_NAME" length="30" />
    </class>
</hibernate-mapping>

AuthorBookAssoc.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated Aug 4, 2011 3:10:41 PM by Hibernate Tools 3.2.4.GA -->
<hibernate-mapping >
    <class name="com.mattiz.persistence.beans.AuthorBookAssoc" table="TB_AUTHORS_BOOKS">
		<composite-id name="id" class="com.mattiz.persistence.beans.AuthorBookAssocId"  >
        	<key-many-to-one name="book" class="com.mattiz.persistence.beans.Book" column="ISBN_CODE" />
        	<key-many-to-one name="author" class="com.mattiz.persistence.beans.Author" column="AUTHOR_ID"  />
    	</composite-id>
        <property name="createdBy" type="java.lang.String">
            <column name="CREATED_BY" not-null="true" />
        </property>
        <property name="createdAt" type="timestamp">
            <column name="CREATED_AT" not-null="true" />
        </property>
	</class>
</hibernate-mapping>

Book.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>
	<class name="com.mattiz.persistence.beans.Book" table="TB_BOOKS" lazy="false">
		<id name="isbn" column="ISBN_CODE" type="int" >
			<generator class="increment"></generator>
		</id>
		 <set name="authorBookAssocs" table="TB_AUTHORS_BOOKS" lazy="true" cascade="save-update" >
			<key column="ISBN_CODE"/>
			<one-to-many class="com.mattiz.persistence.beans.AuthorBookAssoc"/>
		</set>
		<property name="title" type="java.lang.String" column="BOOK_TITLE" length="30" />
	</class>
</hibernate-mapping>

The generated domain classes:

Author.java

package com.mattiz.persistence.beans;
// Generated 17 Oct, 2015 10:59:38 PM by Hibernate Tools 3.2.2.GA
import java.util.HashSet;
import java.util.Set;
/**
 * Author generated by hbm2java
 */
public class Author  implements java.io.Serializable {
     private int authorId;
     private Set authorBookAssocs = new HashSet(0);
     private String name;

    public Author() {
    }
    public Author(Set authorBookAssocs, String name) {
       this.authorBookAssocs = authorBookAssocs;
       this.name = name;
    }   
    public int getAuthorId() {
        return this.authorId;
    }    
    public void setAuthorId(int authorId) {
        this.authorId = authorId;
    }
    public Set getAuthorBookAssocs() {
        return this.authorBookAssocs;
    }    
    public void setAuthorBookAssocs(Set authorBookAssocs) {
        this.authorBookAssocs = authorBookAssocs;
    }
    public String getName() {
        return this.name;
    }    
    public void setName(String name) {
        this.name = name;
    }
}

Book.java

package com.mattiz.persistence.beans;
// Generated 17 Oct, 2015 10:59:38 PM by Hibernate Tools 3.2.2.GA


import java.util.HashSet;
import java.util.Set;
/**
 * Book generated by hbm2java
 */
public class Book  implements java.io.Serializable {
     private int isbn;
     private Set authorBookAssocs = new HashSet(0);
     private String title;

    public Book() {
    }
    public Book(Set authorBookAssocs, String title) {
       this.authorBookAssocs = authorBookAssocs;
       this.title = title;
    }   
    public int getIsbn() {
        return this.isbn;
    }    
    public void setIsbn(int isbn) {
        this.isbn = isbn;
    }
    public Set getAuthorBookAssocs() {
        return this.authorBookAssocs;
    }    
    public void setAuthorBookAssocs(Set authorBookAssocs) {
        this.authorBookAssocs = authorBookAssocs;
    }
    public String getTitle() {
        return this.title;
    }    
    public void setTitle(String title) {
        this.title = title;
    }
}

AuthorBookAssoc.java

package com.mattiz.persistence.beans;
// Generated 17 Oct, 2015 10:59:38 PM by Hibernate Tools 3.2.2.GA
import java.util.Date;
/**
 * AuthorBookAssoc generated by hbm2java
 */
public class AuthorBookAssoc  implements java.io.Serializable {

     private AuthorBookAssocId id;
     private String createdBy;
     private Date createdAt;

    public AuthorBookAssoc() {
    }
    public AuthorBookAssoc(AuthorBookAssocId id, String createdBy, Date createdAt) {
       this.id = id;
       this.createdBy = createdBy;
       this.createdAt = createdAt;
    }   
    public AuthorBookAssocId getId() {
        return this.id;
    }    
    public void setId(AuthorBookAssocId id) {
        this.id = id;
    }
    public String getCreatedBy() {
        return this.createdBy;
    }    
    public void setCreatedBy(String createdBy) {
        this.createdBy = createdBy;
    }
    public Date getCreatedAt() {
        return this.createdAt;
    }    
    public void setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
    }
}

AuthorBookAssocId.java

package com.mattiz.persistence.beans;
// Generated 17 Oct, 2015 10:59:38 PM by Hibernate Tools 3.2.2.GA
/**
 * AuthorBookAssocId generated by hbm2java
 */
public class AuthorBookAssocId  implements java.io.Serializable {
     private Book book;
     private Author author;
    public AuthorBookAssocId() {
    }
    public AuthorBookAssocId(Book book, Author author) {
       this.book = book;
       this.author = author;
    }   
    public Book getBook() {
        return this.book;
    }    
    public void setBook(Book book) {
        this.book = book;
    }
    public Author getAuthor() {
        return this.author;
    }    
    public void setAuthor(Author author) {
        this.author = author;
    }
}

IMattizDelegate.java

package com.mattiz.service.spring;

import java.util.Set;

import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.Book;
import com.mattiz.persistence.data.IMattizDao;

public interface IMattizDelegate {
	public void insertAuthor(Author author);
	public void insertBook(Book book);
	public Set<Book> getBooksForAuthor(int authorId);
	public IMattizDao getMattizDao();
	public void setMattizDao(IMattizDao mattizDao);
}

MattizDelegate.java

package com.mattiz.service.spring;

import java.util.Set;
import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.Book;
import com.mattiz.persistence.data.IMattizDao;

public class MattizDelegate implements IMattizDelegate {

	private IMattizDao mattizDao;

	public void insertAuthor(Author author) {
		getMattizDao().insertAuthor(author);
	}
	public void insertBook(Book book) {
		getMattizDao().insertBook(book);
	}
	public Set<Book> getBooksForAuthor(int authorId) {
		Set<Book> books = getMattizDao().getBooksForAuthor(authorId);
		return books;
	}
	public IMattizDao getMattizDao() {
		return mattizDao;
	}
	public void setMattizDao(IMattizDao mattizDao) {
		this.mattizDao = mattizDao;
	}
}

IMattizDao.java

package com.mattiz.persistence.data;

import java.util.Set;

import org.springframework.dao.DataAccessException;
import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.Book;

public interface IMattizDao {
	public Set<Book> getBooksForAuthor(int authorId) throws DataAccessException;
	public void insertAuthor(Author author) throws DataAccessException;
	public void insertBook(Book book) throws DataAccessException;
}

MattizDao.java

package com.mattiz.persistence.data;

import java.util.HashSet;
import java.util.Set;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.AuthorBookAssoc;
import com.mattiz.persistence.beans.Book;

public class MattizDao implements IMattizDao {

	private HibernateTemplate hibernateTemplate;
	public Set<Book> getBooksForAuthor(int authorId) throws DataAccessException {
		Author authorBean = null;
		Set<Book> books = new HashSet();
		authorBean = (Author) getHibernateTemplate().load(Author.class,
				authorId);
		Set<AuthorBookAssoc> authorBookAssocs = authorBean
				.getAuthorBookAssocs();
		for (AuthorBookAssoc authorBookAssoc : authorBookAssocs) {
			Book book = authorBookAssoc.getId().getBook();
			books.add(book);
		}
		return books;
	}
	public void insertAuthor(Author author) throws DataAccessException {
		HibernateTemplate template = getHibernateTemplate();
		template.saveOrUpdate(author);
		System.out.println("Inserted/Updated AuthorBean " + author.getName());
	}
	public void insertBook(Book book) throws DataAccessException {
		HibernateTemplate template = getHibernateTemplate();
		template.saveOrUpdate(book);
		System.out.println("Inserted/Updated AuthorBean " + book.getTitle());
	}
	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}
}

mattiz.xml – the spring configuration file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean
        id="mattiz.hibernate.dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" >
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/pubsTill12" />
        <property name="user" value="root" />
        <property name="password" value="admin" />
    </bean>
    <bean id="mattiz.abstract.hibernate.sessionfactory" abstract="true" 
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="true" >
        <property name="dataSource" >
            <ref local="mattiz.hibernate.dataSource" />
        </property>
        <property name="hibernateProperties" >
            <props>
                <prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql" >false</prop>
            </props>
        </property>
    </bean>
    <bean id="mattiz.pageSize" class="java.lang.Integer" >
        <constructor-arg value="5000" >
        </constructor-arg>
    </bean>
    <bean id="mattiz.hibernate.sessionfactory" parent="mattiz.abstract.hibernate.sessionfactory" >
        <property name="mappingResources" >
            <list>
                <value>resources/Author.hbm.xml</value>
                <value>resources/Book.hbm.xml</value>
                <value>resources/AuthorBookAssoc.hbm.xml</value>
            </list>
        </property>
    </bean>
    <bean id="mattiz.transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" >
        <property name="sessionFactory" >
            <ref bean="mattiz.hibernate.sessionfactory" />
        </property>
    </bean>
    <bean id="mattiz.hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" >
        <property name="sessionFactory" >
            <ref bean="mattiz.hibernate.sessionfactory" />
        </property>
    </bean>
    <bean id="mattiz.dao.mattizDAO" class="com.mattiz.persistence.data.MattizDao" singleton="true" >
        <property name="hibernateTemplate" >
            <ref bean="mattiz.hibernateTemplate" />
        </property>
    </bean>
    <bean id="mattiz.client" class="com.mattiz.web.managedbeans.MattizMain" singleton="true" >
        <property name="mattizDelegate" ref="mattiz.service.delegate" />
    </bean>
    <bean id="mattiz.service.delegate" class="com.mattiz.service.spring.MattizDelegate" singleton="true" >
        <property name="mattizDao" ref="mattiz.dao.mattizDAO" />
    </bean>
</beans>

MattizMain.java – the standalone java class that tests the use case.

package com.mattiz.web.managedbeans;

import java.util.HashSet;
import java.util.Set;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.AuthorBookAssoc;
import com.mattiz.persistence.beans.AuthorBookAssocId;
import com.mattiz.persistence.beans.Book;
import com.mattiz.service.spring.IMattizDelegate;

public class MattizMain {

	private ApplicationContext applicationContext;
	private IMattizDelegate mattizDelegate;

	public IMattizDelegate getMattizDelegate() {
		mattizDelegate = (IMattizDelegate) applicationContext
				.getBean("mattiz.service.delegate");
		return mattizDelegate;
	}
	public void setMattizDelegate(IMattizDelegate mattizDelegate) {
		this.mattizDelegate = mattizDelegate;
	}
	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}
	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}
	public static void main(String[] args) {
		MattizMain mattizMain = new MattizMain();
		mattizMain.applicationContext = new ClassPathXmlApplicationContext(
				"resources/mattiz.xml");

		Book a = new Book();
		a.setTitle("The Cool Drink");
		mattizMain.getMattizDelegate().insertBook(a);
		Book b = new Book();
		b.setTitle("Lost Island");
		mattizMain.getMattizDelegate().insertBook(b);
		Book j = new Book();
		j.setTitle("Long live His Cotton Socks");
		mattizMain.getMattizDelegate().insertBook(j);
		Book k = new Book();
		k.setTitle("Praise Be to Harman!");
		mattizMain.getMattizDelegate().insertBook(k);

		Author a1 = new Author();

		Set<AuthorBookAssoc> aa = new HashSet<AuthorBookAssoc>();
		AuthorBookAssoc authorBookAssoc1 = new AuthorBookAssoc();
		authorBookAssoc1.setCreatedBy("Jill");
		authorBookAssoc1.setCreatedAt(new java.util.Date());
		AuthorBookAssocId authorBookAssocId = new AuthorBookAssocId();
		authorBookAssocId.setBook(a);
		authorBookAssocId.setAuthor(a1);
		authorBookAssoc1.setId(authorBookAssocId);
		aa.add(authorBookAssoc1);
		AuthorBookAssoc authorBookAssoc2 = new AuthorBookAssoc();
		authorBookAssoc2 = new AuthorBookAssoc();
		authorBookAssoc2.setCreatedBy("Jack");
		authorBookAssoc2.setCreatedAt(new java.util.Date());
		authorBookAssocId = new AuthorBookAssocId();
		authorBookAssocId.setBook(b);
		authorBookAssocId.setAuthor(a1);
		authorBookAssoc2.setId(authorBookAssocId);
		aa.add(authorBookAssoc2);

		a1.setAuthorBookAssocs(aa);
		a1.setName("Mac");

		mattizMain.getMattizDelegate().insertAuthor(a1);

		Author b1 = new Author();

		Set<AuthorBookAssoc> ab = new HashSet<AuthorBookAssoc>();
		AuthorBookAssoc authorBookAssoc3 = new AuthorBookAssoc();
		authorBookAssoc3 = new AuthorBookAssoc();
		authorBookAssoc3.setCreatedBy("Mattiz");
		authorBookAssoc3.setCreatedAt(new java.util.Date());
		authorBookAssocId = new AuthorBookAssocId();
		authorBookAssocId.setBook(j);
		authorBookAssocId.setAuthor(b1);
		authorBookAssoc3.setId(authorBookAssocId);
		ab.add(authorBookAssoc3);
		AuthorBookAssoc authorBookAssoc4 = new AuthorBookAssoc();
		authorBookAssoc4 = new AuthorBookAssoc();
		authorBookAssoc4.setCreatedBy("Jim");
		authorBookAssoc4.setCreatedAt(new java.util.Date());
		authorBookAssocId = new AuthorBookAssocId();
		authorBookAssocId.setBook(k);
		authorBookAssocId.setAuthor(b1);
		authorBookAssoc4.setId(authorBookAssocId);
		ab.add(authorBookAssoc4);
		AuthorBookAssoc authorBookAssoc5 = new AuthorBookAssoc();
		authorBookAssoc5 = new AuthorBookAssoc();
		authorBookAssoc5.setCreatedBy("James");
		authorBookAssoc5.setCreatedAt(new java.util.Date());
		authorBookAssocId = new AuthorBookAssocId();
		authorBookAssoc5.setId(authorBookAssocId);
		authorBookAssocId.setBook(a);
		authorBookAssocId.setAuthor(b1);
		ab.add(authorBookAssoc5);

		b1.setAuthorBookAssocs(ab);
		b1.setName("Kenzie");

		mattizMain.getMattizDelegate().insertAuthor(b1);

		System.out.println("----------------------Author with Id 1");
		Set<Book> books1 = mattizMain.getMattizDelegate().getBooksForAuthor(1);
		for (Book iter1 : books1) {
			System.out.println(iter1.getTitle());
		}
		System.out.println("----------------------Author with Id 2");
		Set<Book> books2 = mattizMain.getMattizDelegate().getBooksForAuthor(2);
		for (Book iter1 : books2) {
			System.out.println(iter1.getTitle());
		}
	}
}

The generated output:

Inserted/Updated AuthorBean The Cool Drink
Inserted/Updated AuthorBean Lost Island
Inserted/Updated AuthorBean Long live His Cotton Socks
Inserted/Updated AuthorBean Praise Be to Harman!
Inserted/Updated AuthorBean Mac
Inserted/Updated AuthorBean Kenzie
----------------------Author with Id 1
Lost Island
The Cool Drink
----------------------Author with Id 2
Long live His Cotton Socks
The Cool Drink
Praise Be to Harman!

The database data:
db
The project explorer view:
project
Jars on the classpath:
jar_classpath

Batch file to rename physical files from CSV entries

This batch file will read a CSV file with “id” in “A” column, user name in “B” column and file name in “C” column. The problem statement is to read user name in column B in the CSV file and rename the file specified in column C with the user name.
Some tips:
a. The following line reads the CSV file in a loop with delimiter as comma:
FOR /F “skip=1 tokens=2-4 delims=,” %%a IN (%1) do ^

b. %%~xi automatically picks up the file extension from a file name.

c. ext is used as a variable here.
setlocal ENABLEDELAYEDEXPANSION enables proper usage of this variable.

d. %%a, %%b, %%c specifies columns A, B, C in the CSV file.

e. Following line extracts the file name extension and echoes it:
for %%i in (%%c) do echo %%~xi

f. The following line copies file name in C column with name in B column with extension variable “ext”
echo copying %%c “%%b!ext!”
Hence original file extensions are preserved while copying/ renaming.

g. The renamed files are copied to folder called “renamed” in the parent folder.

h. usage is rename_files.bat (csv-file)

i. Place the CSV file, bat file and photos in same parent folder

j. The if/else part appears because when an extra column appears in a column b data is pushed to c
column (four digit number in column A causes an extra column to appear in id column)

k. %1 represents the run time argument passed to the batch file.

@echo off
if not exist (%1) (
 echo Input file missing.  Usage: rename_jpg.bat (csv-file)
)
setlocal ENABLEDELAYEDEXPANSION
FOR /F "skip=1 tokens=2-4 delims=," %%a IN (%1) do ^
if [%%c]==[] (
for %%i in (%%b) do echo %%~xi
for %%i in (%%b) do (
 set "ext=%%~xi"
 )
 echo copying %%b "%%a!ext!"
 copy %%b "%%a!ext!"
 move "%%a!ext!" renamed
) else (
for %%i in (%%c) do echo %%~xi
for %%i in (%%c) do (
 set "ext=%%~xi"
 )
 echo copying %%c "%%b!ext!"
 copy %%c "%%b!ext!"
 move "%%b!ext!" renamed
)

example of CSV entries:

Id	User Name	File Name	
1	1408946308922	a2298d70-91a2-4254-a3bf-f721ee2d.jpg	
2	1408946892590	5bc14e6f-5922-4864-b5c6-ceb69ad0.jpg	
3	1408947330112	06545cfb-703a-4d57-aaa8-419b0295.jpg	
4	1408946289199	46f98f8d-b11a-4617-b05a-80c0ff53.jpg	

Many To Many Hibernate Mapping using mapping table

We consider the scenario where one author can write many books and one book can have many authors. This is a many to many relationship that uses a mapping table to manage the many to many associations between authors and books.
The following queries can setup such a database for you.

drop database pubs;
create database pubs;
use pubs;
drop table TB_AUTHORS;
CREATE TABLE TB_AUTHORS (AUTHOR_ID int(11) NOT NULL default '0',AUTHOR_NAME varchar(30) default NULL,PRIMARY KEY (AUTHOR_ID)) ;
drop table TB_BOOKS;
CREATE TABLE TB_BOOKS (ISBN_CODE varchar(10) NOT NULL, BOOK_TITLE varchar(30) default NULL,PRIMARY KEY (ISBN_CODE)) ;
drop table TB_AUTHORS_BOOKS;
CREATE TABLE TB_AUTHORS_BOOKS (AUTHOR_ID_IN_MAP int(11) NOT NULL, ISBN_CODE varchar(10) not NULL);

The domain classes look like this

package com.mattiz.persistence.beans;
// Generated 18 Jan, 2014 6:01:04 AM by Hibernate Tools 3.2.2.GA


import java.util.HashSet;
import java.util.Set;

/**
 * Author generated by hbm2java
 */
public class Author  implements java.io.Serializable {
     private int authorId;
     private Set books = new HashSet(0);
     private String name;

    public Author() {
    }

    public Author(Set books, String name) {
       this.books = books;
       this.name = name;
    }
   
    public int getAuthorId() {
        return this.authorId;
    }
    
    public void setAuthorId(int authorId) {
        this.authorId = authorId;
    }
    public Set getBooks() {
        return this.books;
    }
    
    public void setBooks(Set books) {
        this.books = books;
    }
    public String getName() {
        return this.name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
}
package com.mattiz.persistence.beans;
// Generated 18 Jan, 2014 6:01:04 AM by Hibernate Tools 3.2.2.GA



/**
 * Book generated by hbm2java
 */
public class Book  implements java.io.Serializable {
     private String isbn;
     private String title;

    public Book() {
    }
	
    public Book(String isbn) {
        this.isbn = isbn;
    }
    public Book(String isbn, String title) {
       this.isbn = isbn;
       this.title = title;
    }
   
    public String getIsbn() {
        return this.isbn;
    }
    
    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }
    public String getTitle() {
        return this.title;
    }
    
    public void setTitle(String title) {
        this.title = title;
    }
}

The above class files are generated from the hbm2java tool(See details at bottom)
The corresponding hbm files look like this
Author.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
    <class name="com.mattiz.persistence.beans.Author" lazy="false" table="TB_AUTHORS" >
        <id name="authorId" column="AUTHOR_ID" length="11" type="int" >
        	<generator class="increment"></generator>
        </id>
        <set name="books" table="TB_AUTHORS_BOOKS" cascade="save-update" lazy="false">
            <key column="AUTHOR_ID_IN_MAP" />
            <many-to-many column="ISBN_CODE"  class="com.mattiz.persistence.beans.Book" />
        </set>
        <property name="name" type="java.lang.String" column="AUTHOR_NAME" length="30" />
    </class>
</hibernate-mapping>

Book.hbml.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>
	<class name="com.mattiz.persistence.beans.Book" table="TB_BOOKS" lazy="false">
		<id name="isbn" column="ISBN_CODE" length="10" type="java.lang.String" >
			<generator class="assigned"></generator>
		</id>
		<property name="title" type="java.lang.String" column="BOOK_TITLE" length="30" />
	</class>
</hibernate-mapping>

The Dao class and interface:
IMattizDao.java

package com.mattiz.persistence.data;

import java.util.Set;

import org.springframework.dao.DataAccessException;

import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.Book;

public interface IMattizDao {

	public Set<Book> getBooksForAuthor(int authorId) throws DataAccessException;

	public void insertAuthor(String authorName, Set<Book> books)
			throws DataAccessException;

}

MattizDao.java

package com.mattiz.persistence.data;

import java.util.Set;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.mattiz.persistence.beans.Author;
import com.mattiz.persistence.beans.Book;

public class MattizDao implements IMattizDao {

	private HibernateTemplate hibernateTemplate;

	public Set<Book> getBooksForAuthor(int authorId) throws DataAccessException {
		Author authorBean = null;
		authorBean = (Author) getHibernateTemplate().load(Author.class,
				authorId);
		System.out.println(authorBean.getName()+"n");
		Set<Book> books = authorBean.getBooks();
		for(Book b: books){
			System.out.println(b.getTitle());
		}	
		return books;
	}

	public void insertAuthor(String authorName, Set<Book> books)
			throws DataAccessException {
		Author authorBean = new Author();
		authorBean.setBooks(books);
		authorBean.setName(authorName);
		HibernateTemplate template = getHibernateTemplate();
		template.saveOrUpdate(authorBean);
		System.out.println("Inserted/Updated AuthorBean "
				+ authorBean.getName());
	}

	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}
}

The service class and interface
IMattizDelegate.java

package com.mattiz.service.spring;

import java.util.Set;

import com.mattiz.persistence.beans.Book;
import com.mattiz.persistence.data.IMattizDao;

public interface IMattizDelegate {

	public void insertAuthor(String authorName, Set<Book> books);

	public Set<Book> getBooksForAuthor(int authorId);

	public IMattizDao getMattizDao();

	public void setMattizDao(IMattizDao mattizDao);

}

MattizDelegate.java

package com.mattiz.service.spring;

import java.util.Set;

import com.mattiz.persistence.beans.Book;
import com.mattiz.persistence.data.IMattizDao;

public class MattizDelegate implements IMattizDelegate {

	private IMattizDao mattizDao;

	public void insertAuthor(String authorName, Set<Book> books) {
		getMattizDao().insertAuthor(authorName, books);
	}

	public Set<Book> getBooksForAuthor(int authorId) {
		Set<Book> books = getMattizDao().getBooksForAuthor(authorId);
		return books;
	}

	public IMattizDao getMattizDao() {
		return mattizDao;
	}

	public void setMattizDao(IMattizDao mattizDao) {
		this.mattizDao = mattizDao;
	}

}

The Main class that is a replacement for a front end UI
MattizMain.java

package com.mattiz.web.managedbeans;

import java.util.HashSet;
import java.util.Set;

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

import com.mattiz.persistence.beans.Book;
import com.mattiz.service.spring.IMattizDelegate;

public class MattizMain {

	private ApplicationContext applicationContext;

	private IMattizDelegate mattizDelegate;

	public IMattizDelegate getMattizDelegate() {
		mattizDelegate = (IMattizDelegate) applicationContext
				.getBean("mattiz.service.delegate");
		return mattizDelegate;
	}

	public void setMattizDelegate(IMattizDelegate mattizDelegate) {
		this.mattizDelegate = mattizDelegate;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

	public static void main(String[] args) {
		MattizMain mattizMain = new MattizMain();
		mattizMain.applicationContext = new ClassPathXmlApplicationContext(
				"resources/mattiz.xml");
		Book a = new Book("1e","The Cool Drink");
		Book b = new Book("1a","Lost Island");
		Book c = new Book("1b","Treasure Hunt");
		Book d = new Book("1c","Down With Fever");
		Book e = new Book("1d","Imagination runs Wild");
		Book f = new Book("1r","The Wild West");
		Book g = new Book("1h","Gregorios");
		Book h = new Book("14","Mar Thoma");
		Book i = new Book("15","Christ and the Disciples");
		Book j = new Book("1t","Long live His Cotton Socks");
		Book k = new Book("19","Praise Be to Harman!");
		Set<Book> aa = new HashSet<Book>();
		aa.add(a);
		aa.add(b);
		aa.add(c);		
		aa.add(d);
		aa.add(e);
		aa.add(f);
		aa.add(g);
		Set<Book> ab = new HashSet<Book>();
		ab.add(a);		
		ab.add(b);
		ab.add(h);
		Set<Book> ac = new HashSet<Book>();
		ac.add(i);
		ac.add(j);		
		ac.add(k);
		Set<Book> ad = new HashSet<Book>();
		ad.add(a);		
		ad.add(k);	
		Set<Book> af = new HashSet<Book>();
		af.add(a);
		Set<Book> ag = new HashSet<Book>();
		ag.add(a);	
		Set<Book> ah = new HashSet<Book>();
		ah.add(e);	
		Set<Book> aj = new HashSet<Book>();
		aj.add(f);	
		mattizMain.getMattizDelegate().insertAuthor("Mac",aa);
		mattizMain.getMattizDelegate().insertAuthor("Kenzie", ab);
		mattizMain.getMattizDelegate().insertAuthor("John",ac);		
		mattizMain.getMattizDelegate().insertAuthor("Warbler",ad);
		mattizMain.getMattizDelegate().insertAuthor("Huan",af);
		mattizMain.getMattizDelegate().insertAuthor("Mike",ag);
		mattizMain.getMattizDelegate().insertAuthor("Don",ag);		
		mattizMain.getMattizDelegate().insertAuthor("John",ah);
		mattizMain.getMattizDelegate().insertAuthor("Mark",aj);
		mattizMain.getMattizDelegate().insertAuthor("Jim",ah);
		mattizMain.getMattizDelegate().insertAuthor("Joe",ah);
		mattizMain.getMattizDelegate().insertAuthor("Harry",ad);		
		mattizMain.getMattizDelegate().insertAuthor("Noman",ag);
		mattizMain.getMattizDelegate().insertAuthor("Julian",aj);
		mattizMain.getMattizDelegate().insertAuthor("Tick",af);
		mattizMain.getMattizDelegate().insertAuthor("Toe",ac);
		mattizMain.getMattizDelegate().getBooksForAuthor(1);
		System.out.println("----------------------");
		mattizMain.getMattizDelegate().getBooksForAuthor(5);
	}

}

Spring configuration file:
mattiz.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean
        id="mattiz.hibernate.dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" >
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/pubs" />
        <property name="user" value="root" />
        <property name="password" value="admin" />
    </bean>
    <bean id="mattiz.abstract.hibernate.sessionfactory" abstract="true" 
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" lazy-init="true" >
        <property name="dataSource" >
            <ref local="mattiz.hibernate.dataSource" />
        </property>
        <property name="hibernateProperties" >
            <props>
                <prop key="hibernate.dialect" >org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql" >false</prop>
            </props>
        </property>
    </bean>
    <bean id="mattiz.pageSize" class="java.lang.Integer" >
        <constructor-arg value="5000" >
        </constructor-arg>
    </bean>
    <bean id="mattiz.hibernate.sessionfactory" parent="mattiz.abstract.hibernate.sessionfactory" >
        <property name="mappingResources" >
            <list>
                <value>resources/Author.hbm.xml</value>
                <value>resources/Book.hbm.xml</value>
            </list>
        </property>
    </bean>
    <bean id="mattiz.transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" >
        <property name="sessionFactory" >
            <ref bean="mattiz.hibernate.sessionfactory" />
        </property>
    </bean>
    <bean id="mattiz.hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" >
        <property name="sessionFactory" >
            <ref bean="mattiz.hibernate.sessionfactory" />
        </property>
    </bean>
    <bean id="mattiz.dao.mattizDAO" class="com.mattiz.persistence.data.MattizDao" singleton="true" >
        <property name="hibernateTemplate" >
            <ref bean="mattiz.hibernateTemplate" />
        </property>
    </bean>
    <bean id="mattiz.client" class="com.mattiz.web.managedbeans.MattizMain" singleton="true" >
        <property name="mattizDelegate" ref="mattiz.service.delegate" />
    </bean>
    <bean id="mattiz.service.delegate" class="com.mattiz.service.spring.MattizDelegate" singleton="true" >
        <property name="mattizDao" ref="mattiz.dao.mattizDAO" />
    </bean>
</beans>

Screenshots show structure of file heirarchy, jars and APIs used and SQL output
many_many
library_ref
mapping_table_insertions

The domain files are generated from the hbml.xml hibernate files. For easy reference the code is given below:
The Author.hbm.xml and Book.hbm.xml described above are placed in the “src” folder. The generated java domain classes are created under “generated/src/com/mattiz/persistence/beans” folder.
The jars used for this purpose can be seen in the screenshot.
The only additional piece of code is the build file described below:

build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project default="codegen">
	<target name="codegen">
		<path id="classpath_id">
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.apache.commonscom.springsource.org.apache.commons.beanutils1.8.0com.springsource.org.apache.commons.beanutils-1.8.0.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.apache.commonscom.springsource.org.apache.commons.logging1.1.1com.springsource.org.apache.commons.logging-1.1.1.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.dom4jcom.springsource.org.dom4j1.6.1com.springsource.org.dom4j-1.6.1.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.hibernatecom.springsource.org.hibernate3.3.1.GAcom.springsource.org.hibernate-3.3.1.GA.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.hibernatecom.springsource.org.hibernate.annotations3.4.0.GAcom.springsource.org.hibernate.annotations-3.4.0.GA.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.apache.log4jcom.springsource.org.apache.log4j1.2.15com.springsource.org.apache.log4j-1.2.15.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.apache.commonscom.springsource.org.apache.commons.collections3.2.1com.springsource.org.apache.commons.collections-3.2.1.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.slf4jcom.springsource.slf4j.api1.5.3com.springsource.slf4j.api-1.5.3.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.slf4jcom.springsource.slf4j.jcl1.5.3com.springsource.slf4j.jcl-1.5.3.jar" />
<pathelement location="I:packageshibernate-tools.jarhibernate-tools.jar" />
<pathelement location="I:packagesspring-framework-3.0.2.RELEASE-dependenciesorg.freemarkercom.springsource.freemarker2.3.15com.springsource.freemarker-2.3.15.jar" />
		</path>
		<echo>Zippzip</echo>
		<taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask">
			<classpath refid="classpath_id" />
		</taskdef>
		<hibernatetool destdir="generated/src">
			<configuration>
				<fileset dir=".">
					<include name="src/*.hbm.xml" />
				</fileset>
			</configuration>
			<hbm2java />
		</hibernatetool>
	</target>
</project>

DomainGenerator

The hibernate domain generator can be downloaded here

The many to many hibernate mapping source code can be downloaded here

Merging XML files using XPath

This example is a solution to a commonplace XML problem – merging two XML files into one. Our two input XMLs will not have any indexes mapping one node to another but it is under the assumption that there is a one to one correspondence between the nodes of each XML based on their location in the XML file.
Instead of using user friendly XML parsers such as JDOM and XercesJ we use a less resource intensive light weight technology – XPath that comes bundled with the Java SDK.

Here is the first input XML:

XmlOne.xml

<?xml version="1.0" encoding="UTF-8"?>
<Mattiz>
    <Content>
        <Name>Jo</Name>
        <RollNumber>3</RollNumber>
    </Content>
    <Content>
        <Name>Jack</Name>
        <RollNumber>7</RollNumber>
    </Content>
    <Content>
        <Name>Harrison</Name>
        <RollNumber>14</RollNumber>
    </Content>
    <Content>
        <Name>Mike</Name>
        <RollNumber>26</RollNumber>
    </Content>
    <Content>
        <Name>Mick</Name>
        <RollNumber>98</RollNumber>
    </Content>
    <Content>
        <Name>Jake</Name>
        <RollNumber>101</RollNumber>
    </Content>
    <Content>
        <Name>Tintin</Name>
        <RollNumber>238</RollNumber>
    </Content>
    <Content>
        <Name>Goldie</Name>
        <RollNumber>500</RollNumber>
    </Content>
    <Content>
        <Name>Sommer</Name>
        <RollNumber>501</RollNumber>
    </Content>
    <Content>
        <Name>Hayley</Name>
        <RollNumber>567</RollNumber>
    </Content>
</Mattiz>

The second input XML – XmlTwo.xml

<?xml version="1.0" encoding="UTF-8"?>
<Mattiz>
    <Content>
        <Name>Jo</Name>
        <Age>7</Age>
    </Content>
    <Content>
        <Name>Jack</Name>
        <Age>10</Age>
    </Content>
    <Content>
        <Name>Harrison</Name>
        <Age>11</Age>
    </Content>
    <Content>
        <Name>Mike</Name>
        <Age>15</Age>
    </Content>
    <Content>
        <Name>Mick</Name>
        <Age>16</Age>
    </Content>
    <Content>
        <Name>Jake</Name>
        <Age>16</Age>
    </Content>
    <Content>
        <Name>Tintin</Name>
        <Age>18</Age>
    </Content>
    <Content>
        <Name>Goldie</Name>
        <Age>21</Age>
    </Content>
    <Content>
        <Name>Sommer</Name>
        <Age>71</Age>
    </Content>
    <Content>
        <Name>Hayley</Name>
        <Age>100</Age>
    </Content>
</Mattiz>

And here is the Main class that does the merging:
MergeXml.java

package com.mattiz.merge.xml;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class MergeXml {

	public static void main(String args[]) throws ParserConfigurationException,
			SAXException, IOException, XPathExpressionException,
			TransformerException {
		XPathFactory xPathFactory = XPathFactory.newInstance();
		XPath xpath = xPathFactory.newXPath();
		DocumentBuilderFactory domFactory = DocumentBuilderFactory
				.newInstance();
		domFactory.setNamespaceAware(true);
		DocumentBuilder builder = domFactory.newDocumentBuilder();
		Document doc1 = builder.parse("./resources/XmlOne.xml");
		Document doc2 = builder.parse("./resources/XmlTwo.xml");
		String xPathString = "/Mattiz/Content";
		Document mergedDoc = passThroughXML(xpath, xPathString, doc1, doc2);
		System.out.println(getDocumentAsStringAfterTransformation(mergedDoc));
	}

	private static Document passThroughXML(XPath xpath, String xPathString,
			Document doc1, Document doc2) throws XPathExpressionException,
			TransformerException, IOException {
		Document document = null;
		XPathExpression xPathExpression = xpath.compile(xPathString);
		NodeList nodeList = (NodeList) xPathExpression.evaluate(doc2,
				XPathConstants.NODESET);
		for (int i = 0; i < nodeList.getLength(); i++) {
			XPathExpression innerXpathExpression = xpath.compile(xPathString
					.concat("[position()=" + (i + 1) + "]"));
			document = mergeXml(innerXpathExpression, doc1, doc2);
		}
		document = removeDuplicates(xPathString, xpath, document);
		return document;
	}

	private static Document mergeXml(XPathExpression innerXpathExpression,
			Document doc1, Document doc2) throws XPathExpressionException,
			IOException {
		Node doc1Node = (Node) innerXpathExpression.evaluate(doc1,
				XPathConstants.NODE);
		if (doc1Node == null) {
			throw new RuntimeException(doc1Node
					+ " - expression does not evaluate to a node");
		}
		Node doc2Node = (Node) innerXpathExpression.evaluate(doc2,
				XPathConstants.NODE);
		while (doc2Node.hasChildNodes()) {
			Node childNode = doc2Node.getFirstChild();
			doc2Node.removeChild(childNode);
			childNode = doc1.importNode(childNode, true);
			doc1Node.appendChild(childNode);
		}
		return doc1;
	}

	private static Document removeDuplicates(String xPathString, XPath xpath,
			Document document) throws XPathExpressionException,
			TransformerException {
		XPathExpression xPathExpression = xpath.compile(xPathString
				.concat("/Name[position()=2]"));
		NodeList nodeList = (NodeList) xPathExpression.evaluate(document,
				XPathConstants.NODESET);
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node nodeToRemove = nodeList.item(i);
			nodeToRemove.getParentNode().removeChild(nodeToRemove);
		}
		return document;
	}

	private static String getDocumentAsStringAfterTransformation(Document document)
			throws TransformerConfigurationException, TransformerException {
		TransformerFactory transformerFactory = TransformerFactory
				.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		DOMSource source = new DOMSource(document);
		Writer outWriter = new StringWriter();
		Result result = new StreamResult(outWriter);
		transformer.transform(source, result);
		String stringDoc = outWriter.toString();
		return stringDoc;
	}
}

The output XML that is generated looks something like this on the console:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <Mattiz>
    <Content>
        <Name>Jo</Name>
        <RollNumber>3</RollNumber>        
        <Age>7</Age>
    </Content>
    <Content>
        <Name>Jack</Name>
        <RollNumber>7</RollNumber>        
        <Age>10</Age>
    </Content>
    <Content>
        <Name>Harrison</Name>
        <RollNumber>14</RollNumber>        
        <Age>11</Age>
    </Content>
    <Content>
        <Name>Mike</Name>
        <RollNumber>26</RollNumber>        
        <Age>15</Age>
    </Content>
    <Content>
        <Name>Mick</Name>
        <RollNumber>98</RollNumber>        
        <Age>16</Age>
    </Content>
    <Content>
        <Name>Jake</Name>
        <RollNumber>101</RollNumber>        
        <Age>16</Age>
    </Content>
    <Content>
        <Name>Tintin</Name>
        <RollNumber>238</RollNumber>        
        <Age>18</Age>
    </Content>
    <Content>
        <Name>Goldie</Name>
        <RollNumber>500</RollNumber>        
        <Age>21</Age>
    </Content>
    <Content>
        <Name>Sommer</Name>
        <RollNumber>501</RollNumber>
        <Age>71</Age>
    </Content>
    <Content>
        <Name>Hayley</Name>
        <RollNumber>567</RollNumber>       
        <Age>100</Age>
    </Content>
</Mattiz>

[purchase_link id=”0″ style=”” color=”” text=”Purchase”]file_struct

The source code can be downloaded here

Creating a Simple Web Service using Apache Axis 1.4

Create two projects namely AxisServerExample and AxisClient example.
Download the Axis installation and add the jars in the lib folder of the installation to the lib folder of the Server project. Implement MattizAxisServerImpl.java in the server project.
MattizAxisServerImpl class has the following code:

package com.mattiz.ws.axis.server.impl;

public class MattizAxisServerImpl {
/**
 *
 * @param person
 * @return message
 */
	public String returnMessage(String person){

		return "Hallo "+person+" to the World of Axis!";
	}

}

Run the following two commands from the command prompt to use the java2wsdl utility to create the wsdl from the java class.

set PROJECT_HOME=I:/juno-ws/mvn_custom_plugin/AxisServerExample (This is the location of my axis server project)

java -cp "%PROJECT_HOME%/lib/axis-ant.jar;%PROJECT_HOME%/lib/axis.jar;%PROJECT_HOME%/lib/commons-discovery-0.2.jar;%PROJECT_HOME%/lib/commons-logging-1.0.4.jar;%PROJECT_HOME%/lib/jaxrpc.jar;%PROJECT_HOME%/lib/log4j-1.2.8.jar;%PROJECT_HOME%/lib/saaj.jar;%PROJECT_HOME%/lib/wsdl4j-1.5.1.jar;%PROJECT_HOME%/bin"  org.apache.axis.wsdl.Java2WSDL -o %PROJECT_HOME%/resources/mattiz.wsdl -l "http://localhost:8080/axis/services/MattizAxisTest" -n  "urn:mattiz" -p"com.mattiz.ws.axis.server.impl" "urn:mattiz" com.mattiz.ws.axis.server.impl.MattizAxisServerImpl

This will generate the wsdl file from MattizAxisServerImpl class in the resources folder of the Server project.

Run the following from the command prompt to use the wsdl2java utility to create the java client classes and deploy.wsdd from the wsdl file.

java -cp "%PROJECT_HOME%/lib/axis-ant.jar;%PROJECT_HOME%/lib/axis.jar;%PROJECT_HOME%/lib/commons-discovery-0.2.jar;%PROJECT_HOME%/lib/commons-logging-1.0.4.jar;%PROJECT_HOME%/lib/jaxrpc.jar;%PROJECT_HOME%/lib/log4j-1.2.8.jar;%PROJECT_HOME%/lib/saaj.jar;%PROJECT_HOME%/lib/wsdl4j-1.5.1.jar" org.apache.axis.wsdl.WSDL2Java -o %PROJECT_HOME%/src -p com.mattiz.axis.request -s %PROJECT_HOME%/resources/mattiz.wsdl

deploy.wsdd is created in com.mattiz.axis.request folder along with web serice client stub classes in the Server project.

Copy contents of axis installation webapps folder to tomcat. Modify web.xml by uncommenting this line:

 <!--
  <servlet-mapping>
    <servlet-name>AdminServlet</servlet-name>
    <url-pattern>/servlet/AdminServlet</url-pattern>
  </servlet-mapping>
 -->

Start tomcat and run the following from the command prompt to use the Apache Admin Client to generate your server-config file (wsdd).

java -cp "%PROJECT_HOME%/lib/axis-ant.jar;%PROJECT_HOME%/lib/axis.jar;%PROJECT_HOME%/lib/commons-discovery-0.2.jar;%PROJECT_HOME%/lib/commons-logging-1.0.4.jar;%PROJECT_HOME%/lib/jaxrpc.jar;%PROJECT_HOME%/lib/log4j-1.2.8.jar;%PROJECT_HOME%/lib/saaj.jar;%PROJECT_HOME%/lib/wsdl4j-1.5.1.jar" org.apache.axis.client.AdminClient -lhttp://localhost:8080/axis/services/AdminService %PROJECT_HOME%/src/com/mattiz/axis/request/deploy.wsdd

server-config.wsdd is created in the axis deployment in tomcat in the WEB-INF folder. Copy this to resources folder under Server project.

You are free to delete the axis installation in webapps of tomcat after this step.

Copy web.xml from the axis distribution at axis-1_4/webapps/axis/WEB-INF to WEB-INF under Server project. No changes are required to this file.
Modify returnMessage method in AxisServerExample/src/com/mattiz/axis/request/MattizAxisTestSoapBindingImpl.java

which was generated with the stubs, to look like this:

    public java.lang.String returnMessage(java.lang.String person) throws java.rmi.RemoteException {
        return new MattizAxisServerImpl().returnMessage(person);
    }

Run the following build.xml which creates the server side web service war file – mattiz.war.

<?xml version="1.0"?>
<project name="mattiz" default="war" basedir=".">
	<path id="project.class.path">
		<fileset dir="lib">
			<include name="*.jar" />
		</fileset>
	</path>
	<target name="clean">
		 <delete failonerror="true" includeemptydirs="true">
            <fileset dir="target/classes" includes="**/*" />
            <fileset dir="target" includes="**/*" />
        </delete>
	</target>
	<target name="compile" depends="clean">
		<mkdir dir="target" />
		<mkdir dir="target/classes" />
		<javac srcdir="src" destdir="target/classes" optimize="off"
			classpathref="project.class.path" />
	</target>
	<target name="war" depends="compile">
		<copy file="resources/server-config.wsdd" todir="target/classes" />
		<war destfile="target/mattiz.war" webxml="WEB-INF/web.xml">
			<classes dir="target/classes">
				<include name="**/*.*"/>
			</classes>
			<lib dir="lib">
				<include name="**/*.jar" />
			</lib>
		</war>
	</target>
</project>

Copy mattiz.war to tomcat and start tomcat server.

Run the following url on a browser to view the wsdl file. If the web service is successfully created you will see a xml version of the wsdl file.

http://localhost:8080/mattiz/services/MattizAxisTest?wsdl

Copy contents of com.mattiz.axis.request package to the Client project. Exclude MattizAxisTestSoapBindingImpl class.

Add activation.jar and javamail jars to the classpath of Client project in addition to the axis jars in Server project’s lib folder.

Create MattizWebServiceConsumer.java thus:

package com.mattiz.axis.request;

import java.rmi.RemoteException;
import javax.xml.rpc.ServiceException;

public class MattizWebServiceConsumer {

	public static void main(String[] args) {
		try {
			String endpoint = "http://localhost:8080/mattiz/services/MattizAxisTest";

			MattizAxisServerImplServiceLocator srvLoc = new MattizAxisServerImplServiceLocator();
			srvLoc.setEndpointAddress(new javax.xml.namespace.QName(
					"urn:mattiz", "MattizAxisTest"), endpoint);
			MattizAxisServerImpl serviceimpl = srvLoc.getMattizAxisTest();

			((javax.xml.rpc.Stub) serviceimpl)._setProperty(
					"javax.xml.rpc.session.maintain", Boolean.TRUE);
			String person = "Matty";

			String ret = serviceimpl.returnMessage(person);
			System.out.println("Message " + ret);

		} catch (ServiceException e) {
			// TODO Auto-generated catch blockS
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

Run MattizWebServiceConsumer.java as standalone.

You see the following messsage on the console when the web service java client calls the server:

Message Hallo Matty to the World of Axis!
client

server

The Axis server example can be downloaded here here
The Axis client example can be downloaded here

Converting t+# to Date Format Using JavaScript

Here is a useful utility javascript function that converts date in the format t+# or t-# where t is today’s date and # is the days preceding or following today’s date. Value is input in the value field which popluates the result field on blur.

<form name="ipform">
    REGEX VALUE&nbsp;&nbsp;<input type="text" name="regexValue"
        id="regexValue" onBlur="executeValidation()" />
REGEX
    RESULT&nbsp;&nbsp;<input type="text" name="regexResult"
        id="regexResult" />
</form>
<script>
    function executeValidation() {
        var val = document.forms[0].regexValue.value;
        if (val != "") {
            var regex = "^t$|^t[\\+\\-][\\d]+$";

            if (testRegex(val.toLowerCase(), regex)) {
                var d = new Date();
                if (val == 't' || val == 'T') {
                    val = formatDate(d);
                    document.forms[0].regexResult.value = val;
                } else if (val.indexOf("-") != -1) {
                    var dateParse = val.split("-");
                    if (dateParse.length == 2) {
                        d.setDate(d.getDate() - parseInt(dateParse[1]));
                        val = formatDate(d);
                        document.forms[0].regexResult.value = val;
                    }
                } else if (val.indexOf("+") != -1) {
                    var dateParse = val.split("+");
                    if (dateParse.length == 2) {
                        d.setDate(d.getDate() + parseInt(dateParse[1]));
                        val = formatDate(d);
                        document.forms[0].regexResult.value = val;
                    }
                }
            }
        }
    }
    function formatDate(date) {
        var dateString = "";
        if (date) {
            var d = date.getDate();
            var day = (d < 10) ? '0' + d : d;
            if (isNaN(parseInt(day))) {
                dateString = '00/00/0000';
                return dateString;
            }
            var m = date.getMonth() + 1;
            if (isNaN(parseInt(m))) {
                dateString = '00/00/0000';
                return dateString;
            }
            var month = (m < 10) ? '0' + m : m;
            if (isNaN(parseInt(month))) {
                dateString = '00/00/0000';
                return dateString;
            }
            var yy = date.getFullYear();
            if (isNaN(parseInt(yy))) {
                dateString = '00/00/0000';
                return dateString;
            }
            yy += '';

            switch (yy.length) {
            case 0:
                yy = '0000';
                break;
            case 1:
                yy = '000' + yy;
                break;
            case 2:
                yy = '00' + yy;
                break;
            case 3:
                yy = '0' + yy;
                break;
            }
            dateString = month + "/" + day + "/" + yy;
        }
        return dateString;
    }
    function testRegex(val, regExp) {
        var flag = false;
        var re = new RegExp(regExp);
        if (val != "" && val.length > 0 && val.match(re)) {
            flag = true;
        }
        return flag;
    }
</script>

Polishing the standalone Spring Hibernate Example

I have modified the post here http://cuppajavamattiz.com/2008/06/14/migrating-to-a-standalone-spring-hibernate-application/ to make it look more professional.

Scripts to run:

drop table authors;
drop database authors;
create database AUTHORS;
use AUTHORS;
CREATE TABLE authors (ISBN_CODE varchar(10) NOT NULL default '0',AUTHOR varchar(30) default NULL,PRIMARY KEY (ISBN_CODE)) ;
insert into authors (ISBN_CODE,AUTHOR )values("1e","matty");

The main class:

package com.mattiz.web.managedbeans;

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

import com.mattiz.persistence.beans.AuthorBean;
import com.mattiz.service.spring.IMattizDelegate;

public class MattizMain {

private ApplicationContext applicationContext;

private IMattizDelegate mattizDelegate;

public IMattizDelegate getMattizDelegate() {
 mattizDelegate = (IMattizDelegate) applicationContext
 .getBean("mattiz.service.delegate");
 return mattizDelegate;
 }

public void setMattizDelegate(IMattizDelegate mattizDelegate) {
 this.mattizDelegate = mattizDelegate;
 }

public ApplicationContext getApplicationContext() {
 return applicationContext;
 }

public void setApplicationContext(ApplicationContext applicationContext) {
 this.applicationContext = applicationContext;
 }

public static void main(String[] args) {
 MattizMain mattizMain = new MattizMain();
 mattizMain.applicationContext = new ClassPathXmlApplicationContext(
 "resources/mattiz.xml");
 mattizMain.getMattizDelegate().addAuthor("007", "Bond");
 AuthorBean authorBean = mattizMain.getMattizDelegate().findAuthor("007");
 System.out.println("AUTHOR IS " + authorBean.getAuthor());
 }

}

The Delegate class:

package com.mattiz.service.spring;

import com.mattiz.persistence.beans.AuthorBean;
import com.mattiz.persistence.data.IMattizDao;

public class MattizDelegate implements IMattizDelegate {

private IMattizDao mattizDao;

public void addAuthor(String isbnCode, String author) {
 getMattizDao().insertAuthor(isbnCode, author);
 }

public AuthorBean findAuthor(String isbnCode) {
 AuthorBean authorsBean = getMattizDao().lookupIsbn(isbnCode);
 return authorsBean;
 }

 public IMattizDao getMattizDao() {
 return mattizDao;
 }

public void setMattizDao(IMattizDao mattizDao) {
 this.mattizDao = mattizDao;
 }

}

The delegate interface:

package com.mattiz.service.spring;

import com.mattiz.persistence.beans.AuthorBean;
import com.mattiz.persistence.data.IMattizDao;

public interface IMattizDelegate {

 public void addAuthor(String isbnCode, String author);

public AuthorBean findAuthor(String isbnCode);

 public IMattizDao getMattizDao();

public void setMattizDao(IMattizDao mattizDao);

}

The Domain class:

package com.mattiz.persistence.beans;

public class AuthorBean {
 String author;
 String isbnCode;

public String getAuthor() {
 return author;
 }

public void setAuthor(String author) {
 this.author = author;
 }

public String getIsbnCode() {
 return isbnCode;
 }

public void setIsbnCode(String isbnCode) {
 this.isbnCode = isbnCode;
 }

}

The Dao class:

package com.mattiz.persistence.data;

import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.mattiz.persistence.beans.AuthorBean;

public class MattizDao implements IMattizDao {

private HibernateTemplate hibernateTemplate;

public AuthorBean lookupIsbn(String isbn) throws DataAccessException {
 // List l = getHibernateTemplate().find(
 // "from Authors authorBean where authorBean.isbnCode = ?", isbn);//use
 // when
 // isbn is not PK
 AuthorBean authorBean = null;
 authorBean = (AuthorBean) getHibernateTemplate().load(AuthorBean.class,
 isbn);
 return authorBean;
 }

public void insertAuthor(String isbn, String authorName)
 throws DataAccessException {
 AuthorBean authorBean = new AuthorBean();
 authorBean.setAuthor(authorName);
 authorBean.setIsbnCode(isbn);
 HibernateTemplate template = getHibernateTemplate();
 template.saveOrUpdate(authorBean);
 System.out.println("Inserted/Updated AuthorBean, ISBN "
 + authorBean.getAuthor() + " " + authorBean.getIsbnCode());
 }

public HibernateTemplate getHibernateTemplate() {
 return hibernateTemplate;
 }

public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
 this.hibernateTemplate = hibernateTemplate;
 }
}

The Dao interface:

package com.mattiz.persistence.data;

import org.springframework.dao.DataAccessException;

import com.mattiz.persistence.beans.AuthorBean;

public interface IMattizDao {

public AuthorBean lookupIsbn(String isbn) throws DataAccessException;

public void insertAuthor(String isbn, String authorName)
 throws DataAccessException;

}

The mapping hbm file(Author.hbml.xml):

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
 <class name="com.mattiz.persistence.beans.AuthorBean" table="AUTHORS"
 lazy="false">
 <id name="isbnCode" type="java.lang.String" column="ISBN_CODE"
 length="10" />
 <property name="author" type="java.lang.String" column="AUTHOR"
 length="50" />
 </class>
</hibernate-mapping>

The spring configuration file(mattiz.xml):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

<bean id="mattiz.hibernate.dataSource"
 class="com.mchange.v2.c3p0.ComboPooledDataSource"
 destroy-method="close">
 <property name="driverClass" value="com.mysql.jdbc.Driver" />
 <property name="jdbcUrl"
 value="jdbc:mysql://localhost:3306/authors" />
 <property name="user" value="root" />
 <property name="password" value="admin" />
 </bean>

<bean id="mattiz.abstract.hibernate.sessionfactory"
 class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
 abstract="true" lazy-init="true">
 <property name="dataSource">
 <ref local="mattiz.hibernate.dataSource" />
 </property>
 <property name="hibernateProperties">
 <props>
 <prop key="hibernate.dialect">
 org.hibernate.dialect.MySQLDialect
 </prop>
 <prop key="hibernate.show_sql">false</prop>
 </props>
 </property>
 </bean>

<bean id="mattiz.pageSize" class="java.lang.Integer">
 <constructor-arg value="5000"></constructor-arg>
 </bean>

<bean id="mattiz.hibernate.sessionfactory"
 parent="mattiz.abstract.hibernate.sessionfactory">
 <property name="mappingResources">
 <list>
 <value>resources/Author.hbm.xml</value>
 </list>
 </property>
 </bean>

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

<bean id="mattiz.hibernateTemplate"
 class="org.springframework.orm.hibernate3.HibernateTemplate">
 <property name="sessionFactory">
 <ref bean="mattiz.hibernate.sessionfactory" />
 </property>
 </bean>

<bean id="mattiz.dao.mattizDAO"
 class="com.mattiz.persistence.data.MattizDao"
 singleton="true">
 <property name="hibernateTemplate">
 <ref bean="mattiz.hibernateTemplate" />
 </property>
 </bean>

<bean id="mattiz.client"
 class="com.mattiz.web.managedbeans.MattizMain"
 singleton="true">
 <property name="mattizDelegate" ref="mattiz.service.delegate" />
 </bean>

<bean id="mattiz.service.delegate"
 class="com.mattiz.service.spring.MattizDelegate"
 singleton="true">
 <property name="mattizDao" ref="mattiz.dao.mattizDAO" />
 </bean>

</beans>

The jars I added are from the springsource with dependencies package. Other than that I used the mysql driver, jta.jar (see screenshot)
Capture

Download source code here StandAloneHibernateUpdated

Dynamic Data for Google maps using Java

Here is how to use google maps with dynamic data in a JSF application. Could be easily modified for Struts …etc…
The java classes used:
The POJO

package com.mattiz.web.managedBeans;
public class GoogleMapBean {

	private double latitude;
	private double longitude;
	private String location;

	public double getLatitude() {
		return latitude;
	}
	public void setLatitude(double latitude) {
		this.latitude = latitude;
	}
	public double getLongitude() {
		return longitude;
	}
	public void setLongitude(double longitude) {
		this.longitude = longitude;
	}
	public String getLocation() {
		return location;
	}
	public void setLocation(String location) {
		this.location = location;
	}
}

The backing bean

package com.mattiz.web.managedBeans;
import java.util.ArrayList;
import java.util.List;
public class GoogleDataLoadBean {

	private List<GoogleMapBean> googleMapLocations;

	private double centerLatitude;

	private double centerLongitude;

	public String populateGoogleMapLocations() {
		List<GoogleMapBean> googleMapLocations = new ArrayList<GoogleMapBean>();
		GoogleMapBean googleMapBean1 = new GoogleMapBean();
		googleMapBean1.setLatitude(-33.890542);
		googleMapBean1.setLongitude(151.274856);
		googleMapBean1.setLocation("Bondi Beach");
		GoogleMapBean googleMapBean2 = new GoogleMapBean();
		googleMapBean2.setLatitude(-33.923036);
		googleMapBean2.setLongitude(151.259052);
		googleMapBean2.setLocation("Coogee Beach");
		GoogleMapBean googleMapBean3 = new GoogleMapBean();
		googleMapBean3.setLatitude(-34.028249);
		googleMapBean3.setLongitude(151.157507);
		googleMapBean3.setLocation("Cronulla Beach");
		GoogleMapBean googleMapBean4 = new GoogleMapBean();
		googleMapBean4.setLatitude(-33.80010128657071);
		googleMapBean4.setLongitude(151.28747820854187);
		googleMapBean4.setLocation("Manly Beach");
		GoogleMapBean googleMapBean5 = new GoogleMapBean();
		googleMapBean5.setLatitude(-33.950198);
		googleMapBean5.setLongitude(151.259302);
		googleMapBean5.setLocation("Maroubra Beach");
		googleMapLocations.add(googleMapBean1);
		googleMapLocations.add(googleMapBean2);
		googleMapLocations.add(googleMapBean3);
		googleMapLocations.add(googleMapBean4);
		googleMapLocations.add(googleMapBean5);
		List<Double> latitudeList = new ArrayList<Double>();
		List<Double> longitudeList = new ArrayList<Double>();
		for(GoogleMapBean g: googleMapLocations){
			latitudeList.add(g.getLatitude());
			longitudeList.add(g.getLongitude());
		}
		setCenterLatitude(findAverage(latitudeList));
		setCenterLongitude(findAverage(longitudeList));
		setGoogleMapLocations(googleMapLocations);
		return "googleMapView";
	}
	public List<GoogleMapBean> getGoogleMapLocations() {
		return googleMapLocations;
	}
	public void setGoogleMapLocations(List<GoogleMapBean> googleMapLocations) {
		this.googleMapLocations = googleMapLocations;
	}
	public static double findAverage(List<Double> a){
		double sum = 0;
		for (double num : a)
		sum += num;
		return sum / a.size();
		}

	public double getCenterLatitude() {
		return centerLatitude;
	}
	public void setCenterLatitude(double centerLatitude) {
		this.centerLatitude = centerLatitude;
	}
	public double getCenterLongitude() {
		return centerLongitude;
	}
	public void setCenterLongitude(double centerLongitude) {
		this.centerLongitude = centerLongitude;
	}
}

The jsp page: mapview.jsp

<?xml version="1.0" encoding="ISO-8859-1"?>
<xmlns="http://java.sun.com/xml/ns/j2ee"
   xsi="http://www.w3.org/2001/XMLSchema-instance"
   schemalocation="http://java.sun.com/xml/ns/j2ee   
   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<%@page contentType="text/html"%>
<%@ taglib uri="/WEB-INF/html_basic.tld" prefix="h"%>
<%@ taglib uri="/WEB-INF/jsf_core.tld" prefix="f"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html> 
<head> 
  <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> 
  <title>Google Maps Multiple Markers</title> 
  <script src="http://maps.google.com/maps/api/js?sensor=false"
          type="text/javascript"></script>
</head> 
<body>
  <div id="map" style="width: 500px; height: 400px;"></div>
 
  <script type="text/javascript">
 var locations = [
  <c:forEach items="${loadBean.googleMapLocations}" var="googleLocation"  varStatus ="status">
  ['${googleLocation.location}','${googleLocation.latitude}','${googleLocation.longitude}']
    <c:if test="${!status.last}">    
        ,    
    </c:if>
  </c:forEach>
  ]
    alert(locations);
       var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 10,
      center: new google.maps.LatLng("${loadBean.centerLatitude}", "${loadBean.centerLongitude}"),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
 
    var infowindow = new google.maps.InfoWindow();
 
    var marker, i;
 
    for (i = 0; i < locations.length; i++) {  
      marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map
      });
 
      google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
          infowindow.setContent(locations[i][0]);
          infowindow.open(map, marker);
        }
      })(marker, i));
    }
  </script>
  <table>
    <c:forEach var="googleLocation" items="${loadBean.googleMapLocations}">
        <tr><td>${googleLocation.latitude}<td><td>${googleLocation.longitude}</td></tr>  
    </c:forEach>
</table>
CENTER<tr><td>${loadBean.centerLatitude}<td><td>${loadBean.centerLongitude}</td></tr>
</body>
</html>

The index jsp:

<%@page contentType="text/html"%>
<%@ taglib uri="/WEB-INF/html_basic.tld" prefix="h"%>
<%@ taglib uri="/WEB-INF/jsf_core.tld" prefix="f"%>
<html>
    <head>
        <title>author.jsp</title>
        <meta http-equiv="pragma" content="no-cache">
        <meta http-equiv="cache-control" content="no-cache">
        <meta http-equiv="expires" content="0">
    </head>
    <body>
        <f:view>
            <h:form>
                <h:commandButton value="Load Data" type="submit" action="#{loadBean.populateGoogleMapLocations}" />
            </h:form>
        </f:view>
    </body>
</html>

faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
 
<faces-config>
<navigation-rule>
        <navigation-case>
            <from-outcome>googleMapView</from-outcome>
            <to-view-id>/pages/mapview.jsp</to-view-id>
        </navigation-case>
</navigation-rule>
 
    <managed-bean>
        <description>JSF Backing Bean for populating Google Data</description>
        <managed-bean-name>loadBean</managed-bean-name>
        <managed-bean-class>com.mattiz.web.managedBeans.GoogleDataLoadBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
    <managed-bean>
        <description>JSF Backing Bean for google map view</description>
        <managed-bean-name>googleMapBean</managed-bean-name>
        <managed-bean-class>com.mattiz.web.managedBeans.GoogleMapBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
    </managed-bean>
</faces-config>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <context-param>
        <param-name>javax.faces.CONFIG_FILES</param-name>
        <param-value>/WEB-INF/faces-config.xml</param-value>
    </context-param>
    <servlet>
        <servlet-name>FacesServlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>FacesServlet</servlet-name>
        <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
</web-app>

build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project name="Mattiz" default="clean" basedir=".">
    <property environment="env" />
    <property name="build.dir" location="build" />
    <property name="build.classes.dir" location="${build.dir}/classes" />
    <property name="build.dist.dir" location="${build.dir}/dist" />
    <property name="java.src.dir" location="src/java" />
    <property name="web.src.dir" location="src/web/mattiz" />
    <property name="JBOSS_HOME" location="H:\mattiz_soft\Jboss501GAJDK6\jboss-5.0.1.GA" />
    <property name="install.jboss.deploy.dir" location="${JBOSS_HOME}/server/default/deploy" />
    <property name="jsfJars.dir" location="lib/jsfJars" />
    <path id="build.path">
        <pathelement location="${JBOSS_HOME}/server/default/lib/jboss-j2ee.jar" />
        <pathelement location="H:\mattiz_soft\tomcat6013\apache-tomcat-6.0.13\lib\servlet-api.jar" />
        <pathelement location="${jsfJars.dir}/jsf-api.jar" />
    </path>
    <target name="clean" depends="install">
        <delete file="${build.dist.dir}/mattiz.jar" />
        <delete file="${build.dist.dir}/mattiz.war" />
        <delete dir="${build.classes.dir}" />
    </target>
    <target name="init">
        <mkdir dir="${build.dir}" />
        <mkdir dir="${build.classes.dir}" />
        <mkdir dir="${build.dist.dir}" />
    </target>
    <target name="compile" depends="init">
        <javac srcdir="${java.src.dir}" destdir="${build.classes.dir}" debug="on" deprecation="on" classpathref="build.path" optimize="off" />
    </target>
    <target name="jar" depends="compile">
        <jar destfile="${build.dist.dir}/mattiz.jar">
            <fileset dir="${build.classes.dir}" includes="**/*" excludes="**/*.java" />
        </jar>
        <copy todir="${build.classes.dir}">
            <fileset dir="${java.src.dir}" />
        </copy>
        <war destfile="${build.dist.dir}/mattiz.war" webxml="WebRoot/WEB-INF/web.xml">
            <webinf dir="WebRoot/WEB-INF" />
            <lib dir="${jsfJars.dir}" />
            <lib dir="${build.dist.dir}" includes="mattiz.jar" />
            <zipfileset dir="${web.src.dir}/pages" prefix="pages" />
        </war>
    </target>
    <target name="install" depends="jar">
        <copy overwrite="${FORCE}" todir="${install.jboss.deploy.dir}">
            <fileset dir="${build.dist.dir}">
                <include name="mattiz.war" />
            </fileset>
        </copy>
    </target>
</project>

Resource structure:


The URL to hit:
http://localhost:8080/mattiz/pages/index.faces
The output:

Use of Timer in an asynchronous call in GWT

The following example illustrates the use of a timer that emulates synchronization on an asynchronous RPC call.

The client side waits till an RPC call returns by using the timer.
The code follows for the gwt.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='JSNITest'>
  <!-- Inherit the core Web Toolkit stuff.                        -->
  <inherits name='com.google.gwt.user.User'/>
 
  <inherits name='com.google.gwt.user.theme.standard.Standard'/>
 
  <!-- Specify the app entry point class.                         -->
  <entry-point class='com.mattiz.jsni.client.entrypoint.HelloConnector'/>
   <script src="./js-graph-it.js">
    <![CDATA[
      if ($wnd.$) {
        return true;
      }
      else {
        return false;
      }
    ]]>
    </script>
</module>

For illustrating the concept I have used a js snippet from sourceforge that draws linked labels to form a graph.
The js and css for this can be obtained from http://sourceforge.net/projects/js-graph-it/
The css file and js file can be downloaded from here.

The entrypoint class below:

package com.mattiz.jsni.client.entrypoint;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.rpc.ServiceDefTarget;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.mattiz.jsni.client.model.GraphObject;
import com.mattiz.jsni.client.service.JsniCallback;
import com.mattiz.jsni.client.service.JsniService;
import com.mattiz.jsni.client.service.JsniServiceAsync;

public class HelloConnector implements EntryPoint {

	public void onModuleLoad() {
		Label activeLabel = new Label();
		activeLabel.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				System.out.println(event.getNativeButton());
				System.out.println("You clicked!");
			}
		});
		StringBuffer html = new StringBuffer();
		JsniServiceAsync service = (JsniServiceAsync) GWT
				.create(JsniService.class);
		ServiceDefTarget serviceDef = (ServiceDefTarget) service;
		serviceDef.setServiceEntryPoint(GWT.getModuleBaseURL() + "userService");
		final JsniCallback jsniCallback = new JsniCallback(html, activeLabel);
		service.getGraphObjectList(jsniCallback);
		Timer t = new Timer() {
			public void run() {
				if (jsniCallback.getHtml() != null
						&& jsniCallback.getHtml().length() > 0) {
					RootPanel.get().add(
							new HTML(jsniCallback.getHtml().toString()));
					cancel();
					loadGraph();
				}
			}
		};
		t.schedule(5000);
	}

	private static native void loadGraph()/*-{
		$wnd.initPageObjects();
	}-*/;
}

The callback class:

package com.mattiz.jsni.client.service;

import java.util.List;

import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Label;
import com.mattiz.jsni.client.model.GraphObject;

public class JsniCallback implements AsyncCallback<List<GraphObject>> {

	private StringBuffer html;

	public StringBuffer getHtml() {
		return html;
	}

	public void setHtml(StringBuffer html) {
		this.html = html;
	}

	public JsniCallback(StringBuffer html, Label activeLabel) {
		this.html = html;
	}

	public void onFailure(Throwable caught) {
		Window.alert(caught.getMessage());
	}

 public void onSuccess(List<GraphObject> result) {
        List<GraphObject> graphObjects = result;
		int i = 0;
		String concatenatedHtml = "";
		String connector = "";
		for (GraphObject graphObject : graphObjects) {
			Label label = new Label();
			label.setText(graphObject.getBlockName());
			concatenatedHtml += generateLabelHtml(graphObject, label);
			if (i > 0) {
				connector = generateConnectorHtml(graphObject,
						graphObject.getParentGraphObject());
				concatenatedHtml += connector;
			}
			i++;
		}
		html.append("<div class='canvas' id='mainCanvas'  style='width: 1500px; height: 650px; "
                + "border: 1px solid black;'>" + concatenatedHtml + "</div>");
        setHtml(html);
	}

	private String generateLabelHtml(GraphObject graphObject, Label label) {
		 return "<h1 class='block draggable' id='" + graphObject.getBlockName()
                + "'  style='left: " + graphObject.getInitialPos() + "px; top:"
                + graphObject.getInitialPos() + "px;'>" + label + "</h1>";
	}

	private String generateConnectorHtml(GraphObject parentGraphObject,
			GraphObject graphObject) {
		return "<div class='connector " + parentGraphObject.getBlockName()
				+ " " + graphObject.getBlockName() + "'></div>";
	}
}

The service and async service class:

package com.mattiz.jsni.client.service;

import java.util.List;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.mattiz.jsni.client.model.GraphObject;

@RemoteServiceRelativePath("userService")
public interface JsniService extends RemoteService {

	public List<GraphObject> getGraphObjectList();
}
package com.mattiz.jsni.client.service;

import java.util.List;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.mattiz.jsni.client.model.GraphObject;


public interface JsniServiceAsync {

	void getGraphObjectList(AsyncCallback<List<GraphObject>> callback);
}

The server side class:

package com.mattiz.jsni.server;
 
import java.util.ArrayList;
import java.util.List;
 
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.mattiz.jsni.client.model.GraphObject;
import com.mattiz.jsni.client.service.JsniService;
 
public class JsniServiceImpl extends RemoteServiceServlet implements
        JsniService {
 
    /**
     * 
     */
    private static final long serialVersionUID = -8780636846638058183L;
 
    public List<GraphObject> getGraphObjectList() {
        int initialPos = 0;
        GraphObject parentGraphObject = null;
        List<GraphObject> graphObjects = new ArrayList<GraphObject>();
        for (int i = 0; i < 6; i++) {
            GraphObject graphObject = new GraphObject();
            graphObject.setBlockName("h" + (i + 1) + "_block");
            graphObject.setInitialPos(initialPos);
            initialPos += 100;
            if (i > 0) {
                graphObject.setParentGraphObject(parentGraphObject);
            }
            graphObjects.add(graphObject);
            parentGraphObject = graphObject;            
        }
        return graphObjects;
    }
 
}

The model class that represents each node of the graph:

package com.mattiz.jsni.client.model;

import java.io.Serializable;

public class GraphObject implements Serializable {

	/**
	 *
	 */
	private static final long serialVersionUID = 8456420877276927717L;
	private int initialPos;
	private String connector;
	private String concatenatedHtml;
	private String blockName;
	private GraphObject parentGraphObject;


	public GraphObject getParentGraphObject() {
		return parentGraphObject;
	}
	public void setParentGraphObject(GraphObject parentGraphObject) {
		this.parentGraphObject = parentGraphObject;
	}
	public int getInitialPos() {
		return initialPos;
	}
	public void setInitialPos(int initialPos) {
		this.initialPos = initialPos;
	}
	public String getConnector() {
		return connector;
	}
	public void setConnector(String connector) {
		this.connector = connector;
	}
	public String getConcatenatedHtml() {
		return concatenatedHtml;
	}
	public void setConcatenatedHtml(String concatenatedHtml) {
		this.concatenatedHtml = concatenatedHtml;
	}
	public String getBlockName() {
		return blockName;
	}
	public void setBlockName(String blockName) {
		this.blockName = blockName;
	}
}

JSNITest.html:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="JSNITest.css">
    <link type="text/css" rel="stylesheet" href="js-graph-it.css"/>
    <title>My First GWT application</title>
    <script type="text/javascript" language="javascript" src="jsnitest/JSNITest.nocache.js"></script>
    <script type="text/javascript" language="javascript" src="jsnitest/js-graph-it.js"></script>
    <style>
      .canvas {
        font-family: tahoma;
      }
      .block {
        position: absolute;
        border: 1px solid #7DAB76;
        background-color: #BAFFB0;
        padding: 3px;
      }
      .connector {
        border: 1px solid #7DAB76;
        background-color: #FF9900;
      }
    </style>
   </head>
 
  <body>
 
  </body>
</html>

JSNITest.css

/** Add css rules here for your application. */


/** Example rules used by the template application (remove for your app) */
h1 {
  font-size: 2em;
  font-weight: bold;
  color: #777777;
  margin: 40px 0px 70px;
  text-align: center;
}

.sendButton {
  display: block;
  font-size: 16pt;
}

js-graph-it.css

.draggable
{
	position: absolute;
	cursor: move;
	z-index: 1;
}

.connector
{
	background-color: black;
}

.dock_point
{
	height: 1px;
	width: 1px;
	overflow: hidden;
	padding: 0px !important;
	border: none !important;
	margin: 0px !important;
	position: absolute;
	font-size: 1px;
	visibility: hidden;
}


/** Most GWT widgets already have a style name defined */
.gwt-DialogBox {
  width: 400px;
}

.dialogVPanel {
  margin: 5px;
}

.serverResponseLabelError {
  color: red;
}

/** Set ids using widget.getElement().setId("idOfElement") */
#closeButton {
  margin: 15px 6px 6px;
}
.gwt-Label {
	color: #DF0101;
	font: normal 12px tahoma, arial, helvetica, sans-serif;
	border: 1px solid #99bbe8;
	padding: 14px;
}
.canvas-Style {
	width: 350px;
	height: 250px;
	border: 1px solid black;
}

GWT and Java Script Native Interface (JSNI) calls

package com.mattiz.jsni.client;

import java.util.Date;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.JsDate;
import com.google.gwt.dev.jjs.ast.JStringLiteral;
import com.google.gwt.dev.js.ast.JsStringLiteral;
import com.google.gwt.dev.js.ast.JsVars.JsVar;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;

public class HelloJsni implements EntryPoint {

	@Override
	public void onModuleLoad() {
		Label label = new Label(
				"Enter date in any of these formats: MM/dd/yyyy, M/dd/yyyy, MM/d/yyyy M/d/yyyy, "
						+ "MM.dd.yyyy, M.dd.yyyy, MM.d.yyyy,M.d.yyyy, yyyy/MM/dd, yyyy/MM/d, yyyy/M/dd, yyyy/M/d, "
						+ "yyyy.MM.dd, yyyy.MM.d, yyyy.M.dd, yyyy.M.d, MM/dd/yy, M/d/yy,MM/d/yy M/dd/yy, "
						+ "MM.dd.yy M.d.yy MM.d.yy M.dd.yy ,MMddyyyy");
		label.setStyleName("gwt-Label"); // Change css to use this
		HorizontalPanel hp = new HorizontalPanel();
		RootPanel.get().add(label);
		final TextBox tb = new TextBox();
		tb.addBlurHandler(new BlurHandler() {
			@Override
			public void onBlur(BlurEvent event) {
				String stringJavaDate = tb.getValue();
				String formattedDate = loadDateValidator(stringJavaDate);
				tb.setValue(formattedDate);
			}
		});
		hp.add(tb);
		RootPanel.get().add(label);
		RootPanel.get().add(hp);
	}

	private static native String loadDateValidator(String stringJsVar) /*-{
		return $wnd.convertDateFormat(stringJsVar);//calls method in js file.
	}-*/;
}

Note the js call using JSNI (Java Script Native Interface) in the native function private static native String loadDateValidator().

Source code hierarchy

dateformatter.js (this has been replicated in other posts on this blog)

// Format the Date entered in the any below format to MM/dd/yyyy format:
// Add more date formats here to increase date format range accepted
function convertDateFormat(dateValue) {
    if (!isValidJSDate(dateValue)) {
        alert("Unexpected Date Format");
    }   
    var dateArray = new Array();
    dateArray[0] = "MM/dd/yyyy";
    dateArray[1] = "M/dd/yyyy";
    dateArray[2] = "MM/d/yyyy";
    dateArray[3] = "M/d/yyyy";
 
    dateArray[4] = "yyyy/MM/dd";
    dateArray[5] = "yyyy/MM/d";
    dateArray[6] = "yyyy/M/dd";
    dateArray[7] = "yyyy/M/d";
 
    dateArray[8] = "MM/dd/yy";
    dateArray[9] = "M/d/yy";
    dateArray[10] = "MM/d/yy";
    dateArray[11] = "M/dd/yy";
 
    dateArray[12] = "MM.dd.yyyy";
    dateArray[13] = "M.dd.yyyy";
    dateArray[14] = "MM.d.yyyy";
    dateArray[15] = "M.d.yyyy";
 
    dateArray[16] = "yyyy.MM.dd";
    dateArray[17] = "yyyy.MM.d";
    dateArray[18] = "yyyy.M.dd";
    dateArray[19] = "yyyy.M.d";
 
    dateArray[20] = "MM.dd.yy";
    dateArray[21] = "M.d.yy";
    dateArray[22] = "MM.d.yy";
    dateArray[23] = "M.dd.yy";
 
    dateArray[24] = "MMddyyyy";
 
    if (dateValue != "") {
        for ( var i = 0; i < dateArray.length; ++i) {
            var date = getDateFromFormat(dateValue, dateArray[i]);
            if (date != 0) {
                dateValue = formatDate(new Date(date));
            }
        }
    }
    return dateValue;
}
// to validate the below formats for frontend
// Add more date formats here to increase date format range accepted
function isValidJSDate(dateValue) {
    var flag = false;
    if (dateValue == "") {
        return true;
    }
    var dateArray = new Array();
    dateArray[0] = "MM/dd/yyyy";
    dateArray[1] = "M/dd/yyyy";
    dateArray[2] = "MM/d/yyyy";
    dateArray[3] = "M/d/yyyy";
 
    dateArray[4] = "yyyy/MM/dd";
    dateArray[5] = "yyyy/MM/d";
    dateArray[6] = "yyyy/M/dd";
    dateArray[7] = "yyyy/M/d";
 
    dateArray[8] = "MM/dd/yy";
    dateArray[9] = "M/d/yy";
    dateArray[10] = "MM/d/yy";
    dateArray[11] = "M/dd/yy";
 
    dateArray[12] = "MM.dd.yyyy";
    dateArray[13] = "M.dd.yyyy";
    dateArray[14] = "MM.d.yyyy";
    dateArray[15] = "M.d.yyyy";
 
    dateArray[16] = "yyyy.MM.dd";
    dateArray[17] = "yyyy.MM.d";
    dateArray[18] = "yyyy.M.dd";
    dateArray[19] = "yyyy.M.d";
 
    dateArray[20] = "MM.dd.yy";
    dateArray[21] = "M.d.yy";
    dateArray[22] = "MM.d.yy";
    dateArray[23] = "M.dd.yy";
 
    dateArray[24] = "MMddyyyy";
 
    for ( var i = 0; i < dateArray.length; ++i) {
        var date = getDateFromFormat(dateValue, dateArray[i]);
        if (date != 0) {
            flag = true;
        }
    }
    return flag;
}
 
// Format the Date object to MM/dd/yyyy format:
function formatDate(date) {
    var dateString = "";
    if (date) {
        var d = date.getDate();
        var day = (d < 10) ? '0' + d : d;
        var m = date.getMonth() + 1;
        var month = (m < 10) ? '0' + m : m;
        var yy = date.getFullYear();
        yy += '';
        switch (yy.length) {
        case 0:
            yy = '0000';
            break;
        case 1:
            yy = '000' + yy;
            break;
        case 2:
            yy = '00' + yy;
            break;
        case 3:
            yy = '0' + yy;
            break;
        }
        dateString = month + "/" + day + "/" + yy;
    }
    return dateString;
}
 
// Utility function. returns date in time format.
var MONTH_NAMES = new Array('January', 'February', 'March', 'April', 'May',
        'June', 'July', 'August', 'September', 'October', 'November',
        'December', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
        'Sep', 'Oct', 'Nov', 'Dec');
var DAY_NAMES = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday',
        'Thursday', 'Friday', 'Saturday', 'Sun', 'Mon', 'Tue', 'Wed', 'Thu',
        'Fri', 'Sat');
function LZ(x) {
    return (x < 0 || x > 9 ? "" : "0") + x
}
 
function getDateFromFormat(val, format) {
    val = val + "";
    format = format + "";
    var i_val = 0;
    var i_format = 0;
    var c = "";
    var token = "";
    var token2 = "";
    var x, y;
    var now = new Date();
    var year = now.getYear();
    var month = now.getMonth() + 1;
    var date = 1;
    var hh = now.getHours();
    var mm = now.getMinutes();
    var ss = now.getSeconds();
    var ampm = "";
    while (i_format < format.length) {
        // Get next token from format string
        c = format.charAt(i_format);
        token = "";
        while ((format.charAt(i_format) == c) && (i_format < format.length)) {
            token += format.charAt(i_format++);
        }
        // Extract contents of value based on format token
        if (token == "yyyy" || token == "yy" || token == "y") {
            if (token == "yyyy") {
                x = 4;
                y = 4;
            }
            if (token == "yy") {
                x = 2;
                y = 2;
            }
            if (token == "y") {
                x = 2;
                y = 4;
            }
            year = _getInt(val, i_val, x, y);
            if (year == null) {
                return 0;
            }
            i_val += year.length;
            if (year.length == 2) {
                if (year > 70) {
                    year = 1900 + (year - 0);
                } else {
                    year = 2000 + (year - 0);
                }
            }
        } else if (token == "MMM" || token == "NNN") {
            month = 0;
            for ( var i = 0; i < MONTH_NAMES.length; i++) {
                var month_name = MONTH_NAMES[i];
                if (val.substring(i_val, i_val + month_name.length)
                        .toLowerCase() == month_name.toLowerCase()) {
                    if (token == "MMM" || (token == "NNN" && i > 11)) {
                        month = i + 1;
                        if (month > 12) {
                            month -= 12;
                        }
                        i_val += month_name.length;
                        break;
                    }
                }
            }
            if ((month < 1) || (month > 12)) {
                return 0;
            }
        } else if (token == "EE" || token == "E") {
            for ( var i = 0; i < DAY_NAMES.length; i++) {
                var day_name = DAY_NAMES[i];
                if (val.substring(i_val, i_val + day_name.length).toLowerCase() == day_name
                        .toLowerCase()) {
                    i_val += day_name.length;
                    break;
                }
            }
        } else if (token == "MM" || token == "M") {
            month = _getInt(val, i_val, token.length, 2);
            if (month == null || (month < 1) || (month > 12)) {
                return 0;
            }
            i_val += month.length;
        } else if (token == "dd" || token == "d") {
            date = _getInt(val, i_val, token.length, 2);
            if (date == null || (date < 1) || (date > 31)) {
                return 0;
            }
            i_val += date.length;
        } else if (token == "hh" || token == "h") {
            hh = _getInt(val, i_val, token.length, 2);
            if (hh == null || (hh < 1) || (hh > 12)) {
                return 0;
            }
            i_val += hh.length;
        } else if (token == "HH" || token == "H") {
            hh = _getInt(val, i_val, token.length, 2);
            if (hh == null || (hh < 0) || (hh > 23)) {
                return 0;
            }
            i_val += hh.length;
        } else if (token == "KK" || token == "K") {
            hh = _getInt(val, i_val, token.length, 2);
            if (hh == null || (hh < 0) || (hh > 11)) {
                return 0;
            }
            i_val += hh.length;
        } else if (token == "kk" || token == "k") {
            hh = _getInt(val, i_val, token.length, 2);
            if (hh == null || (hh < 1) || (hh > 24)) {
                return 0;
            }
            i_val += hh.length;
            hh--;
        } else if (token == "mm" || token == "m") {
            mm = _getInt(val, i_val, token.length, 2);
            if (mm == null || (mm < 0) || (mm > 59)) {
                return 0;
            }
            i_val += mm.length;
        } else if (token == "ss" || token == "s") {
            ss = _getInt(val, i_val, token.length, 2);
            if (ss == null || (ss < 0) || (ss > 59)) {
                return 0;
            }
            i_val += ss.length;
        } else if (token == "a") {
            if (val.substring(i_val, i_val + 2).toLowerCase() == "am") {
                ampm = "AM";
            } else if (val.substring(i_val, i_val + 2).toLowerCase() == "pm") {
                ampm = "PM";
            } else {
                return 0;
            }
            i_val += 2;
        } else {
            if (val.substring(i_val, i_val + token.length) != token) {
                return 0;
            } else {
                i_val += token.length;
            }
        }
    }
    // If there are any trailing characters left in the value, it doesn't match
    if (i_val != val.length) {
        return 0;
    }
    // Is date valid for month?
    if (month == 2) {
        // Check for leap year
        if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) { // leap
                                                                            // year
            if (date > 29) {
                return 0;
            }
        } else {
            if (date > 28) {
                return 0;
            }
        }
    }
    if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
        if (date > 30) {
            return 0;
        }
    }
    // Correct hours value
    if (hh < 12 && ampm == "PM") {
        hh = hh - 0 + 12;
    } else if (hh > 11 && ampm == "AM") {
        hh -= 12;
    }
    var newdate = new Date(year, month - 1, date, hh, mm, ss);
    return newdate.getTime();
}
// Utility functions for parsing in getDateFromFormat()
function _isInteger(val) {
    var digits = "1234567890";
    for ( var i = 0; i < val.length; i++) {
        if (digits.indexOf(val.charAt(i)) == -1) {
            return false;
        }
    }
    return true;
}
function _getInt(str, i, minlength, maxlength) {
    for ( var x = maxlength; x >= minlength; x--) {
        var token = str.substring(i, i + x);
        if (token.length < minlength) {
            return null;
        }
        if (_isInteger(token)) {
            return token;
        }
    }
    return null;
}

JSNITest.gwt.xml
Note how the js file has been included in the gwt.xml file and not in the default html file.

<?xml version="1.0" encoding="UTF-8"?>
<module rename-to='JSNITest'>
  <!-- Inherit the core Web Toolkit stuff.                        -->
  <inherits name='com.google.gwt.user.User'/>
 
  <inherits name='com.google.gwt.user.theme.standard.Standard'/>
 
  <!-- Specify the app entry point class.                         -->
  <entry-point class='com.mattiz.jsni.client.HelloJsni'/>
  <script src="./dateFormatter.js">
    <![CDATA[
      if ($wnd.$) {
        return true;
      }
      else {
        return false;
      }
    ]]>
  </script>
</module>

JSNITest.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link type="text/css" rel="stylesheet" href="JSNITest.css">
    <title>My First GWT application</title>
    <script type="text/javascript" language="javascript" src="jsnitest/jsnitest.nocache.js"></script>
  </head>
  <body>
    <!-- OPTIONAL: include this if you want history support -->
    <a href=""></a>
  </body>
</html>

web.xml

<?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>
    <!-- Default page to serve -->
    <welcome-file-list>
        <welcome-file>JSNITest.html</welcome-file>
    </welcome-file-list>
</web-app>

Snapshot below:

Verifying Many to One Bidirectional Hibernate Mapping using Domain Files created by hbm2java

Next we move onto how we use the generated classes in the post below to develop a hibernate application that demonstrates many to one bidirectional relationship. We have a little bit of spring but the highlight is to demonstrate hibernate capabilities.
Refer
http://cuppajavamattiz.com/2012/01/20/hibernate-mappings-with-hbm-xml-files/
and
http://cuppajavamattiz.com/2012/01/30/domain-java-files-from-hibernate-mapping-files/
First we would need to create a database with the following DDL for mySQL:

script

drop database hibemappings;
create database hibemappings;
use hibemappings;
create table Book (isbn_code bigint(3) not null auto_increment, book_title varchar(30), primary key(isbn_code));
create table Author (author_id bigint(3) not null auto_increment, isbn_code_in_author bigint(3), first_name varchar(30), last_name varchar(30), primary key(author_id), foreign Key (isbn_code_in_author) references Book(isbn_code));

The workspace for the project has the following structure on eclipse:

<project>
     <com.mattiz.persistence.beans>
          ...copy over the generated domain files from previous post
          BookWithMultipleAuthors.java
          ContributingAuthor.java
     <com.mattiz.persistnece.data>
          MappingDAO.java
          MappingDAOImpl.java
     <com.mattiz.service.spring>
          AppInvoker.java
     <resources>
         author.hbm.xml(same mapping file used to generate domain files as in previous post)
         book.hbm.xml(same mapping file used to generate domain files as in previous post)
         mattiz.xml(spring configuration file)

I have put most of the jars in http://cuppajavamattiz.com/2008/06/14/migrating-to-a-standalone-spring-hibernate-application/ example on the classpath with a minor change. In addition I have added \spring-framework-2.5.4-with-dependencies\spring-framework-2.5.4\lib\cglib\cglib-nodep-2.1_3.jar also on the classpath.

Copy over the domain classes generated by the hbm2 java and the hbml.xml files to the location shown above. (See previous post)

Note the lazy=false in both hibernate mapping files at two locations by which we enforce eager fetch.

mattiz.xml is the spring configuration file which provides the Spring’s hibernate support to our DAO:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
	<bean id="mattiz.hibernate.dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
		destroy-method="close">
		<property name="driverClass" value="com.mysql.jdbc.Driver" />
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hibemappings" />
		<property name="user" value="root" />
		<property name="password" value="admin" />
	</bean>
	<bean id="mattiz.abstract.hibernate.sessionfactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
		abstract="true" lazy-init="true">
		<property name="dataSource">
			<ref local="mattiz.hibernate.dataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">false</prop>
			</props>
		</property>
	</bean>
	<bean id="mattiz.pageSize" class="java.lang.Integer">
		<constructor-arg value="5000"></constructor-arg>
	</bean>
	<bean id="mattiz.hibernate.sessionfactory" parent="mattiz.abstract.hibernate.sessionfactory">
		<property name="mappingResources">
			<list>
				<value>resources/author.hbm.xml</value>
				<value>resources/book.hbm.xml</value>
			</list>
		</property>
	</bean>
	<bean id="mattiz.transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref bean="mattiz.hibernate.sessionfactory" />
		</property>
	</bean>
	<bean id="mattiz.hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory">
			<ref bean="mattiz.hibernate.sessionfactory" />
		</property>
	</bean>
	<bean id="mattiz.mattizDAO" class="com.mattiz.persistence.data.MappingDAOImpl"
		singleton="true">
		<property name="hibernateTemplate">
			<ref bean="mattiz.hibernateTemplate" />
		</property>
	</bean>
</beans>

We write the following java classes to demonstrate the many to one bidirectional relationship:

MappingDAO.java

package com.mattiz.persistence.data;
 
import java.util.Set;
import com.mattiz.persistence.beans.BookWithMultipleAuthors;
import com.mattiz.persistence.beans.ContributingAuthor;
 
public interface MappingDAO {
     
    public Set<ContributingAuthor> getContributingAuthors(long isbnCode);
 
    public BookWithMultipleAuthors getBookForAuthor(long authorId);
 
    public void initializeDB();
}

MappingDAOImpl.java

package com.mattiz.persistence.data;
 
import java.util.Iterator;
import java.util.Random;
import java.util.Set;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.mattiz.persistence.beans.BookWithMultipleAuthors;
import com.mattiz.persistence.beans.ContributingAuthor;
 
public class MappingDAOImpl implements MappingDAO {
    private HibernateTemplate hibernateTemplate;
 
    public HibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }
 
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }
 
    public Set<ContributingAuthor> getContributingAuthors(long isbnCode) {
        BookWithMultipleAuthors bookWithMultipleAuthors = (BookWithMultipleAuthors) getHibernateTemplate()
                .load(BookWithMultipleAuthors.class, isbnCode);
        Set<ContributingAuthor> authors = bookWithMultipleAuthors
                .getContributingAuthors();
        Iterator<ContributingAuthor> i = authors.iterator();
        while (i.hasNext()) {
            System.out.println("Author "
                    + ((ContributingAuthor) i.next()).getFirstName());
        }
        return authors;
    }
 
    public BookWithMultipleAuthors getBookForAuthor(long authorId) {
        ContributingAuthor contributingAuthor = (ContributingAuthor) getHibernateTemplate()
                .load(ContributingAuthor.class, authorId);
        BookWithMultipleAuthors book = contributingAuthor
                .getBookContributedToByAuthor();
        System.out.println("BOOK " + book.getTitle());
        return book;
    }
 
    public void initializeDB() {// fill up db with random named AUTHORs and
                                // BOOKs
        HibernateTemplate template = getHibernateTemplate();
        BookWithMultipleAuthors bookEntity = new BookWithMultipleAuthors();
        Random random = new Random();
        int ran = generateRandomInteger(65, 74, random);// boiler plate code
        bookEntity.setTitle(new String(new char[] { (char) ran,
                (char) (ran + 3), (char) (ran + 10), (char) (ran + 15) }));
        template.saveOrUpdate(bookEntity);
        System.out.println("Inserted Book, ISBN, Title:  "
                + bookEntity.getIsbnCode() + " " + bookEntity.getTitle());
        for (int i = 0; i < 10; i++) {
            ran = generateRandomInteger(65, 85, random);
            ContributingAuthor contributingAuthor = newContributingAuthor(ran,
                    bookEntity);
            System.out.println("Inserted Author, First and last name:  "
                    + contributingAuthor.getFirstName() + " "
                    + contributingAuthor.getLastName());
        }
    }
 
    private ContributingAuthor newContributingAuthor(int i,
            BookWithMultipleAuthors bookEntity) {
        HibernateTemplate template = getHibernateTemplate();
        ContributingAuthor contributingAuthor = new ContributingAuthor();
        contributingAuthor.setBookId(i);
        contributingAuthor.setFirstName(new String(new char[] { (char) (i + 2),
                (char) (i + 1), (char) (i + 3) }));
        contributingAuthor.setLastName(new String(new char[] { (char) (i + 3),
                (char) (i + 2), (char) (i + 4) }));
        contributingAuthor.setBookContributedToByAuthor(bookEntity);
        template.save(contributingAuthor);
        return contributingAuthor;
    }
 
    private static int generateRandomInteger(int aStart, int aEnd,
            Random aRandom) {// boiler plate code to generate ascii code for A-Z
        if (aStart > aEnd) {
            throw new IllegalArgumentException("Start cannot exceed End.");
        }
        long range = (long) aEnd - (long) aStart + 1;
        long fraction = (long) (range * aRandom.nextDouble());
        int randomNumber = (int) (fraction + aStart);
        return randomNumber;
    } 
}

AppInvoker.java

package com.mattiz.service.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mattiz.persistence.data.MappingDAO;
import com.mattiz.persistence.data.MappingDAOImpl;

public class AppInvoker {
	private ApplicationContext applicationContext;
	private MappingDAO mappingDAOImpl;

	public static void main(String[] args) {
		AppInvoker appInvoker = new AppInvoker();
		appInvoker.setApplicationContext(new ClassPathXmlApplicationContext(
				"resources/mattiz.xml"));
		appInvoker.getMappingDAO().initializeDB();
		appInvoker.getMappingDAO().getContributingAuthors(2L);// demonstrates one to many
		appInvoker.getMappingDAO().getBookForAuthor(11);// demonstrates many to one
	}

	public MappingDAO getMappingDAO() {
		mappingDAOImpl = (MappingDAOImpl) applicationContext
				.getBean("mattiz.mattizDAO");
		return mappingDAOImpl;
	}

	public void setMapppingDAO(MappingDAO mappingDAOImpl) {
		this.mappingDAOImpl = mappingDAOImpl;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}
}

On running the main class in AppInvoker.java you may see an output similar to this on the console:

Inserted Book, ISBN, Title:  9 GJQV
Inserted Author, First and last name:  NMO ONP
Inserted Author, First and last name:  RQS SRT
Inserted Author, First and last name:  JIK KJL
Inserted Author, First and last name:  LKM MLN
Inserted Author, First and last name:  HGI IHJ
Inserted Author, First and last name:  CBD DCE
Inserted Author, First and last name:  RQS SRT
Inserted Author, First and last name:  UTV VUW
Inserted Author, First and last name:  LKM MLN
Inserted Author, First and last name:  GFH HGI
Author HGI
Author LKM
Author QPR
Author POQ
Author ONP
Author FEG
Author TSU
Author GFH
Author EDF
Author MLN
BOOK EHOT

The database might look something like this – verify the mapping->

mysql> select * from book;

+-----------+------------+
| isbn_code | book_title |
+-----------+------------+
|         1 | ILSX       |
|         2 | EHOT       |
|         3 | CFMR       |
|         4 | FIPU       |
|         5 | GJQV       |
|         6 | EHOT       |
|         7 | HKRW       |
|         8 | BELQ       |
|         9 | GJQV       |
+-----------+------------+
9 rows in set (0.00 sec)

mysql> select * from author;
+-----------+---------------------+------------+-----------+
| author_id | isbn_code_in_author | first_name | last_name |
+-----------+---------------------+------------+-----------+
|         1 |                   1 | CBD        | DCE       |
|         2 |                   1 | MLN        | NMO       |
|         3 |                   1 | MLN        | NMO       |
|         4 |                   1 | GFH        | HGI       |
|         5 |                   1 | FEG        | GFH       |
|         6 |                   1 | ONP        | POQ       |
|         7 |                   1 | VUW        | WVX       |
|         8 |                   1 | RQS        | SRT       |
|         9 |                   1 | GFH        | HGI       |
|        10 |                   1 | FEG        | GFH       |
|        11 |                   2 | FEG        | GFH       |
|        12 |                   2 | QPR        | RQS       |
|        13 |                   2 | HGI        | IHJ       |
|        14 |                   2 | LKM        | MLN       |
|        15 |                   2 | TSU        | UTV       |
|        16 |                   2 | MLN        | NMO       |
|        17 |                   2 | ONP        | POQ       |
|        18 |                   2 | GFH        | HGI       |
|        19 |                   2 | EDF        | FEG       |
|        20 |                   2 | POQ        | QPR       |
|        21 |                   3 | LKM        | MLN       |
|        22 |                   3 | VUW        | WVX       |
|        23 |                   3 | DCE        | EDF       |
|        24 |                   3 | ONP        | POQ       |
|        25 |                   3 | UTV        | VUW       |
|        26 |                   3 | DCE        | EDF       |
|        27 |                   3 | SRT        | TSU       |
|        28 |                   3 | IHJ        | JIK       |
|        29 |                   3 | NMO        | ONP       |
|        30 |                   3 | SRT        | TSU       |
|        31 |                   4 | RQS        | SRT       |
|        32 |                   4 | MLN        | NMO       |
|        33 |                   4 | RQS        | SRT       |
|        34 |                   4 | FEG        | GFH       |
|        35 |                   4 | HGI        | IHJ       |
|        36 |                   4 | EDF        | FEG       |
|        37 |                   4 | GFH        | HGI       |
|        38 |                   4 | VUW        | WVX       |
|        39 |                   4 | LKM        | MLN       |
|        40 |                   4 | SRT        | TSU       |

Folder structure here heirarchy

The source code can be downloaded here

Domain java files from hibernate mapping files

This post is related to the discussion on hibernate mappings below.
http://cuppajavamattiz.com/2012/01/20/hibernate-mappings-with-hbm-xml-files/
To take the discussion forward I have created two projects and I shall be dealing with each project in two separate posts.
This post is related to how the hbm2java task creates domain objects mapped to the database on the fly, from hbm.xml files.
The project structure on Eclipse looks like this:

<project>
     <generated/src>
          author.hbm.xml
          book.hbml.xml
          <com.mattiz.persistence.beans>
                 <classes generated by hbm2java.....>
                 BooksWithMultipleAuthors.java
                 ContributingAuthors.java
build.xml
hibernate.properties
log4j.properties
<classpath - jars>
      commons-collections.jar
      commons-logging.jar
      dom4j-1.6.1.jar
     freemarker.jar
     hibernate3.jar
     log4j-1.2.15.jar
     hibernate-annotation.jar
     xercesImpl.jar
     xml-apis.jar
     hibernate-tools.jar

build.xml

<?xml version="1.0" encoding="UTF-8"?>
<project default="codegen">
	<target name="codegen">
		<path id="classpath_id">
			<pathelement
				location="I:/>packages/spring-framework-2.5.4-with-dependencies/spring-framework-2.5.4/lib/jakarta-commons/commons-collections.jar" />
			<pathelement
				location="I:/>packages/spring-framework-2.5.4-with-dependencies/spring-framework-2.5.4/lib/jakarta-commons/commons-logging.jar" />
			<pathelement
				location="I:/>packages/spring-framework-2.5.4-with-dependencies/spring-framework-2.5.4/lib/dom4j/dom4j-1.6.1.jar" />
			<pathelement
				location="I:/>packages/spring-framework-2.5.4-with-dependencies/spring-framework-2.5.4/lib/freemarker/freemarker.jar" />
			<pathelement
				location="I:/>packages/spring-framework-2.5.4-with-dependencies/spring-framework-2.5.4/lib/hibernate/hibernate3.jar" />
			<pathelement
				location="I:/>packages/spring-framework-2.5.4-with-dependencies/spring-framework-2.5.4/lib/log4j/log4j-1.2.15.jar" />
			<pathelement
				location="I:/>packages/spring-framework-2.5.4-with-dependencies/spring-framework-2.5.4/lib/hibernate/hibernate-annotations.jar" />
			<pathelement location="I:/>packages/hibernate-tools.jar/hibernate-tools.jar" />
			<pathelement location="I:/>packages/hsqldb-1_8_0_10.jar" />
		</path>
		<echo>Zippzip</echo>
		<taskdef name="hibernatetool" classname="org.hibernate.tool.ant.HibernateToolTask">
			<classpath refid="classpath_id" />
		</taskdef>
		<hibernatetool destdir="generated/src">
			<configuration propertyfile="./hibernate.properties">
				<fileset dir=".">
					<include name="generated/src/*.hbm.xml" />
				</fileset>
			</configuration>
			<hbm2java />
		</hibernatetool>
	</target>
</project>

author.hbml.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="com.mattiz.persistence.beans">
	<class name="ContributingAuthor" table="Author" lazy="false">
		<id name="bookId" column="author_id" type="long">
			<generator class="native" />
		</id>
		<property name="firstName" type="string" length="20" column="first_name" />
		<property name="lastName" type="string" length="20" column="last_name" />
		<many-to-one name="bookContributedToByAuthor" column="isbn_code_in_author"
			class="BookWithMultipleAuthors" not-null="true" lazy="false" />
	</class>
</hibernate-mapping>

book.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="com.mattiz.persistence.beans">
	<class name="BookWithMultipleAuthors" table="Book" lazy="false">
		<id name="isbnCode" column="isbn_code" type="long">
			<generator class="native" />
		</id>
		<property name="title" type="string" length="20" column="book_title" />
		<set name="contributingAuthors" inverse="true" lazy="false">
			<key column="isbn_code_in_author" />
			<one-to-many class="ContributingAuthor" />
		</set>
	</class>
</hibernate-mapping>

hibernate.properties

hibernate.connection.driver_class=org.hsqldb.jdbcDriver
hibernate.connection.url=jdbc\:hsqldb\:hsql\://localhost
hibernate.connection.username=user
hibernate.connection.password=user
hibernate.connection.pool_size=2
hibernate.dialect=net.sf.hibernate.dialect.HSQLDialect

log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=warn, stdout
log4j.logger.net.sf.hibernate=info
### log just the SQL
log4j.logger.net.sf.hibernate.SQL=debug
### log JDBC bind parameters ###
log4j.logger.net.sf.hibernate.type=info
### log schema export/update ###
log4j.logger.net.sf.hibernate.tool.hbm2ddl=debug
### log cache activity ###
log4j.logger.net.sf.hibernate.cache=debug
### enable the following line if you want to track down connection ###
### leakages when using DriverManagerConnectionProvider ###
log4j.logger.net.sf.hibernate.connection.DriverManagerConnectionProvider=trace

When you run build.xml, the following two classes are generated by hbm2java utility

package com.mattiz.persistence.beans;

// Generated 31 Jan by Hibernate Tools 3.2.2.GA
import java.util.HashSet;
import java.util.Set;

/**
 * BookWithMultipleAuthors generated by hbm2java
 */
public class BookWithMultipleAuthors implements java.io.Serializable {
	private long isbnCode;
	private String title;
	private Set contributingAuthors = new HashSet(0);

	public BookWithMultipleAuthors() {
	}

	public BookWithMultipleAuthors(String title, Set contributingAuthors) {
		this.title = title;
		this.contributingAuthors = contributingAuthors;
	}

	public long getIsbnCode() {
		return this.isbnCode;
	}

	public void setIsbnCode(long isbnCode) {
		this.isbnCode = isbnCode;
	}

	public String getTitle() {
		return this.title;
	}

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

	public Set getContributingAuthors() {
		return this.contributingAuthors;
	}

	public void setContributingAuthors(Set contributingAuthors) {
		this.contributingAuthors = contributingAuthors;
	}
}
package com.mattiz.persistence.beans;

// Generated 31 Jan by Hibernate Tools 3.2.2.GA
/**
 * ContributingAuthor generated by hbm2java
 */
public class ContributingAuthor implements java.io.Serializable {
	private long bookId;
	private String firstName;
	private String lastName;
	private BookWithMultipleAuthors bookContributedToByAuthor;

	public ContributingAuthor() {
	}

	public ContributingAuthor(BookWithMultipleAuthors bookContributedToByAuthor) {
		this.bookContributedToByAuthor = bookContributedToByAuthor;
	}

	public ContributingAuthor(String firstName, String lastName,
			BookWithMultipleAuthors bookContributedToByAuthor) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.bookContributedToByAuthor = bookContributedToByAuthor;
	}

	public long getBookId() {
		return this.bookId;
	}

	public void setBookId(long bookId) {
		this.bookId = bookId;
	}

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return this.lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public BookWithMultipleAuthors getBookContributedToByAuthor() {
		return this.bookContributedToByAuthor;
	}

	public void setBookContributedToByAuthor(
			BookWithMultipleAuthors bookContributedToByAuthor) {
		this.bookContributedToByAuthor = bookContributedToByAuthor;
	}
}

Check this download for a similar app here

Or download source code here

Hibernate Mappings With hbm.xml Files

SCENARIO: Many authors contribute to one book

• Unidirectional associations – Many-to-one

create table Author ( author_id bigint not null primary key, book_id bigint not null, first_name varchar, last_name varchar )
create table Book ( book_id bigint not null primary key )

Author.book_id is foreign key from Book.

author.hbml.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="com.mattiz.persistence.beans">
	<class name="Author">
		<id name="authorid" column="author_Id" type="long">
			<generator class="native" />
		</id>
		<property name="firstName" type="string" length="20" column="first_name" />
		<property name="lastName" type="string" length="20" column="last_name" />
		<many-to-one name="book" column="book_Id" class="Book"
			not-null=”true” />
	</class>
</hibernate-mapping>

In the many-to-one tag the name is “book”, so that means that if you use a getter it would be author.getBook() or if you use HQL author.book.
The many to one tag implies that book_id is a foreign key for this relationship

book.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="com.mattiz.persistence.beans">
	<class name="Book">
		<id name="bookid" column="book_id" type="long">
			<generator class="native" />
		</id>
	</class>
</hibernate-mapping>
package com.mattiz.persistence.beans;

public class Author implements java.io.Serializable {
	private long authorid;
	private String firstName;
	private String lastName;
	private Book book;

	public Author() {
	}

	public Author(Book book) {
		this.book = book;
	}

	public Author(String firstName, String lastName, Book book) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.book = book;
	}

	public long getAuthorid() {
		return this.authorid;
	}

	public void setAuthorid(long authorid) {
		this.authorid = authorid;
	}

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return this.lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public Book getBook() {
		return this.book;
	}

	public void setBook(Book book) {
		this.book = book;
	}
}
package com.mattiz.persistence.beans;

public class Book implements java.io.Serializable {
	private long bookid;

	public Book() {
	}

	public long getBookid() {
		return this.bookid;
	}

	public void setBookid(long bookid) {
		this.bookid = bookid;
	}
}


• Bidirectionality in Many to One

Bidirectional many-to-one

create table Author ( author_id bigint not null primary key, book_id  bigint not null, first_name varchar, last_name varchar )
create table Book ( book_id bigint not null primary key )

Author.book_id is foreign key from Book

author.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping package="com.mattiz.persistence.beans">
	<class name="Author">
		<id name="authorid" column="author_Id" type="long">
			<generator class="native" />
		</id>
		<property name="firstName" type="string" length="20" column="first_name" />
		<property name="lastName" type="string" length="20" column="last_name" />
		<many-to-one name="book" column="book_Id" class="Book"
			not-null="true" />
<!—book_id is FK in Author table from Book table->
	</class>
</hibernate-mapping>

book.hbml.xml

<hibernate-mapping package="com.mattiz.persistence.beans">
	<class name="Book">
		<id name="bookid" column="book_id" type="long">
			<generator class="native" />
		</id>
		<set name="authors" inverse="true"><!—book_id references column in Author table-->
			<key column="book_id" />
			<one-to-many class="Author" />
		</set>
	</class>
</hibernate-mapping>
package com.mattiz.persistence.beans;

public class Author implements java.io.Serializable {
	private long authorid;
	private String firstName;
	private String lastName;
	private Book book;

	public Author() {
	}

	public Author(Book book) {
		this.book = book;
	}

	public Author(String firstName, String lastName, Book book) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.book = book;
	}

	public long getAuthorid() {
		return this.authorid;
	}

	public void setAuthorid(long authorid) {
		this.authorid = authorid;
	}

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return this.lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public Book getBook() {
		return this.book;
	}

	public void setBook(Book book) {
		this.book = book;
	}
}
package com.mattiz.persistence.beans;

import java.util.HashSet;
import java.util.Set;

public class Book implements java.io.Serializable {
	private long bookid;
	private Set authors = new HashSet(0);

	public Book() {
	}

	public Book(Set authors) {
		this.authors = authors;
	}

	public long getBookid() {
		return this.bookid;
	}

	public void setBookid(long bookid) {
		this.bookid = bookid;
	}

	public Set getAuthors() {
		return this.authors;
	}

	public void setAuthors(Set authors) {
		this.authors = authors;
	}
}

If author in book is many-to-one, book to author is one- to-many and is a set.
The FK to author is the primary key in book.

From book.hbm.xml:

<set name="authors" inverse="true">
	<key column="book_id" />
	<one-to-many class="Author" />
</set>

Let’s consider

<key column=”book_id” />

in book.hbm.xml. Here the key book_id is in the other table, i.e. Author. So getAuthors() will use the book_id column (FK) in the Author table.
So Author has PK author_id and FK book_id while Book has PK book_id. This relationship gets the authors (looked up based on FK book_id) associated with that Book. So authors are looked up based on their FK which is book_id and you get multiple authors which is a set. Basically in a one to many the key has to be in the other table.
the fk in a many to one, the key is in this table
The underlying table structure has to match hibernate’s definition else it will give you a runtime exception.
When you see

<key> 

it means refer to the key in the table where it is an FK.

Here is a simplistic explanation of the references:

author.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping package="com.mattiz.persistence.beans">
	<class name="ContributingAuthor">
		<id name="id" column="id" type="long">
			<generator class="native" />
		</id>
		<property name="firstName" type="string" length="20" column="first_name" />
		<property name="lastName" type="string" length="20" column="last_name" />
		<many-to-one name="bookContributedToByAuthor" column="book_Id_in_Author"
			class="BookWithMultipleAuthors" not-null="true" />
	</class>
</hibernate-mapping>

book.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping package="com.mattiz.persistence.beans">
	<class name="BookWithMultipleAuthors">
		<id name="id" column="id" type="long">
			<generator class="native" />
		</id>
		<set name="contributingAuthors" inverse="true">
			<key column="book_Id_in_Author" />
			<one-to-many class="ContributingAuthor" />
		</set>
	</class>
</hibernate-mapping>

Generated classes:

package com.mattiz.persistence.beans;

import java.util.HashSet;
import java.util.Set;

public class BookWithMultipleAuthors implements java.io.Serializable {
	private long id;
	private Set contributingAuthors = new HashSet(0);

	public BookWithMultipleAuthors() {
	}

	public BookWithMultipleAuthors(Set contributingAuthors) {
		this.contributingAuthors = contributingAuthors;
	}

	public long getId() {
		return this.id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public Set getContributingAuthors() {
		return this.contributingAuthors;
	}

	public void setContributingAuthors(Set contributingAuthors) {
		this.contributingAuthors = contributingAuthors;
	}
}
package com.mattiz.persistence.beans;

public class ContributingAuthor implements java.io.Serializable {
	private long id;
	private String firstName;
	private String lastName;
	private BookWithMultipleAuthors bookContributedToByAuthor;

	public ContributingAuthor() {
	}

	public ContributingAuthor(BookWithMultipleAuthors bookContributedToByAuthor) {
		this.bookContributedToByAuthor = bookContributedToByAuthor;
	}

	public ContributingAuthor(String firstName, String lastName,
			BookWithMultipleAuthors bookContributedToByAuthor) {
		this.firstName = firstName;
		this.lastName = lastName;
		this.bookContributedToByAuthor = bookContributedToByAuthor;
	}

	public long getId() {
		return this.id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return this.lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public BookWithMultipleAuthors getBookContributedToByAuthor() {
		return this.bookContributedToByAuthor;
	}

	public void setBookContributedToByAuthor(
			BookWithMultipleAuthors bookContributedToByAuthor) {
		this.bookContributedToByAuthor = bookContributedToByAuthor;
	}
}

Executing a one-to-many book.getAuthors() is the equivalent of writing this sql
select * from t_author where book_id=? Where book_id is the FK in t_author
The book_id would have to be already present in book as a rule via referential integrity
Executing a many to one author.getBook() is the equivalent of writing this sql
select * from t_book where book_id = ? where the parameter in the last query would be from the author table; which would return one (obviously) since you are querying by PK.

• Unidirectional one to one

create table  Author( author_id  bigint not null primary key, book_id  bigint not null unique )
create table Book ( book_id bigint not null primary key )

A unidirectional one-to-one association on a foreign key is almost identical. The only difference is the column unique constraint.
Of course the underlying table structure has to match hibernate’s definition else it will give you a runtime exception.

create table Book ( isbn bigint not null primary key )
create table Author ( isbn bigint not null primary key )
<class name="Book">
<id name="id" column="isbn">
	<generator class="native" />
</id>
</class>
<class name="Author">
	<id name="id" column="isbn">
		<generator class="foreign">
			<param name="property">book</param>
		</generator>
	</id>
	<one-to-one name="book" constrained="true" />
</class>

There are two ways of doing a one-to-one, In the second option the two tables share the same id as the primary key which makes sense since it is a one to one. Both tables have isbn as primary key
One method is by sharing the primary key, the other method is by having a Primarykey and foreign key but enforcing uniqueness on the foreign key. Both isbn ids are generated so they must match, so you see only one has a native generator and the other has a ‘foreign’ generator meaning it relies on the first
If both generate separately they’d get out of synch. We only need to take away that there are two ways of defining a one-to-one
1. Sharing primary key – one table generates the primary key and the other one syncs with the first
2. The other option is to have a PK FK relationship but uniqueness enforced on the FK – so there will only be one.

One attribute that could be useful is the cascade attribute. In a one-to-many or many-to-one relation –
• cascade=”none” means that if saving or deleting first hibernate object has no affect on related objects.
• cascade=”save” means if first object is saved it automatically saves related objects.
• Similarly cascade = “delete” will delete related objects.
• cascade=”all” will save, delete, etc related objects even if they have FK constraints. Everything gets deleted, and hibernate takes care of that.

http://docs.jboss.org/hibernate/core/3.5/reference/en/html/associations.htmlhttp://ndpsoftware.com/HibernateMappingCheatSheet.html

Easy Debugging!

Many a times one needs to debug an application by printing out the state of a java bean or multiple java beans with complex inner variables which may themselves be java beans or complex data types such as arraylists. This task is simplified a lot using the gson utility.

The following standalone application implements two java beans that print out their state by extending a base class that overrides Java Object class’ toString() method.

In the toString() method gson is used to print out formatted state of the java bean that inherits it.

Bean.java


package com.mattiz.bean;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Bean {
	@Override
	public String toString() {
		Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting()
				.create();
		return gson.toJson(this);
	}
}

SampleBean.java

package com.mattiz.bean;

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

public class SampleBean extends Bean {
	private String name;
	private int id;
	private List names;
	private SampleBean2 sampleBean2 = new SampleBean2();

	public SampleBean2 getSampleBean2() {
		return sampleBean2;
	}

	public void setSampleBean2(SampleBean2 sampleBean2) {
		this.sampleBean2 = sampleBean2;
	}

	public SampleBean() {
		this.name = "SampleBean";
		this.id = 1;
		this.names = new ArrayList();
		this.names.add("One");
		this.names.add("Two");
		this.names.add(null);

	}

	public String getName() {
		return name;
	}

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

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public List getNames() {
		return names;
	}

	public void setNames(List names) {
		this.names = names;
	}
}

SampleBean2.java

package com.mattiz.bean;

public class SampleBean2 extends Bean {
	private String address1;
	private String address2;
	private String city;

	public String getAddress1() {
		return address1;
	}

	public void setAddress1(String address1) {
		this.address1 = address1;
	}

	public String getAddress2() {
		return address2;
	}

	public void setAddress2(String address2) {
		this.address2 = address2;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}
}

The main class that tests this functionality:

package com.mattiz;

import com.mattiz.bean.SampleBean;
import com.mattiz.bean.SampleBean2;

public class TestJson_2_4 {
	public static void main(String[] args) {
		SampleBean2 sp2 = new SampleBean2();
		SampleBean sp = new SampleBean();
		sp2.setAddress1("MJ street");
		sp.setSampleBean2(sp2);
		System.out.println("SampleBean : " + sp);
		System.out.println("SampleBean2 : " + sp2);
	}
}

Output looks something like this:

SampleBean : {
"name": "SampleBean",
"id": 1,
"names": [
"One",
"Two",
null
],
"sampleBean2": {
"address1": "MJ street",
"address2": null,
"city": null
}
}
SampleBean2 : {
"address1": "MJ street",
"address2": null,
"city": null
}

The only jar I am using is gson-1.7.1.jar which has this debug utility.

PDF and Excel downloads from a Web Application using POI and iText

This is a web project that employs two servlets, ExcelCreator and PdfCreator.java. In addition to the normal jars associated with servlets(most of these can be found in tomcat lib folders), we need two extra jars for our purposes. I have used itext_1.5.4.jar and poi-2.5.1.jar. Both these jars need to be on the classpath of the project and web-inf lib of the war. itext makes pdf creation simple while poi is associated with excel creation.
Java code used in the application follows:

ExcelCreator.java which is a servlet that creates the Excel file.


package com.mattiz.excelPdf;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

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

import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class ExcelCreator extends HttpServlet {
	public void doPost(HttpServletRequest req, HttpServletResponse res) {
		ClassVO classVO = new PopulationHandler().populateData();
		res.setContentType("application/vnd.ms-excel");
		res.setHeader("Content-disposition", "attachment; filename="
				+ "SchoolReport.xls");
		HSSFWorkbook workBook = new HSSFWorkbook();
		workBook = createHSSFSheet(classVO, workBook);
		try {
			OutputStream out = res.getOutputStream();
			workBook.write(out);
			out.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private HSSFWorkbook createHSSFSheet(ClassVO classVO, HSSFWorkbook workBook) {
		HSSFSheet sheet = workBook.createSheet("School Report");
		int rowNum = 0;
		HSSFRow rowHeader = sheet.createRow(rowNum++);
		rowHeader.createCell((short) 0).setCellValue("Class Name");
		rowHeader.createCell((short) 1).setCellValue("Age Group");
		HSSFRow rowContent = sheet.createRow(rowNum++);
		rowContent.createCell((short) 0).setCellValue(classVO.getClassName());
		rowContent.createCell((short) 1).setCellValue(classVO.getAgeGroup());
		HSSFRow blankRow1 = sheet.createRow(rowNum++);
		blankRow1.createCell((short) 0).setCellValue("");
		HSSFRow innerRowHeader = sheet.createRow(rowNum++);
		innerRowHeader.createCell((short) 0).setCellValue("First Name");
		innerRowHeader.createCell((short) 1).setCellValue("Last Name");
		innerRowHeader.createCell((short) 2).setCellValue("Date Of Birth");
		innerRowHeader.createCell((short) 3).setCellValue("Grade");
		innerRowHeader.createCell((short) 4).setCellValue("Physics");
		innerRowHeader.createCell((short) 5).setCellValue("Chemistry");
		innerRowHeader.createCell((short) 6).setCellValue("Maths");
		innerRowHeader.createCell((short) 7).setCellValue("Biology");
		long phyMarks = 0;
		long chemMarks = 0;
		long mathMarks = 0;
		long bioMarks = 0;
		List<StudentVO> studentDetailsList = classVO.getStudentDetails();
		for (int j = 0; j < studentDetailsList.size(); j++) {
			StudentVO studentVO = studentDetailsList.get(j);
			// create the row data
			HSSFRow innerRowContent = sheet.createRow(rowNum++);
			innerRowContent.createCell((short) 0).setCellValue(
					studentVO.getFirstName());
			innerRowContent.createCell((short) 1).setCellValue(
					studentVO.getLastName());
			innerRowContent.createCell((short) 2).setCellValue(
					studentVO.getDateOfBirth());
			innerRowContent.createCell((short) 3).setCellValue(
					studentVO.getGrade());
			innerRowContent.createCell((short) 4).setCellValue(
					studentVO.getPhysicsMarks());
			phyMarks += studentVO.getPhysicsMarks();
			innerRowContent.createCell((short) 5).setCellValue(
					studentVO.getChemistryMarks());
			chemMarks += studentVO.getChemistryMarks();
			innerRowContent.createCell((short) 6).setCellValue(
					studentVO.getMathsMarks());
			mathMarks += studentVO.getMathsMarks();
			innerRowContent.createCell((short) 7).setCellValue(
					studentVO.getBiologyMarks());
			bioMarks += studentVO.getBiologyMarks();
		}
		HSSFRow blankRow2 = sheet.createRow(rowNum++);
		blankRow2.createCell((short) 0).setCellValue("");
		HSSFRow outerRowHeader = sheet.createRow(rowNum++);
		outerRowHeader.createCell((short) 0).setCellValue(
				"Average Marks In Physics");
		outerRowHeader.createCell((short) 1).setCellValue(
				"Average Marks In Chemistry");
		outerRowHeader.createCell((short) 2).setCellValue(
				"Average Marks In Maths");
		outerRowHeader.createCell((short) 3).setCellValue(
				"Average Marks In Biology");
		HSSFRow outerRowContent = sheet.createRow(rowNum++);
		outerRowContent.createCell((short) 0).setCellValue(
				phyMarks / studentDetailsList.size());
		outerRowContent.createCell((short) 1).setCellValue(
				chemMarks / studentDetailsList.size());
		outerRowContent.createCell((short) 2).setCellValue(
				mathMarks / studentDetailsList.size());
		outerRowContent.createCell((short) 3).setCellValue(
				bioMarks / studentDetailsList.size());
		HSSFRow blankRow3 = sheet.createRow(rowNum++);
		blankRow3.createCell((short) 0).setCellValue("");
		return workBook;
	}

	public void doGet(HttpServletRequest req, HttpServletResponse res) {
		doPost(req, res);
	}
}

PdfCreator.java also a servlet that generates the PDF from sample data.

package com.mattiz.excelPdf;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

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

import com.lowagie.text.BadElementException;
import com.lowagie.text.Cell;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Table;
import com.lowagie.text.pdf.PdfWriter;

import java.awt.Color;

public class PdfCreator extends HttpServlet {
	public void doPost(HttpServletRequest req, HttpServletResponse res) {
		try {
			Document document = new Document();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			PdfWriter.getInstance(document, baos);
			document = createTable(document,
					new PopulationHandler().populateData());
			res.setContentType("application/pdf");
			res.setHeader("Content-disposition", "attachment; filename="
					+ "SchoolReport.pdf");
			res.setContentLength(baos.size());
			OutputStream out = res.getOutputStream();
			baos.writeTo(out);
			out.flush();
			out.close();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private Document createTable(Document document, ClassVO classVO) {
		document.open();
		try {
			HeaderFooter header = new HeaderFooter(new Paragraph(
					"School Report", FontFactory.getFont("Arial", 7)), true);
			document.setHeader(header);
			Font arialSmall = FontFactory.getFont("Arial", 7);
			Font arialMedium = FontFactory.getFont("Arial", 9);
			Table table0 = new Table(4, 2);
			table0.setBorderWidth(0);
			table0.setBorderColor(new Color(0, 0, 255));
			table0.setSpacing(0);
			table0.setPadding(2);
			Font normal21 = new Font(Font.HELVETICA, 11, Font.NORMAL);
			Paragraph para = new Paragraph(30, "School Report", normal21);
			document.add(para);
			table0.addCell(getHeaderLabelCell(arialMedium, "CLASS DETAILS"));
			table0.addCell(getLabelCell(arialSmall, "Class Name"));
			table0.addCell(getContentCell(arialSmall, classVO.getClassName()));
			table0.addCell(getLabelCell(arialSmall, "Age Group"));
			table0.addCell(getContentCell(arialSmall, classVO.getAgeGroup()));
			document.add(table0);
			List<StudentVO> studentDetailList = classVO.getStudentDetails();
			long physicsSum = 0;
			long chemistrySum = 0;
			long mathsSum = 0;
			long biologySum = 0;
			for (int j = 0; j < studentDetailList.size(); j++) {
				StudentVO studentVO = studentDetailList.get(j);
				Table table1 = new Table(4, 6);
				table1.setBorderWidth(0);
				table1.setPadding(2);
				table1.setSpacing(0);
				table1.addCell(getHeaderLabelCell(arialMedium,
						"Student Details"));
				table1.addCell(getNameLabelCell(
						arialSmall,
						studentVO.getFirstName() + " "
								+ studentVO.getLastName()));
				table1.endHeaders();
				table1.addCell(getLabelCell(arialSmall, "Date Of Birth"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getDateOfBirth()));
				table1.addCell(getLabelCell(arialSmall, "Physics"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getPhysicsMarks() + ""));
				physicsSum += studentVO.getPhysicsMarks();
				table1.addCell(getLabelCell(arialSmall, "Grade"));
				table1.addCell(getContentCell(arialSmall, studentVO.getGrade()));
				table1.addCell(getLabelCell(arialSmall, "Chemistry"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getChemistryMarks() + ""));
				chemistrySum += studentVO.getChemistryMarks();
				table1.addCell(getLabelCell(arialSmall, ""));
				table1.addCell(getContentCell(arialSmall, ""));
				table1.addCell(getLabelCell(arialSmall, "Maths"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getMathsMarks() + ""));
				mathsSum += studentVO.getMathsMarks();
				table1.addCell(getLabelCell(arialSmall, ""));
				table1.addCell(getContentCell(arialSmall, ""));
				table1.addCell(getLabelCell(arialSmall, "Biology"));
				table1.addCell(getContentCell(arialSmall,
						studentVO.getBiologyMarks() + ""));
				biologySum += studentVO.getBiologyMarks();
				document.add(table1);
			}
			Table table2 = new Table(4, 2);
			table2.setBorderWidth(0);
			table2.setBorderColor(new Color(0, 0, 255));
			table2.setSpacing(0);
			table2.setPadding(2);
			table2.addCell(getHeaderLabelCell(arialMedium, "Statistics"));
			table2.addCell(getLabelCell(arialSmall, "Average In Physics"));
			table2.addCell(getContentCell(arialSmall,
					(physicsSum / studentDetailList.size()) + ""));
			table2.addCell(getLabelCell(arialSmall, "Average In Maths"));
			table2.addCell(getContentCell(arialSmall,
					(mathsSum / studentDetailList.size()) + ""));
			table2.addCell(getLabelCell(arialSmall, "Average In Chemistry"));
			table2.addCell(getContentCell(arialSmall,
					(chemistrySum / studentDetailList.size()) + ""));
			table2.addCell(getLabelCell(arialSmall, "Average In Biology"));
			table2.addCell(getContentCell(arialSmall,
					(biologySum / studentDetailList.size()) + ""));
			document.add(table2);
		} catch (BadElementException e) {
			e.printStackTrace();
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		document.close();
		return document;
	}

	private Cell getLabelCell(Font arialSmall, String arg) {
		Cell cell = null;
		try {
			arialSmall.setStyle(Font.BOLD);
			cell = new Cell(new Paragraph(arg, arialSmall));
			cell.setGrayFill(0.85f);
			cell.setBorderWidth(0.3f);
		} catch (BadElementException e) {
			e.printStackTrace();
		}
		return cell;
	}

	private Cell getContentCell(Font arialSmall, String arg) {
		Cell cell = null;
		try {
			cell = new Cell(new Paragraph(arg, arialSmall));
			cell.setBorderWidth(0.3f);
		} catch (BadElementException e) {
			e.printStackTrace();
		}
		return cell;
	}

	private Cell getHeaderLabelCell(Font arialMedium, String arg) {
		Cell cell = null;
		try {
			cell = new Cell(new Paragraph(arg, arialMedium));
			arialMedium.setStyle(Font.BOLD);
			cell.setHeader(true);
			cell.setColspan(4);
			cell.setBorderColor(new Color(255, 0, 0));
			cell.setBackgroundColor(Color.LIGHT_GRAY);
			cell.setBorderWidth(0.3f);
		} catch (BadElementException e) {
			e.printStackTrace();
		}
		return cell;
	}

	private Cell getNameLabelCell(Font arialSmall, String arg) {
		Cell cc = null;
		try {
			cc = new Cell(new Paragraph(arg, arialSmall));
			cc.setHeader(true);
			cc.setColspan(4);
			cc.setBorderColor(new Color(0, 0, 255));
			cc.setBackgroundColor(Color.LIGHT_GRAY);
			cc.setBorderWidth(0.3f);
		} catch (BadElementException e) {
			e.printStackTrace();
		}
		return cc;
	}

	public void doGet(HttpServletRequest req, HttpServletResponse res) {
		doPost(req, res);
	}
}

Next follow the value objects used in the application.

ClassVO.java which is a POJO class.

package com.mattiz.excelPdf;

import java.util.List;

public class ClassVO {

	private String className;
	private String ageGroup;
	private List<StudentVO> studentDetails;
	private Integer averageMarksInPhysics;
	private Integer averageMarksInChemistry;
	private Integer averageMarksInMaths;
	private Integer averageMarksInBiology;

	public String getAgeGroup() {
		return ageGroup;
	}

	public void setAgeGroup(String ageGroup) {
		this.ageGroup = ageGroup;
	}

	public Integer getAverageMarksInBiology() {
		return averageMarksInBiology;
	}

	public void setAverageMarksInBiology(Integer averageMarksInBiology) {
		this.averageMarksInBiology = averageMarksInBiology;
	}

	public Integer getAverageMarksInChemistry() {
		return averageMarksInChemistry;
	}

	public void setAverageMarksInChemistry(Integer averageMarksInChemistry) {
		this.averageMarksInChemistry = averageMarksInChemistry;
	}

	public Integer getAverageMarksInMaths() {
		return averageMarksInMaths;
	}

	public void setAverageMarksInMaths(Integer averageMarksInMaths) {
		this.averageMarksInMaths = averageMarksInMaths;
	}

	public Integer getAverageMarksInPhysics() {
		return averageMarksInPhysics;
	}

	public void setAverageMarksInPhysics(Integer averageMarksInPhysics) {
		this.averageMarksInPhysics = averageMarksInPhysics;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

	public List<StudentVO> getStudentDetails() {
		return studentDetails;
	}

	public void setStudentDetails(List<StudentVO> studentDetails) {
		this.studentDetails = studentDetails;
	}
}

StudentVO.java also a POJO class

package com.mattiz.excelPdf;

public class StudentVO {

	private String firstName;
	private String lastName;
	private String grade;
	private String dateOfBirth;
	private Integer physicsMarks;
	private Integer chemistryMarks;
	private Integer mathsMarks;
	private Integer biologyMarks;

	public Integer getBiologyMarks() {
		return biologyMarks;
	}

	public void setBiologyMarks(Integer biologyMarks) {
		this.biologyMarks = biologyMarks;
	}

	public Integer getChemistryMarks() {
		return chemistryMarks;
	}

	public void setChemistryMarks(Integer chemistryMarks) {
		this.chemistryMarks = chemistryMarks;
	}

	public Integer getMathsMarks() {
		return mathsMarks;
	}

	public void setMathsMarks(Integer mathsMarks) {
		this.mathsMarks = mathsMarks;
	}

	public Integer getPhysicsMarks() {
		return physicsMarks;
	}

	public void setPhysicsMarks(Integer physicsMarks) {
		this.physicsMarks = physicsMarks;
	}

	public String getDateOfBirth() {
		return dateOfBirth;
	}

	public void setDateOfBirth(String dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getGrade() {
		return grade;
	}

	public void setGrade(String grade) {
		this.grade = grade;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
}

PopulationHandler.java is the helper class the provides ad hoc data populated randomly.

package com.mattiz.excelPdf;

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

public class PopulationHandler {
	public ClassVO populateData() {
		ClassVO classVO = new ClassVO();
		classVO.setClassName("V");
		classVO.setAgeGroup("12-14");
		List<StudentVO> studentDetails = new ArrayList<StudentVO>();
		for (int i = 0; i < 15; i++) {
			StudentVO studentVO = new StudentVO();
			studentVO.setFirstName(new String(new char[] { (char) (i + 65 + 1),
					(char) (i + 65 + 2), (char) (i + 65 + 3),
					(char) (i + 65 + 4) }));
			studentVO.setLastName(new String(new char[] { (char) (i + 65 + 4),
					(char) (i + 65 + 3), (char) (i + 65 + 2),
					(char) (i + 65 + 1) }));
			studentVO.setDateOfBirth((i + 10) + "/09/1971");
			studentVO.setGrade((char) (65 + i) + "");
			studentVO.setPhysicsMarks(50 + i);
			studentVO.setChemistryMarks(55 + i);
			studentVO.setMathsMarks(60 + i);
			studentVO.setBiologyMarks(75 + i);
			studentDetails.add(studentVO);
		}
		classVO.setStudentDetails(studentDetails);
		return classVO;
	}
}

My web.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>InnerJSTL</display-name>
    <servlet>
        <servlet-name>PdfCreator</servlet-name>
        <servlet-class>com.mattiz.excelPdf.PdfCreator</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>ExcelCreator</servlet-name>
        <servlet-class>com.mattiz.excelPdf.ExcelCreator</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>PdfCreator</servlet-name>
        <url-pattern>/PdfCreator</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>ExcelCreator</servlet-name>
        <url-pattern>/ExcelCreator</url-pattern>
    </servlet-mapping>
</web-app>

home.jsp looks like this:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
            <title>PDF Generator</title>
    </head>
    <body>
        <a href="/ExcelPdf/PdfCreator">PDF</a>
        <br />
        <a href="/ExcelPdf/ExcelCreator">Excel</a>
    </body>
</html>

The application can be called using the following url:
http://localhost:8080//ExcelPdf/home.jsp

After the excel successfully downloads it looks something like this:

Auto Conversion Of Date Format and Validation through JavaScript

The following html file shows how you can automatically convert different date formats entered by the user to mm/dd/yyyy format and validate for incorrect values.

<head>
<title>Auto Conversion Of Date to DD/MM/YYYY Format and Date
    Validation</title>
</head>
<body>
    <FORM>
        Enter date in any of these formats:<br /> <br /> MM/dd/yyyy
        M/dd/yyyy MM/d/yyyy M/d/yyyy <br /> MM.dd.yyyy M.dd.yyyy MM.d.yyyy
        M.d.yyyy <br /> yyyy/MM/dd yyyy/MM/d yyyy/M/dd yyyy/M/d <br />
        yyyy.MM.dd yyyy.MM.d yyyy.M.dd yyyy.M.d <br /> MM/dd/yy M/d/yy
        MM/d/yy M/dd/yy <br /> MM.dd.yy M.d.yy MM.d.yy M.dd.yy <br />
        MMddyyyy <br /> <br />
        <tr>
            <td><INPUT type="text" id="datevar" name="datevar" value=""
                onblur="executeOnBlur()">
            </td>
        </tr>
    </FORM>
    <SCRIPT type=text/javascript>
function executeOnBlur()
{
var dateValue = document.getElementById("datevar").value;
if(dateValue != "")
{
dateValue = convertDateFormat(dateValue); 
document.forms[0].datevar.value = dateValue;
}
}
// Format the Date entered in the any below format to MM/dd/yyyy format:
// Add more date formats here to increase date format range accepted 
function convertDateFormat(dateValue) {
if(!isValidJSDate(dateValue)){
alert("Unexpected Date Format");
}
var dateArray = new Array();
dateArray[0] = "MM/dd/yyyy";
dateArray[1] = "M/dd/yyyy";
dateArray[2] = "MM/d/yyyy";
dateArray[3] = "M/d/yyyy";
 
dateArray[4] = "yyyy/MM/dd";
dateArray[5] = "yyyy/MM/d";
dateArray[6] = "yyyy/M/dd";
dateArray[7] = "yyyy/M/d";
 
dateArray[8] = "MM/dd/yy";
dateArray[9] = "M/d/yy";
dateArray[10] = "MM/d/yy";
dateArray[11] = "M/dd/yy";
 
dateArray[12] = "MM.dd.yyyy";
dateArray[13] = "M.dd.yyyy";
dateArray[14] = "MM.d.yyyy";
dateArray[15] = "M.d.yyyy";
 
dateArray[16] = "yyyy.MM.dd";
dateArray[17] = "yyyy.MM.d";
dateArray[18] = "yyyy.M.dd";
dateArray[19] = "yyyy.M.d";
 
dateArray[20] = "MM.dd.yy";
dateArray[21] = "M.d.yy";
dateArray[22] = "MM.d.yy";
dateArray[23] = "M.dd.yy";
 
dateArray[24] = "MMddyyyy";
 
if(dateValue != "") {
for(var i=0; i < dateArray.length; ++i){
var date = getDateFromFormat(dateValue, dateArray[i]);
if (date != 0) {
dateValue = formatDate(new Date(date));
}
} 
}
return dateValue;
}
// to validate the below formats for frontend
// Add more date formats here to increase date format range accepted 
function isValidJSDate(dateValue) {
var flag = false;
if(dateValue==""){
return true;
} 
var dateArray = new Array();
dateArray[0] = "MM/dd/yyyy";
dateArray[1] = "M/dd/yyyy";
dateArray[2] = "MM/d/yyyy";
dateArray[3] = "M/d/yyyy";
 
dateArray[4] = "yyyy/MM/dd";
dateArray[5] = "yyyy/MM/d";
dateArray[6] = "yyyy/M/dd";
dateArray[7] = "yyyy/M/d";
 
dateArray[8] = "MM/dd/yy";
dateArray[9] = "M/d/yy";
dateArray[10] = "MM/d/yy";
dateArray[11] = "M/dd/yy";
 
dateArray[12] = "MM.dd.yyyy";
dateArray[13] = "M.dd.yyyy";
dateArray[14] = "MM.d.yyyy";
dateArray[15] = "M.d.yyyy";
 
dateArray[16] = "yyyy.MM.dd";
dateArray[17] = "yyyy.MM.d";
dateArray[18] = "yyyy.M.dd";
dateArray[19] = "yyyy.M.d";
 
dateArray[20] = "MM.dd.yy";
dateArray[21] = "M.d.yy";
dateArray[22] = "MM.d.yy";
dateArray[23] = "M.dd.yy";
 
dateArray[24] = "MMddyyyy";
 
for(var i=0;i<dateArray.length;++i)
{
var date = getDateFromFormat(dateValue,dateArray[i]);
if (date!=0) { 
flag = true; 
}
}
return flag;
}
 
// Format the Date object to MM/dd/yyyy format:
function formatDate(date) {
var dateString = "";
if(date) {
var d = date.getDate();
var day = (d < 10) ? '0' + d : d;
var m = date.getMonth() + 1;
var month = (m < 10) ? '0' + m : m;
var yy = date.getFullYear();
yy += ''; 
switch(yy.length) {
case 0:
yy = '0000';
break;
case 1:
yy = '000' + yy;
break;
case 2:
yy = '00' + yy;
break;
case 3:
yy = '0' + yy;
break;
}
dateString = month + "/" + day + "/" + yy;
}
return dateString;
}
 
// Utility function. returns date in time format.
var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
var DAY_NAMES=new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat');
function LZ(x) {return(x<0||x>9?"":"0")+x}
 
function getDateFromFormat(val,format) {
val=val+"";
format=format+"";
var i_val=0;
var i_format=0;
var c="";
var token="";
var token2="";
var x,y;
var now=new Date();
var year=now.getYear();
var month=now.getMonth()+1;
var date=1;
var hh=now.getHours();
var mm=now.getMinutes();
var ss=now.getSeconds();
var ampm="";
while (i_format < format.length) {
// Get next token from format string
c=format.charAt(i_format);
token="";
while ((format.charAt(i_format)==c) && (i_format < format.length)) {
token += format.charAt(i_format++);
}
// Extract contents of value based on format token
if (token=="yyyy" || token=="yy" || token=="y") {
if (token=="yyyy") { x=4;y=4; }
if (token=="yy") { x=2;y=2; }
if (token=="y") { x=2;y=4; }
year=_getInt(val,i_val,x,y);
if (year==null) { return 0; }
i_val += year.length;
if (year.length==2) {
if (year > 70) { year=1900+(year-0); }
else { year=2000+(year-0); }
}
}
else if (token=="MMM"||token=="NNN"){
month=0;
for (var i=0; i<MONTH_NAMES.length; i++) {
var month_name=MONTH_NAMES[i];
if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
if (token=="MMM"||(token=="NNN"&&i>11)) {
month=i+1;
if (month>12) { month -= 12; }
i_val += month_name.length;
break;
}
}
}
if ((month < 1)||(month>12)){return 0;}
}
else if (token=="EE"||token=="E"){
for (var i=0; i<DAY_NAMES.length; i++) {
var day_name=DAY_NAMES[i];
if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
i_val += day_name.length;
break;
}
}
}
else if (token=="MM"||token=="M") {
month=_getInt(val,i_val,token.length,2);
if(month==null||(month<1)||(month>12)){return 0;}
i_val+=month.length;}
else if (token=="dd"||token=="d") {
date=_getInt(val,i_val,token.length,2);
if(date==null||(date<1)||(date>31)){return 0;}
i_val+=date.length;}
else if (token=="hh"||token=="h") {
hh=_getInt(val,i_val,token.length,2);
if(hh==null||(hh<1)||(hh>12)){return 0;}
i_val+=hh.length;}
else if (token=="HH"||token=="H") {
hh=_getInt(val,i_val,token.length,2);
if(hh==null||(hh<0)||(hh>23)){return 0;}
i_val+=hh.length;}
else if (token=="KK"||token=="K") {
hh=_getInt(val,i_val,token.length,2);
if(hh==null||(hh<0)||(hh>11)){return 0;}
i_val+=hh.length;}
else if (token=="kk"||token=="k") {
hh=_getInt(val,i_val,token.length,2);
if(hh==null||(hh<1)||(hh>24)){return 0;}
i_val+=hh.length;hh--;}
else if (token=="mm"||token=="m") {
mm=_getInt(val,i_val,token.length,2);
if(mm==null||(mm<0)||(mm>59)){return 0;}
i_val+=mm.length;}
else if (token=="ss"||token=="s") {
ss=_getInt(val,i_val,token.length,2);
if(ss==null||(ss<0)||(ss>59)){return 0;}
i_val+=ss.length;}
else if (token=="a") {
if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
else {return 0;}
i_val+=2;}
else {
if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
else {i_val+=token.length;}
}
}
// If there are any trailing characters left in the value, it doesn't match
if (i_val != val.length) { return 0; }
// Is date valid for month?
if (month==2) {
// Check for leap year
if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
if (date > 29){ return 0; }
}
else { if (date > 28) { return 0; } }
}
if ((month==4)||(month==6)||(month==9)||(month==11)) {
if (date > 30) { return 0; }
}
// Correct hours value
if (hh<12 && ampm=="PM") { hh=hh-0+12; }
else if (hh>11 && ampm=="AM") { hh-=12; }
var newdate=new Date(year,month-1,date,hh,mm,ss);
return newdate.getTime();
} 
// Utility functions for parsing in getDateFromFormat()
function _isInteger(val) {
var digits="1234567890";
for (var i=0; i < val.length; i++) {
if (digits.indexOf(val.charAt(i))==-1) { return false; }
}
return true;
}
function _getInt(str,i,minlength,maxlength) {
for (var x=maxlength; x>=minlength; x--) {
var token=str.substring(i,i+x);
if (token.length < minlength) { return null; }
if (_isInteger(token)) { return token; }
}
return null;
}
</SCRIPT>
</body>
</html>

Navigating complex data structures using JSTL

This is a simple example showing how to navigate through a complex data structure of inner objects using JSTL.

InnerJSTLTest.jsp looks like this:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
			<title>Inner JSTL Test</title>
	</head>
	<body>
		<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
		<table width="100%" class="table">
			<tr>
				<td>
					<b>JSTL Iteration</b>
				</td>
			</tr>

			<tr>
				<td>
					<table width="100%" class="table" cellpadding="0"
						cellspacing="5" border="0" bgcolor="#FFFFFF">
						<c:set var="listsize" value="1" scope="page" />
						<c:forEach var="arrayElement" items="${messageVO.outerArrayList}"
							varStatus="listsize">
							<c:set var="currentlistindex" value="${listsize.count}"
								scope="page" />
							<br />
							<tr>
								<td width="20%">
									<b>
										<u>
											Section
											<c:out value="${currentlistindex}" />
										</u>
									</b>
									<br />
									<c:forEach var="outerMapElement" items="${arrayElement}">
										<b>Sub-Section: ${outerMapElement.key}</b>
										<br />
										<c:set var="flag" value="0" scope="page" />
										<c:forEach var="innerMapElement" items="${outerMapElement.value}"
											varStatus="innermapsize">
											<u>Sub-Sub-Section: ${innerMapElement.key}</u>
											<br />
											<c:forEach var="innerArrayElement" items="${innerMapElement.value}">
												<c:forEach var="elem" items="${innerArrayElement}">
													<li>${elem}</li>
													<br />
												</c:forEach>
											</c:forEach>
											<c:set var="flag" value="${innermapsize.count}" scope="page" />
										</c:forEach>
										<c:if test='${flag== 0}'>
											<p style="color:#009900">
												<b>EMPTY SUB SECTION!</b>
											</p>
										</c:if>
									</c:forEach>
									<hr />
								</td>
							</tr>
						</c:forEach>

					</table>
				</td>
			</tr>
		</table>
	</body>
</html>


JSTLTestServlet.java looks like this:


package com.mattiz.jstlTest;

import java.io.IOException;

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

public class JSTLTestServlet extends HttpServlet {
	public void doPost(HttpServletRequest req, HttpServletResponse res) {
		try {
			JSTLTestVO jstlTestVO = new JSTLTestVO();
			req.setAttribute("messageVO", jstlTestVO);
			getServletConfig().getServletContext()
					.getRequestDispatcher("/InnerJSTLTest.jsp")
					.forward(req, res);
		} catch (ServletException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void doGet(HttpServletRequest req, HttpServletResponse res) {
		doPost(req, res);
	}
}

JSTLVO.java which builds up the data structure and makes it available to the jsp looks like this


package com.mattiz.jstlTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JSTLTestVO {

	private List outerArrayList;

	public List getOuterArrayList() {
		return populateVO();
	}

	public void setOuterArrayList(List outerArrayList) {
		this.outerArrayList = outerArrayList;
	}

	public List populateVO() {
		List innerList1 = new ArrayList();
		innerList1.add("Java Rocks");
		innerList1.add("Down With M$");
		innerList1.add("Ever Tried Java?");
		innerList1.add(".NET sucks");
		innerList1.add("Make Java while the SUN shines");
		innerList1.add("Java has Everything Under The SUN!");
		innerList1.add("God Bless the SUN");
		innerList1.add("Java rules!");
		List innerList2 = new ArrayList();
		innerList2.add("IBM= I Blame Microsoft!");
		innerList2.add("MAC = Most Applications Crash!");
		innerList2.add("MAC= Most Applications Crash Or System Hangs!");
		List innerList3 = new ArrayList();
		innerList3.add("Good Day!");
		innerList3.add("Guten Tag!");
		innerList3.add("Au Revoir!");
		List innerList4 = new ArrayList();
		innerList4.add("Damn It!");
		innerList4.add("It sucks!");
		Map innermap1 = new HashMap();
		innermap1.put("Java", innerList1);
		Map innermap2 = new HashMap();
		innermap2.put("Acronyms", innerList2);
		innermap2.put("Greetings", innerList3);
		Map innermap3 = new HashMap();
		Map outerMap1 = new HashMap();
		outerMap1.put("Geek Tongue", innermap1);
		outerMap1.put("Mother Tongues", innermap2);
		Map outerMap2 = new HashMap();
		outerMap2.put("Empty?", innermap3);
		List outerArrayList = new ArrayList();
		outerArrayList.add(outerMap1);
		outerArrayList.add(outerMap2);
		return outerArrayList;
	}
}

web.xml looks like this for starters:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
	xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>InnerJSTL</display-name>
	<servlet>
		<servlet-name>JSTLTestServlet</servlet-name>
		<servlet-class>com.mattiz.jstlTest.JSTLTestServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>JSTLTestServlet</servlet-name>
		<url-pattern>/JSTLTestServlet</url-pattern>
	</servlet-mapping>
</web-app>

The URL to run the app is

http://localhost:8080/JSTLInner/JSTLTestServlet

The output looks something like this:

JSTL Iteration
Section  1
Sub-Section:  Mother Tongues 
Sub-Sub-Section:  Greetings
Good Day!
Guten Tag!
Au Revoir!
Sub-Sub-Section:  Acronyms
IBM= I Blame Microsoft!
MAC = Most Applications Crash!
MAC= Most Applications Crash Or System Hangs!
Sub-Section:  Geek Tongue
Sub-Sub-Section:  Java
Java Rocks
Down With M$
Ever Tried Java?
.NET sucks
Make Java while the SUN shines
Java has Everything Under The SUN!
God Bless the SUN
Java rules!
--------------------------------------------------------------------------------
Section  2
Sub-Section:  Empty?
EMPTY SUB SECTION

CLOB insertion – sample code

package com.mattiz.dao;

import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import oracle.jdbc.OraclePreparedStatement;
import oracle.sql.BLOB;
import oracle.sql.CLOB;

public class Query {

	public void insertClob() {

		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		DataSource ds = getDS();
		try {
			conn = ds.getConnection();
			conn.setAutoCommit(false); // we must control the commit
			String sql = "INSERT INTO TEMP_TABLE(UID, CLOB_DATA) VALUES(?,?)";
			ps = conn.prepareStatement(sql);
			ps.setString(1, "1");
			ps.setClob(2, CLOB.empty_lob());
			ps.executeUpdate();
			PreparedStatement getEmptyClob = conn
					.prepareStatement("SELECT CLOB_DATA FROM TEMP_TABLE WHERE UID = ? FOR UPDATE");
			getEmptyClob.setString(1, "1");
			rs = getEmptyClob.executeQuery();
			rs.next();
			Clob clobFromTable = rs.getClob(1); // get the clob from rs
			((oracle.sql.CLOB) clobFromTable).putChars(1,
					"VERY LARGE STRING".toCharArray()); // update the clob
			rs.close();
			conn.commit();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (rs != null) {
					rs.close();
				}
				if (ps != null) {
					ps.close();
				}
				if (conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

A Taglib example of practical use!

This is an interesting experiment where we populate placeholders in a template from the database with arbitrary values whose type and number are also defined in the database.
Before you proceed with this sample application it would be advisable to go through http://cuppajavamattiz.com/2007/05/21/web-design-patterns-at-work-with-pagination/ – for setting up a JSF app.
The basic idea is to show how a custom tablib is implemented with all its frills, but the app could be of practical use too, say in dyanmic web content management.
Before you start coding, you need to create some mysql tables which will be used by the app DAO.
Here they are for starters:

create database template;
DROP TABLE IF EXISTS template;
CREATE TABLE  template(template_id int(11) NOT NULL auto_increment,template_text varchar(512), PRIMARY KEY  (template_id));
DROP TABLE IF EXISTS template_vars;
CREATE TABLE  template_vars(template_id int(11) NOT NULL,var_id int(11) NOT NULL,var_type varchar(5) default NULL,  PRIMARY KEY  (template_id,var_id), FOREIGN KEY (template_id) REFERENCES template (template_id));
insert into template(template_text)values("Dear Mr. **$**, Dated **$** your telephone number **$** will no longer be active. Please make a note of this.");
insert into template(template_text)values("Hallo Mr. **$**, This is to inform you that you have won the grand raffle worth $ **$**. Please do the needful and collect it from our **$** office. The offer expires on **$**");
insert into template_vars values(1, 1, "A");
insert into template_vars values(1, 2, "D");
insert into template_vars values(1, 3, "N");
insert into template_vars values(2, 1,"A" );
insert into template_vars values(2, 2,"N");
insert into template_vars values(2, 3,"A");
insert into template_vars values(2, 4,"D");

I have used the following code:

A – Alphanumeric
D- Date
N – NUmeric

If you are familiar with eclipse as I am, that would make work easier. The otherwise you would have to go through the whole hog of creating a web app through the Ant build tool, of which you will have lots of examples on this site.

I made the following change to mysql-ds.xml in server/default/deploy of the Jboss server.

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
	<local-tx-datasource>
		<jndi-name>dbpool</jndi-name>
		<connection-url>jdbc:mysql://localhost:3306/TEMPLATE</connection-url>
		<driver-class>com.mysql.jdbc.Driver</driver-class>
		<user-name>admin</user-name>
		<password>admin</password>
		<metadata>
			<type-mapping>mySQL</type-mapping>
		</metadata>
	</local-tx-datasource>
</datasources>

My WAR file has the following structure:

templatePage.jsp
templatePopulation.jsp
displayPopulatedTemplate.jsp
<meta-INF>
<web-INF>
        ContentMgmtTag.tld
        faces-config.xml
        html_basic.tld (from jboss impl.)
        jsf_core.tld (from jboss impl.)
        web.xml
        <classes>
          <com>
              <mattiz>
                  <contentmgmt>
                      <dao>
                          ContentMgmtDAO.class
                      <domain>
                          ContentMgmtBean.class
                      <taglib>
                          ContentMgmtTag.class
                      <util>
                          MattizException.class
                      <vo>
                          ContentMgmtVO.class

The taglib and the tld file:

ContentMgmtTag.java

package com.mattiz.contentmgmt.taglib;
 
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import com.mattiz.contentmgmt.dao.ContentMgmtDAO;
import com.mattiz.contentmgmt.util.MattizException;
import com.mattiz.contentmgmt.vo.ContentMgmtVO;
 
public class ContentMgmtTag implements Tag {
    private PageContext pc = null;
    private Tag parent = null;
    private Object templateId;
 
    public void setPageContext(PageContext p) {
        pc = p;
    }
 
    public void setParent(Tag t) {
        parent = t;
    }
 
    public Tag getParent() {
        return parent;
    }
 
    public int doStartTag() throws JspException {
        try {
            ContentMgmtDAO contentMgmtDao = new ContentMgmtDAO();
            List contentMgmtVOList = contentMgmtDao.getVariableData(Integer
                    .parseInt(getTemplateId().toString()));
            Iterator cmvoli = contentMgmtVOList.iterator();
            pc.getOut().write("<table>");
            int i = 0;
            while (cmvoli.hasNext()) {
                i++;
                String param = null;
                if (pc.getRequest().getAttribute("param" + i) != null) {
                    param = (String) pc.getRequest().getAttribute("param" + i);
                }
                ContentMgmtVO contentMgmtVO = (ContentMgmtVO) cmvoli.next();
                String varType = contentMgmtVO.getVarType();
                String varTypeFull = null;
                if (varType.equals("A")) {
                    varTypeFull = "Alphanumeric";
                } else if (varType.equals("D")) {
                    varTypeFull = "Date";
                } else if (varType.equals("N")) {
                    varTypeFull = "Numeric";
                }
                pc.getOut().write("<tr><td>");
                if (pc.getRequest().getAttribute("param" + i) == null) {
                    pc.getOut()
                            .write(contentMgmtVO.getVarId()
                                    + "</td><td>   "
                                    + "<input type=\"text\" maxlength = \"10\" size=\"10\" name = \"populationParam\"/><br/>"
                                    + "</td><td>   " + varTypeFull);
                    pc.getOut().write(
                            "<input type=\"hidden\" name= \"populationParamType\" value=\""
                                    + varType + "\">");
                    pc.getOut().write("</td></tr>");
                } else {
                    pc.getOut()
                            .write(contentMgmtVO.getVarId()
                                    + "</td><td>   "
                                    + "<input type=\"text\" maxlength = \"10\" size=\"10\" name = \"populationParam\" value = \""
                                    + param + "\"/><br/>" + "</td><td>   "
                                    + varTypeFull);
                    pc.getOut().write(
                            "<input type=\"hidden\" name= \"populationParamType\" value=\""
                                    + varType + "\">");
                    pc.getOut().write("</td></tr>");
                }
 
            }
            pc.getOut().write("</table>");
            pc.getOut().write(
                    "<input type=\"hidden\" name=\"templateId\" value=\""
                            + getTemplateId().toString() + "\">");
        } catch (MattizException e) {
            throw new JspException("Error in tag", e);
        } catch (IOException e) {
            e.printStackTrace();
            throw new JspException("Error in tag", e);
        }
        return SKIP_BODY;
    }
 
    public int doEndTag() throws JspException {
        return 0;
    }
 
    public void release() {
        pc = null;
        parent = null;
    }
 
    public Object getTemplateId() {
        return templateId;
    }
 
    public void setTemplateId(Object templateId) {
        this.templateId = templateId;
    }
}

The ContentMgmtTag.tld needs to be put under WEB-INF with the other JSF taglibs

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">

<taglib>
	<tlibversion>1.0</tlibversion>
	<jspversion>1.1</jspversion>
	<shortname>MattizTag</shortname>
	<uri>http://www.mattiz.com</uri>
	<info>Jsf Content Mgmt Custom Tag</info>

	<tag>
		<name>ContentMgmtTag</name>
		<tagclass>
			com.mattiz.contentmgmt.taglib.ContentMgmtTag
</tagclass>
		<bodycontent>empty</bodycontent>
		<info>Jsf Content Mgmt Custom Tag</info>

		<attribute>
			<name>templateId</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
	</tag>
</taglib>

The jsf pages:

templatePage.jsp

<%@page contentType="text/html"%>
<%@ taglib
uri="/WEB-INF/html_basic.tld" prefix="h"%>
<%@ taglib
uri="/WEB-INF/jsf_core.tld" prefix="f"%>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
			<title>Insert title here</title>
	</head>
	<body>
		<f:view>
			<h:form id="templateForm">
				<h:selectOneListbox value="#{contentMgmtBean.selectedTemplateId}"
					id="selectedTemplate">
					<f:selectItems id="templateIdList" value="#{contentMgmtBean.templates}" />
				</h:selectOneListbox>
				<br />
				<h:commandButton value="Submit" type="submit"
					action="#{contentMgmtBean.submitTemplate}" />
			</h:form>
		</f:view>
	</body>
</html>

templatePopulation.jsp

<%@page contentType="text/html"%>
<%@ taglib
uri="/WEB-INF/html_basic.tld" prefix="h"%>
<%@ taglib
uri="/WEB-INF/jsf_core.tld" prefix="f"%>
<%@ taglib
uri="/WEB-INF/ContentMgmtTag.tld" prefix="mattiz"%>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
			<title>Insert title here</title>
	</head>
	<body>
		<f:view>
			<h:outputText value="#{contentMgmtBean.template}" />
			<br />
			<h:form id="populationForm">
				<h:message for="populationForm" id="msgForm"></h:message>
				<br />
				<mattiz:ContentMgmtTag
					templateId='<%=request.getAttribute("selectedTemplate")%>' />
				<h:commandButton value="Add" type="submit"
					action="#{contentMgmtBean.populateTemplate}" />
			</h:form>
		</f:view>
	</body>
</html>

displayPopulatedTemplate.jsp

<%@page contentType="text/html"%>
<%@ taglib
uri="/WEB-INF/html_basic.tld" prefix="h"%>
<%@ taglib
uri="/WEB-INF/jsf_core.tld" prefix="f"%>
<%@ taglib
uri="/WEB-INF/ContentMgmtTag.tld" prefix="mattiz"%>
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
			<title>Insert title here</title>
	</head>
	<body>
		<f:view>
			<h:outputText value="#{contentMgmtBean.populatedTemplate}" />
			<br />
		</f:view>
	</body>
</html>

I have used a single backing bean ContentMgmtBean.java for all the jsp pages for simplicity (or does it make things more complex?)

package com.mattiz.contentmgmt.domain;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;
import com.mattiz.contentmgmt.dao.ContentMgmtDAO;
import com.mattiz.contentmgmt.util.MattizException;

public class ContentMgmtBean {
	FacesContext context = FacesContext.getCurrentInstance();
	HttpServletRequest request = (HttpServletRequest) context
			.getExternalContext().getRequest();
	private int selectedTemplateId = 1;
	private String populatedTemplate;

	public String populateTemplate() {
		try {
			String[] populationParamArr = request
					.getParameterValues("populationParam");
			String[] populationParamTypeArr = request
					.getParameterValues("populationParamType");
			for (int i = 0; i < populationParamArr.length; i++) {
				if (populationParamTypeArr[i].equals("N")) {
					if (!validateNumericValue(populationParamArr[i])) {
						FacesMessage aMessage = new FacesMessage(
								FacesMessage.SEVERITY_ERROR, null,
								"Invalid numeric value.");
						context.addMessage("populationForm", aMessage);
						populateParamRequestAttributes(populationParamArr);
						request.setAttribute("selectedTemplate",
								request.getParameter("templateId"));
						return "";
					}
				}
				if (populationParamTypeArr[i].equals("D")) {
					if (!validateDate(populationParamArr[i])) {
						FacesMessage aMessage = new FacesMessage(
								FacesMessage.SEVERITY_ERROR,
								"The date that you provided is invalid. Please         enter date in dd/MM/yy format.",
								null);
						context.addMessage("populationForm", aMessage);
						populateParamRequestAttributes(populationParamArr);
						request.setAttribute("selectedTemplate",
								request.getParameter("templateId"));
						return "";
					}
				}
				if (populationParamTypeArr[i].equals("A")) {
					// do nothing
				}
			}
			int templateId = Integer.parseInt(request
					.getParameter("templateId"));

			ContentMgmtDAO contentMgmtDao = new ContentMgmtDAO();
			String templateText = contentMgmtDao.getTemplate(templateId);
			for (int i = 0; i < populationParamArr.length; i++) {
				templateText = templateText.replaceFirst("\\*\\*\\$\\*\\*",
                        populationParamArr[i]);
			}

			setPopulatedTemplate(templateText);
			return "variablesPopulated";
		} catch (MattizException e) {
			FacesMessage aMessage = new FacesMessage(
					FacesMessage.SEVERITY_ERROR, null,
					"Critical Error while populating template");
			context.addMessage("templateForm", aMessage);
			return "";
		}
	}

	public List getTemplates() {
		try {
			ContentMgmtDAO contentMgmtDao = new ContentMgmtDAO();
			List templateList = contentMgmtDao.getTemplates();
			Iterator tli = templateList.iterator();
			List templateIdSelectItems = new ArrayList();
			while (tli.hasNext()) {
				String templateId = (String) tli.next();
				SelectItem selectItem = new SelectItem(templateId);
				templateIdSelectItems.add(selectItem);
			}
			return templateIdSelectItems;
		} catch (MattizException e) {
			return null;
		}
	}

	public String submitTemplate() {
		request.setAttribute("selectedTemplate", (getSelectedTemplateId() + ""));
		return "templateSelected";
	}

	public int getSelectedTemplateId() {
		return selectedTemplateId;
	}

	public void setSelectedTemplateId(int selectedTemplateId) {
		this.selectedTemplateId = selectedTemplateId;
	}

	public String getTemplate() {
		try {
			ContentMgmtDAO contentMgmtDao = new ContentMgmtDAO();
			String templateText = contentMgmtDao
					.getTemplate(getSelectedTemplateId());
			return templateText;
		} catch (MattizException e) {
			FacesMessage aMessage = new FacesMessage(
					FacesMessage.SEVERITY_ERROR, null,
					"Critical Error while getting template text");
			context.addMessage("populationForm", aMessage);
			return "";
		}
	}

	public String getPopulatedTemplate() {
		return populatedTemplate;
	}

	public void setPopulatedTemplate(String populatedTemplate) {
		this.populatedTemplate = populatedTemplate;
	}

	private boolean validateNumericValue(String numericValue) {
		String numericTemplate = "1234567890";
		for (int i = 0; i < numericValue.length(); i++) {
			if (numericTemplate.indexOf(numericValue.charAt(i)) == -1) {
				return false;
			}
		}
		return true;
	}

	private boolean validateDate(String dateParam) {
		DateFormat dateFormat = null;
		Date date = null;
		boolean flag = true;
		try {
			dateFormat = new SimpleDateFormat("dd/MM/yy");
			date = dateFormat.parse(dateParam);
			if (!dateFormat.format(date).equals(dateParam)) {
				FacesMessage msg = new FacesMessage(
						FacesMessage.SEVERITY_ERROR,
						"The date that you provided is invalid ", null);
				context.addMessage("dateId", msg);
				flag = false;
			}
		} catch (ParseException e) {
			flag = false;
		}
		return flag;
	}

	public void populateParamRequestAttributes(String[] params) {
		for (int i = 0; i < params.length; i++) {
			request.setAttribute("param" + (i + 1), params[i]);
		}
	}
}

The other java classes:

ContentMgmtVO.java the only value object

package com.mattiz.contentmgmt.vo;

public class ContentMgmtVO {
	private int varId;
	private String varType;

	public int getVarId() {
		return varId;
	}

	public void setVarId(int varId) {
		this.varId = varId;
	}

	public String getVarType() {
		return varType;
	}

	public void setVarType(String varType) {
		this.varType = varType;
	}
}

MattizException.java as usual

package com.mattiz.contentmgmt.util;

public class MattizException extends Exception {
	public MattizException() {
		super();
	}

	public MattizException(String msg, Throwable t) {
		super(msg, t);
	}
}

The DAO class that gets to the DB:

ContentMgmtDAO.java

package com.mattiz.contentmgmt.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import com.mattiz.contentmgmt.util.MattizException;
import com.mattiz.contentmgmt.vo.ContentMgmtVO;

public class ContentMgmtDAO {
	private static DataSource ds;
	private Connection conn;
	public static final String DATASOURCE_LOOKUP_NAME = "java:dbpool";

	public ContentMgmtDAO() throws MattizException {
		try {
			InitialContext ctx = null;
			ctx = new InitialContext();
			ds = (DataSource) ctx.lookup(DATASOURCE_LOOKUP_NAME);
		} catch (javax.naming.NamingException jnx) {
			throw new MattizException("Error creating datasource", jnx);
		}
	}

	public List getVariableData(int templateId) throws MattizException {
		ResultSet rs = null;
		PreparedStatement ps = null;
		List contentMgmtVOList = new ArrayList();
		try {
			conn = ds.getConnection();
			String qry = "select var_id, var_type from template_vars where template_id = ?";
			ps = conn.prepareStatement(qry);
			ps.setInt(1, templateId);
			rs = ps.executeQuery();
			while (rs.next()) {
				int varId = rs.getInt(1);
				String varType = rs.getString(2);
				ContentMgmtVO contentMgmtVO = new ContentMgmtVO();
				contentMgmtVO.setVarId(varId);
				contentMgmtVO.setVarType(varType);
				contentMgmtVOList.add(contentMgmtVO);
			}
			return contentMgmtVOList;
		} catch (SQLException e) {
			throw new MattizException("Error getting variable data", e);
		} finally {
			closeStatements(rs, ps, conn);
		}
	}

	public List getVariableTypeList(int templateId) throws MattizException {
		ResultSet rs = null;
		PreparedStatement ps = null;
		String varType = null;
		ArrayList varTypesList = new ArrayList();
		try {
			conn = ds.getConnection();
			String qry = "select var_type from template_vars where template_id = ?";
			ps = conn.prepareStatement(qry);
			ps.setInt(1, templateId);
			rs = ps.executeQuery();
			while (rs.next()) {
				varType = rs.getString(1);
				varTypesList.add(varType);
			}
			return varTypesList;
		} catch (SQLException e) {
			throw new MattizException("Error getting variable type list", e);
		} finally {
			closeStatements(rs, ps, conn);
		}
	}

	public List getTemplates() throws MattizException {
		ResultSet rs = null;
		PreparedStatement ps = null;
		int templateId = 0;
		ArrayList templateIdList = new ArrayList();
		try {
			conn = ds.getConnection();
			String qry = "select template_id from template";
			ps = conn.prepareStatement(qry);
			rs = ps.executeQuery();
			while (rs.next()) {
				templateId = rs.getInt(1);
				templateIdList.add(templateId + "");
			}
			return templateIdList;
		} catch (SQLException e) {
			throw new MattizException("Error getting template IDs", e);
		} finally {
			closeStatements(rs, ps, conn);
		}
	}

	public String getTemplate(int templateId) throws MattizException {
		ResultSet rs = null;
		PreparedStatement ps = null;
		String templateText = null;
		try {
			conn = ds.getConnection();
			String qry = "select template_text from template where template_id = ?";
			ps = conn.prepareStatement(qry);
			ps.setInt(1, templateId);
			rs = ps.executeQuery();
			while (rs.next()) {
				templateText = rs.getString(1);
			}
			return templateText;
		} catch (SQLException e) {
			throw new MattizException("Error getting template text", e);
		} finally {
			closeStatements(rs, ps, conn);
		}
	}

	private void closeStatements(ResultSet rs, PreparedStatement ps,
			Connection conn) throws MattizException {
		if (rs != null) {
			try {
				rs.close();
			} catch (Exception e) {
				throw new MattizException("Error while closing result set", e);
			}
			rs = null;
		}
		if (ps != null) {
			try {
				ps.close();
			} catch (Exception e) {
				throw new MattizException("Error while closing prepared stmt",
						e);
			}
			ps = null;
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (Exception e) {
				throw new MattizException("Error while closing connection", e);
			}
			conn = null;
		}
	}
}

faces-config.xml the heart of JSF:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
	<navigation-rule>
		<navigation-case>
			<from-outcome>variablesPopulated</from-outcome>
			<to-view-id>/displayPopulatedTemplate.jsp</to-view-id>
		</navigation-case>
	</navigation-rule>
	<navigation-rule>
		<navigation-case>
			<from-outcome>templateSelected</from-outcome>
			<to-view-id>/templatePopulation.jsp</to-view-id>
		</navigation-case>
	</navigation-rule>
	<managed-bean>
		<description>
			JSF Backing Bean for temp.jsp
</description>
		<managed-bean-name>contentMgmtBean</managed-bean-name>
		<managed-bean-class>
			com.mattiz.contentmgmt.domain.ContentMgmtBean
</managed-bean-class>
		<managed-bean-scope>request</managed-bean-scope>
	</managed-bean>
</faces-config>

web.xml with no changes:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="2.4"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<context-param>
		<param-name>javax.faces.CONFIG_FILES</param-name>
		<param-value>/WEB-INF/faces-config.xml</param-value>
	</context-param>
	<servlet>
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>0</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.faces</url-pattern>
	</servlet-mapping>
</web-app>

Actually the request attribute(selectedTemplate) passed to the mattiz:ContentMgmtTag in templatePopulation.jsp is superfluous. It can be extracted from the request object as are other request attributes done in the taglib class. But this illustrates how a run time expression can be passed dynamically to a custom tag.
Also note that you can enhance your taglib in the Taglib class to output the “value” attribute, so that the page retains the values that were previously entered. That way you can avoid writing scriptlets for this in the jsp.

The url to call->
http://localhost:8080/ContentManagement/templatePage.faces

The application in action:

one3

two2

three2

four2

five2