<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Persistent Designs Inc.</title>
	<atom:link href="http://persistentdesigns.com/wp/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://persistentdesigns.com/wp</link>
	<description>Java Enterprising Ideas</description>
	<pubDate>Thu, 11 Mar 2010 13:49:52 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.2</generator>
	<language>en</language>
			<item>
		<title>Excel Report Via Simple Java Annotations</title>
		<link>http://persistentdesigns.com/wp/?p=512</link>
		<comments>http://persistentdesigns.com/wp/?p=512#comments</comments>
		<pubDate>Wed, 10 Feb 2010 19:51:18 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=512</guid>
		<description><![CDATA[Introduction
<p>This is the second part of the two part series on creating Excel spreadsheets from objects in generic collection classes. In the first part&#160; Excel read-writeable Reports through Generics, Reflection and Apache POI we discussed the core aspects of creating the Excel spreadsheets through the Apache POI library as well as leveraging the benefits of [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>This is the second part of the two part series on creating Excel spreadsheets from objects in generic collection classes. In the first part&nbsp; <a href="http://persistentdesigns.com/wp/?p=491">Excel read-writeable Reports through Generics, Reflection and Apache POI</a> we discussed the core aspects of creating the Excel spreadsheets through the Apache POI library as well as leveraging the benefits of generics and reflection.&nbsp; In this second part we are adding more control of what is persisted to the spread sheet and how it is displayed through the use of simple annotations.</p>
<h2>Annotations</h2>
<p>Annotations became available in the Java SDK in version 1.5.&nbsp; They have become very popular with good reason.&nbsp; They provide efficiently add function to programs.&nbsp; We&nbsp; are adding runtime annotations that will be able to analyse our generic collection for reporting.</p>
<p>We are adding the following two annotations:</p>
<h3><strong>@ExcelReport</strong></h3>
<p>&nbsp;Use the @ExcelReport annotation to designate the class as available for excel reporting.&nbsp; This annotation immediately marks all accessor methods in the class available for persistence to the Excel spreadsheet.&nbsp; The @ExcelColumn annotation, described below, allows the user to refine the reporting.<span style="font-size: smaller;"><span style="font-size: larger;"><br />
</span></span></p>
<h4>@ExcelReport Attributes</h4>
<table width="501" height="41" cellspacing="1" cellpadding="1" border="1" style="">
<tbody>
<tr>
<td>Attribute</td>
<td>Required</td>
<td>Description</td>
</tr>
<tr>
<td>reportName</td>
<td>true</td>
<td>The name of the Excel file the report is written to.</td>
</tr>
</tbody>
</table>
<h5>&nbsp;Example</h5>
<p style="margin-left: 40px;">@ExcelReport(reportName=&quot;test.xls&quot;)<br />
public class TestClass { &#8230; }</p>
<p>&nbsp;</p>
<p><strong>@ExcelColumn</strong></p>
<p>The @ExcelColumn annotation can be used in a class that has been annotated by @ExcelReport .&nbsp; @ExcelColumn allows the user to ignore an accessor method or provide a custom description of the field the accessor returns.&nbsp; The getter method must have a symantically equivlent field.&nbsp; So for instance if the accessor is <strong>getFoo</strong> () there must be a field <strong>foo</strong>.</p>
<h4>@ExcelColumn Attributes</h4>
<table width="501" height="41" cellspacing="1" cellpadding="1" border="1" style="">
<tbody>
<tr>
<td>Attribute</td>
<td>Required</td>
<td>Description</td>
</tr>
<tr>
<td>ignore</td>
<td>false</td>
<td>false by default.&nbsp; This attribute will make the accessor unavailable to reporting</td>
</tr>
<tr>
<td>label</td>
<td>false</td>
<td>The value for label will be used as the column heading in the spreadsheet</td>
</tr>
</tbody>
</table>
<h5>&nbsp;Example</h5>
<p style="margin-left: 40px;">@ExcelColumn(label=&quot;Test Name&quot;)<br />
&nbsp;&nbsp; &nbsp;public String getName() {&#8230;}</p>
<p style="margin-left: 40px;">or</p>
<p style="margin-left: 40px;">@ExcelColumn(ignore=true)<br />
&nbsp;&nbsp;&nbsp; public Double getDoubleField() {&#8230;}</p>
<p>The code for the to Annotations are below:</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.TYPE)
public @interface ExcelReport {
	String reportName();
}
</pre>
<pre class="brush:java; collapse:false; wrap-lines:true;">
@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.METHOD)
public @interface ExcelColumn {
	boolean ignore() default false;
	String label() default &quot;&quot;;
}
</pre>
<p>Expand the section below for an example of a domain class with Excel Annotations:</p>
<pre class="brush:java; collapse:true; wrap-lines:true;">
package com.persistent.utils.excel;

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

@ExcelReport(reportName=&quot;test.xls&quot;)
public class TestClass {
	private String name;
	private String path;
	private String directory;
	private Integer containedFiles;
	private Double doubleField;

	public TestClass() {
	}

	public TestClass(String name, String path, String directory,
			Integer containedFiles, Double doubleField) {
		super();
		this.name = name;
		this.path = path;
		this.directory = directory;
		this.containedFiles = containedFiles;
		this.doubleField = doubleField;
	}

	@ExcelColumn(label=&quot;Test Name&quot;)
	public String getName() {
		return name;
	}

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

	@ExcelColumn(label=&quot;Path&quot;)
	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	@ExcelColumn(label=&quot;Directory&quot;)
	public String getDirectory() {
		return directory;
	}

	public void setDirectory(String directory) {
		this.directory = directory;
	}

	@ExcelColumn(label=&quot;Number of Files in Directory&quot;)
	public Integer getContainedFiles() {
		return containedFiles;
	}

	public void setContainedFiles(Integer containedFiles) {
		this.containedFiles = containedFiles;
	}

	@ExcelColumn(ignore=true)
	public Double getDoubleField() {
		return doubleField;
	}

	public void setDoubleField(Double doubleField) {
		this.doubleField = doubleField;
	}

	@Override
	public String toString() {
		return &quot;TestClass [containedFiles=&quot; + containedFiles + &quot;, directory=&quot;
				+ directory + &quot;, doubleField=&quot; + doubleField + &quot;, name=&quot; + name
				+ &quot;, path=&quot; + path + &quot;]&quot;;
	}

	public static List&lt;TestClass&gt; getTestData() {
		List&lt;TestClass&gt; testClasses = new ArrayList&lt;TestClass&gt;();

		String currentDirectory = System.getProperty(&quot;user.dir&quot;);
		File currentDirectoryFile = new File(currentDirectory);
		File[] files = currentDirectoryFile.listFiles();
		double dbl = 0;
		for (File file : files) {
			TestClass testClass = null;
			if (file.isDirectory()) {
				testClass = new TestClass(file.getName(), file.getPath(),
						&quot;directory&quot;, file.list().length,dbl++);
			} else {
				testClass = new TestClass(file.getName(), file.getPath(),
						&quot;file&quot;, 0,dbl++);
			}
			testClasses.add(testClass);
		}
		return testClasses;
	}

	public static void main(String[] args) {
		String currentDirectory = System.getProperty(&quot;user.dir&quot;);
		File currentDirectoryFile = new File(currentDirectory);
		File[] files = currentDirectoryFile.listFiles();

		System.out.println(&quot;Is there anything in the list:&quot; + files.length);
		double dbl = 0;
		for (File file : files) {
			System.out.println(file.getName());
			System.out.println(file.getAbsoluteFile());
			System.out.println(file.getPath());
			if (file.isDirectory()) {
				System.out.println(&quot;Directory&quot;);
				new TestClass(file.getName(), file.getPath(),
						&quot;directory&quot;, file.list().length,dbl++);
			} else {
				new TestClass(file.getName(), file.getPath(),
						&quot;file&quot;, 0,dbl++);
			}
		}
	}

}
</pre>
<p>&nbsp;</p>
<h2>Annotations and Reflection</h2>
<p>The change over the first implementation is the annotations.&nbsp; This information is resolved in the reflection process just as before but now we have that extra mark-up information to aid in presentation.&nbsp; Internally the report program does some simple manipulations and comparisons of the fields with the collected annotated methods.</p>
<p>Here is the method that extracts the information from the annotations:</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
	private &lt;T&gt; void processAnnotations(T object) {
		Class&lt;?&gt; clazz = object.getClass();
		ExcelReport reportAnnotation = (ExcelReport) clazz.getAnnotation(ExcelReport.class);
		logger.info(&quot;Report Name  : &quot; + reportAnnotation.reportName());
		String reportName = reportAnnotation.reportName();
		if((reportName==null)||(reportName.trim().length()&lt;1)){
			// should never get here.
			logger.error(&quot;Invalid Worksheet Name&quot;);
		}
		setWorkbookName(reportAnnotation.reportName());
		for (Method method : clazz.getMethods()) {
			ExcelColumn excelColumn = method.getAnnotation(ExcelColumn.class);
			if ((excelColumn != null) &amp;&amp; !excelColumn.ignore()) {
				getFieldLabelMap().put(excelColumn.label(),method.getName());
				getOrderLabels().add(excelColumn.label());
				logger.info(&quot;Annotation on method: &quot; + method.getName());
				logger.info(&quot;Ignore: &quot; + excelColumn.ignore() + &quot;  label: &quot;
						+ excelColumn.label());
			}
		}
	}
</pre>
<p>&nbsp;Additionally the Apache POI software does allow one to go deeply into the Excel standard markup to add style to cells here we have added some style for the column headers:</p>
<p>&nbsp;</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
private CellStyle createColumnHeaderCellStyle() {
	CellStyle cellStyle = getWorkbook().createCellStyle();
	cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
	cellStyle.setFillBackgroundColor(new HSSFColor.GREY_25_PERCENT().getIndex());
	cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
	cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
	cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
	cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
	return cellStyle;
}
</pre>
<p>Ultimately are newly marked up domain object produces a spreadsheet that looks like the following:</p>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/excel_output2.jpeg"><img width="450" height="160" src="http://persistentdesigns.com/wp/wp-content/uploads/excel_output2.jpeg" alt="Spreadsheet" /></a></p>
<p>&nbsp;</p>
<h3>Installing and Running</h3>
<p>The program requires the following jar files:</p>
<ul>
<li>poi-3.5-FINAL-20090928.jar</li>
<li>poi-ooxml-3.5-FINAL-20090928.jar</li>
<li>log4j-1.2.15.jar</li>
<li>JUnit 4</li>
</ul>
<p>The POI file are available <a href="http://poi.apache.org/download.html">here</a>.&nbsp; Log4J is available <a href="http://logging.apache.org/log4j/1.2/download.html">here</a>.</p>
<p>The source code for this project is <a href="http://persistentdesigns.com/wp/wp-content/uploads/ExcelAnnotationReport.zip">here</a>.</p>
<p>&nbsp;The program runs as a JUnit test from the class <em>AnnotatedExcelReportTest</em> located under the test directory.</p>
<h2>About The&nbsp;Author</h2>
<p><b>David Sells</b> is a computer consultant in Toronto, Ontario who specializes in Java Enterprise Development. He has&nbsp; provided innovative solutions for clients including: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p>He holds the following certifications:</p>
<ul>
<li>Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5 (2009)</li>
<li>Sun Certified Web Component Developer</li>
<li>Sun Certified Java Programmer.</li>
</ul>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Spring%20Spring-WS%20Application%5Bwith%20JPA%20and%20Jersey%20REST%5D'">david@persistentdesigns.com</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=512</wfw:commentRss>
		</item>
		<item>
		<title>Excel read-writable Reports through Generics, Reflection and Apache POI</title>
		<link>http://persistentdesigns.com/wp/?p=491</link>
		<comments>http://persistentdesigns.com/wp/?p=491#comments</comments>
		<pubDate>Thu, 04 Feb 2010 14:22:41 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=491</guid>
		<description><![CDATA[Introduction
<p>In this article we use generics, reflection and Apache POI to construct a general utility to read and write a generic collection of objects to an Excel spreadsheet.</p>
<p>I was recently in a project that required a lot of data to be made available from the object model to both view and modify.&#160; There was already [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>In this article we use generics, reflection and Apache POI to construct a general utility to read and write a generic collection of objects to an Excel spreadsheet.</p>
<p>I was recently in a project that required a lot of data to be made available from the object model to both view and modify.&nbsp; There was already a utility in place that would dump the information into text files.&nbsp; This was nice but the number of columns of information that were required made text files difficult to use.&nbsp; The information would be far easier to view and manipulate in a spreadsheet.&nbsp; This led to the creation of the tool described in this article.</p>
<p>This is part one of a two part series.&nbsp; In the second part we will utilize Annotations to refine the information exported to the Excel spreadsheet.</p>
<h2>Apache POI</h2>
<p>The <a href="http://poi.apache.org/">Apache POI project</a> provides a very simple tool for interacting with the Excel format.&nbsp; The POI project extends beyond Excel servicing the Office Open XML standards (OOXML) and Microsoft&#8217;s OLE 2 Compound Document format (OLE2).&nbsp; These formats also include those for MS Powerpoint and Microsoft Word.</p>
<p>The Object Model for interacting with Excel spreadsheets is very intuitive.&nbsp; The primary classes from POI that we use are:</p>
<ul>
<li>org.apache.poi.ss.usermodel.Cell;</li>
<li>org.apache.poi.ss.usermodel.Row;</li>
<li>org.apache.poi.ss.usermodel.Sheet;</li>
<li>org.apache.poi.ss.usermodel.Workbook;</li>
</ul>
<p>&nbsp;In the code snippet below these classes are utilized with the facilities of Reflection to write the contents of a Generic collection to an Excel file.&nbsp; The code is fairly intuitive.</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
public &lt;T&gt; void writeReportToExcel(List&lt;T&gt; data) throws Exception {
                Sheet sheet = getWorkbook().createSheet(
                                data.get(0).getClass().getName());
                setupFieldsForClass(data.get(0).getClass());
                // Create a row and put some cells in it. Rows are 0 based.
                int rowCount = 0;
                int columnCount = 0;

                Row row = sheet.createRow(rowCount++);
                for (String fieldName : fieldNames) {
                        Cell cel = row.createCell(columnCount++);
                        cel.setCellValue(fieldName);
                }
                Class&lt;? extends Object&gt; classz = data.get(0).getClass();
                for (T t : data) {
                        row = sheet.createRow(rowCount++);
                        columnCount = 0;
                        for (String fieldName : fieldNames) {
                                Cell cel = row.createCell(columnCount);
                                Method method = classz.getMethod(&quot;get&quot; + capitalize(fieldName));
                                Object value = method.invoke(t, (Object[]) null);
                                if (value != null) {
                                        if (value instanceof String) {
                                                cel.setCellValue((String) value);
                                        } else if (value instanceof Long) {
                                                cel.setCellValue((Long) value);
                                        } else if (value instanceof Integer) {
                                                cel.setCellValue((Integer)value);
                                        }else if (value instanceof Double) {
                                                cel.setCellValue((Double) value);
                                        }
                                }
                                columnCount++;
                        }
                }
        }
</pre>
<h2>Reflection</h2>
<p>We utilize reflection to set-up the columns.&nbsp; Reflection is used to gather the fields associated to the target class.&nbsp; These field names will also serve as the column headings too.&nbsp; The information is retained and used to obtain the getter and setters for each field as we obtain and set these values.&nbsp; There are two rules for classes to work with this utility :</p>
<ol>
<li><strong>For each field there must be a semantically standard getter and setter associated with it. <br />
    </strong></li>
<li><strong>The fields must be of the supported domain types, currently: String, Long, Double and Integer.</strong></li>
</ol>
<p>Below is the code for gathering the field information.</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
private boolean setupFieldsForClass(Class&lt;?&gt; clazz) throws Exception {
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i &lt; fields.length; i++) {
                fieldNames.add(fields[i].getName());
        }
        return true;
}
</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>Generic</h2>
<p>Below is the JUnit test case for writing a generic collection to the Excel spreadsheet.&nbsp; As can be seen the only requirements made of the parameter to writeReportToExcel(List&lt;T&gt;) is that the collection be generic and the class of the generic collection follow the rules stated above above.&nbsp; Internal to the utility, as described, we use the information from the parameter to extract the information required to construct the Excel table.</p>
<p>&nbsp;The test harness&nbsp; for this code is as follows.&nbsp; Note that we can dump any class consisting of simple types: String, Integer, Long and Double.&nbsp; It can be easily extended. The generic collection that is being exported to an Excel spread sheet is List&lt;TestClass&gt;.</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
public void testReadData() {
        ExcelReporter ExcelReport = new ExcelReporter(&quot;TestCaseData.xsl&quot;);
        try {
                List&lt;TestClass&gt; results = ExcelReport
                                .readData(TestClass.class.getName());
                for (TestClass testClass : results) {
                        System.out.println(testClass);
                }
        } catch (Exception e) {
                e.printStackTrace();
        }
}

@Test
public void testWriteReportToExcel() {
        setTestClasses(TestClass.getTestData());
        ExcelReporter excelReport = new ExcelReporter(&quot;TestCaseData.xsl&quot;);
        try {
                logger.info(&quot;The number of data elements is: &quot;+getTestClasses().size());
                excelReport.writeReportToExcel(getTestClasses());
                excelReport.closeWorksheet();
        } catch (Exception e) {
                logger.error(&quot;Error: &quot;+e.toString());
                fail();
        }
}

public List&lt;TestClass&gt; getTestClasses() {
        return testClasses;
}
</pre>
<p>&nbsp;</p>
<p>Below is the the TestClass which is the class used in the Generic List.&nbsp; Note that it generates data from the files/directories in the current directory of the executing program.</p>
<p>&nbsp;</p>
<pre class="brush:java; collapse:true; wrap-lines:true;">
package com.persistent.utils.excel;

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

public class TestClass {
        private String name;
        private String path;
        private String directory;
        private Integer containedFiles;
        private Double doubleField;

        public TestClass() {
        }

        public TestClass(String name, String path, String directory,
                        Integer containedFiles, Double doubleField) {
                super();
                this.name = name;
                this.path = path;
                this.directory = directory;
                this.containedFiles = containedFiles;
                this.doubleField = doubleField;
        }

        public String getName() {
                return name;
        }

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

        public String getPath() {
                return path;
        }

        public void setPath(String path) {
                this.path = path;
        }

        public String getDirectory() {
                return directory;
        }

        public void setDirectory(String directory) {
                this.directory = directory;
        }

        public Integer getContainedFiles() {
                return containedFiles;
        }

        public void setContainedFiles(Integer containedFiles) {
                this.containedFiles = containedFiles;
        }

        public Double getDoubleField() {
                return doubleField;
        }
        public void setDoubleField(Double doubleField) {
                this.doubleField = doubleField;
        }

        @Override
        public String toString() {
                return &quot;TestClass [containedFiles=&quot; + containedFiles + &quot;, directory=&quot;
                                + directory + &quot;, doubleField=&quot; + doubleField + &quot;, name=&quot; + name
                                + &quot;, path=&quot; + path + &quot;]&quot;;
        }

        // Generate some sample data.
        public static List&lt;TestClass&gt; getTestData() {
                List&lt;TestClass&gt; testClasses = new ArrayList&lt;TestClass&gt;();

                String currentDirectory = System.getProperty(&quot;user.dir&quot;);
                File currentDirectoryFile = new File(currentDirectory);
                File[] files = currentDirectoryFile.listFiles();
                double dbl = 0;
                for (File file : files) {
                        TestClass testClass = null;
                        if (file.isDirectory()) {
                                testClass = new TestClass(file.getName(), file.getPath(),
                                                &quot;directory&quot;, file.list().length,dbl++);
                        } else {
                                testClass = new TestClass(file.getName(), file.getPath(),
                                                &quot;file&quot;, 0,dbl++);
                        }
                        testClasses.add(testClass);
                }
                return testClasses;
        }
}</pre>
<p>&nbsp;</p>
<h2>Running the JUnit Tests</h2>
<p>To run this program download the jar file from the link at the bottom of the article.&nbsp; It was built in an Eclipse environment.&nbsp; If you are using that IDE then import it and run the unit tests.&nbsp; The output of the program is Spartan: yes there is lots of room here for enhancements but still it is useful as a tool in development as is.</p>
<p>As one is developing you can create classes for the purpose of reporting, according to the rules, and dump them to Excel spreadsheets.&nbsp; Another feature of this utility is that each Collection writes to a tab which holds the name of its&#8217; class. This means that you can write several different class collections to the same workbook and see their data on separate tabs identified by their class name.</p>
<p>Here is the resulting output of the JUnit test:</p>
<p><a onclick="window.open(this.href,'ExcelOuput','resizable=no,location=no,menubar=no,scrollbars=no,status=no,toolbar=no,fullscreen=no,dependent=no,width=400,height=300,status'); return false" href="http://persistentdesigns.com/wp/wp-content/uploads/image/images/excel_output.jpeg"><img width="450" height="191" alt="Excel Ouput" src="http://persistentdesigns.com/wp/wp-content/uploads/excel_output.jpeg" /></a></p>
<p>The program is also capable of reading the information back from the Excel spread sheet and populating the Generic collection.&nbsp; In the case of multiple tabs the program uses the class name to select the appropriate tab.&nbsp; The details are left to interested developers.</p>
<h3>Installing</h3>
<p>The program requires the following jar files:</p>
<ul>
<li>poi-3.5-FINAL-20090928.jar</li>
<li>poi-ooxml-3.5-FINAL-20090928.jar</li>
<li>log4j-1.2.15.jar</li>
<li>JUnit 4</li>
</ul>
<p>The POI file are available <a href="http://poi.apache.org/download.html">here</a>.&nbsp; Log4J is available <a href="http://logging.apache.org/log4j/1.2/download.html">here</a>.</p>
<p>The source code for this project is <a href="http://persistentdesigns.com/wp/wp-content/uploads/ExcelReport.zip">here</a>.</p>
<p>&nbsp;Enjoy!</p>
<p>&nbsp;</p>
<h2>About The&nbsp;Author</h2>
<p><b>David Sells</b> is a computer consultant in Toronto, Ontario who specializes in Java Enterprise Development. He has&nbsp; provided innovative solutions for clients including: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p>He holds the following certifications:</p>
<ul>
<li>Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5 (2009)</li>
<li>Sun Certified Web Component Developer</li>
<li>Sun Certified Java Programmer.</li>
</ul>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Spring%20Spring-WS%20Application%5Bwith%20JPA%20and%20Jersey%20REST%5D'">david@persistentdesigns.com</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=491</wfw:commentRss>
		</item>
		<item>
		<title>Vaadin Web Application with Jersey REST</title>
		<link>http://persistentdesigns.com/wp/?p=479</link>
		<comments>http://persistentdesigns.com/wp/?p=479#comments</comments>
		<pubDate>Fri, 30 Oct 2009 12:14:57 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=479</guid>
		<description><![CDATA[Introduction
<p>It was a pleasure to learn about Google Web Toolkit (GWT) and its ability to remove some of the drudgery from program the presentation layer.&#160; It was even more satisfying to look into Vaadin with it rich CSS and DHTML magic.&#160; This article just skims the surface of Vaadin&#8217;s offerings as it is used to [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>It was a pleasure to learn about <a href="http://code.google.com/webtoolkit/">Google Web Toolkit (GWT)</a> and its ability to remove some of the drudgery from program the presentation layer.&nbsp; It was even more satisfying to look into <a href="http://vaadin.com/home">Vaadin</a> with it rich CSS and DHTML magic.&nbsp; This article just skims the surface of Vaadin&#8217;s offerings as it is used to implement the web front end in the integration of the REST client&nbsp; API developed in the previous article:<a href="http://persistentdesigns.com/wp/?p=466"> Jersey REST Client</a>.</p>
<h2>Implementation</h2>
<p>Vaadin was very easy to configure.&nbsp; All the HTTP requests are mapped through the Vaadin GWT servlet:</p>
<p><span style="font-size: smaller;"><em>From the web.xml</em></span></p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
 &lt;servlet&gt;
  	&lt;servlet-name&gt;Wow Application&lt;/servlet-name&gt;
  	&lt;servlet-class&gt;
  	com.vaadin.terminal.gwt.server.ApplicationServlet&lt;/servlet-class&gt;
  	&lt;init-param&gt;
  		&lt;description&gt;
  		Vaadin application class to start&lt;/description&gt;
  		&lt;param-name&gt;application&lt;/param-name&gt;
  		&lt;param-value&gt;com.persistent.app.WowApplication&lt;/param-value&gt;
  	&lt;/init-param&gt;
  &lt;/servlet&gt;

  &lt;servlet-mapping&gt;
  	&lt;servlet-name&gt;Wow Application&lt;/servlet-name&gt;
  	&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
</pre>
<p>Integrating the REST API is just a matter of including the gclient dependency in the POM file and utilizing the RestCompanyDirectory class.  This class relies on the Jersey REST API and there is no need for any Spring configuration in this application.</p>
<p><span style="font-size: smaller;"><em>From pom.xml</em></span></p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;dependency&gt;
	&lt;groupId&gt;com.persistent&lt;/groupId&gt;
		&lt;artifactId&gt;gclient&lt;/artifactId&gt;
		&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
	&lt;/dependency&gt;
&lt;/dependencies&gt;
</pre>
<p>The Vaadin API is well constructed and they have both an excellent demo page and downloadable book on the framework.  I am just presenting a short exemplar of their products ease of use.</p>
<p>The resulting application looks as follows:</p>
<p><a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/image/images/vaadin-client.jpg"><img width="450" height="282" alt="" src="http://persistentdesigns.com/wp/wp-content/uploads/image/images/vaadin-client.jpg" /></a></p>
<p>&nbsp;</p>
<p>The link below contains the code required to render the user interface shown above as well as interact with the REST web service.</p>
<pre class="brush:java; collapse:true; wrap-lines:true;">
package com.persistent.app;

import java.util.ArrayList;
import java.util.Collection;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringUtils;

import com.persistent.dto.Company;
import com.persistent.dto.Person;
import com.persistent.rest.client.RestCompanyDirectory;
import com.vaadin.Application;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.SplitPanel;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;

public class WowApplication extends Application {
	private static final long serialVersionUID = 2192808513028842236L;
	private Collection&lt;Company&gt; companies;
	private Table contactList = new Table();
	private Form contactEditor = new Form();
	private HorizontalLayout bottomLeftCorner = new HorizontalLayout();
	private Button contactRemovalButton;
	private IndexedContainer companyDirectoryData = retrieveCompanyDirectoryData();
	private ArrayList&lt;Company&gt; companyArray = null;
	private Collection&lt;Person&gt; persons = null;

	boolean updateFlag = false;

	public enum Column {
		id(&quot;Id&quot;), first(&quot;First Name&quot;), last(&quot;Last Name&quot;), age(&quot;Age&quot;), company(
				&quot;Company&quot;), companyId(&quot;CompanyId&quot;);
		private static Column[] visible = { first, last, company };
		private String displayName;

		public static String[] getVisibleColumnNames() {
			String[] visibleColumnNames = new String[visible.length];
			int i = 0;
			for (Column column : visible) {
				visibleColumnNames[i++] = column.displayName;
			}
			return visibleColumnNames;
		}
		Column(String displayName) {
			this.displayName = displayName;
		}
		public String getDisplayName() {
			return displayName;
		}
		public static Column[] getVisibleColumns() {
			return visible;
		}
	}

	private NativeSelect getCompaniesNativeSelect() {
		final NativeSelect companies = new NativeSelect(&quot;Company&quot;);
		companies.setWidth(&quot;30em&quot;);
		if (companyArray == null) {
			Collection&lt;Company&gt; theCompanies = getCompanies();
			companyArray = new ArrayList&lt;Company&gt;(theCompanies);
		}
		for (Company company : companyArray) {
			companies.addItem(company.getName());
		}
		return companies;
	}

	@Override
	public void init() {
		initLayout();
		initContactAddRemoveButtons();
		initAddressList();
		initFilteringControls();
	}

	private void initLayout() {
		SplitPanel splitPanel = new SplitPanel(
				SplitPanel.ORIENTATION_HORIZONTAL);
		setMainWindow(new Window(&quot;Address Book&quot;, splitPanel));
		// Left Side
		VerticalLayout left = new VerticalLayout();
		left.setSizeFull();
		left.addComponent(contactList);
		contactList.setSizeFull();
		left.setExpandRatio(contactList, 1);
		splitPanel.addComponent(left);
		bottomLeftCorner.setWidth(&quot;100%&quot;);
		left.addComponent(bottomLeftCorner);
		// other side
		splitPanel.addComponent(contactEditor);
		contactEditor.setSizeFull();
		contactEditor.getLayout().setMargin(true);
		contactEditor.setImmediate(true);
		contactEditor.setFormFieldFactory(new PersonFactory());
	}

	@SuppressWarnings(&quot;serial&quot;)
	private void initContactAddRemoveButtons() {
		// New item button
		bottomLeftCorner.addComponent(new Button(&quot;+&quot;,
				new Button.ClickListener() {
					public void buttonClick(ClickEvent event) {
						Object id = contactList.addItem();
						contactList.setValue(id);
					}
				}));

		// Remove item button
		contactRemovalButton = new Button(&quot;-&quot;, new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				final Item item = contactList.getItem(contactList.getValue());
				final String personId = (String) item.getItemProperty(Column.id.displayName)
						.getValue();
				final RestCompanyDirectory companyDirectory = new RestCompanyDirectory();
				companyDirectory.deletePerson(Long.parseLong(personId));
				contactList.removeItem(contactList.getValue());
				contactList.select(null);
			}
		});
		contactRemovalButton.setVisible(false);
		bottomLeftCorner.addComponent(contactRemovalButton);
	}

	@SuppressWarnings(&quot;serial&quot;)
	private void initAddressList() {
		contactList.setContainerDataSource(companyDirectoryData);
		contactList.setVisibleColumns(Column.getVisibleColumnNames());
		contactList.setSelectable(true);
		contactList.setImmediate(true);

		contactList.addListener(new Property.ValueChangeListener() {
			public void valueChange(ValueChangeEvent event) {
				Object id = contactList.getValue();
				updateFlag = true;
				contactEditor.setItemDataSource(id == null ? null : contactList
						.getItem(id));
				contactRemovalButton.setVisible(id != null);
				updateFlag = false;
			}
		});
	}

	@SuppressWarnings(&quot;serial&quot;)
	private void initFilteringControls() {
		for (final Column column : Column.getVisibleColumns()) {

			if (!column.equals(Column.company)) {
				final TextField sf = new TextField();
				bottomLeftCorner.addComponent(sf);
				sf.setWidth(&quot;100%&quot;);
				sf.setInputPrompt(column.displayName);
				sf.setImmediate(true);
				bottomLeftCorner.setExpandRatio(sf, 1);
				sf.addListener(new Property.ValueChangeListener() {
					public void valueChange(ValueChangeEvent event) {
						companyDirectoryData
								.removeContainerFilters(column.displayName);
						if (sf.toString().length() &gt; 0
								&amp;&amp; !column.displayName.equals(sf.toString())) {
							companyDirectoryData.addContainerFilter(
									column.displayName, sf.toString(), true,
									false);
						}
						getMainWindow().showNotification(
								&quot;&quot; + companyDirectoryData.size() + &quot; matches found&quot;);
					}
				});
			} else {
				final NativeSelect ns = getCompaniesNativeSelect();
				bottomLeftCorner.addComponent(ns);
				ns.setImmediate(true);
				ns.setCaption(&quot;&quot;);
				ns.addListener(new Property.ValueChangeListener() {
					public void valueChange(ValueChangeEvent event) {
						companyDirectoryData
								.removeContainerFilters(column.displayName);
						if (ns.getValue() != null) {
							companyDirectoryData.addContainerFilter(
									column.displayName, (String) ns.getValue(),
									true, false);
						}
						getMainWindow().showNotification(
								&quot;&quot; + companyDirectoryData.size() + &quot; matches found&quot;);
					}

				});
			}
		}
	}

	@SuppressWarnings(&quot;serial&quot;)
	private class PersonFactory extends DefaultFieldFactory {

		public PersonFactory() {
		}

		@Override
		public Field createField(final Item item, Object propertyId,
				Component uiContext) {
			Field result = null;
			if (Column.company.displayName.equals(propertyId)) {
				final NativeSelect companies = new NativeSelect(
						Column.company.displayName);
				companies.setWidth(&quot;30em&quot;);
				Collection&lt;Company&gt; theCompanies = getCompanies();
				ArrayList&lt;Company&gt; a = new ArrayList&lt;Company&gt;(theCompanies);
				for (Company company : a) {
					companies.addItem(company.getName());
				}
				companies.setValue(uiContext);
				result = companies;
			} else {
				result = super.createField(item, propertyId, uiContext);
				if (Column.id.displayName.equals(propertyId)
						|| Column.companyId.displayName.equals(propertyId)) {
					result.setVisible(false);
				}
			}
			result.addListener(new Property.ValueChangeListener() {
				public void valueChange(ValueChangeEvent event) {
					if (!updateFlag &amp;&amp; isValid(item)) {
						updateFlag = true;
						getMainWindow().showNotification(
								&quot;Updated Record: &quot;
										+ (String) item.getItemProperty(
												Column.id.displayName)
												.getValue());
						WowApplication.this.updateDB(item);
						updateFlag = false;
					}
				}
			});
			return result;
		}
	}

	public boolean isValid(Item item) {
		String first = (String) item.getItemProperty(Column.first.displayName)
				.getValue();
		String last = (String) item.getItemProperty(Column.last.displayName)
				.getValue();
		String company = (String) item.getItemProperty(
				Column.company.displayName).getValue();
		String age = (String) item.getItemProperty(Column.age.displayName)
				.getValue();
		if (!StringUtils.isNumeric(age)) {
			getMainWindow().showNotification(&quot;Age must be numeric&quot;,
					Window.Notification.TYPE_ERROR_MESSAGE);
		}
		return StringUtils.isNotBlank(first) &amp;&amp; StringUtils.isNotBlank(last)
				&amp;&amp; StringUtils.isNotBlank(company)
				&amp;&amp; StringUtils.isNotBlank(age) &amp;&amp; StringUtils.isNumeric(age);
	}

	private IndexedContainer retrieveCompanyDirectoryData() {
		Collection&lt;Person&gt; persons = getPersons();
		ArrayList&lt;Person&gt; aperson = new ArrayList&lt;Person&gt;(persons);
		IndexedContainer ic = new IndexedContainer();

		for (Column p : Column.values()) {
			ic.addContainerProperty(p.displayName, String.class, &quot;&quot;);
		}
		for (Person person : aperson) {
			Object id = ic.addItem();
			StringTokenizer tokenizer = new StringTokenizer(person.getName());
			if (tokenizer.hasMoreElements()) {
				ic.getContainerProperty(id, Column.first.displayName).setValue(
						tokenizer.nextToken());
				if (tokenizer.hasMoreElements()) {
					ic.getContainerProperty(id, Column.last.displayName)
							.setValue(tokenizer.nextToken());
				}
			}
			ic.getContainerProperty(id, Column.company.displayName).setValue(
					person.getCompany().getName());
			ic.getContainerProperty(id, Column.id.displayName).setValue(
					person.getId());
			ic.getContainerProperty(id, Column.companyId.displayName).setValue(
					person.getCompany().getId());
			ic.getContainerProperty(id, Column.age.displayName).setValue(
					person.getAge());
		}
		return ic;
	}

	public void updateDB(final Item item) {
		RestCompanyDirectory companyDirectory = new RestCompanyDirectory();
		String sid = (String) item.getItemProperty(Column.id.displayName)
				.getValue();
		String companyName = (String) item.getItemProperty(
				Column.company.displayName).getValue();
		if (StringUtils.isNotBlank(sid)) {
			Long id = Long.parseLong(sid);
			Person person = companyDirectory.getPerson(id);
			populatePerson(item, person);
			if (!companyName.equals(person.getCompany().getName())) {
				Company company = getCompany(companyName);
				if (company != null) {
					person.setCompany(company);
				}
			}
			companyDirectory.updatePerson(person);
		} else {
			Person person = new Person();
			populatePerson(item, person);
			Company company = getCompany(companyName);
			person.setCompany(company);
			Person newPerson = companyDirectory.createPerson(person);
			item.getItemProperty(Column.id.displayName).setValue(
					newPerson.getId());
		}
	}

	private Company getCompany(String companyName) {
		Company selectedCompany = null;
		for (Company company : companyArray) {
			if (company.getName().equals(companyName)) {
				selectedCompany = company;
				break;
			}
		}
		return selectedCompany;
	}

	private void populatePerson(Item item, Person person) {
		String first = (String) item.getItemProperty(Column.first.displayName)
				.getValue();
		String last = (String) item.getItemProperty(Column.last.displayName)
				.getValue();
		String age = (String) item.getItemProperty(Column.age.displayName)
				.getValue();
		person.setName(first + &quot; &quot; + last);
		person.setAge(Short.parseShort(age));
	}

	private Collection&lt;Person&gt; getPersons() {
		if (persons == null) {
			RestCompanyDirectory companyDirectory = new RestCompanyDirectory();
			persons = companyDirectory.getPersons();
		}
		return persons;
	}

	private Collection&lt;Company&gt; getCompanies() {
		if (companies == null) {
			RestCompanyDirectory companyDirectory = new RestCompanyDirectory();
			companies = companyDirectory.getCompanies();
		}
		return companies;
	}
}
</pre>
<h2>Installation</h2>
<p>There are three steps to install this application:</p>
<ol>
<li>Starting the REST Web Service</li>
<li>Build REST Client Code</li>
<li>The Vaadin Application</li>
</ol>
<h3>Installing the REST&nbsp;Web Service</h3>
<p>The REST Webservice was developed in previous articles.&nbsp; It can be downloaded by <a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/general_oct_29_2009.zip">this link</a>.&nbsp; Uncompress and run the following maven command:</p>
<p style="margin-left: 40px;">clean install jetty:run -Djetty.port=9444</p>
<p>This command will download dependencies, compile the code and deploy the application in Jetty at port 9444.</p>
<p>We need to export the client API from the service to build the client code.&nbsp; This is done after the build through a script available in the src/main/resource directory called:<strong> installit.sh</strong></p>
<p>This bash script simply installs the client jar into the appropriate location to be utilized in other programs.&nbsp; For more information see <a href="http://persistentdesigns.com/wp/?p=346#Build_Instructions">Simple Spring-WS Application</a>.</p>
<h3>&nbsp;</h3>
<h3>Building REST Client Code</h3>
<p>This is described in the previous article <a href="http://persistentdesigns.com/wp/?p=466">Jersey REST Client</a>.</p>
<p>&nbsp;</p>
<h3>Building the Vaadin Project</h3>
<p>Download the code <a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/vaadin_one_oct_30_2009.zip">linked here.</a></p>
<p>&nbsp;To build unzip and from the root directory type:</p>
<p style="margin-left: 40px;"><strong>mvn clean install</strong></p>
<p>A target directory will be created and within it there will be a war file called: <strong>vaadin_one.war</strong></p>
<p>Take this war and deploy it in your web server.&nbsp; I am working with tomcat 6.0.20.</p>
<p>The Vaadin web application URL is: <strong>http://localhost:8080/vaadin_one</strong></p>
<p>Enjoy!&nbsp; If you have any questions just send me a note.</p>
<p>&nbsp;</p>
<h2>About The&nbsp;Author</h2>
<p style="margin-left: 40px;"><b>David Sells</b> is a computer consultant in Toronto, Ontario who specializes in Java Enterprise Development. He has&nbsp; provided innovative solutions for clients including: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p style="margin-left: 40px;">He also holds the following certifications:</p>
<ul>
<li>Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5 (2009)</li>
<li>Sun Certified Web Component Developer</li>
<li>Sun Certified Java Programmer.</li>
</ul>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Jersey%2CSpring%20and%20JPA'">david@persistentdesigns.com</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=479</wfw:commentRss>
		</item>
		<item>
		<title>Jersey REST Client</title>
		<link>http://persistentdesigns.com/wp/?p=466</link>
		<comments>http://persistentdesigns.com/wp/?p=466#comments</comments>
		<pubDate>Thu, 29 Oct 2009 17:52:28 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=466</guid>
		<description><![CDATA[Introduction
<p>In this article we are constructing a simple Jersey REST client API that will be available for use within projects that wish to take advantage of our Company Directory REST web service.&#160; This project is part of the continuing project whose purpose is to integrate technologies various technologies with in a Maven2 build environment.&#160; This [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>In this article we are constructing a simple Jersey REST client API that will be available for use within projects that wish to take advantage of our Company Directory REST web service.&nbsp; This project is part of the continuing project whose purpose is to integrate technologies various technologies with in a Maven2 build environment.&nbsp; This article is extending a client project, presented in: <a href="http://persistentdesigns.com/wp/?p=409">Simple SOAP Client using XMLBeans</a>,&nbsp; in this article we constructed client classes to interact with our SOAP interface into our web service. At the end of this article we will have a Maven2 dependency that will allow applications to interact with the Company Directory web service by either SOAP or REST.</p>
<p>When we introduced our our REST web service we created to client programs to interact with this service: one through Ajax calls and the other through Groovy.&nbsp; These articles are:</p>
<ul>
<li>The Ajax client was in the original REST article: <a href="http://persistentdesigns.com/wp/?p=292">REST Project Digest and Generic Data Repository		</a></li>
<li>The Groovy client was presented in: <a href="http://persistentdesigns.com/wp/?p=329">A Groovy Rest Client for the JPA, Jersey, Spring Integration Project		</a></li>
</ul>
<div class="post-headline">&nbsp;This solution is decoupled from the application such that it would be available to any java application.&nbsp; The product of this project will be used in our next article when we build our client application with <strong>VAADIN</strong>, a <strong>GWT</strong> deriviative, with REST communicating with the backend.</div>
<h2>Implementation</h2>
<p>One class is required for the implementation utilizing Jersey&#8217;s APIs.&nbsp; The coding is straight foward with a couple of places of interest.&nbsp; One being the use of Jersey&#8217;s <strong>GenericType</strong>.&nbsp; The <strong>GenericType&nbsp;</strong>class allows us to deal with type erase that happens in generic collections at run time.&nbsp; This loss of type information makes unmarshalling of collection data difficult as the type information has been removed.</p>
<p>The solution of this problem was done in steps.&nbsp;</p>
<ol>
<li>The entity objects was mapped into Data Transfer Objects.</li>
<li>The data transfer classes have the JAXB annotations that will provide the XML utilized by Jersey&#8217;s JSON adapter.</li>
<li>The collection classes of entities types are preserved through Jersey&#8217;s GenericType class</li>
</ol>
<p>The REST server has the following API for providing a list of Companies:</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
@GET
@Path(&quot;/companies&quot;)
@Produces(&quot;application/json&quot;)
public List&lt;com.persistent.dto.Company&gt; getCompanies() {
	List&lt;Company&gt; companies = companyDirectory.getCompanies();
	List&lt;com.persistent.dto.Company&gt; companyDtos = new ArrayList&lt;&lt;com.persistent.dto.Company&gt;();
	for (Company company : companies) {
		com.persistent.dto.Company companyDto = servermapper.map(company, com.persistent.dto.Company.class);
		companyDtos.add(companyDto);
	}
	return companyDtos;
}</pre>
<p>The Jersey software intercepts the request and wraps the Generic collection with their GenericType.&nbsp; At the client side as shown in the code snippet below we are able to retrieve the Collection of Company objects through the use of the GenericType.</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
public Collection&lt;Company&gt; getCompanies() {
		WebResource.Builder builder = createWebResourceBuilder(UriBuilder
				.fromUri(&quot;http://localhost/&quot;).port(getPort(DEFAULT_PORT)).path(
						URL + &quot;companies&quot;).build((Object[]) null));
		GenericType&lt;Collection&lt;Company&gt;&gt; genericType = new GenericType&lt;Collection&lt;Company&gt;&gt;() {
		};
		return builder.get(genericType);
	}</pre>
<p>&nbsp;The remainder of the class is in the link below.&nbsp;</p>
<pre class="brush:java; collapse:true; wrap-lines:true;">
package com.persistent.rest;

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

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;

import org.apache.log4j.Logger;
import org.dozer.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.persistent.entity.Person;
import com.persistent.entity.Company;
import com.persistent.service.CompanyDirectory;

@Component
@Path(&quot;/&quot;)
@Scope(&quot;singleton&quot;)
public class CompanyDirectoryRest  {
	Logger log = Logger.getLogger(this.getClass());
	@Autowired
	Mapper servermapper;

	@Autowired
	private CompanyDirectory companyDirectory;
	@Context
	UriInfo ui;

	@GET
	@Path(&quot;/persons&quot;)
	@Produces(&quot;application/json&quot;)
	public List&lt;com.persistent.dto.Person&gt; getPersons() {
		log.info(&quot;getPersons entered&quot;);
		List&lt;Person&gt; persons = companyDirectory.getPersons();
		List&lt;com.persistent.dto.Person&gt; personDTOs = new ArrayList&lt;com.persistent.dto.Person&gt;();

		for (Person person : persons) {
			personDTOs.add(getPersonDto(person));
		}

		return personDTOs;
	}

	private com.persistent.dto.Person getPersonDto(Person person) {
		com.persistent.dto.Person personDTO = servermapper.map(person, com.persistent.dto.Person.class);
		return personDTO;
	}

	@GET
	@Path(&quot;/companies&quot;)
	@Produces(&quot;application/json&quot;)
	public List&lt;com.persistent.dto.Company&gt; getCompanies() {
		List&lt;Company&gt; companies = companyDirectory.getCompanies();
		List&lt;com.persistent.dto.Company&gt; companyDtos = new ArrayList&lt;com.persistent.dto.Company&gt;();
		for (Company company : companies) {
			com.persistent.dto.Company companyDto = servermapper.map(company, com.persistent.dto.Company.class);
			companyDtos.add(companyDto);
		}
		return companyDtos;
	}

	@GET
	@Path(&quot;/person/{id}&quot;)
	@Produces(&quot;application/json&quot;)
	public com.persistent.dto.Person getPerson(@PathParam(&quot;id&quot;) final String sid) {
		Long id = Long.parseLong(sid);
		com.persistent.dto.Person result = null;
		Person person = companyDirectory.getPerson(id);
		if(person!=null) {
			result = getPersonDto(person);
		}
		return result;
	}

	@PUT
	@Consumes(&quot;application/json&quot;)
	@Path(&quot;/person/update&quot;)
	public void updatePerson(final com.persistent.dto.Person person) {
		Person personE = servermapper.map(person,Person.class);
		companyDirectory.updatePerson(personE);
	}

	@POST
	@Path(&quot;/person&quot;)
	@Consumes(&quot;application/json&quot;)
	@Produces(&quot;application/json&quot;)
	public com.persistent.dto.Person addPerson(final com.persistent.dto.Person person) {
		Person personE = servermapper.map(person,Person.class);
		return getPersonDto(companyDirectory.addPerson(personE));
	}

	@DELETE
	@Path(&quot;/persons/{id}&quot;)
	@Produces(&quot;text/plain&quot;)
	public String deletePerson(@PathParam(&quot;id&quot;) final String sid) {
		Long id = Long.parseLong(sid);
		companyDirectory.deletePerson(id);
		final MultivaluedMap&lt;String, String&gt; queryParams = ui
				.getQueryParameters();
		final List&lt;String&gt; ids = queryParams.get(&quot;id&quot;);

		if (ids == null) {
			log.debug(&quot;\n\nThe ids is null&quot;);
		} else {
			log.info(&quot;The ids are: &quot;+ids.size());
			for (String currentid : ids) {
				log.info(&quot;Delete: &quot;+currentid);
				companyDirectory.deletePerson(Long.parseLong(currentid));
			}
		}
		return &quot;finished&quot;;
	}

	@GET
	@Path(&quot;/company/{id}&quot;)
	@Produces(&quot;application/json&quot;)
	public com.persistent.dto.Company getCompany(@PathParam(&quot;id&quot;) final String sid) {
		log.info(&quot;Entering findByCompanyId Rest method&quot;);
		return servermapper.map(companyDirectory.getCompany(Long.parseLong(sid)), com.persistent.dto.Company.class);

	}

	@GET
	@Path(&quot;/company/count&quot;)
	@Produces(&quot;text/plain&quot;)
	public String countSCompanies() {
		return companyDirectory.countCompanies().toString();
	}

	@GET
	@Path(&quot;/person/count&quot;)
	@Produces(&quot;text/plain&quot;)
	public String countSPersons() {
		return companyDirectory.countPersons().toString();
	}

	// The Java method will process HTTP GET requests
	@GET
	@Path(&quot;/persons/test&quot;)
	public String simpleTest() {
		return &quot;Hello Foo&quot;;
	}
}</pre>
<p>The installation instruction are similar to those given in this link:<a href="http://persistentdesigns.com/wp/?p=409#installation">Simple SOAP Client using XMLBeans</a>.  There are JUnit test cases that will exercise the newly added functionality.</p>
<h2>The Source Code</h2>
<p>Follow<a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/gclient_oct_29_2009.zip"> this link</a> to down load the source code.</p>
<h2>About The&nbsp;Author</h2>
<p style="margin-left: 40px;"><b>David Sells</b> is a computer consultant in Toronto, Ontario who specializes in Java Enterprise Development. He has&nbsp; provided innovative solutions for clients including: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p style="margin-left: 40px;">He also holds the following certifications:</p>
<ul>
<li>Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5 (2009)</li>
<li>Sun Certified Web Component Developer</li>
<li>Sun Certified Java Programmer.</li>
</ul>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Spring%20Spring-WS%20Application%5Bwith%20JPA%20and%20Jersey%20REST%5D'">david@persistentdesigns.com</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=466</wfw:commentRss>
		</item>
		<item>
		<title>Simple GWT Client integrated with Spring built with Maven</title>
		<link>http://persistentdesigns.com/wp/?p=422</link>
		<comments>http://persistentdesigns.com/wp/?p=422#comments</comments>
		<pubDate>Mon, 19 Oct 2009 19:31:14 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=422</guid>
		<description><![CDATA[Introduction
<p>In this article we will integrate the SOAP client generated in the article:&#160; Simple Spring-WS Application [with JPA and Jersey REST] into a GWT-Spring web application.&#160; Again we are using Maven2 to build the application.&#160; The web application is broken into to two GWT projects: Server and Web which can be built through a Parent [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>In this article we will integrate the SOAP client generated in the article:&nbsp; Simple Spring-WS Application [with JPA and Jersey REST] into a GWT-Spring web application.&nbsp; Again we are using Maven2 to build the application.&nbsp; The web application is broken into to two GWT projects: Server and Web which can be built through a Parent project.&nbsp; The Server project implments a GWT remote services with the Springframework working in the background to provide the SOAP connectivity.&nbsp; GWT provides servlets that the GWT persentation layer communicates.</p>
<h2>Implementation</h2>
<p>The structure for this article is based upon the build environment created by <a href="http://code.google.com/p/gwt-maven2-starter-app/">Sam Brodking</a>.&nbsp; There are tools available which will allow for the building of the front and backend of Spring-GWT in a single project but I feel that there is value in this division from the perspective of unit testing and independent development.</p>
<h3>The Server Project</h3>
<p>The server side deals with the SOAP connection, extracts the entity objects from the SOAP messages, maps the entity objects into their DTO counter parts and makes operations available through a GWT servlet.</p>
<p>The SOAP connection is simple since it was solved in the last article: <a href="http://persistentdesigns.com/wp/?p=409">Simple SOAP Client Using XMLBeans</a>.&nbsp; To utilize its&#8217; services we need only to add it as a dependency.&nbsp; All the jar files related to enabling this dependency to perform are automatically installed through the definition of the dependency: this one of the great benifits to developing with Maven.</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;dependency&gt;
	&lt;groupId&gt;com.persistent&lt;/groupId&gt;
	&lt;artifactId&gt;gclient&lt;/artifactId&gt;
	&lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
&lt;/dependency&gt;</pre>
<p>To create are service we need to provide the following:</p>
<ol>
<li>Create the remote interface to the service we are providing extending: <em>com.google.gwt.user.client.rpc.RemoteService</em></li>
<li>The implementation of that remote interface while also extending:<em>import com.google.gwt.user.server.rpc.RemoteServiceServlet</em></li>
<li>Additionally we create the Async Interface that is registered in our ServiceRegistry through which our client screens will execute commands against the service this occurs in the Web project and we will discuss it in more detail in that section.</li>
</ol>
<p>This application defines one service which is the CompanyDirectory service.</p>
<p>The remote interface CompanyDirectoryDTO:</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
import com.google.gwt.user.client.rpc.RemoteService;
import com.persistent.client.domain.CompanyDTO;
import com.persistent.client.domain.PersonDTO;

public interface CompanyDirectoryDTO extends RemoteService {
	public PersonDTO addPersonDTO(PersonDTO person);
	public Integer countCompanies();
	public Integer countPersonDTOs();
	public String deletePersonDTO(String sid);
	public ArrayList&lt;PersonDTO&gt; findByCompanyDTOId(Long id);
	public ArrayList&lt;PersonDTO&gt; findByCompanyDTOIds(ArrayList&lt;Long&gt; ids);
	public ArrayList&lt;CompanyDTO&gt; getCompanies();
	public PersonDTO getPersonDTO(Long id);
	public ArrayList&lt;PersonDTO&gt; getPersonDTOs();
	public PersonDTO updatePersonDTO(PersonDTO person);
}
</pre>
<p>The implementation of the remote inter face CompanyDirectoryDTOImpl:</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.persistent.client.CompanyDirectoryDTO;
import com.persistent.client.domain.CompanyDTO;
import com.persistent.client.domain.PersonDTO;
import com.persistent.ws.client.SoapClient;

public class CompanyDirectoryDTOImpl extends RemoteServiceServlet implements
		CompanyDirectoryDTO {
	public PersonDTO addPersonDTO(PersonDTO person) {
		return SoapClient.addPersonDTO(person);
	}

	public String deletePersonDTO(String sid){
		return deletePersonDTO(Long.parseLong(sid));
	}

	public String deletePersonDTO(Long id) {
		if (id != null) {
			if (SoapClient.getCompanyDirectory() != null) {
				SoapClient.getCompanyDirectory().deletePerson(id);
			}
		}
		return &quot;Success&quot;;
	}

	public ArrayList&lt;PersonDTO&gt; findByCompanyDTOId(Long id) {
		ArrayList&lt;PersonDTO&gt; result;
		if(id==null) {
			result = new ArrayList&lt;PersonDTO&gt;();
		} else {
			result = SoapClient.findByCompanyDTOId(id);
		}
		return result;
	}

	public ArrayList&lt;CompanyDTO&gt; getCompanies() {
			return SoapClient.getCompanies();
	}

	public ArrayList&lt;PersonDTO&gt; getPersonDTOs() {
		return (ArrayList&lt;PersonDTO&gt;) SoapClient.getPersonDTOs();
	}

	public PersonDTO updatePersonDTO(PersonDTO person) {
		return SoapClient.updatePerson(person);
	}

	public ArrayList&lt;PersonDTO&gt; findByCompanyDTOIds(ArrayList&lt;Long&gt; ids) {
		ArrayList&lt;PersonDTO&gt; result = new ArrayList&lt;PersonDTO&gt;();
		for (Long id : ids) {
			result.addAll(findByCompanyDTOId(id));
		}
		return result;
	}
   :
   :
}</pre>
<p>The CompanyDirectoryDTOAsync:</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
import com.google.gwt.http.client.Request;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.persistent.client.domain.CompanyDTO;
import com.persistent.client.domain.PersonDTO;

public interface CompanyDirectoryDTOAsync {
	public Request addPersonDTO(PersonDTO person,AsyncCallback&lt;PersonDTO&gt; callback);
	public Request countCompanies(AsyncCallback&lt;Integer&gt; callback);
	public Request countPersonDTOs(AsyncCallback&lt;Integer&gt; callback);
	public Request deletePersonDTO(String sd,AsyncCallback&lt;String&gt; callback);
	public Request findByCompanyDTOId(Long id,AsyncCallback&lt;ArrayList&lt;PersonDTO&gt;&gt; asyncCallback);
	public Request findByCompanyDTOIds(ArrayList&lt;Long&gt; ids ,AsyncCallback&lt;ArrayList&lt;PersonDTO&gt;&gt; asyncCallback);
	public Request getCompanies(AsyncCallback&lt;ArrayList&lt;CompanyDTO&gt;&gt; asyncCallback);
	public Request getPersonDTO(Long id,AsyncCallback&lt;PersonDTO&gt; callback);
	public Request getPersonDTOs(AsyncCallback&lt;ArrayList&lt;PersonDTO&gt;&gt; asyncCallback);
	public Request updatePersonDTO(PersonDTO person, AsyncCallback&lt;PersonDTO&gt; callback);
}
</pre>
<p>These server function work in conjunction to the SOAP client.&nbsp; We utilize the soap client through a simple api as generated in the: <a href="http://persistentdesigns.com/wp/?p=409"><em>Simple SOAP Client using XMLBeans</em></a>. To communicate through the GWT Servlet we need to make a data transfer object. Again we utilize the servces Dozer as described in a <a href="http://persistentdesigns.com/wp/?p=423#Dozer">previous article here</a>.</p>
<p>&nbsp;Here is a general picture of the classes in the Server project ( external classes are not included).</p>
<p><a onclick="window.open(this.href,'ServerProjectClasses','resizable=no,location=no,menubar=no,scrollbars=no,status=no,toolbar=no,fullscreen=no,dependent=no,status'); return false" href="http://persistentdesigns.com/wp/wp-content/uploads/image/images/server.jpg"><img width="450" height="323" alt="" src="http://persistentdesigns.com/wp/wp-content/uploads/image/images/server.jpg" /></a></p>
<p>&nbsp;</p>
<h2>The Web Project</h2>
<p>We will focus on the communication services of this layer and update and leave the GWT presentation code to the reader.</p>
<p>The web application has a ClientMain class setups the application entry loading the GWT module and constructing the main pane with the ServiceRegistry.&nbsp;&nbsp; The ServiceRegistry is were all communications with the server side are registered.&nbsp; In this application we have one service registered:</p>
<p><em>Service Registry:</em></p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
public class ServiceRegistry {
	private CompanyDirectoryDTOAsync companyDirectoryDTO;
	public CompanyDirectoryDTOAsync getCompanyDirectoryDTO() {
		if(companyDirectoryDTO == null) {
			companyDirectoryDTO = GWT.create(CompanyDirectoryDTO.class);
			((ServiceDefTarget)companyDirectoryDTO).setServiceEntryPoint(GWT.getModuleBaseURL() + &quot;companyDirectoryDTO&quot;);
		}
		return companyDirectoryDTO;
	}
}
</pre>
<p>The communciation with the server side is done asynchronously.&nbsp; The widgets are populated through AJAX callbacks as part of the GWT toolkit.&nbsp; Below is an example of such a call when we populate all the persons in a company.</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
private void retrievePersonsInCompanies(ArrayList&lt;Long&gt; selectedCompanies) {
	getServiceRegistry().getCompanyDirectoryDTO().findByCompanyDTOIds(
			selectedCompanies, new AsyncCallback&lt;ArrayList&lt;PersonDTO&gt;&gt;() {
				public void onFailure(Throwable caught) {
					Window.alert(&quot;RPC failed.&quot;);
				}
				public void onSuccess(ArrayList&lt;PersonDTO&gt; pPersons) {
					persons.addAll(pPersons);
					refreshPersonsTable();
				}
			});
}
</pre>
<p><em>An overview of the Web Project classes</em></p>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/image/images/web.jpg" onclick="window.open(this.href,'','resizable=no,location=no,menubar=no,scrollbars=no,status=no,toolbar=no,fullscreen=no,dependent=no,status'); return false"><em><img width="450" height="348" src="http://persistentdesigns.com/wp/wp-content/uploads/image/images/web.jpg" alt="Web Project Class View" /></em></a></p>
<h3>PersonChangeEvent: keeping screen information current</h3>
<p>We have two screens that alow us to interact with the CompanyDirectories.&nbsp; If we alter the information on one screen we want to insure that when we switch to the other screen that the information has been refreshed otherwise we will run into cached stale data.&nbsp; To accomplish this we have implemented a simple PersonChangeEvent.&nbsp; This is accomplished in the following way:</p>
<p>Each screen that maintains person information:</p>
<ol>
<li>implements the PersonChangeListener interface adding the personChange method to handle the change to the Person information</li>
<li>registers themselves with the PersonChangePublisher</li>
<li>when a screen alters Person data they publish a change through the pubilsh with a notifyPersonChange</li>
</ol>
<p>The Screens look as follows</p>
<h4>The Checkbox Screen</h4>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/image/images/checkbox_screen.jpg" onclick="window.open(this.href,'','resizable=no,location=no,menubar=no,scrollbars=no,status=no,toolbar=no,fullscreen=no,dependent=no,status'); return false"><br />
<input width="450" type="image" height="247" src="http://persistentdesigns.com/wp/wp-content/uploads/image/images/checkbox_screen.jpg" /></a></p>
<h4>The Tree Screen</h4>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/image/images/Tree_Screen.jpg" onclick="window.open(this.href,'','resizable=no,location=no,menubar=no,scrollbars=no,status=no,toolbar=no,fullscreen=no,dependent=no,status'); return false"><br />
<input width="450" type="image" height="248" src="http://persistentdesigns.com/wp/wp-content/uploads/image/images/Tree_Screen.jpg" alt="Tree Screen" /></a></p>
<h2>Compiling and Running the Application</h2>
<p>There are a number of steps required to get this application working.&nbsp; There are now two applications that need to run for both the JUnit test cases and the running application.</p>
<h3>Prerequisite Tasks</h3>
<p>Prior to building the GWT application we need to get the SOAP Service started.&nbsp; It is prerequisite to have this SOAP service installed in the system&nbsp; along with its client jar entered into the repository and the SOAP Client built .&nbsp; Below are the links to the instructions to perform these&nbsp; tasks:</p>
<ol>
<li><a href="http://persistentdesigns.com/wp/?p=346#Build_Instructions">Installing the SOAP Service</a></li>
<li><a href="http://persistentdesigns.com/wp/?p=346#Soap_Stub">Deploy the client jar into the repository</a></li>
<li><a href="http://persistentdesigns.com/wp/?p=409">Building the SOAP client</a></li>
</ol>
<h3>Building the GWT Server and Web Project</h3>
<p>Without running the test cases you can build the projects through parent directory with the following command:</p>
<p style="margin-left: 40px;">mvn clean install -Dmaven.skip.test=true</p>
<p>This <em>should </em> build both projects.&nbsp; Unfortuantely I find that there are problems at times with this approach and would highly recommend build with the test cases.</p>
<p>To build with the test cases one will have to start the SOAP service for the test cases to complete successfully.&nbsp; We are going to have two web applications running the SOAP server and the GWT application.&nbsp; For the SOAP&nbsp;server we can alter the port that Jetty runs the application on with the following command run from the SOAP server&#8217;s root directory:</p>
<p style="margin-left: 40px;">mvn jetty:run -Djetty.port=9444</p>
<p>We are now free to run the GWT build along with it&#8217;s test cases.&nbsp; The GWT application is coded to utilize the SOAP service on port 9444 of the localhost.&nbsp; Again the command to build the GWT application is from the Parent project root directory:</p>
<p style="margin-left: 40px;">mvn clean install</p>
<p>I have found that sometimes there are problems in the building of the Web project.&nbsp; In this case I go into the Web project root directory and issue that same command.&nbsp; Hopefully this will resolve the problem.&nbsp; If not send me an e-mail and we&#8217;ll get it straightened out.</p>
<p>At this point we should have a war file in the Web project&#8217;s target directory which is ready for deployment in a tomcat6.x /Java 1.5 environment.&nbsp; I have not tested others so you&#8217;ll be on your own if you need to use an alternate.</p>
<p>Here is a trick part (part of the build process I didn&#8217;t get ironed out (feel free to send me the answer)).&nbsp; I copy the web-1.&#8211;SNAPSHOT.war into the <em>webapp</em> directory of tomcat and when it has deployed I copy the following two files from Server project:</p>
<ol>
<li>server/src/main/resources/applicationContext.xml</li>
<li>server/src/main/resources/dozer-bean-mappings.xml</li>
</ol>
<p>The application should not be available for use at:</p>
<p style="margin-left: 40px;">http://localhost:8080/web-1.0-SNAPSHOT/com.persistent.Application/Application.html</p>
<p>Additionally the REST server should also be available, since it is included in the SOAP Server, at:</p>
<p style="margin-left: 40px;">http://localhost:9444/general/crud.html</p>
<p>&nbsp;</p>
<h2>Source Code</h2>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/GWT-Project.zip">Here is the source code.</a></p>
<h2>Conclusion</h2>
<p>That concludes the simple GWT user interface into the Company Directory SOAP Service.&nbsp; It is a complex setup.&nbsp; If you are interested in installing this on your local machine please don&#8217;t hesitate to contact me if you should have any difficulties setting it up.</p>
<p>&nbsp;</p>
<h2>About The&nbsp;Author</h2>
<p style="margin-left: 40px;"><b>David Sells</b> is a computer consultant in Toronto, Ontario who specializes in Java Enterprise Development. He has&nbsp; provided innovative solutions for clients including: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p style="margin-left: 40px;">He also holds the following certifications:</p>
<ul>
<li>Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5 (2009)</li>
<li>Sun Certified Web Component Developer</li>
<li>Sun Certified Java Programmer.</li>
</ul>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Spring%20Spring-WS%20Application%5Bwith%20JPA%20and%20Jersey%20REST%5D'">david@persistentdesigns.com</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p style="margin-left: 40px;">&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=422</wfw:commentRss>
		</item>
		<item>
		<title>Separation of Concerns: Refactoring of Evolving Project</title>
		<link>http://persistentdesigns.com/wp/?p=423</link>
		<comments>http://persistentdesigns.com/wp/?p=423#comments</comments>
		<pubDate>Sun, 18 Oct 2009 21:45:10 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=423</guid>
		<description><![CDATA[Introduction
<p>This article is in relationship to refactoring the SOAP/REST server presented in: Simple Spring-WS Application [with JPA and Jersey REST].</p>
<p>As the project has evolved some ugly coupling has reared its&#8217; head.&#160; In an expedient way the entity classes were annotated with JAXB annotations to make them available for serialization for our REST implementation.&#160; Here the [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>This article is in relationship to refactoring the SOAP/REST server presented in: <a href="http://persistentdesigns.com/wp/?p=346">Simple Spring-WS Application [with JPA and Jersey REST]</a>.</p>
<p>As the project has evolved some ugly coupling has reared its&#8217; head.&nbsp; In an expedient way the entity classes were annotated with JAXB annotations to make them available for serialization for our REST implementation.&nbsp; Here the JAXB worked in conjunction with Jersey REST adapters to create JSON messages to serialize our objects.&nbsp;</p>
<h2>The Refactoring</h2>
<p>There are many draw backs to taking this direct approach:</p>
<ul>
<li>Muddying the definition of entity objects</li>
<li>Need to use GenericEntity to handle type erasure in the entity class which alters the class signature</li>
<li>From using GenericEntity and JAXB Annotations these libraries would have to be included in applications using the entity object even if these features were not used.</li>
<li>Complicates extensions to the entity</li>
<li>From a REST perspective it does not give us clean control over the information we choose to serialize.</li>
</ul>
<p><em>&nbsp;The Original com.persistent.entity.Company Class</em></p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
@XmlRootElement(name = &quot;company&quot;)
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
@Entity
@Table(name = &quot;COMPANY&quot;)
@NamedQueries( { @NamedQuery(name = &quot;Company.EagerFindByID&quot;, query = &quot;SELECT c FROM Company c left join fetch c.employees where c.id =?1&quot;)
				}
			)
public class Company {
	private static final long serialVersionUID = -142950147106627846L;
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	private String name;
	@OneToMany(mappedBy = &quot;company&quot;, fetch = FetchType.LAZY)
	private List&lt;Person&gt; employees = new ArrayList&lt;Person&gt;();

	/**
	 *
	 */
	public Company() {
	}

	@XmlElement
	public Long getId() {
		return id;
	}
	public void setId(final Long id) {
		this.id = id;
	}
	@XmlElement
	public String getName() {
		return name;
	}
	public void setName(final String name) {
		this.name = name;
	}

	public GenericEntity&lt;List&lt;Person&gt;&gt; getEmployees() {
		return new GenericEntity&lt;List&lt;Person&gt;&gt;(employees) {};
	}
</pre>
<p>The standard solution to this problem is the <a href="http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html">Transfer Object</a> pattern.&nbsp; Although we are changing the entity class annotations in an environment where it is being utilized by both REST and SOAP only the REST protion of the project is affected.&nbsp; The SOAP functionality generates its own JAXB annotated transfer objects through the use XJC.</p>
<p>The following steps were required to implement the refactoring:</p>
<ol>
<li>Removed the JAXB annotations from the entity classes</li>
<li>Create the transfer objects for each of the entity classes with JAXB annotations</li>
<li>Added <a href="http://dozer.sourceforge.net/">Dozer</a> to facilitate the mapping from the entity classes to the transfer objects</li>
<li>execute the mappings in the CompanyDirectoryRest class were the conversion is required.</li>
</ol>
<p><em>&nbsp;The com.persistent.entity.Company Class</em> after the decoupling</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
@Entity
@Table(name = &quot;COMPANY&quot;)
@NamedQueries( { @NamedQuery(name = &quot;Company.EagerFindByID&quot;, query = &quot;SELECT c FROM Company c left join fetch c.employees where c.id =?1&quot;) })
public class Company implements Serializable {
	private static final long serialVersionUID = -142950147106627846L;
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	private String name;
	@OneToMany(mappedBy = &quot;company&quot;, fetch = FetchType.LAZY)
	private List&lt;Person&gt; employees = new ArrayList&lt;Person&gt;();

	/**
	 *
	 */
	public Company() {
	}

	public Long getId() {
		return id;
	}

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

	public String getName() {
		return name;
	}

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

	public List&lt;Person&gt; getEmployees() {
		return employees;
	}</pre>
<p><em>The com.persistent.dto.Company Class for Data Transfer</em></p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
@XmlRootElement(name = &quot;company&quot;)
@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
public class Company implements Serializable {
	@XmlTransient
	private static final long serialVersionUID = -142950147106627846L;

	private Long id;
	private String name;
	private List&lt;Person&gt; employees = new ArrayList&lt;Person&gt;();
	/**
	 *
	 */
	public Company() {
	}

	public Company(com.persistent.entity.Company company) {
		this.name = company.getName();
		this.id = company.getId();
	}

	@XmlElement
	public Long getId() {
		return id;
	}
	public void setId(final Long id) {
		this.id = id;
	}
	@XmlElement
	public String getName() {
		return name;
	}
	public void setName(final String name) {
		this.name = name;
	}

	public GenericEntity&lt;List&lt;Person&gt;&gt; getEmployees() {
		return new GenericEntity&lt;List&lt;Person&gt;&gt;(employees) {};
	}</pre>
<p>&nbsp;</p>
<p>The JUnit test cases proved their worth as these changes were made to quickly establish their effectiveness.</p>
<p>The interfaces between components is maintained so that the JUnit tests do not need to change.&nbsp; This refactoring mainly effects the maintainability and extensibility of the software.&nbsp; This application will work with the SOAP Client described in the previous article: <a href="http://persistentdesigns.com/wp/?p=409">Simple SOAP Client using XMLBeans</a>.</p>
<h3><a name="Dozer">A Note on Dozer</a></h3>
<p>Dozer does implicit-explicit mappings between classes.&nbsp; It provides complex mapping between dis-similar classes.&nbsp; We are utilizing it simply but it is an application that does provide flexibility that will provide value in the long run when there may be more interest in interesting mappings.&nbsp; Even used simply it does provide an intuitive flow to the code which leads to maintainability as we show below.</p>
<p>By providing a simple mapping file, as in our case <em>general-dozer-bean-mappings.xml</em>, we describe the desired mapping.&nbsp; We rely on the implicit mapping fascilities of the tool:</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;mappings xmlns=&quot;http://dozer.sourceforge.net&quot;
xmlns:xs=&quot;http://www.w3.org/2001/XMLSchema&quot;
xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xsi:schemaLocation=&quot;http://dozer.sourceforge.net
http://dozer.sourceforge.net/schema/beanmapping.xsd&quot;&gt;

  &lt;mapping&gt;
    &lt;class-a&gt;com.persistent.entity.Company&lt;/class-a&gt;
    &lt;class-b&gt;com.persistent.dto.Company&lt;/class-b&gt;
    &lt;field-exclude&gt;
      &lt;a&gt;employees&lt;/a&gt;
      &lt;b&gt;employees&lt;/b&gt;
    &lt;/field-exclude&gt;
  &lt;/mapping&gt;
  &lt;mapping&gt;
    &lt;class-a&gt;com.persistent.entity.Person&lt;/class-a&gt;
    &lt;class-b&gt;com.persistent.dto.Person&lt;/class-b&gt;
  &lt;/mapping&gt;
&lt;/mappings&gt;
</pre>
<p>Now performing the mapping is trivial in this snippet, taken from <em>CompanyDirectoryRest.java</em>,&nbsp; we map the entity object into a JAXB annotated transfer object for serialization.</p>
<p>&nbsp;</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
@Autowired
Mapper servermapper;

@GET
@Path(&quot;/persons&quot;)
@Produces(&quot;application/json&quot;)
public List&lt;com.persistent.dto.Person&gt; getPersons() {
	log.info(&quot;getPersons entered&quot;);
	List&lt;Person&gt; persons = companyDirectory.getPersons();
	List&lt;com.persistent.dto.Person&gt; personDTOs = new ArrayList&lt;com.persistent.dto.Person&gt;();

	for (Person person : persons) {
		personDTOs.add(getPersonDto(person));
	}

	return personDTOs;
}

private com.persistent.dto.Person getPersonDto(Person person) {
	com.persistent.dto.Person personDTO = servermapper.map(person, com.persistent.dto.Person.class);
	return personDTO;
}</pre>
<h2>Conclusion</h2>
<p>We have decoupled the JAXB annotations from the entity objects and have utilized a data transfer object to provide the JAXB conversion.&nbsp; This decoupling leads to greater easy of extention to our entities and places the JAXB services closer to the point of use rather than bleeding them into other parts of the application.</p>
<h2>Build Instructions</h2>
<p>The build instructions are the same as before.&nbsp;<a href="http://persistentdesigns.com/wp/?p=346#Build_Instructions"> Click here for the build instructions</a>.</p>
<h2>The Source Code</h2>
<p>updated <a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/general_oct_29_2009.zip">Source Code</a>: October 29, 2009</p>
<h2>About The&nbsp;Author</h2>
<p style="margin-left: 40px;"><b>David Sells</b> is a computer consultant in Toronto, Ontario who specializing in Java Enterprise Development. He has&nbsp; provided innovative solutions for clients including: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p style="margin-left: 40px;">He also holds the following certifications:</p>
<ul>
<li>Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5 (2009)</li>
<li>Sun Certified Web Component Developer</li>
<li>Sun Certified Java Programmer.</li>
</ul>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Spring%20Spring-WS%20Application%5Bwith%20JPA%20and%20Jersey%20REST%5D'">david@persistentdesigns.com</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=423</wfw:commentRss>
		</item>
		<item>
		<title>Simple SOAP Client using XMLBeans</title>
		<link>http://persistentdesigns.com/wp/?p=409</link>
		<comments>http://persistentdesigns.com/wp/?p=409#comments</comments>
		<pubDate>Fri, 16 Oct 2009 20:46:46 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=409</guid>
		<description><![CDATA[Introduction
<p>In this article we discuss the construction of a client API to the Soap Server constructed in the prervious article: Simple Spring-WS Application [with JPA and Jersey REST].&#160;&#160;&#160; The product of this client project will be a jar file that can be included as a pom depenency (Maven) to provide easy access to the web [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>In this article we discuss the construction of a client API to the Soap Server constructed in the prervious article: <em>Simple Spring-WS Application [with JPA and Jersey REST]</em>.&nbsp;&nbsp;&nbsp; The product of this client project will be a <em>jar</em> file that can be included as a pom depenency (Maven) to provide easy access to the web services of that previous article. In the next article we will utilizes this client jar file to connect to the web service where we will see the benfit both of the sepration of concerns as well as the ease in which we can integrate through Maven.</p>
<h3>Implementing the SOAP Client using XMLBeans</h3>
<p>From the last article we created a service for a company directories which allowed the following functionality:</p>
<ul>
<li>get all persons</li>
<li>get all companies</li>
<li>get persons in a company</li>
<li>update person</li>
<li>create person</li>
<li>delete person</li>
</ul>
<p>In our client project we wish to make a request on a web service which will carry out the following basic behaviour:</p>
<ol>
<li>dispatch a request to the web service</li>
<li>recieve a response from the web service</li>
</ol>
<p>On the SOAP Server side we utilized XJC to generate from the XSD the classes that are used to serialize our entity objects in and out of SOAP messages.&nbsp; These intermediaries act as a sort of data transfer object which come with their own bean mapper: mapping the entity objects into the XSD generated schema objects.</p>
<p>On the client side we are utilizing XMLBeans services to provide the marhalling of our objects.&nbsp; <a href="http://xmlbeans.apache.org/">XMLBeans</a> xml beans is a technology that enables access to XML through binding it to Java types.&nbsp; Much of the work is automated by the <strong>xmlbeans-maven-plugin</strong> in the POM file.&nbsp; We include the general-client.jar that we created in the previous article.&nbsp; This jar contains the XSD file used by the XMLBean plugin to generate the schema classes that we will be populating with our SchemaUtil.&nbsp; Below are the related additions to the POM file.</p>
<pre class="brush=xml">
&lt;plugin&gt;
	&lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
	&lt;artifactId&gt;xmlbeans-maven-plugin&lt;/artifactId&gt;
	&lt;version&gt;2.3.2&lt;/version&gt;
	&lt;executions&gt;
		&lt;execution&gt;
			&lt;goals&gt;
				&lt;goal&gt;xmlbeans&lt;/goal&gt;
			&lt;/goals&gt;
		&lt;/execution&gt;
	&lt;/executions&gt;
	&lt;inherited&gt;true&lt;/inherited&gt;
	&lt;configuration&gt;
		&lt;xsdJars&gt;
			&lt;xsdJar implementation=&quot;java.lang.String&quot;&gt;com.persistent:general-client&lt;/xsdJar&gt;
		&lt;/xsdJars&gt;
		&lt;schemaDirectory&gt;target/xmlbeans-xsds/schema&lt;/schemaDirectory&gt;
		&lt;sourceGenerationDirectory&gt;target/generated/xmlbeans&lt;/sourceGenerationDirectory&gt;
		&lt;verbose&gt;true&lt;/verbose&gt;
	&lt;/configuration&gt;
&lt;/plugin&gt;</pre>
<p>To send the message to <strong>add a person</strong> we will be serializing a person object from the client side.&nbsp; The following sequence diagram describes what is happening in process of dispatching an add person request and response:</p>
<p>&nbsp;</p>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/Marshall.jpg" target="_blank"><img width="450" height="253" alt="Sequence Diagram" src="http://persistentdesigns.com/wp/wp-content/uploads/Marshall.jpg" /></a></p>
<p>&nbsp;</p>
<p>To Connect with the Web Service we utilize <a href="http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/client/core/support/WebServiceGatewaySupport.html">WebServiceGatewaySupport</a> from Spring.&nbsp; The WebServiceGatewaySupport is a convenient super class for applications that need Web services.&nbsp; We are utilizing it in a very generic way with our single endpoint.</p>
<p>The coding required to implement the client is minimal.&nbsp; As illustrated in the sequence diagram above here is the code that implements the add person function:</p>
<pre class="brush=java">
public Person createPerson(final Person person) throws DatatypeConfigurationException {
		logger.info(&quot;Entered SoapCompanyDirectory createPerson&quot;);
		Enum add = Operation.CREATE;
		PersonRequestDocument personRequestDocument = PersonRequestDocument.Factory.newInstance();
		PersonRequest personRequest = personRequestDocument.addNewPersonRequest();
		personRequest.setOperation(add);
		logger.info(&quot;Before null assert&quot;);
		assert(person!=null);
		logger.info(&quot;After null assert&quot;);
		personRequest.setPerson(SchemaConversionUtil.toSchemaType(person));
		PersonResponseDocument personResponseDocument = (PersonResponseDocument)getWebServiceTemplate().marshalSendAndReceive(personRequest);
		PersonResponseDocument.PersonResponse personResponse = personResponseDocument.getPersonResponse();
		return SchemaConversionUtil.toEntityType(personResponse.getPerson());
	}</pre>
<p>The class SoapCompanyDirectory extends the <a href="http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/client/core/support/WebServiceGatewaySupport.html">WebServiceGatewaySupport</a> class to provide the functions required to support the methods available on the SOAP server.&nbsp; We utilize this class in CompanyDirectoryImpl.&nbsp; This class implements the CompanyDirectory interface that we developed in the service project.&nbsp; This now provides us with the option of inject, in a Spring application, either a local or remote SOAP CompanyDirectory service.</p>
<p>The following is the class diagram:</p>
<p><a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/image/images/client-cd.jpg"><img width="450" height="364" src="http://persistentdesigns.com/wp/wp-content/uploads/image/images/client-cd.jpg" alt="Client Class Diagram" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h3>Spring ApplicationContext</h3>
<p>The Spring ApplicationContext file pulls the elements together setting the messageFactory used by the SoapCompanyDirectory ( derived from&nbsp; WebServiceGatewaySupport) to SaajSoapMessageFactory.&nbsp; <a href="http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/ws/soap/saaj/SaajSoapMessageFactory.html">SaajSoapMessageFactory</a> provides the SSAJ-specific implementation implemention of the WebServiceMessageFactory utilized by SoapCompanyDirectory.&nbsp; Additionally the marshalling of the objects from schema to entity class representation is provided throught the <a href="http://static.springsource.org/spring-ws/sites/1.5/apidocs/org/springframework/oxm/xmlbeans/XmlBeansMarshaller.html">XmlBeanMarshaller</a>.&nbsp;</p>
<pre class="brush=xml">
&lt;bean id=&quot;messagFactory&quot; class=&quot;org.springframework.ws.soap.saaj.SaajSoapMessageFactory&quot;/&gt;

&lt;bean id=&quot;abstractClient&quot; abstract=&quot;true&quot;&gt;
    &lt;constructor-arg ref=&quot;messagFactory&quot;/&gt;
    &lt;property name=&quot;destinationProvider&quot;&gt;
        &lt;bean class=&quot;org.springframework.ws.client.support.destination.Wsdl11DestinationProvider&quot;&gt;
            &lt;property name=&quot;wsdl&quot; value=&quot;http://localhost:8080/general/companies/companySearch.wsdl&quot;/&gt;
        &lt;/bean&gt;
    &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id=&quot;marshaller&quot; class=&quot;org.springframework.oxm.xmlbeans.XmlBeansMarshaller&quot;/&gt;

&lt;bean id=&quot;soapCompanyDirectory&quot; parent=&quot;abstractClient&quot; class=&quot;com.persistent.ws.client.SoapCompanyDirectory&quot;&gt;
    &lt;property name=&quot;marshaller&quot; ref=&quot;marshaller&quot;/&gt;
    &lt;property name=&quot;unmarshaller&quot; ref=&quot;marshaller&quot;/&gt;
&lt;/bean&gt;</pre>
<h2><a name="installation">Installation Instructions</a></h2>
<ol>
<li>On down loading the source code which is in a zip filed called: gclient.zip uncompress it</li>
<li>To build type: mvn install -Dmaven.test.skip=true</li>
<li>Start the SOAP server as described in the previous article.</li>
<li>run the tests to validate the installation and build of the SOAP Client with: mvn test</li>
</ol>
<h2>The Source Code</h2>
<p>Follow<a href="http://persistentdesigns.com/wp/wp-content/uploads/gclient.zip"> this link</a> to down load the source code.</p>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/gclient_oct_29_2009.zip">Update code</a> (Addition of REST Client code see: <a href="http://persistentdesigns.com/wp/?p=466&amp;preview=true">Jersey REST Client</a>) October 29, 2009</p>
<h2>About The&nbsp;Author</h2>
<p style="margin-left: 40px;"><b>David Sells</b> is a computer consultant in Toronto, Ontario who specializing in Java Enterprise Development. He has&nbsp; provided innovative solutions for clients including: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p style="margin-left: 40px;">He also holds the following certifications:</p>
<ul>
<li>Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5 (2009)</li>
<li>Sun Certified Web Component Developer</li>
<li>Sun Certified Java Programmer.</li>
</ul>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Spring%20Spring-WS%20Application%5Bwith%20JPA%20and%20Jersey%20REST%5D'">david@persistentdesigns.com</a></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=409</wfw:commentRss>
		</item>
		<item>
		<title>Simple Spring-WS Application [with JPA and Jersey REST]</title>
		<link>http://persistentdesigns.com/wp/?p=346</link>
		<comments>http://persistentdesigns.com/wp/?p=346#comments</comments>
		<pubDate>Wed, 23 Sep 2009 18:50:35 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=346</guid>
		<description><![CDATA[Introduction
<p>In this article we will add a SOAP service utilizing Spring-WS to our evolving project.&#160; This is a continuing series of articles whose purpose is to provide working examples of technologies integrated in a Spring based web application. Our latest edition will join the previously integrated technologies which include: Jersey (REST), JPA, Hibernate, JavaScript, AJAX [...]]]></description>
			<content:encoded><![CDATA[<h1>Introduction</h1>
<p>In this article we will add a SOAP service utilizing Spring-WS to our evolving project.&nbsp; This is a continuing series of articles whose purpose is to provide working examples of technologies integrated in a Spring based web application. Our latest edition will join the previously integrated technologies which include: Jersey (REST), JPA, Hibernate, JavaScript, AJAX and Groovy.&nbsp; These are developed in a Maven2 build environment with testing through JUnit4 and reporting via PMD and Cobertura.  This installment will add a SOAP service but we will put off writing the client until the next article and in its place we will utilize an useful application called <strong>SoapUI</strong> to test our SOAP service.&nbsp; The following article will utilize XmlBeans and Spring MVC to create a web client for the SOAP service.</p>
<h2>Using Spring-WS 1.5</h2>
<h4>Contract-First versus Contract-Last</h4>
<p>There are two ways to implement web services:</p>
<ol>
<li>The contact-last approach allows for the generation of the xsd and wsdl directly from the Java classes.</li>
<li>The contract-first utilize the wsdl as the contract.&nbsp; The java classes are constructed with respect to that contract.</li>
</ol>
<p>Spring has chosen to implement the contract-first approach.&nbsp; They have,discussed this point in the Spring Web Services Reference in <a href="http://static.springsource.org/spring-ws/sites/1.5/reference/html/why-contract-first.html">Chapter 2. Why Contract First?</a> To summarize, from their article, the key advantages to this approach are:</p>
<ul>
<li>Easing the Object/XML impedance mismatch by allowing&nbsp; explict handling of:
<ul>
<li>xsd extensions</li>
<li>unportable types</li>
<li>cyclic graphs</li>
</ul>
</li>
<li>Additionally the contract-approach provides a less fragile solution with reusable components.</li>
</ul>
<h4>Describing the Schema</h4>
<p>In the schema we will model the entity classes and the messages that we wish to send through our SOAP service.  Our domain model is simple and small consisting of two class Person and Company.&nbsp; Below is what they look like as encoded in the XMLSchema:</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;complexType name=&quot;Company&quot;&gt;
	&lt;sequence&gt;
		&lt;element name=&quot;id&quot; type=&quot;long&quot; minOccurs=&quot;1&quot; /&gt;
		&lt;element name=&quot;name&quot; type=&quot;string&quot; minOccurs=&quot;1&quot; /&gt;
		&lt;element name=&quot;employees&quot; type=&quot;tns:Person&quot; minOccurs=&quot;0&quot; maxOccurs=&quot;unbounded&quot; /&gt;
	&lt;/sequence&gt;
&lt;/complexType&gt;

&lt;complexType name=&quot;Person&quot;&gt;
	&lt;sequence&gt;
		&lt;element name=&quot;id&quot; type=&quot;long&quot; minOccurs=&quot;1&quot;&gt;&lt;/element&gt;
		&lt;element name=&quot;name&quot; type=&quot;string&quot; minOccurs=&quot;1&quot;&gt;&lt;/element&gt;
		&lt;element name=&quot;age&quot; type=&quot;short&quot; minOccurs=&quot;1&quot;&gt;&lt;/element&gt;
		&lt;element name=&quot;company&quot; type=&quot;tns:Company&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;&gt;&lt;/element&gt;
	&lt;/sequence&gt;
&lt;/complexType&gt;</pre>
<p>We also need describe the messages that will request data.&nbsp; We are limiting our web service operations to the following service api:</p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
CompaniesResponse getCompanies(CompaniesRequest companiesRequest);
PersonResponse getPerson(PersonRequest personRequest);
PersonsResponse getPersons(PersonsRequest personSearchRequest);
TableCountResponse getTableCount(TableCountRequest tableCountRequest);</pre>
<p>Through these methods we will be able to service the functions that we have been using in our previous REST implementation.&nbsp; The functions include:</p>
<ul>
<li>get all persons</li>
<li>get all companies</li>
<li>get persons in a company</li>
<li>update person</li>
<li>create person</li>
<li>delete person</li>
</ul>
<p>Note in the service api, above, we are utilizing the following classes:</p>
<ul>
<li>CompanyRequest/CompanyRequest</li>
<li>PersonRequest/PersonResponse</li>
<li>TableCountRequest/TableCountResponse</li>
<li>PersonSearch</li>
</ul>
<p>These are utility classes that are generated to pass the request and response information through our SOAP messages.&nbsp; These classes are not actually written directly in java but are generated from their XSD definition via the SUN xjc compiler.&nbsp; These elements are defined in the <em><strong>CompanySearch.xsd</strong></em>.&nbsp; To get a feel for writing the XSD definitions we will work through the definition of the PersonRequest/PersonResponse elements.  First note that there are xml elements to deal with the Person class both singly and in a collection.&nbsp; The PersonRequest/PersonResponse elements deal with single Person operations such as: create, read, update and delete (crud).  Looking first at the <em>PersonRequest</em> it contains a sequence that requires one-and-only-one operation defined and optionally a PersonCriteria or/and Person element.&nbsp; So first we have an <em>Operation</em>, this operation has been encoded as an enumeration with the CRUD methods we wish to apply to a Person element/entity .  The operations that the PersonRequest can make are:</p>
<ul>
<li>CREATE operation require that the person element be supplied</li>
<li>READ operation this will be done with a PersonCriteria element, this PersonCriteria element gives us the criteria for the search for the appropriate Person.</li>
<li>UPDATE operation requires the person element</li>
<li>DELETE operation requires the person element</li>
</ul>
<p>Schema definitions of <em>PersonRequest</em>, <em>PersonResponse</em> and <em>Operation</em></p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;element name=&quot;PersonRequest&quot;&gt;
	&lt;complexType&gt;
		&lt;sequence&gt;
			&lt;element name=&quot;operation&quot; type=&quot;tns:Operation&quot; minOccurs=&quot;1&quot;
				maxOccurs=&quot;1&quot; /&gt;
			&lt;element ref=&quot;tns:PersonCriteria&quot; minOccurs=&quot;0&quot; maxOccurs=&quot;1&quot; /&gt;
			&lt;element name=&quot;person&quot; type=&quot;tns:Person&quot; minOccurs=&quot;0&quot;
				maxOccurs=&quot;1&quot; /&gt;
		&lt;/sequence&gt;
	&lt;/complexType&gt;
&lt;/element&gt;

&lt;simpleType name=&quot;Operation&quot;&gt;
	&lt;restriction base=&quot;string&quot;&gt;
		&lt;enumeration value=&quot;CREATE&quot; /&gt;
		&lt;enumeration value=&quot;UPDATE&quot; /&gt;
		&lt;enumeration value=&quot;READ&quot; /&gt;
		&lt;enumeration value=&quot;DELETE&quot; /&gt;
	&lt;/restriction&gt;
&lt;/simpleType&gt;</pre>
<p>The entire CompanySearch.xsd can viewed in the link below.</p>
<pre class="brush:xml; collapse:true; wrap-lines:true;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;schema xmlns=&quot;http://www.w3.org/2001/XMLSchema&quot; targetNamespace=&quot;http://persistent.com/schema&quot;
	xmlns:tns=&quot;http://persistent.com/schema&quot; elementFormDefault=&quot;qualified&quot;&gt;

	&lt;complexType name=&quot;Company&quot;&gt;
		&lt;sequence&gt;
			&lt;element name=&quot;id&quot; type=&quot;long&quot; minOccurs=&quot;1&quot; /&gt;
			&lt;element name=&quot;name&quot; type=&quot;string&quot; minOccurs=&quot;1&quot; /&gt;
			&lt;element name=&quot;employees&quot; type=&quot;tns:Person&quot; minOccurs=&quot;0&quot;
				maxOccurs=&quot;unbounded&quot; /&gt;
		&lt;/sequence&gt;
	&lt;/complexType&gt;

	&lt;complexType name=&quot;Person&quot;&gt;
		&lt;sequence&gt;
			&lt;element name=&quot;id&quot; type=&quot;long&quot; minOccurs=&quot;1&quot;&gt;&lt;/element&gt;
			&lt;element name=&quot;name&quot; type=&quot;string&quot; minOccurs=&quot;1&quot;&gt;&lt;/element&gt;
			&lt;element name=&quot;age&quot; type=&quot;short&quot; minOccurs=&quot;1&quot;&gt;&lt;/element&gt;
			&lt;element name=&quot;company&quot; type=&quot;tns:Company&quot; minOccurs=&quot;1&quot;
				maxOccurs=&quot;1&quot;&gt;&lt;/element&gt;
		&lt;/sequence&gt;
	&lt;/complexType&gt;

	&lt;element name=&quot;CompaniesRequest&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element ref=&quot;tns:CompanySearchCriteria&quot; minOccurs=&quot;0&quot;&gt;&lt;/element&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;simpleType name=&quot;Operation&quot;&gt;
		&lt;restriction base=&quot;string&quot;&gt;
			&lt;enumeration value=&quot;CREATE&quot; /&gt;
			&lt;enumeration value=&quot;UPDATE&quot; /&gt;
			&lt;enumeration value=&quot;READ&quot; /&gt;
			&lt;enumeration value=&quot;DELETE&quot; /&gt;
		&lt;/restriction&gt;
	&lt;/simpleType&gt;

	&lt;simpleType name=&quot;TableNames&quot;&gt;
		&lt;restriction base=&quot;string&quot;&gt;
			&lt;enumeration value=&quot;Person&quot;&gt;&lt;/enumeration&gt;
			&lt;enumeration value=&quot;Company&quot;&gt;&lt;/enumeration&gt;
		&lt;/restriction&gt;
	&lt;/simpleType&gt;

	&lt;element name=&quot;TableCountRequest&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element name=&quot;table&quot; type=&quot;tns:TableNames&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;/&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;element name=&quot;TableCountResponse&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element name=&quot;table&quot; type=&quot;tns:TableNames&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;/&gt;
				&lt;element name=&quot;count&quot; type=&quot;integer&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot;/&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;element name=&quot;PersonRequest&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element name=&quot;operation&quot; type=&quot;tns:Operation&quot; minOccurs=&quot;1&quot;
					maxOccurs=&quot;1&quot; /&gt;
				&lt;element ref=&quot;tns:PersonCriteria&quot; minOccurs=&quot;0&quot; maxOccurs=&quot;1&quot; /&gt;
				&lt;element name=&quot;person&quot; type=&quot;tns:Person&quot; minOccurs=&quot;0&quot;
					maxOccurs=&quot;1&quot; /&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;element name=&quot;PersonsRequest&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element ref=&quot;tns:PersonSearchCriteria&quot; minOccurs=&quot;0&quot;&gt;&lt;/element&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;element name=&quot;PersonSearchCriteria&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element name=&quot;companyId&quot; type=&quot;long&quot; minOccurs=&quot;0&quot;
					maxOccurs=&quot;1&quot; /&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;element name=&quot;PersonCriteria&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element name=&quot;id&quot; type=&quot;long&quot; minOccurs=&quot;1&quot; maxOccurs=&quot;1&quot; /&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;element name=&quot;PersonResponse&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element name=&quot;person&quot; type=&quot;tns:Person&quot; nillable=&quot;true&quot; /&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;element name=&quot;PersonsResponse&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element name=&quot;personList&quot; type=&quot;tns:Person&quot; minOccurs=&quot;0&quot;
					maxOccurs=&quot;unbounded&quot;&gt;&lt;/element&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;element name=&quot;CompanySearchCriteria&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element name=&quot;name&quot; type=&quot;string&quot; nillable=&quot;true&quot; /&gt;
				&lt;element name=&quot;id&quot; type=&quot;short&quot; nillable=&quot;true&quot; /&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;

	&lt;element name=&quot;CompaniesResponse&quot;&gt;
		&lt;complexType&gt;
			&lt;sequence&gt;
				&lt;element name=&quot;companyList&quot; type=&quot;tns:Company&quot; minOccurs=&quot;0&quot;
					maxOccurs=&quot;unbounded&quot;&gt;&lt;/element&gt;
			&lt;/sequence&gt;
		&lt;/complexType&gt;
	&lt;/element&gt;
&lt;/schema&gt;</pre>
<h4>SOAP Request to endpoint</h4>
<p>Lets backup a bit and take a higher level view of what is happening here.&nbsp; Below is a diagram that helps provide context to the code, xml and configuration.&nbsp; In the diagram we see what happens as a message comes into our web service and is mapped to an endpoint in the application which services the requests and returns a response message.  <a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/image/images/endpointmapping.png"><img width="450" height="212" alt="Endpoint mapping" src="http://persistentdesigns.com/wp/wp-content/uploads/image/images/endpointmapping.png" /></a>  We will now step through these processes to get an understanding of how this sequence of events is encoded in our application.</p>
<h4>Message to MessageDispacher</h4>
<p>First the web server receives a SOAP Request.&nbsp; For example: PersonRequest.&nbsp; The web.xml file is configured as follows:</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;servlet&gt;
	&lt;servlet-name&gt;spring-ws&lt;/servlet-name&gt;
	&lt;servlet-class&gt;org.springframework.ws.transport.http.MessageDispatcherServlet&lt;/servlet-class&gt;
	&lt;init-param&gt;
		&lt;param-name&gt;transformWsdlLocations&lt;/param-name&gt;
		&lt;param-value&gt;true&lt;/param-value&gt;
	&lt;/init-param&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
	&lt;servlet-name&gt;spring-ws&lt;/servlet-name&gt;
	&lt;url-pattern&gt;/companies/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;</pre>
<p>Soap Message would look like this (it is a create Person request):</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:sch=&quot;http://persistent.com/schema&quot;&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;sch:PersonRequest&gt;
         &lt;sch:operation&gt;CREATE&lt;/sch:operation&gt;

         &lt;sch:person&gt;
            &lt;sch:id&gt;-1&lt;/sch:id&gt;
            &lt;sch:name&gt;New Name&lt;/sch:name&gt;
            &lt;sch:age&gt;12&lt;/sch:age&gt;
            &lt;sch:company&gt;
               &lt;sch:id&gt;1&lt;/sch:id&gt;
               &lt;sch:name&gt;IBM&lt;/sch:name&gt;
            &lt;/sch:company&gt;
         &lt;/sch:person&gt;
      &lt;/sch:PersonRequest&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre>
<p>The soap message is passed to a web service url which would be: http://localhost:8080/general/companies.  The servlet mapping would map the soap request passing it on to determine its endpoint mapping.</p>
<h4>EndpointMapping, EndpointAdapter and Endpoint</h4>
<h5>EndpointMapping</h5>
<p>The interface <em>EndpointMapping</em> defines the mapping between a message request and their associated endpoint objects.  <em>PayloadRootQNameEndpointMapping</em> and <em>SoapActionEndpointMapping</em> are implementation of this interface additionally, and most importantly for our case, <em>AbstractEndpointMapping</em><strong><em> </em></strong>implements the interface which will serve Spring&#8217;s endpoint interceptor. Looking at the spring-ws-servlet.xml we are utilizing a specializting of the <em>AbstractEndpointMapping</em> called <em>PayloadRootAnnotationMethodEndpointMapping</em>.&nbsp; Below shows snippets from the configuration and a view of how the endpoint annotations are applied.  <em>From spring-ws-servlet.xml</em></p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;bean id=&quot;annotationMapping&quot;
          class=&quot;org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping&quot;&gt;
        &lt;description&gt;
            Detects @PayloadRoot annotations on @Endpoint bean methods. The CompanyDirectoryEndpoint
            has such annotations. It uses two interceptors: one that logs the message payload, and the other validates
            it according to the 'ComapnySearch.xsd' schema file.
        &lt;/description&gt;
        &lt;property name=&quot;interceptors&quot;&gt;
            &lt;list&gt;
                &lt;bean class=&quot;org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor&quot;/&gt;
                &lt;bean class=&quot;org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor&quot;&gt;
                    &lt;property name=&quot;xsdSchemaCollection&quot; ref=&quot;schemaCollection&quot;/&gt;
                    &lt;property name=&quot;validateRequest&quot; value=&quot;true&quot;/&gt;
                    &lt;property name=&quot;validateResponse&quot; value=&quot;true&quot;/&gt;
                &lt;/bean&gt;
            &lt;/list&gt;
        &lt;/property&gt;
        &lt;property name=&quot;order&quot; value=&quot;1&quot;/&gt;
&lt;/bean&gt;</pre>
<p><a name="CompanyDirectoryEndpoint.java"><em>From CompanyDirectoryEndpoint.java</em></a></p>
<pre class="brush:java; collapse:false; wrap-lines:true;">
@Endpoint
public class CompanyDirectoryEndpoint implements CompanyDirectoryService {
@PayloadRoot(localPart = &quot;PersonRequest&quot;, namespace = &quot;http://persistent.com/schema&quot;)
	public PersonResponse getPerson(PersonRequest personRequest)
			throws DatatypeConfigurationException {
		Operation operation = personRequest.getOperation();
		PersonResponse personResponse = objectFactory.createPersonResponse();
		if( operation.equals(Operation.READ)) {
			long id = personRequest.getPersonCriteria().getId();
			Person person = companyDirectory.getPerson(id);
			personResponse.setPerson(SchemaConversionUtil.toSchemaType(person));
		} else 	if( operation.equals(Operation.DELETE)) {
			long theId = personRequest.getPersonCriteria().getId();
			Person person = companyDirectory.getPerson(personRequest.getPersonCriteria().getId());
			deletePerson(theId);
			personResponse.setPerson(SchemaConversionUtil.toSchemaType(person));
		} else if(operation.equals(Operation.CREATE)) {
			Person person = createPerson(personRequest.getPerson());
			personResponse.setPerson(SchemaConversionUtil.toSchemaType(person));
		}  else if(operation.equals(Operation.UPDATE)) {
			updatePerson(personRequest.getPerson());
		}
		return personResponse;
	}</pre>
<h5>EndpointAdapter</h5>
<p>The application uses the <em>GenericMarshallingMethodEndpointAdapter</em>.&nbsp; Given that the message is appropriate for the adapter the adapter transformes the message with the configured marshaller.&nbsp; In our application we are utilizing a Jaxb2Marshaller.&nbsp; Below is the configuration of the EndpointAdapter and its&#8217; marshaller.&nbsp;&nbsp; The Jaxb2Marshaller builds the approprate factories to map and build the schema objects from the incoming xml elements and types.</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
   &lt;bean id=&quot;companyDirectoryEndpoint&quot; class=&quot;com.persistent.ws.CompanyDirectoryEndpoint&quot;&gt;
	      &lt;description&gt;
            This endpoint handles the Company Directory Service messages using JAXB2 marshalling.
        &lt;/description&gt;
        &lt;property name=&quot;companyDirectory&quot; ref=&quot;companyDirectory&quot;/&gt;
	&lt;/bean&gt;
 	&lt;bean id=&quot;annotationMapping&quot;
          class=&quot;org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping&quot;&gt;
        &lt;description&gt;
            Detects @PayloadRoot annotations on @Endpoint bean methods. The CompanyDirectoryEndpoint
            has such annotations. It uses two interceptors: one that logs the message payload, and the other validates
            it according to the 'ComapnySearch.xsd' schema file.
        &lt;/description&gt;
        &lt;property name=&quot;interceptors&quot;&gt;
            &lt;list&gt;
                &lt;bean class=&quot;org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor&quot;/&gt;
                &lt;bean class=&quot;org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor&quot;&gt;
                    &lt;property name=&quot;xsdSchemaCollection&quot; ref=&quot;schemaCollection&quot;/&gt;
                    &lt;property name=&quot;validateRequest&quot; value=&quot;true&quot;/&gt;
                    &lt;property name=&quot;validateResponse&quot; value=&quot;true&quot;/&gt;
                &lt;/bean&gt;
            &lt;/list&gt;
        &lt;/property&gt;
        &lt;property name=&quot;order&quot; value=&quot;1&quot;/&gt;
    &lt;/bean&gt;</pre>
<h5>Endpoint</h5>
<p>The final destination is one of the CompanyDirectoryEndpoints methods or as annotated @PayloadRoot.&nbsp; The java docs PayloadRoot marks an endpoint method as the handler for an incoming request. The annotation values signify the the request  payload root element that is handled by the method.&nbsp; You can see the @PayloadRoot used in <a href="#CompanyDirectoryEndpoint.java">CompanyDirectoryEndpoint.java</a> above.</p>
<h2>WSDL Creation</h2>
<p>Although the Spring-WS philosophy is Contract-First we do still get some xml automation and this comes in a bean which creates are WSDL file.&nbsp; All we need to do is provide a few parameters: the xsd file(s),&nbsp; port name, location uri and its&#8217; target namespace.&nbsp; Here is the bean definition from spring-ws-servlet.xml:</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;bean id=&quot;companySearch&quot;
	class=&quot;org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition&quot;&gt;
	&lt;description&gt;
		Builds a WSDL from the schema/CompanySearch.xsd.
	&lt;/description&gt;

	&lt;property name=&quot;schemaCollection&quot; ref=&quot;schemaCollection&quot; /&gt;
	&lt;!-- wsdl:portType describes messages in an operation --&gt;
	&lt;property name=&quot;portTypeName&quot; value=&quot;companies&quot; /&gt;
	&lt;!-- we use a relative uri that will be transformed by spring-ws dep--&gt;
	&lt;property name=&quot;locationUri&quot; value=&quot;/companies/&quot; /&gt;
	&lt;property name=&quot;targetNamespace&quot; value=&quot;http://com.persistent/definitions&quot; /&gt;
&lt;/bean&gt;

&lt;bean id=&quot;schemaCollection&quot;
	class=&quot;org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection&quot;&gt;
	&lt;description&gt; This bean wrap the messages.xsd (which imports types.xsd), and inlines them as a one. &lt;/description&gt;
	&lt;property name=&quot;xsds&quot; value=&quot;/schema/CompanySearch.xsd&quot; /&gt;
	&lt;property name=&quot;inline&quot; value=&quot;true&quot; /&gt;
&lt;/bean&gt;</pre>
<p>The entire spring-ws-servlet.xml can be viewed below:</p>
<pre class="brush:xml; collapse:true; wrap-lines:true;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
	xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
	xmlns:jee=&quot;http://www.springframework.org/schema/jee&quot; xmlns:lang=&quot;http://www.springframework.org/schema/lang&quot;
	xmlns:util=&quot;http://www.springframework.org/schema/util&quot; xmlns:p=&quot;http://www.springframework.org/schema/p&quot;
	xmlns:sws=&quot;http://www.springframework.org/schema/web-services&quot;
	xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
       http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
       http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
       http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-1.5.xsd&quot;&gt;
	&lt;!-- START --&gt;

	&lt;bean id=&quot;companySearch&quot;
		class=&quot;org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition&quot;&gt;
		&lt;description&gt;
			Builds a WSDL from the schema/CompanySearch.xsd.
		&lt;/description&gt;

		&lt;property name=&quot;schemaCollection&quot; ref=&quot;schemaCollection&quot; /&gt;
		&lt;!-- wsdl:portType describes messages in an operation --&gt;
		&lt;property name=&quot;portTypeName&quot; value=&quot;companies&quot; /&gt;
		&lt;!-- we use a relative uri that will be transformed by spring-ws dep--&gt;
		&lt;property name=&quot;locationUri&quot; value=&quot;/companies/&quot; /&gt;
		&lt;property name=&quot;targetNamespace&quot; value=&quot;http://com.persistent/definitions&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;schemaCollection&quot;
		class=&quot;org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection&quot;&gt;
		&lt;description&gt; This bean wrap the messages.xsd (which imports
			types.xsd), and inlines them as a one. &lt;/description&gt;
		&lt;property name=&quot;xsds&quot; value=&quot;/schema/CompanySearch.xsd&quot; /&gt;
		&lt;property name=&quot;inline&quot; value=&quot;true&quot; /&gt;
	&lt;/bean&gt;

	&lt;bean id=&quot;companyDirectoryEndpoint&quot; class=&quot;com.persistent.ws.CompanyDirectoryEndpoint&quot;&gt;
	      &lt;description&gt;
            This endpoint handles the Company Directory Service messages using JAXB2 marshalling.
        &lt;/description&gt;
        &lt;property name=&quot;companyDirectory&quot; ref=&quot;companyDirectory&quot;/&gt;
	&lt;/bean&gt;
 	&lt;bean id=&quot;annotationMapping&quot;
          class=&quot;org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping&quot;&gt;
        &lt;description&gt;
            Detects @PayloadRoot annotations on @Endpoint bean methods. The CompanyDirectoryEndpoint
            has such annotations. It uses two interceptors: one that logs the message payload, and the other validates
            it according to the 'ComapnySearch.xsd' schema file.
        &lt;/description&gt;
        &lt;property name=&quot;interceptors&quot;&gt;
            &lt;list&gt;
                &lt;bean class=&quot;org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor&quot;/&gt;
                &lt;bean class=&quot;org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor&quot;&gt;
                    &lt;property name=&quot;xsdSchemaCollection&quot; ref=&quot;schemaCollection&quot;/&gt;
                    &lt;property name=&quot;validateRequest&quot; value=&quot;true&quot;/&gt;
                    &lt;property name=&quot;validateResponse&quot; value=&quot;true&quot;/&gt;
                &lt;/bean&gt;
            &lt;/list&gt;
        &lt;/property&gt;
        &lt;property name=&quot;order&quot; value=&quot;1&quot;/&gt;
    &lt;/bean&gt;

    	&lt;!--
		The GenericMarshallingMethodEndpointAdapter converts the incoming XML
		messages to marshalled objects used as parameters and return value;
		the PayloadRootAnnotationMethodEndpointMapping is the mapping that
		detects and handles the @PayloadRoot annotations.
		--&gt;
    &lt;bean
    	class=&quot;org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter&quot;&gt;
			&lt;constructor-arg ref=&quot;marshaller&quot; index=&quot;0&quot; /&gt;
		&lt;/bean&gt;
    &lt;bean id=&quot;marshaller&quot; class=&quot;org.springframework.oxm.jaxb.Jaxb2Marshaller&quot;&gt;
		&lt;property name=&quot;classesToBeBound&quot;&gt;
			&lt;list&gt;
				&lt;value&gt;com.persistent.schema.Company
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.CompaniesRequest
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.CompaniesResponse
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.CompanySearchCriteria
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.Person
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.PersonRequest
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.PersonResponse
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.PersonsResponse
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.PersonsRequest
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.PersonCriteria
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.PersonSearchCriteria
				&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.TableCountRequest&lt;/value&gt;
				&lt;value&gt;com.persistent.schema.TableCountResponse&lt;/value&gt;
			&lt;/list&gt;
		&lt;/property&gt;
		&lt;property name=&quot;schema&quot; value=&quot;/schema/CompanySearch.xsd&quot; /&gt;
	&lt;/bean&gt;
&lt;/beans&gt;</pre>
<h2>Notes on the Web Services Build</h2>
<p>In the build of the web application Sun&#8217;s XJC compiler builds the schema objects from the <strong>xsd</strong> file.&nbsp; You can see the generated files off of the target/generated-sources/xjc directory.&nbsp; These classes are utilized in the application as shown above in the snippet from CompanyDirectoryEndpoint.java where we are utilizing classes such as PersonRequest and PersonResponse which are both products of this generation process.&nbsp; The xjc compiler is configured in the build section of our pom.xml:</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;plugin&gt;
	&lt;groupId&gt;com.sun.tools.xjc.maven2&lt;/groupId&gt;
	&lt;artifactId&gt;maven-jaxb-plugin&lt;/artifactId&gt;	&lt;version&gt;1.1&lt;/version&gt;
	&lt;executions&gt;
		&lt;execution&gt;
			&lt;phase&gt;generate-sources&lt;/phase&gt;
			&lt;goals&gt;
				&lt;goal&gt;generate&lt;/goal&gt;
			&lt;/goals&gt;
		&lt;/execution&gt;
	&lt;/executions&gt;
	&lt;configuration&gt;&lt;generatePackage&gt;com.persistent.schema&lt;/generatePackage&gt;
		&lt;schemaDirectory&gt;src/main/webapp/schema&lt;/schemaDirectory&gt;
	&lt;/configuration&gt;
&lt;/plugin&gt;</pre>
<p>Additionally we have added a section to the POM file to create a client jar that can be added to the repository to be used as a dependency is a client to this webservice.</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;plugin&gt;
	&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
	&lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
	&lt;executions&gt;
		&lt;execution&gt;
			&lt;phase&gt;package&lt;/phase&gt;
			&lt;goals&gt;
				&lt;goal&gt;jar&lt;/goal&gt;
			&lt;/goals&gt;
			&lt;configuration&gt;
				&lt;description&gt;
	This plugin is being used to capture the information that will be used
 	in our client application.  Creating this jar will also create an associated
 	pom which will carry all its required dependencies so we will not need to deal
 	with in the client application.
				&lt;/description&gt;
 			&lt;classifier&gt;client&lt;/classifier&gt;
			&lt;classesDirectory&gt;target/general/WEB-INF/classes&lt;/classesDirectory&gt;
				&lt;includes&gt;
					&lt;include&gt;**/*.xsd&lt;/include&gt;
					&lt;include&gt;**/persistent/entity/*&lt;/include&gt;
					&lt;include&gt;**/persistent/datasource/*&lt;/include&gt;
					&lt;include&gt;**/persistent/service/*&lt;/include&gt;
				&lt;/includes&gt;
			&lt;/configuration&gt;
		&lt;/execution&gt;
	&lt;/executions&gt;
&lt;/plugin&gt;</pre>
<h3><a name="Soap_Stub">Installing SOAP Stubs for client</a></h3>
<p>The maven-jar-plugin will create a jar file called general-client.jar.&nbsp; I did see a way to automatically make it a first class repository item so I used the following script to install the jar file in the repository for easy access from a pom needing access to it.&nbsp; The <strong>installit.sh</strong> is located in the resource directory and is to be run from that location.&nbsp; Its contents are as follows:  mvn install:install-file -Dfile=../../../target/general-client.jar -DgroupId=com.persistent -DartifactId=general-client -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true</p>
<h2>Two Models</h2>
<p>There is a divergence from our REST implementation.&nbsp; There we marked-up the Entity object directly with JAXB annotations to make them available for serialization to our clients (albeit also transformed to JSON).&nbsp; To service the SOAP request we are using two models which we convert between.&nbsp; One model is assocated with the schema where the class are generated through the XJC compiler we just mentioned above.&nbsp; The other model the entity model which we have been working with.&nbsp; This decoupling of the schema and entity model can be viewed having both positive and negative attributes.&nbsp; There is a untility class that helps with the conversin between model called: <em>SchemaConversionUtil. </em>Its&#8217; use can be seen in the CompanyDirectoryEndpoint.java class.</p>
<h2>Running SoapUI against the SOAP Web Service</h2>
<ol>
<li>You will find how to get the SOAP server up and running from the <strong>Installation Instructions</strong> section below.&nbsp; To get the SoapUI client running we need to follow the following steps:</li>
<li>Down load and install the SoapUI application.&nbsp; There is a free version provided by EviWare located <a href="http://www.soapui.org/">here</a>.</li>
<li>Start the web application and start SoapUI</li>
<li>In the SoapUI interface select the menu item under <em>File</em> called <em>New soapUI Project. </em> Assign any project name you prefer and for the <em>Inital WSDL/WADL</em> enter: <em>http://localhost:8080/general/companies/companySearch.wsdl</em> as shown below:</li>
</ol>
<p style="margin-left: 40px;"><a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/NewSoapUIProject.png"><img width="450" height="203" alt="New SoapUI Project" src="http://persistentdesigns.com/wp/wp-content/uploads/NewSoapUIProject.png" /></a></p>
<ol>
<li>On selecting OK the SoapUI application read the WSDL at the the URI provided.&nbsp; With the information from the WSDL SoapUI will provide a tree menu of SOAP request that you can send.&nbsp; Below is a picture of using the TableCountRequest where we have set the table name to the Enumeration (as defined in the CompanySearch.wsdl) Person.&nbsp; On the right hand side we can see that the web service returned a value of 10.</li>
</ol>
<p style="margin-left: 40px;"><a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/TableCount.png"><img width="450" height="184" alt="SoapUI Table Count Sample" src="http://persistentdesigns.com/wp/wp-content/uploads/TableCount.png" /></a></p>
<p style="margin-left: 40px;">The other Soap requests of interest are:</p>
<pre class="brush:xml; collapse:false; wrap-lines:true;">
&lt;!-- Get all companies (the CompanyCriteria is not currently being utilized) --&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:sch=&quot;http://persistent.com/schema&quot;&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;sch:CompaniesRequest&gt;
      &lt;/sch:CompaniesRequest&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;

&lt;!-- This PersonsRequest will get all Persons that are of company id 1 (This would map to IBM). --&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:sch=&quot;http://persistent.com/schema&quot;&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;sch:PersonsRequest&gt;
         &lt;!--Optional:--&gt;
         &lt;sch:PersonSearchCriteria&gt;
            &lt;sch:companyId&gt;1&lt;/sch:companyId&gt;
         &lt;/sch:PersonSearchCriteria&gt;
      &lt;/sch:PersonsRequest&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;

&lt;!-- This PersonsRequest will get all Persons: note no criteria required --&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:sch=&quot;http://persistent.com/schema&quot;&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;sch:PersonsRequest&gt;
      &lt;/sch:PersonsRequest&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;

&lt;!-- This PersonRequest will CREATE a new user.  Note it is helpful look at the xsd while understanding these requests --&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:sch=&quot;http://persistent.com/schema&quot;&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;sch:PersonRequest&gt;
         &lt;sch:operation&gt;CREATE&lt;/sch:operation&gt;

         &lt;sch:person&gt;
            &lt;sch:id&gt;-1&lt;/sch:id&gt;
            &lt;sch:name&gt;New Name&lt;/sch:name&gt;
            &lt;sch:age&gt;12&lt;/sch:age&gt;
            &lt;sch:company&gt;
               &lt;sch:id&gt;1&lt;/sch:id&gt;
               &lt;sch:name&gt;IBM&lt;/sch:name&gt;
            &lt;/sch:company&gt;
         &lt;/sch:person&gt;
      &lt;/sch:PersonRequest&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;

&lt;!-- This PersonRequest will retrieve (READ) a Person by Person Id --&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:sch=&quot;http://persistent.com/schema&quot;&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;sch:PersonRequest&gt;
         &lt;sch:operation&gt;READ&lt;/sch:operation&gt;
         &lt;!--Optional:--&gt;
         &lt;sch:PersonCriteria&gt;
            &lt;sch:id&gt;10&lt;/sch:id&gt;
         &lt;/sch:PersonCriteria&gt;
      &lt;/sch:PersonRequest&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;

&lt;!-- The PersonRequest will UPDATE a Person.  It is the same as CREATE except that the person element's id is greater than 0 --&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:sch=&quot;http://persistent.com/schema&quot;&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;sch:PersonRequest&gt;
         &lt;sch:operation&gt;UPDATE&lt;/sch:operation&gt;

         &lt;sch:person&gt;
            &lt;sch:id&gt;11&lt;/sch:id&gt;
            &lt;sch:name&gt;New Name&lt;/sch:name&gt;
            &lt;sch:age&gt;14&lt;/sch:age&gt;
            &lt;sch:company&gt;
               &lt;sch:id&gt;1&lt;/sch:id&gt;
               &lt;sch:name&gt;IBM&lt;/sch:name&gt;
            &lt;/sch:company&gt;
         &lt;/sch:person&gt;
      &lt;/sch:PersonRequest&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;

&lt;!-- This PersonRequest will retrieve (DELETE) a Person by Person Id --&gt;
&lt;soapenv:Envelope xmlns:soapenv=&quot;http://schemas.xmlsoap.org/soap/envelope/&quot; xmlns:sch=&quot;http://persistent.com/schema&quot;&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;sch:PersonRequest&gt;
         &lt;sch:operation&gt;DELETE&lt;/sch:operation&gt;
         &lt;!--Optional:--&gt;
         &lt;sch:PersonCriteria&gt;
            &lt;sch:id&gt;11&lt;/sch:id&gt;
         &lt;/sch:PersonCriteria&gt;
      &lt;/sch:PersonRequest&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;</pre>
<p style="margin-left: 40px;">&nbsp;</p>
<h2>Class Diagram</h2>
<p>The class diagram builds out only a couple of classes from our previous project.&nbsp; It does however utilize the components available to it through programming to an interface and Springs IOC.  <a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/GeneralWSClassDiagram.png"><img width="450" height="414" alt="Class Diagram" src="http://persistentdesigns.com/wp/wp-content/uploads/GeneralWSClassDiagram.png" /></a></p>
<h2><a name="Build_Instructions">Installation Instructions</a></h2>
<ol>
<li>On down loading the source code which is in a jar filed called: general.jar uncompress it:</li>
</ol>
<p style="margin-left: 80px;"><em>jar xvf general.jar</em></p>
<p style="margin-left: 40px;">There will now be a new directory called <strong>general</strong>.</p>
<ol>
<li>Database configuration.&nbsp; In the directory <em>general/main/resources</em> the file general.properties contains the information regarding your database configuration including: user, password, Driver and database name.&nbsp; If you are using MySQL locally then all that needs to change would be the <strong>user</strong><strong>name</strong> and <strong>password</strong>.&nbsp; You will also either need to change the <strong>jdbc.url</strong> to a database you have already or create the database <strong>jpa</strong> used by the project.</li>
</ol>
<ol>
<li>Go back to the <strong>general</strong> directory where the <strong>pom.xml</strong> file is and you are ready to compile and run the program.&nbsp; Maven2 makes this simple.&nbsp; To compile and run (the <strong>clear</strong> command is in here too. It isn&rsquo;t important for the first build but is important as one begins development with the code).</li>
</ol>
<p style="margin-left: 80px;"><em>mvn clean install</em></p>
<p style="margin-left: 40px;">In this process the program will run through the JUnit test cases.&nbsp; If a test fails you will not be able to run the program until the defect is fixed.&nbsp; You can override the tests (and hope the program will run) by using a flag:</p>
<p style="margin-left: 80px;"><em>mvn clean install -Dmaven.test.skip=true</em></p>
<ol>
<li>Now we are ready to run the program. Enter:</li>
</ol>
<p style="margin-left: 80px;"><em>mvn jetty:run</em></p>
<p style="margin-left: 40px;">The jetty server will startup and you will then be able to interact with the application&rsquo;s REST webservice using cURL or the html webpage. To use the html webpage use this URL:</p>
<p style="margin-left: 80px;"><em>http://localhost:8080/general/</em></p>
<p style="margin-left: 40px;">Additionally you will be able to run the SoapUI against the SOAP web service.</p>
<ol type="1">
<li>As descirbed above, for clients to this SOAP service, add the general-client jar into the repository to be available as a dependency:</li>
</ol>
<p style="margin-left: 80px;">The <strong>installit.sh</strong> is located in the resource directory and is to be run from that location.&nbsp; Its contents are as follows:</p>
<p style="margin-left: 120px;">mvn install:install-file -Dfile=../../../target/general-client.jar -DgroupId=com.persistent -DartifactId=general-client -Dversion=1.0 -Dpackaging=jar -DgeneratePom=true</p>
<h4>Running Reports</h4>
<p style="margin-left: 40px;">There are three report plugins configured in the pom.xml.&nbsp; Sample output of these reporting engines can be viewed through the links in the <strong>Project Reports</strong> section of the article. The simple Maven command to create each of these reports are as follows:<strong> </strong></p>
<p style="margin-left: 80px;"><strong>PMD Report</strong></p>
<p style="margin-left: 120px;"><em>mvn pmd:pmd</em></p>
<p style="margin-left: 80px;"><strong>Cobertura Report</strong></p>
<p style="margin-left: 120px;"><em>mvn cobertura:cobertura</em></p>
<p style="margin-left: 80px;"><strong>Surefire Report</strong></p>
<p style="margin-left: 120px;"><em>surefire-report:report-only</em><strong> </strong></p>
<h4>Eclipse Integration</h4>
<p style="margin-left: 40px;">If you are interested in importing this project into your eclipse environment the following command will create the configuration files required to import the project into eclipse as an <em>existing eclipse project</em>.&nbsp; This command is run, as the others are, from the root directory <em>general</em>:</p>
<p style="margin-left: 80px;"><em>mvn eclipse:eclipse</em></p>
<p style="margin-left: 40px;">Also when the application is imported into the Eclipse environment insure that the generate code directory is included as a source directory to the project.&nbsp; This is done by opening the properties dialog of the imported project and selecting the <em>Java Build Path </em>and from the <em>Source</em> tab select <em>Add Folder</em> and add the general/target/generated-sources/xjc directory.</p>
<p style="margin-left: 80px;">&nbsp;</p>
<h2>Conclusion</h2>
<p>That concludes this article.&nbsp; We now have an application that makes available the Company Directory information through SOAP services.&nbsp; This is in a environment which will also service REST requests.&nbsp; In the next article we will supply the client portion to this SOAP service which will utilize XmlBeans and Spring MVC.</p>
<h2>The Source Code</h2>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/generalws.zip">The complete code listing is here.</a>  <span style="color: rgb(255, 0, 0);">Note there has been a refactoring on this code</span>.&nbsp; The refactoring pertains to the REST portion of the application but does effect the entity objects.&nbsp; For more information please see this article: <a href="http://persistentdesigns.com/wp/?p=423">Separation of Concerns: Refactoring of Evolving Project</a>  <a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/general_refactored.zip">Refactored Maven2 Project</a>.</p>
<h2>About The&nbsp;Author</h2>
<p style="margin-left: 40px;"><strong>David Sells</strong> is a computer consultant in Toronto, Ontario who specializing in Java Enterprise Development. He has&nbsp; provided innovative solutions for clients including: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p style="margin-left: 40px;">He also holds the following certifications:</p>
<ul>
<li>Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5 (2009)</li>
<li>Sun Certified Web Component Developer</li>
<li>Sun Certified Java Programmer.</li>
</ul>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Spring%20Spring-WS%20Application%5Bwith%20JPA%20and%20Jersey%20REST%5D'">david@persistentdesigns.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=346</wfw:commentRss>
		</item>
		<item>
		<title>A Groovy Rest Client for the JPA, Jersey, Spring Integration Project</title>
		<link>http://persistentdesigns.com/wp/?p=329</link>
		<comments>http://persistentdesigns.com/wp/?p=329#comments</comments>
		<pubDate>Sat, 12 Sep 2009 02:32:13 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=329</guid>
		<description><![CDATA[&#160;Introduction
<p>In this article we are presenting a simple Groovy client to use with our REST service created in the previous article: REST Project Digest and Generic Data Repository.&#160; In that last article we constructed a REST service that uses JPA/Hibernate in the backend to service a simple Company Directory.&#160; It is a two table one-to-many [...]]]></description>
			<content:encoded><![CDATA[<h2>&nbsp;Introduction</h2>
<p>In this article we are presenting a simple Groovy client to use with our REST service created in the previous article: <a href="http://persistentdesigns.com/wp/?p=292">REST Project Digest and Generic Data Repository</a>.&nbsp; In that last article we constructed a REST service that uses JPA/Hibernate in the backend to service a simple Company Directory.&nbsp; It is a two table one-to-many relationship between <em>Companies</em> and <em>Persons</em>.&nbsp; In that article the client was written with a combination of html and JavaScript, utilizing the services of Protocol.js.</p>
<p>We are using Groovy to render a REST client using Java Swing application.&nbsp; For communication we use <a href="http://hc.apache.org/httpclient-3.x/">HTTPClient</a> from Apache.&nbsp; We also use a <a href="http://json-lib.sourceforge.net/">JSON library</a> for encoding and decoding the transmitted data.&nbsp; Groovy is a wonderful utility for taking the drudgery out of using the Swing libraries.&nbsp; Although Swing is an excellent implementation the result/effort ratio is low.</p>
<p>&nbsp;</p>
<h2>Design</h2>
<p>This is a utility program without a great deal of function so the design is slim.&nbsp; The progarm is broken into three parts: entity, REST client and a Swing script.&nbsp; All the parts are written in Groovy.</p>
<h4>Entities</h4>
<p>There are two entities: Person and Client.&nbsp; They are simple pojos. Part of the Person class is shown below the Company class is similarly straight forward.</p>
<pre class="brush:groovy">
public class Person{
	private int id;
	private String name;
	private int age;
	private Company company;

	public Person() {
	}
	public Person(String name,int age, Company company){
		this.name = name
		this.age = age
		this.company = company
	}
	public Person(int id, String name,int age, Company company){
		this.id = id
		this.name = name
		this.age = age
		this.company = company
	}
	:
	:</pre>
<h4>The REST Client</h4>
<p>The rest client construction utlizes two tools: HTTPClient and a JSON library.&nbsp; The HTTPClient software provides an efficent api for our POST, PUT, GET and DELETE commands.&nbsp; The REST service we are using produces and consumes JSON objects, the JSON library helps us switch between JSON and beans in the application.</p>
<p>Below is the update method.&nbsp; We did have some difficulties using the JSON library to it&#8217;s full potential due to confusion between Numbers and Strings.&nbsp; The values from the REST service were surround, as Strings are, by quotations.&nbsp; This resulted in our POJOs being populated with the ASCII numeric of the number.&nbsp; In the snippet below we are using a brute force method to encode the JSON for transmission.</p>
<pre class="brush:groovy;">
public List putUpdate(Person person) {
		def url = &quot;http://localhost:8080/general/webresources/person/update&quot;
		def brute ='{&quot;id&quot;:&quot;'+person.id+'&quot;,&quot;name&quot;:&quot;'+person.name+'&quot;,&quot;age&quot;:&quot;'+person.age+'&quot;,&quot;company&quot;:{&quot;id&quot;:&quot;'+person.company.id+'&quot;,&quot;name&quot;:&quot;'+person.company.name+'&quot;}}'

		PutMethod put = new PutMethod(url);
		RequestEntity entity = new StringRequestEntity(brute, &quot;application/json&quot;, &quot;ISO-8859-1&quot;);

		put.setRequestEntity(entity);
		execute(put);
		return getDirectory();
	}
</pre>
<p>The full class is below if you would like to take a closer look.</p>
<pre class="brush:groovy;">
package com.persistent.client

import com.persistent.entity.Company
import com.persistent.entity.Person

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.methods.RequestEntity
import net.sf.json.groovy.JsonSlurper;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import groovy.text.SimpleTemplateEngine

/**
 * @author david
 *
 */

public class DirectoryClient{
	static String URL_BASE = &quot;http://localhost:8080/general/webresources&quot;
	def directories = [];

	public DirectoryClient() {

	}

	private void execute(HttpMethodBase method){
		HttpClient httpclient = new HttpClient();

		try {
			httpclient.executeMethod(method);
		} finally {
			// Release current connection to the connection pool once you are
			// done
			method.releaseConnection();
		}
	}

	public void deleteDelete(Integer id) {
		def url = URL_BASE+&quot;/persons/&quot;+id;
		DeleteMethod delete = new DeleteMethod(url);
		execute(delete);
	}

	public List putUpdate(Person person) {
		def url = URL_BASE+&quot;/person/update&quot;
		def brute ='{&quot;id&quot;:&quot;'+person.id+'&quot;,&quot;name&quot;:&quot;'+person.name+'&quot;,&quot;age&quot;:&quot;'+person.age+'&quot;,&quot;company&quot;:{&quot;id&quot;:&quot;'+person.company.id+'&quot;,&quot;name&quot;:&quot;'+person.company.name+'&quot;}}'

		PutMethod put = new PutMethod(url);
		RequestEntity entity = new StringRequestEntity(brute, &quot;application/json&quot;, &quot;ISO-8859-1&quot;);

		put.setRequestEntity(entity);
		execute(put);
		return getDirectory();
	}

	public List postAdd(Person person) {
		def url = URL_BASE+&quot;/person&quot;
			def brute ='{&quot;id&quot;:&quot;'+person.id+'&quot;,&quot;name&quot;:&quot;'+person.name+'&quot;,&quot;age&quot;:&quot;'+person.age+'&quot;,&quot;company&quot;:{&quot;id&quot;:&quot;'+person.company.id+'&quot;,&quot;name&quot;:&quot;'+person.company.name+'&quot;}}'
			PostMethod put = new PostMethod(url);
			RequestEntity entity = new StringRequestEntity(brute, &quot;application/json&quot;, &quot;ISO-8859-1&quot;);
			put.setRequestEntity(entity);
			execute(put);
			return getDirectory();
	}

	public List getCompanies() {
		def url = URL_BASE+&quot;/companies&quot;

		def get = new GetMethod(url)
		get.setRequestHeader(&quot;Accept&quot;, &quot;application/json&quot;)

		def client = new HttpClient()
		client.executeMethod(get)
		JSONObject jsonObject = JSONObject.fromObject( get.getResponseBodyAsString().toString() );
		JSONArray jsonArray = JSONArray.fromObject(jsonObject.get(&quot;company&quot;));
		return jsonArray;
	}

	public List getDirectory() {
		def url = URL_BASE+&quot;/persons&quot;
		def get = new GetMethod(url)
		get.setRequestHeader(&quot;Accept&quot;, &quot;application/json&quot;)

		def client = new HttpClient()
		client.executeMethod(get)
		JSONObject jsonObject = JSONObject.fromObject( get.getResponseBodyAsString().toString() );
		JSONArray personJSONArray = JSONArray.fromObject(jsonObject.get(&quot;person&quot;));

		def companies = getCompanies();
		def companiesNew = []

		for(Company c in companies) {
			def id = c.id;
		    def count = 0;
		    def personArray = [] 

			for(Person dude in personJSONArray) {
				if(id == dude.company.id) {
					// unfortunately the id for the JSON Company object is returned as a String such that 1 becomes 50 in ascii when converted to an integer
					// hence we re-construct the object correctly.
				    def person = new Person(id:dude.id.toInteger(),name:dude.name,age:dude.age.toInteger(),company:new Company(id:c.id.toInteger(),name:c.name));
					personArray.add(person);
				}
			}
		    companiesNew.add(new Company(id:c.id.toInteger(),name:c.name,employees:personArray))
		}

		return companiesNew;
	}
	public List getDirectories() {
		return directories;
	}
}
</pre>
<h4>Groovy Swing Client</h4>
<p>This is one place that Groovy really shines.&nbsp; It makes Swing a far more productive tool.&nbsp; In this example I have choosen a scripting style to produce the user interface.&nbsp; One could have also created a class but give the utility nature of the exersise I choose to use the less formal approach.&nbsp; Although Groovy does reduce the code required to produce your end result it does not relinquish you of the need to understand Swing framework.</p>
<pre class="brush:groovy;">
import java.awt.Dimension
import java.util.LinkedHashMap
import javax.swing.*
import javax.swing.tree.DefaultMutableTreeNode as TreeNode
import groovy.swing.SwingBuilder
import groovy.model.ValueHolder
import groovy.model.DefaultTableColumn
import groovy.model.DefaultTableModel
import groovy.model.PropertyModel
import javax.swing.event.TableModelListener
import javax.swing.event.ListSelectionListener
import java.awt.BorderLayout
import java.awt.FlowLayout;
import javax.swing.JComboBox

import com.persistent.client.DirectoryClient
import com.persistent.entity.Person
import com.persistent.entity.Company

def directoryClient = new DirectoryClient();

def directoryList = directoryClient.getDirectory()

def employeeList = [];
def employeeTable;
def swing = new SwingBuilder()
def nameTF;
def ageTF;
def combo;
JTree directoryTree
Company currentCompany;
Person selectedPerson;

def addButton;
def updateButton;
def deleteButton;
def clearButton;

def updateTree = {
		directoryTree.model.root.removeAllChildren()
		directoryList.each {company -&gt;
		    def node = new TreeNode(company)
		    company.employees.each { employee -&gt; node.add( new TreeNode(employee));}
		    directoryTree.model.root.add(node)
		}
		directoryTree.model.reload(directoryTree.model.root)
}

def selectEmployee2 = { person -&gt;
	if( person != null) {
		nameTF.text = person.name;
		ageTF.text = person.age;
		println &quot;Select id with: &quot;+person.company.id
		println &quot;Or name: &quot;+person.company.name

		println &quot;Is the index&quot;+directoryList.indexOf(person.company)
		// Too cool for school
		// The statement below find in the directoryList the company that the person is associated with and we
		// use that company to find the index in the list of that company.
		combo.selectedIndex = directoryList.indexOf(directoryList.find(){it.id==person.company.id})
		selectedPerson = person
		  deleteButton.visible = true;
 		  addButton.visible = false;
 		  updateButton.visible = true;
	}
};

def selectEmployee = { employeeId -&gt;
	selectEmployee2(currentCompany.employees.get(employeeId))
}

def setEmployeeTableModel = { company -&gt;
		employeeList = company.employees;
	    def listModel = new ValueHolder(employeeList)
	    def model = new DefaultTableModel(listModel)
	    model.addColumn(new DefaultTableColumn(&quot;Identifier&quot;, new PropertyModel(model.rowModel, &quot;id&quot;)))
	    model.addColumn(new DefaultTableColumn(&quot;Name&quot;, new PropertyModel(model.rowModel, &quot;name&quot;)))
	    model.addColumn(new DefaultTableColumn(&quot;Age&quot;, new PropertyModel(model.rowModel, &quot;age&quot;)))
	    swing.table1.setModel(model)
	    currentCompany = company;
}
def selectFirstInCompany = { company -&gt;
//Initialize the employee table and Employee section using first company in directory
//and the first employee in the companies employ.
setEmployeeTableModel(company);
selectEmployee2(company.employees.get(0))
}

swing.frame(title: 'CompanyDirectories', defaultCloseOperation: JFrame.DISPOSE_ON_CLOSE,
    size: [900, 350], show: true, locationRelativeTo: null) {
    lookAndFeel(&quot;system&quot;)
    menuBar() {
        menu(text: &quot;File&quot;, mnemonic: 'F') {
            menuItem(text: &quot;Exit&quot;, mnemonic: 'X', actionPerformed: {dispose() })
        }
    }
    splitPane {
        scrollPane(constraints: &quot;left&quot;, preferredSize: [160, -1]) {
            directoryTree = tree(rootVisible: false)
        }
        splitPane(orientation:JSplitPane.VERTICAL_SPLIT, dividerLocation:40) {
        	scrollPane(constraints: &quot;top&quot;) { textArea(id:'companyInfo') }
            scrollPane(constraints:&quot;bottom&quot;) {
            	panel {
            		borderLayout()

            		employeeTable = table(autoCreateColumnsFromModel:true,id:'table1',constraints:BorderLayout.NORTH) {
            			current.selectionModel.addListSelectionListener({e -&gt;
            				if(e.source.minSelectionIndex &gt;-1){
            					selectEmployee(e.source.minSelectionIndex);
            				}
            			} as ListSelectionListener)
            		tableModel(list:employeeList) {
            			propertyColumn(header:'Name', propertyName:'name')
            			propertyColumn(header:'Age',propertyName:'age')
            		}
            	}
            	panel(constraints:BorderLayout.CENTER){
            	}
            	panel(constraints:BorderLayout.SOUTH){
            				name = label()
            				name.text = &quot;Name:&quot;
            				nameTF = textField()
            				nameTF.columns = 15

            				age = label()
            				age.text = &quot;Age:&quot;
            				ageTF = textField()
            				ageTF.columns = 2

            				combo = comboBox(items:directoryList)

            			    updateButton = button(
            			            text:'Update',
            			            actionPerformed: {
            			    			selectedPerson.age = ageTF.text.toInteger()
            			    			selectedPerson.name = nameTF.text
            			    			selectedPerson.company = combo.model.getSelectedItem();
            			    			println &quot;The selected company is: &quot;+selectedPerson.company
            			    			println &quot;The id of the selected company is: &quot;+selectedPerson.company.id
            			    			println &quot;The name of the selected company is: &quot;+selectedPerson.company.name

            			    			directoryList = null;
            			                directoryList = directoryClient.putUpdate(selectedPerson);
            			                updateTree()
            			                selectFirstInCompany(directoryList.get(0))
            			            }
            			        )
            			     addButton = button(
            			            text:'Add',
            			            actionPerformed: {
            							selectedPerson = new Person(nameTF.text,ageTF.text.toInteger(),combo.model.getSelectedItem())
            			                directoryClient.postAdd(selectedPerson);
            			                directoryList = directoryClient.getDirectory();
            			                updateTree()
            			                selectFirstInCompany(directoryList.get(0))
            			            }
            			        )
            			     addButton.visible = false
            			     clearButton = button(
            			    		 text:'Clear',
            			    		 actionPerformed: {
							ageTF.text = '';
	            			    		 nameTF.text=''
							deleteButton.visible = false;
							addButton.visible = true;
							updateButton.visible = false;
            			    		 }
            			    	)
            			    deleteButton = button(
            			    		 text:'Delete',
            			    		 actionPerformed: {
            			    			 ageTF.text = '';
            			    			 nameTF.text=''
            			    			directoryClient.deleteDelete(selectedPerson.id);
             			                directoryList = directoryClient.getDirectory();
             			                updateTree()
             			                selectFirstInCompany(directoryList.get(0))

            			    		 }
            			    	)
            			}
            }
           }

        }
    }
}

directoryTree.valueChanged = {
	node = (TreeNode) directoryTree.getLastSelectedPathComponent();
	if (node != null) {
		if(node.getUserObject() instanceof Person) {
			Person aselectedPerson = (Person)node.getUserObject();
			// The parent node is the Company to whom the selected person belongs.
			parentNode = node.getParent();
			currentCompany = parentNode.getUserObject();
			selectEmployee2(aselectedPerson);
		    	if( aselectedPerson.company instanceof Company) {
				def theDirectory = directoryList.find{ it.id == aselectedPerson.company.id }
				if( theDirectory != null ) {
		    			setEmployeeTableModel(theDirectory)
				}
			} else {
				println &quot;UNEXPECTED: &quot;+parentNode.getClass().getName()
			}
		} else {
		    	// the node has a key and a value.  The key is this id of the company selected.  The value is the Company object.
		    	if( node.getUserObject() instanceof Company) {
		    		setEmployeeTableModel(node.getUserObject())

			}
		}
		swing.companyInfo.text = currentCompany.name;
	}
}

updateTree()
selectFirstInCompany(directoryList.get(0))
swing.companyInfo.text = currentCompany.name;
</pre>
<h4>A Picture of the User Interface in Action</h4>
<h2><a href="http://persistentdesigns.com/wp/wp-content/uploads/image/images/groovy.png" target="_blank"><img width="450" height="175" src="http://persistentdesigns.com/wp/wp-content/uploads/image/images/groovy.png" alt="" /></a></h2>
<h2>Source Code and Instructions</h2>
<p>Here is the source code in a jar file.  I suppose that my choice of file name is questionable but here it is: <a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/groovy.jar">groovy.jar</a>.</p>
<h4>Installation</h4>
<ol>
<li>Dowload the jar file</li>
<li>Extract the jar file with the command: <strong>jar xvf groovy.jar</strong></li>
<li>There will now be a directory called <strong>groovy.</strong> Navigate into groovy and execute: <strong>mvn install.&nbsp;&nbsp;</strong>This will pull in the required jar files and build the project.</li>
<li>Start the REST service of the previous article.</li>
<li>Start the Groovy REST client with this command: <strong>mvn exec:java</strong></li>
</ol>
<p>&nbsp;</p>
<h2>Conclusion</h2>
<p>&nbsp;That&#8217;s it!&nbsp; A simple user interface into a REST service utilizing Groovy.</p>
<p>&nbsp;</p>
<h2>About The&nbsp;Author</h2>
<p style="margin-left: 40px;"><b>David Sells</b> is a computer consultant in Toronto, Ontario specializing in Java Enterprise Development. His clients have included companies such as: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p style="margin-left: 40px;">Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5</p>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Jersey%2CSpring%20and%20JPA'">david@persistentdesigns.com</a></p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=329</wfw:commentRss>
		</item>
		<item>
		<title>REST Project Digest and Generic Data Repository</title>
		<link>http://persistentdesigns.com/wp/?p=292</link>
		<comments>http://persistentdesigns.com/wp/?p=292#comments</comments>
		<pubDate>Tue, 01 Sep 2009 23:17:57 +0000</pubDate>
		<dc:creator>zen</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://persistentdesigns.com/wp/?p=292</guid>
		<description><![CDATA[Introduction
<p>In this installment we will review the progression made through the previous REST-Jersey-JPA-Spring articles. We will also be extending our sample program in two ways.&#160; First we are going to service two tables with a one-to-many association.&#160; The enhancement will present a few new challenges and provide a stronger base for future developments.&#160; Second we [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>In this installment we will review the progression made through the previous REST-Jersey-JPA-Spring articles. We will also be extending our sample program in two ways.&nbsp; First we are going to service two tables with a one-to-many association.&nbsp; The enhancement will present a few new challenges and provide a stronger base for future developments.&nbsp; Second we are adding some design elements to our application which will increase the extensibility, manageability and scalability of the solution.</p>
<h2>Progression of the Project</h2>
<p><a target="_blank" href="http://persistentdesigns.com/wp/?p=75">Jersey,Spring and JPA</a></p>
<p>In this article we presented the integration of Jersey, Spring and JPA.&nbsp; An integration that was worth blogging to illuminate the conflict between jar versions blocking a quick efficient integration.&nbsp; The client code for this project was a simple webpage or through the user of cURL.</p>
<p><a target="_blank" href="http://persistentdesigns.com/wp/?p=228">REST CRUD: Jersey, Spring and JPA</a></p>
<p>Here we extended our original project to include the full CRUD (create, read, update and delete) functionality through REST.&nbsp; An enhanced web client was introduced to demonstrate the functionality.&nbsp; The Ajax interaction was provided through a modified Prototype.js library.</p>
<p><a target="_blank" href="http://persistentdesigns.com/wp/?p=230">Extending the CRUD Example Utilizing JAX-B and Jersey&#8217;s JSON</a></p>
<p>The previous article created json manually by constructing of a string.&nbsp; In this article we use JAX-B 2&#8217;s annotations to mark-up the entity to make these POJO&#8217;s available for serialization into XML and onto JSON.</p>
<p><a target="_blank" href="http://persistentdesigns.com/wp/?p=260">Quality Control: get rid of the CRUD and get REST</a></p>
<p>Here we added proper unit tests and reporting tools.&nbsp; Additionally we returned are modified Prototype.js library to it&#8217;s prestent state and instead added our own Ajax REST javascripts (albiet heavily based upon Prototype.js).</p>
<h2>&nbsp;</h2>
<h2>Sample Application</h2>
<p>To be more demostrative of the user of the technologies in the application another entity has been added to the model with a one-to-many association.&nbsp; In business terms a company(Company) can have many employees (Person).&nbsp; We will be able to interact with these entites through the <em>CompanyDirectoryRest </em>REST resource.</p>
<h2>Design Considerations</h2>
<p>Currently the project is a straight-up implementation to meet the needs of integrating the technologies of interests with a crude implementation of the core CRUD operations.&nbsp; Through design the components of the application can be considered with respect to its ability to respond well to service level requirements such as: extensibility, scalability and manageability.</p>
<p>Here are some loose requirements that the application must full fill:</p>
<ol>
<li>Provide a way to create services for a variety of clients</li>
<li>flexibility in the application design such that it may switch between protocols to the client such as: HTTP and SOAP.</li>
<li>abstract our data source such that we can alter where our data arise from: JPA, Hibernate, JDBC, a Webservice, EJB etc.</li>
</ol>
<h3>J2EE Patterns</h3>
<p>First off we leverage a lot of support in providing a <em>component</em><em>-oriented</em> application through the use of Spring&#8217;s dependency injection (DI).&nbsp; The first two requirements are satisfied through utilizing DI along with the J2EE Pattern <strong>Business </strong><strong>Object</strong>.&nbsp; In this design the REST resource, CompanyDirectory,&nbsp; is a consumer of the Business Object.&nbsp; The <strong>Business Object</strong> being the object that handles are the association of the datasources and higher level business function.&nbsp;&nbsp; The REST resource, <em>CompanyDirectoryRest,</em> is a simple GOF <strong>Adapter</strong>; it modifies the interface of the business object to serve its&#8217; client&#8217;s needs.&nbsp; This same strategy can be applied to extend the application to support other protocols.&nbsp; It can easily be imagined how one might create a SOAP Adapter to service SOAP Clients. Again the SOAP Adapter would consume the services of the Business Object and provide the SOAP functionaliy for communication of the information to the SOAP clients.&nbsp;</p>
<p>The third item in the requirements list is about data source abstraction.&nbsp; Again we are programming to an interface and utilizing DI.&nbsp; We are also programming with generics which provide a big boost to productivity and provide a point for <span goog-spell-original="extention" style="" class="goog-spellcheck-word">extension</span>.&nbsp; There is a very good article by the author of this portion of the code at the <a target="_blank" href="http://www.bejug.org/confluenceBeJUG/display/BeJUG/Generic+DAO+example">Belgium Jugs website</a>. So we have the oportunity here to support other database through the GenericRepository and through newly introduced datasource interfaces we can consider adding alternate datasource such as: EJB&#8217;s, webservices, DAO and so on.</p>
<p>Programming to an interface along with DI creates the ability to make configuration changes simple and in turn addressing those interests in: extensibility, scalability and manageability.</p>
<p>&nbsp;</p>
<p>&nbsp;<em>diagram </em>Class Diagram of the REST Project</p>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/REST_CLASS_DIAGRAM.png" target="_blank"><img width="450" height="334" src="http://persistentdesigns.com/wp/wp-content/uploads/file/files/REST_CLASS_DIAGRAM.png" alt="Class Diagram of new project" /></a></p>
<p>&nbsp;</p>
<h2>Implementation</h2>
<p>For more details on the implementation please see the other articles identified at the top of the document.&nbsp; In this section we will discuss details which arose in this implementation that differed from the previous projects.</p>
<h3>JAXB and Generic Collections</h3>
<p>We introduced the Company entity that maintains a collection of employees (Person).&nbsp; The class is marked-up this class with JAXB Annotations as the Person class was.&nbsp; There is a difficulty with using Generics with JaxB which needs to be delt with.&nbsp; The problem arises from the fact that the class types declared in a Generic collection is available only at compile time and is erased at runtime (type erasure).&nbsp; So when we JAXB utilizes an accessor to a generic collection such as:</p>
<pre class="brush: java;">
@OneToMany(mappedBy = &quot;company&quot;, fetch = FetchType.EAGER)
private List&lt;Person&gt; employees = new ArrayList&lt;Person&gt;();
</pre>
<p>or</p>
<pre class="brush: java;">
	public List&lt;Person&gt; getEmployees() {
		return employees;
	}
</pre>
<p>at runtime the information with respect to the type Person is no longer available.&nbsp; So as JAXB attempts to serialize the collection it throws an exception because it can not determine the class type of collection. This will occur whether the class is annotated for access through fields or members.&nbsp; I don&#8217;t know of a way of doing this borth adirect and clean way.&nbsp; The solution employed in this sample is through the use of the <em>GenericEntity</em> class.&nbsp; This class is part of javax.ws.rs.core and is used precisely for this purpose.&nbsp; We have altered the getEmployees() method in <em>Company </em>to the following plus we have annotated the class with XmlAccessType set to PUBLIC_MEMBER so that when the class is transformed by JAXB it will use the method rather than the field.</p>
<pre class="brush: java;">
public GenericEntity&lt;List&lt;Person&gt;&gt; getEmployees() {
	return new GenericEntity&lt;List&lt;Person&gt;&gt;(employees) {};
}</pre>
<p>The solution is a little unattractive since it alters are natural use of the entity class and bleeds the jax.ws.rs api into the model which now makes it coupled.</p>
<p>&nbsp;</p>
<h2>GenericRepository (DAO)</h2>
<p>As mentioned earlier the DAO or repository for our project is using Generics heavily.&nbsp; Our implementation is from this <a target="_blank" href="http://www.bejug.org/confluenceBeJUG/display/BeJUG/Generic+DAO+example">Belgium Jugs website</a> the efforts of Jurgen Lush and Stephan Janssen.&nbsp; The generics remove the code replication that appears among implementation of DAOs.&nbsp; Coding to the GenericRepository inteface we open the possabilites to many persitent providers.&nbsp; In the sample a JPA provider GenericJpaRepository is coded.&nbsp; The generics can make DAO&nbsp;as simple as implement the following class and interface:</p>
<pre class="brush: java;">
@Service(&quot;personDS&quot;)
public class PersonJpaRepository extends GenericJpaRepository&lt;Person, Long&gt;
		implements PersonDS {
	//we inherit the basic CRUD operations from the GenericRepository
}</pre>
<p>&nbsp;And</p>
<pre class="brush: java;">
public interface PersonRepository extends GenericRepository&lt;Person, Long&gt; {
}
</pre>
<p>That is a very brief way to construct a DAO.&nbsp; Note that wehave the PersonJpaRepository implementing the PersonDS (Person Data Source).&nbsp; This interface gives us the ability to consider options such as EJB&#8217;s or Webservices as datasources whcih fall outside the perview of the DAO.</p>
<p>Additionally we have moved the transactional management of the methods out of the class and are apply them through annotation defined in the applicationContext.xml.&nbsp; The settings are shown below:</p>
<pre class="brush: xml;">
&lt;tx:advice id=&quot;transactionAdvice&quot; transaction-manager=&quot;transactionManager&quot;&gt;
	 &lt;!-- the transactional semantics... --&gt;
	&lt;tx:attributes&gt;
		&lt;tx:method name=&quot;find*&quot; read-only=&quot;true&quot;/&gt;
		&lt;tx:method name=&quot;get*&quot; read-only=&quot;true&quot;/&gt;
		&lt;tx:method name=&quot;count*&quot; read-only=&quot;true&quot;/&gt;
		&lt;tx:method name=&quot;save*&quot; read-only=&quot;false&quot; propagation=&quot;REQUIRED&quot; /&gt;
		&lt;tx:method name=&quot;update*&quot; read-only=&quot;false&quot; propagation=&quot;REQUIRED&quot; /&gt;
		&lt;tx:method name=&quot;delete*&quot; read-only=&quot;false&quot; propagation=&quot;REQUIRED&quot; /&gt;
	&lt;/tx:attributes&gt;
&lt;/tx:advice&gt;
&lt;!--
	ensure that the above transactional advice runs for any execution of
	an interfaces in the com.persistent.repository package
--&gt;
&lt;aop:config&gt;
	&lt;aop:pointcut id=&quot;repositoryMethods&quot;
		expression=&quot;execution(* com.persistent.repository.util.*.*(..))&quot; /&gt;
	&lt;aop:advisor advice-ref=&quot;transactionAdvice&quot; pointcut-ref=&quot;repositoryMethods&quot; /&gt;
&lt;/aop:config&gt;
</pre>
<h3>REST Web Client</h3>
<p>The web client from the previous projects has been extended to include the Company information as shown below.</p>
<p>&nbsp;<a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/RESTClient.png"><img width="450" height="338" alt="" src="http://persistentdesigns.com/wp/wp-content/uploads/image/images/RESTClient.png" /></a></p>
<h3>Performance Improvement</h3>
<p>We do have a great inefficiency here with our one-to-many relationship.&nbsp; We have annotated the relationship as having an eager fetch mode.&nbsp; This does provide some conveniences for coding but we pay for them through a big performance hit.&nbsp; For instance when the web page above loads it requests a list of companies and when it is retrieves that list in an eager fetch all the associated employees are also retrieved.&nbsp; When you have all that information then sent to the web page in JSON format, well its just not a good idea.&nbsp; Changing our&nbsp; fetch mode is a simple change.&nbsp; Our new employee accessor is annotated LAZY:</p>
<pre class="brush: java;">
@OneToMany(mappedBy = &quot;company&quot;, fetch = FetchType.LAZY)
private List&lt;Person&gt; employees = new ArrayList&lt;Person&gt;();
</pre>
<p>Additionally since the data is loaded lazily we will need a query for loading the Company object eagerly.  For this we have added a <em>NamedQuery</em> annotation at the the top of the Company class.  We have also expanded the <em>CompanyDS</em> to include a method to access data through named queries.&nbsp; There are other options we could explore that would not expose the method as a JPA/ORM/SQL query which would fascilitate a better interface for non-JPA/ORM/SQL interfaces, such as adding a method to the <em>CompanyJpaRepository</em> class but for now we&#8217;ll take the short cut.</p>
<p>A left join of the Company and a Fetch over the employees does the trick.&nbsp; The query is name <em>Company.EagerFindById </em>for ease of entity association and purpse.</p>
<pre class="brush: java;">
@Table(name = &quot;COMPANY&quot;)
@NamedQueries( { @NamedQuery(name = &quot;Company.EagerFindByID&quot;, query = &quot;FROM Company c left join fetch c.employees where c.id =?1&quot;) })
public class Company {
</pre>
<p>&nbsp;Here is the expanded CompanyDS interface:</p>
<pre class="brush: java;">
public interface CompanyDS {
	public List&lt;Company&gt; findAll();
	public Company findById(final Long id);
	public Company save(final Company person);
	public Company update(final Company person);
	public Integer countAll();
	public void delete(final Company person);
	public List&lt;Company&gt; findByNamedQuery(final String name,final Object... params);
}
</pre>
<p>&nbsp;This is the new query in action.</p>
<pre class="brush: java;">
List&lt;Company&gt; companies = companyDS.findByNamedQuery(&quot;Company.EagerFindByID&quot;, companyId);
Company persistedCompany = null;
if(companies.size()&gt;0) {
	persistedCompany= companies.get(0);
}
</pre>
<h3>Conclusion</h3>
<p>In conclusion we accomplished a few items to improve our ever evolving project they include:</p>
<ul>
<li>re-structued the code for extensibility, manageablity and scalability.</li>
<li>introduced a one-to-many relationship and made adjust must to the entity to accommodate for <em>type erasure</em> with respect to JAXB.</li>
<li>added a generic DAO that dramatically reduces the coding required to support a entity</li>
<li>switched the application to use AOP for transaction management</li>
</ul>
<h4>&nbsp;Project Reports</h4>
<ul>
<li><a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/general/site/pmd.html">PMD Report</a></li>
<li><a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/general/site/cobertura/index.html">Cobertura Test Coverage Report</a></li>
<li><a target="_blank" href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/general/site/surefire-report.html">Surefire Report</a></li>
</ul>
<h2>The Source Code</h2>
<p><a href="http://persistentdesigns.com/wp/wp-content/uploads/file/files/general.jar">The complete code listing is here.</a></p>
<h4>Installation Instructions</h4>
<ol>
<li>On down loading the source code which is in a jar filed called: general.jar uncompress it:</li>
</ol>
<p style="margin-left: 80px;"><em>jar xvf general.jar</em></p>
<p style="margin-left: 40px;">There will now be a new directory called <strong>general</strong>.</p>
<ol start="2">
<li>Database configuration.&nbsp; In the directory <em>general/main/resources</em> the file general.properties contains the information regarding your database configuration including: user, password, Driver and database name.&nbsp; If you are using MySQL locally then all that needs to change would be the <strong>user</strong><strong>name</strong> and <strong>password</strong>.&nbsp; You will also either need to change the <strong>jdbc.url</strong> to a database you have already or create the database <strong>jpa</strong> used by the project.</li>
</ol>
<ol start="3">
<li>Go back to the <strong>general</strong> directory where the <strong>pom.xml</strong> file is and you are ready to compile and run the program.&nbsp; Maven2 makes this simple.&nbsp; To compile and run (the <strong>clear</strong> command is in here too. It isn&#8217;t important for the first build but is important as one begins development with the code).</li>
</ol>
<p style="margin-left: 80px;"><em>mvn clean install</em></p>
<p style="margin-left: 40px;">In this process the program will run through the JUnit test cases.&nbsp; If a test fails you will not be able to run the program until the defect is fixed.&nbsp; You can override the tests (and hope the program will run) by using a flag:</p>
<p style="margin-left: 80px;"><em>mvn clean install -Dmaven.test.skip=true</em></p>
<ol start="4">
<li>Now we are ready to run the program. Enter:</li>
</ol>
<p style="margin-left: 80px;"><em>mvn jetty:run</em></p>
<p style="margin-left: 40px;">The jetty server will startup and you will then be able to interact with the application&#8217;s REST webservice using cURL or the html webpage. To use the html webpage use this URL:</p>
<p style="margin-left: 80px;"><em>http://localhost:8080/general/</em></p>
<h4>Running Reports</h4>
<p style="margin-left: 40px;">There are three report plugins configured in the pom.xml.&nbsp; Sample output of these reporting engines can be viewed through the links in the <strong>Project Reports</strong> section of the article. The simple Maven command to create each of these reports are as follows:<strong><br />
</strong></p>
<p style="margin-left: 80px;"><strong>PMD Report</strong></p>
<p style="margin-left: 120px;"><em>mvn pmd:pmd</em></p>
<p style="margin-left: 80px;"><strong>Cobertura Report</strong></p>
<p style="margin-left: 120px;"><em>mvn cobertura:cobertura</em></p>
<p style="margin-left: 80px;"><strong>Surefire Report</strong></p>
<p style="margin-left: 120px;"><em>surefire-report:report-only</em><strong><br />
</strong></p>
<h4>Eclipse Integration</h4>
<p style="margin-left: 40px;">If you are interested in importing this project into your eclipse environment the following command will create the configuration files required to import the project into eclipse as an <em>existing eclipse project</em>.&nbsp; This command is run, as the others are, from the root directory <em>general</em>:</p>
<p style="margin-left: 80px;"><em>mvn eclipse:eclipse</em></p>
<p style="margin-left: 40px;">&nbsp;</p>
<h2>About The&nbsp;Author</h2>
<p style="margin-left: 40px;"><b>David Sells</b> is a computer consultant in Toronto, Ontario specializing in Java Enterprise Development. His clients have included companies such as: IBM, Goldman Sachs, Merrill Lynch and Deutsche Bank.</p>
<p style="margin-left: 40px;">Sun Certified Enterprise Architect for the Java Platform, Enterprise Edition 5</p>
<p style="margin-left: 40px;"><strong>Contact:</strong> <a href="javascript:location.href='mailto:'+String.fromCharCode(100,97,118,105,100,64,112,101,114,115,105,115,116,101,110,116,100,101,115,105,103,110,115,46,99,111,109)+'?subject=Re%3A%20Jersey%2CSpring%20and%20JPA'">david@persistentdesigns.com</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://persistentdesigns.com/wp/?feed=rss2&amp;p=292</wfw:commentRss>
		</item>
	</channel>
</rss>
