<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Thought Forge</title>
	<atom:link href="http://thoughtforge.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://thoughtforge.net</link>
	<description></description>
	<lastBuildDate>Mon, 01 Mar 2010 19:27:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>jBPM Developer Guide</title>
		<link>http://thoughtforge.net/2010/03/01/jbpm-developer-guide/</link>
		<comments>http://thoughtforge.net/2010/03/01/jbpm-developer-guide/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 19:26:23 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Book Review]]></category>
		<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[jBPM]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=697</guid>
		<description><![CDATA[Business Process Management (BPM) has been around in one guise or another for quite a while now and most people have had some exposure to its many facets.   With so much promised, it is easy to see why it has generated so much interest.
jBPM is an open source BPM framework from JBoss that has [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.co.uk/JBPM-Developer-Guide-Mauricio-Salatino/dp/1847195687%3FSubscriptionId%3DAKIAIEF6UQB4LZ3JULBQ%26tag%3Dthouforg-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1847195687"><img class="alignright" src="http://ecx.images-amazon.com/images/I/5164H5ij-RL._SL160_.jpg" alt="" width="130" height="160" /></a>Business Process Management (BPM) has been around in one guise or another for quite a while now and most people have had some exposure to its many facets.   With so much promised, it is easy to see why it has generated so much interest.</p>
<p>jBPM is an open source BPM framework from JBoss that has matured into a real alternative to the many other BPM offerings.   The &#8216;jBPM Developer Guide&#8217; introduces to its readers the main artifacts of BPM and what is involved in implementing typical jBPM solution.</p>
<p>The book begins by providing a background to BPM and how it can be leveraged to deliver benefit to the business.   This includes an introduction to processes, tasks and process management (Business Process Management or BAM).   As any good book should, terminologies that are associated with BPM are introduced and defined.   Thankfully, the definitions are void of the usual marketing hype.</p>
<p>With the help of an example, graph orientated programming (GOP) is then introduced and its relevance to jBPM discussed.   Specifically the Node, Transition and Process Definition concepts are covered before the author works through sample implementations of each.   Wait states (asynchronous system interactions and human tasks) and automatic nodes are compared before process execution is demonstrated through a sample process execution engine implementation.</p>
<p>The book goes on to give some background to the jBPM project and covers the setup of tools to be used throughout the remainder of the book (Maven, MySql, Eclipse etc.).  It outlines how to install jBPM from a distribution and from source.  I used the installer to install the version used for the examples (3.2.6.SP1).</p>
<p>Two example process projects are then created using the eclipse designer plugin and then the maven plugin to contrast both approaches.   Use of the &#8216;Graphical Process Editor&#8217; is also demonstrated.</p>
<p>The jPDL language is then explored in greater depth describing in detail the XML\Class definitions of the process, the various node types (Node, Start State, End State, State, Decision), transitions and the execution token.  As an example (recruitment) process is automated with the jBPM framework.   This is achieved iteratively adding more detail in each stage.</p>
<p>Process instance persistence is discussed in depth.   This includes details on how and when process definition amd process instance persistence occurs.   A brief review is given of the jBPM API to interact with the database and the jBPM\Hibernate persistence configuration.</p>
<p>Human Task&#8217;s are explained including details on input data, task action and output data.   The distinction between a TaskNode and Task is also made.  A brief introduction to the jBPM Identity module is provided during a discussion about task assignment before demonstrating an example process.</p>
<p>The transactional behaviour of jBPM is then discussed along with a more detailed discussion on variable mappings and task assignment.  Process variables and the type&#8217;s of information stored in process variables are explained and the specific API for variable manipulation is covered in brief, along with the variable persistence and hierarchy.  These concepts are demonstrated with a concrete example.</p>
<p>More advanced node types are covered in this chapter including Fork and Join nodes, Super state nodes, Process state nodes and the Email node.  Variable mapping strategies as discussed in depth and related to the Process State node.</p>
<p>Further examples of using Super state nodes and Process state nodes are covered in addition to asynchronous execution and the JobExecutor.   The examples focused on the asynchronous execution are thorough and provide a good understanding of this process.</p>
<p>The book finished by discussing the use of jBPM within a JEE environment.   In particular, JTA, Data Source&#8217;s, the CommandServiceBean, the JobExecutor and JMS and finally Timers and reminders.</p>
<p>My overall impression of the book was that it relayed the key information required to get up and running with jBPM.  The author was clearly knowledgeable in the subject and provided useful examples to complement the concept&#8217;s being discussed.  I liked the fact that the author gives details on installing the developer tools as it allows the reader to follow along with the examples.</p>
<p>The only negative comment I can make was that I found the poor construction of sentences and awkward use of English a little distracting.  It reads as a book that was translated into  English from another language.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/03/01/jbpm-developer-guide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Logging Aspect with Spring AOP and AspectJ</title>
		<link>http://thoughtforge.net/2010/02/16/creating-a-logging-aspect-with-spring-aop-and-aspectj/</link>
		<comments>http://thoughtforge.net/2010/02/16/creating-a-logging-aspect-with-spring-aop-and-aspectj/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 22:56:17 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Spring AOP]]></category>
		<category><![CDATA[Spring Framework]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=665</guid>
		<description><![CDATA[After working in software development for a number of years, one tends  to build up a repository of useful code examples and utilities.  I&#8217;m  certainly no different in this regard and go one step further by  maintaining a hosted Subversion repository to keep such code examples safe and sound (and readily accessible).
One [...]]]></description>
			<content:encoded><![CDATA[<p>After working in software development for a number of years, one tends  to build up a repository of useful code examples and utilities.  I&#8217;m  certainly no different in this regard and go one step further by  maintaining a <a id="t2cy" title="hosted" href="http://wush.net/" target="_blank">hosted</a> <a id="ei2i" title="Subversion" href="http://subversion.tigris.org/" target="_blank">Subversion</a> repository to keep such code examples safe and sound (and readily accessible).</p>
<p>One such code example that I often turn to is a  logging aspect implemented using <a id="mk0m" title="Spring" href="http://www.springsource.org/" target="_blank">Spring</a> AOP and <a id="ol95" title="AspectJ" href="http://www.eclipse.org/aspectj/" target="_blank">AspectJ</a>.   This logging aspect traces method entry and exit which proves very  useful if you need to perform root cause analysis in pre-production environments.</p>
<p>In what follows, I&#8217;m going to share this code  example.  I have also made the <a href="http://thoughtforge.net/wp-content/uploads/2010/02/spring-tracing-aspect.zip" target="_blank">logging aspect source code</a> available for download.</p>
<p>I have assumed you have a reasonable grasp of  Aspect Orientated Programming concepts and terminologies.<br />
<span id="more-665"></span><br />
<strong>The  Logger</strong></p>
<p>There are a few options to choose from when  considering a logging framework and these have evolved over the years so  it is probably best to abstract the logging framework from the aspect.   For this purpose, I have implemented a simple logging interface and log level enum.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.logger;

public interface Logger {

&nbsp;&nbsp;&nbsp;&nbsp;boolean isLogLevel(LogLevel logLevel, Class&lt;?&gt; clazz);

&nbsp;&nbsp;&nbsp;&nbsp;void log(LogLevel logLevel, Class&lt;?&gt; clazz, Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String pattern, Object... arguments);
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 1 : Logger.java</p>
</div>
<p><br/></p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.logger;

public enum LogLevel {
&nbsp;&nbsp;DEBUG,
&nbsp;&nbsp;ERROR,
&nbsp;&nbsp;FATAL,
&nbsp;&nbsp;INFO,
&nbsp;&nbsp;TRACE,
&nbsp;&nbsp;WARN
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 2 : LogLevel.java</p>
</div>
<p><br/></p>
<p>In  the majority of cases, I end up using the <a id="z1n2" title="Commons  Logging" href="http://commons.apache.org/logging/" target="_blank">Commons Logging</a> framework and so have included this  implementation of the Logger in the source download.</p>
<p>You  may decide that this level of abstraction is overkill and that you are  willing to commit to using a specific logging framework.  When making  this decision, keep in mind that you will be specifying the log level  throughout your code base.</p>
<p><strong>The Logging Aspect</strong></p>
<p>I am  going to use the @Aspect approach to implement the logging aspect which  is to say I will use annotations to specify the advice.  I want the  logging aspect to log the method name, argument values, return value and  any exception thrown so I will use the @Before, @AfterThrowing and  @AfterReturning annotations.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&nbsp;&nbsp;@Before(value = &quot;@annotation(trace)&quot;, argNames = &quot;joinPoint, trace&quot;)
&nbsp;&nbsp;public void before(JoinPoint joinPoint, Loggable loggable) {

&nbsp;&nbsp;&nbsp;&nbsp;Class&lt;? extends Object&gt; clazz = joinPoint.getTarget().getClass();
&nbsp;&nbsp;&nbsp;&nbsp;String name = joinPoint.getSignature().getName();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if (ArrayUtils.isEmpty(joinPoint.getArgs())) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.log(loggable.value(), clazz, null, BEFORE_STRING, name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constructArgumentsString(clazz, joinPoint.getArgs()));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.log(loggable.value(), clazz, null, BEFORE_WITH_PARAMS_STRING, name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constructArgumentsString(clazz, joinPoint.getArgs()));&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 3 : @Before Code Snippet</p>
</div>
<p><br/></p>
<p>The  &#8216;Before&#8217; advice simply logs (at the appropriate log level) the method  name and the toString value of all arguments (if any).  &#8216;Before&#8217; advice  executes when a join point is reached.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&nbsp;&nbsp;@AfterThrowing(value = &quot;@annotation(net.thoughtforge.aspect.Loggable)&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throwing = &quot;throwable&quot;, argNames = &quot;joinPoint, throwable&quot;)
&nbsp;&nbsp;public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {

&nbsp;&nbsp;&nbsp;&nbsp;Class&lt;? extends Object&gt; clazz = joinPoint.getTarget().getClass();
&nbsp;&nbsp;&nbsp;&nbsp;String name = joinPoint.getSignature().getName();
&nbsp;&nbsp;&nbsp;&nbsp;logger.log(LogLevel.ERROR, clazz, throwable, AFTER_THROWING, name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throwable.getMessage(), constructArgumentsString(clazz,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;joinPoint.getArgs()));
&nbsp;&nbsp;}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 4 : @AfterThrowing Code Snippet</p>
</div>
<p><br/></p>
<p>The &#8216;AfterThrowing&#8217; advice logs the method name,  exception message and the toString value of all arguments (if any).   &#8216;AfterThrowing&#8217; advice executes after a method exits by throwing an  exception.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&nbsp;&nbsp;@AfterReturning(value = &quot;@annotation(trace)&quot;, returning = &quot;returnValue&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argNames = &quot;joinPoint, trace, returnValue&quot;)
&nbsp;&nbsp;public void afterReturning(JoinPoint joinPoint, Loggable loggable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Object returnValue) {

&nbsp;&nbsp;&nbsp;&nbsp;Class&lt;? extends Object&gt; clazz = joinPoint.getTarget().getClass();
&nbsp;&nbsp;&nbsp;&nbsp;String name = joinPoint.getSignature().getName();

&nbsp;&nbsp;&nbsp;&nbsp;if (joinPoint.getSignature() instanceof MethodSignature) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MethodSignature signature = (MethodSignature) joinPoint
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getSignature();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Class&lt;?&gt; returnType = signature.getReturnType();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (returnType.getName().compareTo(&quot;void&quot;) == 0) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger.log(loggable.value(), clazz, null, AFTER_RETURNING_VOID,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name, constructArgumentsString(clazz, returnValue));

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;logger.log(loggable.value(), clazz, null, AFTER_RETURNING, name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constructArgumentsString(clazz, returnValue));
&nbsp;&nbsp;}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 5 : @AfterReturning Code Snippet</p>
</div>
<p><br/></p>
<p>The  &#8216;AfterReturning&#8217; advice logs the method name and the toString value of  the returned value (if any).  &#8216;AfterReturning&#8217; advice executes after a  method exits normally.</p>
<p>You will notice that I log the toString  value to identify objects.  I routinely use the Apache Commons  ToStringBuilder to create the toString value.   I find this particularly  useful when working with persistent entities as it allows me to clearly  identify the entity.</p>
<p>Another possible implementation that avoids using the toString method is to use the Apache Commons ReflectionToStringBuilder within the logging aspect to create a string representation of the object being logged.</p>
<p>If you are writing your own toString  implementations (the Commons implementation is perfectly adequate) and  are implementing an object with complex properties be aware of recursive  invocations that may result in a stack overflow exception.</p>
<p><strong>Specifying  the Pointcut</strong></p>
<p>A pointcut expression is an expression that  specifies where in the code the advice will be applied.  With AspectJ,  you can create a pointcut by specifying package, class and method  attributes among other things.  I find the easiest way to specify a  pointcut for the logging aspect is by matching methods that have a  specific annotation.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.aspect;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import net.thoughtforge.logger.LogLevel;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Loggable {

&nbsp;&nbsp;&nbsp;&nbsp;LogLevel value();
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 6 : Loggable.java</p>
</div>
<p><br/></p>
<p>As you can see,  the Loggable annotation has one property that specifies the log level at  which the log statement should be output.  Using the annotation means  that developers never need to alter the pointcut expression to add or  remove methods to the pointcut.  A developer only has to add the annotation to a method to have the logging aspect applied.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.bean;

import java.util.Date;

import net.thoughtforge.aspect.Loggable;
import net.thoughtforge.logger.LogLevel;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.stereotype.Component;

@Component(value = &quot;simpleBean&quot;)
public class SimpleBean {

&nbsp;&nbsp;private Date dateProperty;

&nbsp;&nbsp;private Integer integerProperty;

&nbsp;&nbsp;private String stringProperty;

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public Date getDateProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;return dateProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public void setDateProperty(final Date dateProperty) {
&nbsp;&nbsp;&nbsp;&nbsp;this.dateProperty = dateProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public Integer getIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;return integerProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public void setIntegerProperty(final Integer integerProperty) {
&nbsp;&nbsp;&nbsp;&nbsp;this.integerProperty = integerProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public String getStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;return stringProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public void setStringProperty(final String stringProperty) {
&nbsp;&nbsp;&nbsp;&nbsp;this.stringProperty = stringProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Override
&nbsp;&nbsp;public String toString() {
&nbsp;&nbsp;&nbsp;&nbsp;return new ToStringBuilder(this).append(&quot;dateProperty&quot;, dateProperty)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.append(&quot;integerProperty&quot;, integerProperty).append(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;stringProperty&quot;, stringProperty).toString();
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 7 : SimpleBean.java</p>
</div>
<p><br/></p>
<p>The SimpleBean and SimpleBeanSubclass are for  demonstration purposes.  You can see that each method is annotated with  the @Loggable annotation and the log level is set to TRACE.  You can  obviously use different log levels for different methods as required.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.bean;

import java.math.BigDecimal;

import net.thoughtforge.aspect.Loggable;
import net.thoughtforge.logger.LogLevel;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.stereotype.Component;

@Component(value = &quot;simpleBeanSubclass&quot;)
public class SimpleBeanSubclass extends SimpleBean {

&nbsp;&nbsp;private BigDecimal decimalProperty;

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public BigDecimal getDecimalProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;return decimalProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Loggable(value = LogLevel.TRACE)
&nbsp;&nbsp;public void setDecimalProperty(final BigDecimal decimalProperty) {
&nbsp;&nbsp;&nbsp;&nbsp;this.decimalProperty = decimalProperty;
&nbsp;&nbsp;}

&nbsp;&nbsp;@Override
&nbsp;&nbsp;public String toString() {
&nbsp;&nbsp;&nbsp;&nbsp;return new ToStringBuilder(this).append(&quot;decimalProperty&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decimalProperty).appendSuper(super.toString()).toString();
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 8 : SimpleBeanSubclass.java</p>
</div>
<p><br/></p>
<p>Also note the use of the  ToStringBuilder to create the toString value.  You may choose to use the  ReflectionToStringBuilder or some other mechanism.</p>
<p><strong>Testing  the Logging Aspect</strong></p>
<p>One way to test the logging aspect is to  simply have a test invoke instrumented methods and observe the log  statements produced.  This is a useful exercise but requires manual  intervention to determine if the test was successful.</p>
<p>In order to  create an automated test for the logging aspect, I needed to create a  mock logger that simulates the actions of a logger and allows me to  interrogate the log statements produced.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.mock.logger;

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

import net.thoughtforge.logger.LogLevel;
import net.thoughtforge.logger.Logger;

import org.springframework.stereotype.Component;

@Component
public class MockLogger implements Logger {

&nbsp;&nbsp;private Map&lt;Class&lt;?&gt;, LogLevel&gt; logLevelMap =
&nbsp;&nbsp;&nbsp;&nbsp;new HashMap&lt;Class&lt;?&gt;, LogLevel&gt;();
&nbsp;&nbsp;
&nbsp;&nbsp;private Map&lt;Class&lt;?&gt;, List&lt;LogMessage&gt;&gt; messages = new HashMap&lt;Class&lt;?&gt;, List&lt;LogMessage&gt;&gt;();
&nbsp;&nbsp;
&nbsp;&nbsp;public boolean isLogLevel(LogLevel logLevel,&nbsp;&nbsp;Class&lt;?&gt; clazz) {
&nbsp;&nbsp;&nbsp;&nbsp;boolean result = false;

&nbsp;&nbsp;&nbsp;&nbsp;switch (logLevel) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case DEBUG:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.DEBUG);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case ERROR:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.ERROR);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FATAL:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.FATAL);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case INFO:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.INFO);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case TRACE:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.TRACE);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case WARN:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = isLogLevelEnabled(clazz, LogLevel.WARN);
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result = false;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return result;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void log(LogLevel logLevel,&nbsp;&nbsp;Class&lt;?&gt; clazz,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Throwable throwable,&nbsp;&nbsp;String pattern,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;switch (logLevel) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case DEBUG:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;debug(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case ERROR:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case FATAL:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fatal(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case INFO:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case TRACE:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trace(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case WARN:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;warn(clazz, throwable, pattern, arguments);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void debug(Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.DEBUG, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.DEBUG, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void error(Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.ERROR, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.ERROR, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void fatal(Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.FATAL, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.FATAL, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void info(Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.INFO, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.INFO, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void trace( Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.TRACE, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.TRACE, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private void warn( Class&lt;?&gt; clazz,&nbsp;&nbsp;Throwable throwable,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;if (throwable != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.WARN, format(pattern, arguments), throwable));
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getMessages(clazz).add(new LogMessage(LogLevel.WARN, format(pattern, arguments)));
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;private String format( String pattern,&nbsp;&nbsp;Object... arguments) {

&nbsp;&nbsp;&nbsp;&nbsp;return MessageFormat.format(pattern, arguments);
&nbsp;&nbsp;}

&nbsp;&nbsp;public void resetLoggers() {
&nbsp;&nbsp;&nbsp;&nbsp;messages = new HashMap&lt;Class&lt;?&gt;, List&lt;LogMessage&gt;&gt;();
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public List&lt;LogMessage&gt; getMessages(Class&lt;?&gt; clazz) {
&nbsp;&nbsp;&nbsp;&nbsp;if (messages.get(clazz) == null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;messages.put(clazz, new ArrayList&lt;LogMessage&gt;());
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return messages.get(clazz);
&nbsp;&nbsp;}

&nbsp;&nbsp;private boolean isLogLevelEnabled(Class&lt;?&gt; clazz, LogLevel logLevel) {
&nbsp;&nbsp;&nbsp;&nbsp;return logLevelMap.get(clazz) != null &amp;&amp; logLevelMap.get(clazz).equals(logLevel);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public void setLogLevel(Class&lt;?&gt; clazz, LogLevel logLevel) {
&nbsp;&nbsp;&nbsp;&nbsp;logLevelMap.put(clazz, logLevel);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public class LogMessage {
&nbsp;&nbsp;&nbsp;&nbsp;private LogLevel logLevel;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;private String message;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;private Throwable throwable;

&nbsp;&nbsp;&nbsp;&nbsp;public LogMessage(LogLevel logLevel, String message, Throwable throwable) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this(logLevel, message);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.throwable = throwable;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public LogMessage(LogLevel logLevel, String message) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.logLevel = logLevel;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.message = message;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public LogLevel getLogLevel() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return logLevel;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public String getMessage() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return message;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public Throwable getThrowable() {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return throwable;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 9 : MockLogger.java</p>
</div>
<p><br/></p>
<p>The  logging aspect test utilises the MockLogger and makes assertions about  the log statements produced.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
package net.thoughtforge.aspect;

import java.math.BigDecimal;

import junit.framework.Assert;
import net.thoughtforge.bean.SimpleBean;
import net.thoughtforge.bean.SimpleBeanSubclass;
import net.thoughtforge.logger.LogLevel;
import net.thoughtforge.mock.logger.MockLogger;
import net.thoughtforge.mock.logger.MockLogger.LogMessage;

import org.apache.commons.lang.time.DateUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
&nbsp;&nbsp;&nbsp;&nbsp;&quot;/applicationContext/applicationContext-aspect.xml&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;/applicationContext/applicationContext-logger.xml&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&quot;/applicationContext/applicationContext.xml&quot; })
public class LoggingAspectTest {

&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;private MockLogger logger;
&nbsp;&nbsp;
&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;@Qualifier(value = &quot;simpleBean&quot;)
&nbsp;&nbsp;public SimpleBean simpleBean;

&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;public SimpleBeanSubclass simpleBeanSubclass;

&nbsp;&nbsp;@Before
&nbsp;&nbsp;public void before() {
&nbsp;&nbsp;&nbsp;&nbsp;logger.setLogLevel(SimpleBean.class, LogLevel.TRACE);
&nbsp;&nbsp;&nbsp;&nbsp;logger.setLogLevel(SimpleBeanSubclass.class, LogLevel.TRACE);
&nbsp;&nbsp;&nbsp;&nbsp;logger.resetLoggers();
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_SetDateProperty() throws Exception {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.setDateProperty(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateUtils.parseDate(&quot;01/01/2010&quot;, new String[] {&quot;dd/MM/yyyy&quot;}));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setDateProperty &gt; with params Fri Jan 01 00:00:00 GMT 2010 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setDateProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_SetIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.setIntegerProperty(100);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setIntegerProperty &gt; with params 100 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setIntegerProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_SetStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.setStringProperty(&quot;stringProperty&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setStringProperty &gt; with params stringProperty ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setStringProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_GetDateProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.getDateProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getDateProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getDateProperty &gt; returning Fri Jan 01 00:00:00 GMT 2010 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_GetIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.getIntegerProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getIntegerProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getIntegerProperty &gt; returning 100 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBean_GetStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBean.getStringProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBean.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getStringProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBean.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getStringProperty &gt; returning stringProperty ]&quot;);
&nbsp;&nbsp;}

&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_SetDateProperty() throws Exception {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.setDateProperty(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateUtils.parseDate(&quot;01/01/2010&quot;, new String[] {&quot;dd/MM/yyyy&quot;}));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setDateProperty &gt; with params Fri Jan 01 00:00:00 GMT 2010 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setDateProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_SetDecimalProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.setDecimalProperty(new BigDecimal(&quot;0.25&quot;));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setDecimalProperty &gt; with params 0.25 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setDecimalProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_SetIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.setIntegerProperty(100);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setIntegerProperty &gt; with params 100 ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setIntegerProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_SetStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.setStringProperty(&quot;stringProperty&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; setStringProperty &gt; with params stringProperty ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; setStringProperty &gt; ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_GetDateProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.getDateProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getDateProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getDateProperty &gt; returning Fri Jan 01 00:00:00 GMT 2010 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_GetDecimalProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.getDecimalProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getDecimalProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getDecimalProperty &gt; returning 0.25 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_GetIntegerProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.getIntegerProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getIntegerProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getIntegerProperty &gt; returning 100 ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void testSimpleBeanSubclass_GetStringProperty() {
&nbsp;&nbsp;&nbsp;&nbsp;simpleBeanSubclass.getStringProperty();
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(2, logger.getMessages(SimpleBeanSubclass.class).size());
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(0),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ entering &lt; getStringProperty &gt; ]&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(logger.getMessages(SimpleBeanSubclass.class).get(1),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogLevel.TRACE,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;[ leaving &lt; getStringProperty &gt; returning stringProperty ]&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;private void assertEquals(LogMessage logMessage, LogLevel logLevel, String message) {
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(logLevel, logMessage.getLogLevel());
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(message, logMessage.getMessage());&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 10 : LoggingAspectTest.java</p>
</div>
<p><br/></p>
<p>The  test is not exhaustive but suffices to test the general operation of  the logging aspect.</p>
<p><strong>Final Word</strong></p>
<p>Hopefully you found  my example useful but I will finish by saying that there are many  choices that I made in deciding on this approach.</p>
<p>A strong  argument could be made for the use of XML configuration as opposed to  the @Aspect approach which allows you greater control over the execution  of the advice without modifying code.  This would be particularly relevant in an environment where performance was a major focus.  I  personally have found that the control provided by logging frameworks to  enable and disable particular loggers is sufficient in most environments.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/02/16/creating-a-logging-aspect-with-spring-aop-and-aspectj/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Form Validation with JBoss RichFaces and Hibernate Validator</title>
		<link>http://thoughtforge.net/2010/02/09/web-form-validation-with-jboss-richfaces-and-hibernate-validator/</link>
		<comments>http://thoughtforge.net/2010/02/09/web-form-validation-with-jboss-richfaces-and-hibernate-validator/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 21:02:09 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Rich Faces]]></category>
		<category><![CDATA[Spring Webflow]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=634</guid>
		<description><![CDATA[Last month I posted about Building a Dynamic Tree with JBoss RichFaces and Spring Web Flow.  Since then, I have received a few requests to demonstrate how to implement validation within the modal dialog.  There are several internet resources that already deal with this but none that provide a complete working example so [...]]]></description>
			<content:encoded><![CDATA[<p>Last month I posted about <a href="http://thoughtforge.net/2010/01/19/building-a-dynamic-tree-with-jboss-richfaces-and-spring-web-flow/" target="_blank">Building a Dynamic Tree with JBoss RichFaces and Spring Web Flow</a>.  Since then, I have received a few requests to demonstrate how to implement validation within the modal dialog.  There are several internet resources that already deal with this but none that provide a complete working example so I decided I would do just that.</p>
<p>You can download the <a href="http://thoughtforge.net/wp-content/uploads/2010/02/richfaces-modaldialog-ajax-validation.zip" target="_self">source code</a> in the form of a Maven project and follow along.</p>
<p><strong>Hibernate Validator Dependencies</strong></p>
<p>First step is to add the <a href="https://www.hibernate.org/412.html" target="_blank">Hibernate Validator</a> dependency to the project pom.  I have used Hibernate Validator 4.0.0.GA because it is a JSR 303 compliant implementation.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&lt;dependency&gt;
&nbsp;&nbsp;&lt;groupId&gt;org.hibernate&lt;/groupId&gt;
&nbsp;&nbsp;&lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;
&nbsp;&nbsp;&lt;version&gt;4.0.0.GA&lt;/version&gt;
&nbsp;&nbsp;&lt;scope&gt;compile&lt;/scope&gt;
&lt;/dependency&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 1 : Hibernate Validator Dependency</p>
</div>
<p><br/><br />
<span id="more-634"></span><br />
<strong>Annotating the Model Class</strong></p>
<p>JSR 303 allows for the specification of validation constraints via Annotations and\or XML.  The Hibernate Validator documentation has recently been updated to include details on specifying the validation.xml if you prefer to use XML.</p>
<p>For this example I am going to use Annotations to specify a &#8216;Size&#8217; constraint on the name and description properties of the Organisation class.  These are basic constraints but they will suffice for demonstration purposes.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.model;

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

import javax.validation.constraints.Size;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(&quot;prototype&quot;)
public class Organisation implements Serializable {

&nbsp;&nbsp;private static final long serialVersionUID = -2023156931701914562L;

&nbsp;&nbsp;private List&lt;Organisation&gt; children;
&nbsp;&nbsp;
&nbsp;&nbsp;@Size(min=3, max=200, message=&quot;Description must be between 3 and 200 characters in length.&quot;)
&nbsp;&nbsp;private String description;
&nbsp;&nbsp;
&nbsp;&nbsp;@Size(min=3, max=50, message=&quot;Name must be between 3 and 50 characters in length.&quot;)
&nbsp;&nbsp;private String name;

&nbsp;&nbsp;private Organisation parent;
&nbsp;&nbsp;
&nbsp;&nbsp;public void addChild(Organisation child) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (child.getParent() == null || !child.getParent().equals(this)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;child.setParent(this);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (children == null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children = new ArrayList&lt;Organisation&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!children.contains(child)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children.add(child);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public void removeChild(Organisation child) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (child.getParent() != null &amp;&amp; child.getParent().equals(this)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;child.setParent(null);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (children != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children.remove(child);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;public List&lt;Organisation&gt; getChildren() {
&nbsp;&nbsp;&nbsp;&nbsp;if (children == null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children = new ArrayList&lt;Organisation&gt;();
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;return Collections.unmodifiableList(children);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;public String getDescription() {
&nbsp;&nbsp;&nbsp;&nbsp;return description;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setDescription(String description) {
&nbsp;&nbsp;&nbsp;&nbsp;this.description = description;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getName() {
&nbsp;&nbsp;&nbsp;&nbsp;return name;
&nbsp;&nbsp;}

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

&nbsp;&nbsp;public Organisation getParent() {
&nbsp;&nbsp;&nbsp;&nbsp;return parent;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setParent(Organisation parent) {
&nbsp;&nbsp;&nbsp;&nbsp;this.parent = parent;
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 2 : Organisation.java</p>
</div>
<p><br/><br />
<strong>Applying the Constraints</strong></p>
<p>Of course, as annotations do nothing in and of themselves, I need to invoke the validator to apply the constraints.  RichFaces provides 3 components that invoke either the Hibernate or JSR 303 bean validator during the JSF &#8216;Process Validations&#8217; phase.</p>
<p>I wanted to validate the Organisation name and description properties.  These are set within the &#8216;addChildModalPanel&#8217; and updated within the &#8216;editChildModalPanel&#8217;.  The validations are applied to each in exactly the same way.</p>
<p>To apply validations to the name and description &#8216;inputText&#8217; fields I added a child  field.  Adding this child component results in the validator being invoked during the &#8216;Process Validations&#8217; phase.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 100px; width: 100%;">
<pre><pre>
&lt;h:inputText value=&quot;#{addChildOrganisation.name}&quot;&gt;
&nbsp;&nbsp;&lt;rich:beanValidator/&gt;
&lt;/h:inputText&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 3 : rich:beanValidator</p>
</div>
<p><br/><br />
If the validation fails, messages are added to the FacesContext and will be displayed using the  component.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&lt;rich:messages&gt;
&nbsp;&nbsp;&lt;f:facet name=&quot;errorMarker&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:panelGroup&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:graphicImage value=&quot;/image/error.gif&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;&nbsp;&nbsp;&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:panelGroup&gt;
&nbsp;&nbsp;&lt;/f:facet&gt;
&lt;/rich:messages&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 4 : rich:messages</p>
</div>
<p><br/><br />
Displaying Validation Messages within the Modal Dialog</p>
<p>Finally, I needed to keep the Modal Dialog from closing when validation failures occured.  This is achieved by modifying the a4j:commandButton as shown below.  It is worth highlighting that each <rich:modalPanel> has its own <h:form> and this is very important (as highlighted in the JBoss RichFaces documentation).</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 150px; width: 100%;">
<pre><pre>
&lt;a4j:commandButton action=&quot;addChildModalPanelConfirm&quot;
&nbsp;&nbsp;&nbsp;&nbsp;value=&quot;Ok&quot;
&nbsp;&nbsp;&nbsp;&nbsp;oncomplete=&quot;if (#{!facesContext.messages.hasNext()}) {Richfaces.hideModalPanel(&#039;addChildModalPanel&#039;)};&quot;
&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;styleClass=&quot;commandButton&quot;/&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 5 : a4j:commandButton</p>
</div>
<p><br/><br />
What I ended up with was a really intuitive and responsive UI with appropriate validations.  It was an interesting exercise especially due to the intricacies of the  component.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/02/09/web-form-validation-with-jboss-richfaces-and-hibernate-validator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Marshalling XML with Spring WS and JAXB</title>
		<link>http://thoughtforge.net/2010/02/04/marshalling-xml-with-spring-ws-and-jaxb/</link>
		<comments>http://thoughtforge.net/2010/02/04/marshalling-xml-with-spring-ws-and-jaxb/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 22:21:09 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Spring Framework]]></category>
		<category><![CDATA[Spring Web Services]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=610</guid>
		<description><![CDATA[The &#8216;object-relational impedance mismatch&#8217; is a well documented set of conceptual and technical difficulties that are often encountered when a relational database management system is being used by a program written in an object-oriented programming language.  A similar impedance mismatch exists when XML is used by a program written in an object-oriented programming language.
Many [...]]]></description>
			<content:encoded><![CDATA[<p>The &#8216;object-relational impedance mismatch&#8217; is a well documented set of conceptual and technical difficulties that are often encountered when a relational database management system is being used by a program written in an object-oriented programming language.  A similar impedance mismatch exists when XML is used by a program written in an object-oriented programming language.</p>
<p>Many popular &#8216;Object-Relational Mapping&#8217; (ORM) frameworks exist that address the object-relational impedance mismatch and no doubt helped to inspire the evolution of &#8216;Object-XML Mapping&#8217; (OXM) frameworks to address the object-xml impedance mismatch.</p>
<p>For the Java community, there are a number of OXM frameworks from which to choose (<a href="http://www.castor.org/" target="_blank">Castor</a>, <a href="http://xstream.codehaus.org/" target="_blank">XStream</a>, <a href="http://jibx.sourceforge.net/" target="_blank">JiBX</a>, <a href="https://jaxb.dev.java.net/" target="_blank">JAXB</a>) with each having particular strengths and weaknesses.  The standard OXM framework for Java is JAXB.</p>
<p>In the following I work through a simple example that demonstrates object to XML marshalling (and demarshalling) using <a href="http://www.springsource.org/about" target="_blank">Spring</a>, <a href="http://static.springsource.org/spring-ws/sites/1.5/" target="_blank">Spring WS</a> and JAXB (and later <a href="http://community.jboss.org/wiki/JAXBIntroductions" target="_blank">JAXB Introductions</a>!)</p>
<p>I have provided Maven projects for download so you can follow along:</p>
<p><a href="http://thoughtforge.net/wp-content/uploads/2010/02/spring-springws-jaxb.zip" target="_blank">Spring OXM and JAXB Source Download</a><br />
<a href="http://thoughtforge.net/wp-content/uploads/2010/02/spring-springws-jaxb-introductions.zip" target="_blank">Spring OXM, JAXB and JAXB Introductions Download</a><br />
<span id="more-610"></span><br />
<strong>The Model</strong></p>
<p>The model object that I have used for this example is a simple object representing a &#8216;Person&#8217;.  The class contains only simple attributes.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.model;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Calendar;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(
&nbsp;&nbsp;&nbsp;&nbsp;name=&quot;Person&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;namespace=&quot;http://thoughtforge.net/model&quot;)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
public class Person implements Serializable {

&nbsp;&nbsp;private static final long serialVersionUID = 8465162879793776395L;

&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private Calendar dateOfBirth;
&nbsp;&nbsp;
&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private String firstName;
&nbsp;&nbsp;
&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private BigDecimal height;
&nbsp;&nbsp;
&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private String lastName;
&nbsp;&nbsp;
&nbsp;&nbsp;@XmlElement(namespace=&quot;http://thoughtforge.net/model&quot;)
&nbsp;&nbsp;private BigDecimal weight;

&nbsp;&nbsp;public Calendar getDateOfBirth() {
&nbsp;&nbsp;&nbsp;&nbsp;return dateOfBirth;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setDateOfBirth(Calendar dateOfBirth) {
&nbsp;&nbsp;&nbsp;&nbsp;this.dateOfBirth = dateOfBirth;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getFirstName() {
&nbsp;&nbsp;&nbsp;&nbsp;return firstName;
&nbsp;&nbsp;}

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

&nbsp;&nbsp;public BigDecimal getHeight() {
&nbsp;&nbsp;&nbsp;&nbsp;return height;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setHeight(BigDecimal height) {
&nbsp;&nbsp;&nbsp;&nbsp;this.height = height;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getLastName() {
&nbsp;&nbsp;&nbsp;&nbsp;return lastName;
&nbsp;&nbsp;}

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

&nbsp;&nbsp;public BigDecimal getWeight() {
&nbsp;&nbsp;&nbsp;&nbsp;return weight;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setWeight(BigDecimal weight) {
&nbsp;&nbsp;&nbsp;&nbsp;this.weight = weight;
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 1 : Person.java</p>
</div>
<p><br/><br />
As you can see from the listing, the class is annotated with JAXB annotations that are fairly self explanatory.  I will leave it to you to look up the precise definition and consequence of these annotations (which can be found on the JAXB Reference Implementation website).</p>
<p><strong>The XML Schema (XSD)</strong></p>
<p>JAXB does not require an XML schema (a default schema can be generated), but for this example (and always on commercial projects) I have explicitly specified a schema in order to include type restrictions.  It is important to remember that the XSD forms the contract between XML producers and consumers (marshaller and unmarshaller) and should be as detailed as possible.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;xsd:schema xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
&nbsp;&nbsp;targetNamespace=&quot;http://thoughtforge.net/model&quot;
&nbsp;&nbsp;xmlns:tns=&quot;http://thoughtforge.net/model&quot;
&nbsp;&nbsp;attributeFormDefault=&quot;unqualified&quot;
&nbsp;&nbsp;elementFormDefault=&quot;qualified&quot;
&nbsp;&nbsp;version=&quot;1.0&quot;&gt;

&nbsp;&nbsp;&lt;xsd:element name=&quot;Person&quot; type=&quot;tns:Person&quot;/&gt;
&nbsp;&nbsp;
&nbsp;&nbsp;&lt;xsd:complexType name=&quot;Person&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:sequence&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;dateOfBirth&quot; type=&quot;xsd:dateTime&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;firstName&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:restriction base=&quot;xsd:string&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:maxLength value=&quot;50&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:restriction&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:element&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;height&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:restriction base=&quot;xsd:decimal&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:fractionDigits value=&quot;2&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:restriction&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:element&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;lastName&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:restriction base=&quot;xsd:string&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:maxLength value=&quot;50&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:restriction&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:element&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:element name=&quot;weight&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:restriction base=&quot;xsd:decimal&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;xsd:fractionDigits value=&quot;2&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:restriction&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:simpleType&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:element&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/xsd:sequence&gt;
&nbsp;&nbsp;&lt;/xsd:complexType&gt;
&lt;/xsd:schema&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 2 : person.xsd</p>
</div>
<p><br/><br />
<strong>The Marshaller Abstraction</strong></p>
<p>Rather than use the Spring Marshaller/Unmarshaller interface directly, I often use an abstraction for the Marshaller.  The abstraction I used here is very simple and of course would not be practical for use with large XML files as it does not support streaming etc.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.marshaller;

public interface Marshaller {

&nbsp;&nbsp;String marshal(Object object);

&nbsp;&nbsp;Object unmarshal(String string);
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 3 : Marshaller.java</p>
</div>
<p><br/><br />
The implementation of the marshaller delegates to a Spring JAXB marshaller.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.marshaller;

import java.io.StringWriter;

import javax.xml.transform.stream.StreamResult;

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

@Component(value=&quot;marshaller&quot;)
public class Jaxb2Marshaller implements Marshaller {

&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;@Qualifier(value=&quot;jaxb2Marshaller&quot;)
&nbsp;&nbsp;private org.springframework.oxm.jaxb.Jaxb2Marshaller marshaller;
&nbsp;&nbsp;
&nbsp;&nbsp;public String marshal(Object object) {
&nbsp;&nbsp;&nbsp;&nbsp;final StringWriter out = new StringWriter();
&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(object, new StreamResult(out));
&nbsp;&nbsp;&nbsp;&nbsp;return out.toString();
&nbsp;&nbsp;}

&nbsp;&nbsp;public Object unmarshal(String string) {
&nbsp;&nbsp;&nbsp;&nbsp;return marshaller.unmarshal(new StringSource(string));
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 4 : Jaxb2Marshaller.java</p>
</div>
<p><br/><br />
<strong>The Configuration</strong></p>
<p>Using Spring to define a JAXB marshaller is relatively straight forward as the listing shows.  I have specified the classes to be bound and the XML schema.  If the XML schema is specified, the marshaller will instruct the XML parser to validate XML against the schema.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
&nbsp;&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
&nbsp;&nbsp;xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
&nbsp;&nbsp;xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd&quot;&gt;

&nbsp;&nbsp;&lt;context:component-scan base-package=&quot;net.thoughtforge.marshaller&quot;/&gt;
&nbsp;&nbsp;
&nbsp;&nbsp;&lt;bean id=&quot;jaxb2Marshaller&quot; class=&quot;org.springframework.oxm.jaxb.Jaxb2Marshaller&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;classesToBeBound&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;list&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;net.thoughtforge.model.Person&lt;/value&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/list&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;schema&quot; value=&quot;classpath:schema/person.xsd&quot;/&gt;
&nbsp;&nbsp;&lt;/bean&gt;
&lt;/beans&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 5 : applicationContext-marshaller.xml</p>
</div>
<p><br/><br />
<strong>The Test</strong></p>
<p>The following test is not exhaustive but demonstrates the marshalling and unmarshalling of a Person object.  It also demonstrates XML schema validation occurring during the marshalling and unmarshalling process.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.marshaller;

import java.math.BigDecimal;
import java.util.Calendar;

import net.thoughtforge.model.Person;

import org.apache.commons.lang.text.StrBuilder;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
&nbsp;&nbsp;&nbsp;&nbsp;&quot;classpath:applicationContext/applicationContext-*.xml&quot;})
public class Jaxb2MarshallerTest {

&nbsp;&nbsp;private static final String MARSHALLED_PERSON =
&nbsp;&nbsp;&nbsp;&nbsp;&quot;&lt;?xml version=\&quot;1.0\&quot; encoding=\&quot;UTF-8\&quot; standalone=\&quot;yes\&quot;?&gt;&lt;Person xmlns=\&quot;http://thoughtforge.net/model\&quot;&gt;&lt;dateOfBirth&gt;1965-01-01T00:00:00Z&lt;/dateOfBirth&gt;&lt;firstName&gt;Joe&lt;/firstName&gt;&lt;height&gt;1.85&lt;/height&gt;&lt;lastName&gt;Bloggs&lt;/lastName&gt;&lt;weight&gt;12.2&lt;/weight&gt;&lt;/Person&gt;&quot;;
&nbsp;&nbsp;
&nbsp;&nbsp;private static Calendar dateOfBirth;
&nbsp;&nbsp;
&nbsp;&nbsp;private static String firstName;
&nbsp;&nbsp;
&nbsp;&nbsp;private static BigDecimal height;
&nbsp;&nbsp;
&nbsp;&nbsp;private static String lastName;
&nbsp;&nbsp;
&nbsp;&nbsp;private static BigDecimal weight;
&nbsp;&nbsp;
&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;@Qualifier(value=&quot;marshaller&quot;)
&nbsp;&nbsp;private Jaxb2Marshaller marshaller;

&nbsp;&nbsp;@BeforeClass
&nbsp;&nbsp;public static void beforeClass() {
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth = Calendar.getInstance();
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth.clear();
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth.set(Calendar.DATE, 1);
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth.set(Calendar.MONTH, Calendar.JANUARY);
&nbsp;&nbsp;&nbsp;&nbsp;dateOfBirth.set(Calendar.YEAR, 1965);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;firstName = &quot;Joe&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;height = new BigDecimal(&quot;1.85&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;lastName = &quot;Bloggs&quot;;
&nbsp;&nbsp;&nbsp;&nbsp;weight = new BigDecimal(&quot;12.2&quot;);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPerson() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(firstName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height);
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(lastName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;String xml = marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertNotNull(xml);
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(MARSHALLED_PERSON, xml);
&nbsp;&nbsp;}

&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPersonInvalidFirstName() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(new StrBuilder(firstName).appendPadding(50, &#039;0&#039;).toString());
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height);
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(lastName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.fail(&quot;First name length restriction not applied.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} catch (MarshallingFailureException marshallingFailureException) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable rootCause = marshallingFailureException.getRootCause();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertFalse(rootCause.getMessage().indexOf(&quot;is not facet-valid with respect to maxLength &#039;50&#039;&quot;) == -1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPersonInvalidHeight() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(firstName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height.add(new BigDecimal(&quot;0.1111&quot;)));
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(lastName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.fail(&quot;Height precision restriction not applied.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} catch (MarshallingFailureException marshallingFailureException) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable rootCause = marshallingFailureException.getRootCause();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertFalse(rootCause.getMessage().indexOf(&quot;the number of fraction digits has been limited to 2&quot;) == -1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPersonInvalidLastName() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(firstName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height);
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(new StrBuilder(lastName).appendPadding(50, &#039;0&#039;).toString());
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.fail(&quot;First name length restriction not applied.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} catch (MarshallingFailureException marshallingFailureException) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable rootCause = marshallingFailureException.getRootCause();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertFalse(rootCause.getMessage().indexOf(&quot;is not facet-valid with respect to maxLength &#039;50&#039;&quot;) == -1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void marshallPersonInvalidWeight() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = new Person();
&nbsp;&nbsp;&nbsp;&nbsp;person.setDateOfBirth(dateOfBirth);
&nbsp;&nbsp;&nbsp;&nbsp;person.setFirstName(firstName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setHeight(height);
&nbsp;&nbsp;&nbsp;&nbsp;person.setLastName(lastName);
&nbsp;&nbsp;&nbsp;&nbsp;person.setWeight(weight.add(new BigDecimal(&quot;0.1111&quot;)));
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;try {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;marshaller.marshal(person);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.fail(&quot;Weight precision restriction not applied.&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;} catch (MarshallingFailureException marshallingFailureException) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Throwable rootCause = marshallingFailureException.getRootCause();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertFalse(rootCause.getMessage().indexOf(&quot;the number of fraction digits has been limited to 2&quot;) == -1);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void unmarshallPerson() {
&nbsp;&nbsp;&nbsp;&nbsp;Person person = (Person) marshaller.unmarshal(MARSHALLED_PERSON);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertNotNull(person);
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertTrue(dateOfBirth.compareTo(person.getDateOfBirth()) == 0);
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(firstName, person.getFirstName());
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(height, person.getHeight());
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(lastName, person.getLastName());
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(weight, person.getWeight());
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 6 : Jaxb2MarshallerTest.java</p>
</div>
<p><br/><br />
<strong>Removing JAXB Annotations</strong></p>
<p>If you are using the reference implementation of JAXB you are required to use annotations to map objects to XML.  As I mentioned in a previous post, I&#8217;m not a fan of using annotations for the purpose of mapping objects to some other format (relational database or XML or A.N. Other).  I find it creates code clutter especially in instances were entity model classes are mapped to both a relational database and XML (using JAXB).  In modular projects, it also creates unnecessary dependencies on the model module.</p>
<p>Luckily, some bright spark came along and created JAXB Introductions which allows you to define the mapping of objects to XML in an XML file.  I&#8217;m not going to regurgitate the information on the JAXB Introductions website but I will outline the modifications I had to make to allow me to use JAXB Introductions with the example above.</p>
<p>First, I added the maven dependency to the project.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&nbsp;&nbsp;&nbsp;&nbsp;&lt;dependency&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;groupId&gt;jboss.jaxbintros&lt;/groupId&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;artifactId&gt;jboss-jaxb-intros&lt;/artifactId&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;version&gt;1.0.1.GA&lt;/version&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/dependency&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 7 : JAXB Introductions Maven Dependency</p>
</div>
<p><br/><br />
Second, I created a JAXB Introductions mapping file.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;?xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot;?&gt;

&lt;jaxb-intros xmlns=&quot;http://www.jboss.org/xsd/jaxb/intros&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;Class name=&quot;net.thoughtforge.model.Person&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlType/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlRootElement name=&quot;Person&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlAccessorType value=&quot;FIELD&quot;/&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;dateOfBirth&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;dateOfBirth&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;firstName&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;firstName&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;height&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;height&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;lastName&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;lastName&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Field name=&quot;weight&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;XmlElement name=&quot;weight&quot; namespace=&quot;http://thoughtforge.net/model&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Field&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/Class&gt;
&lt;/jaxb-intros&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 8 : marshaller-mapping.xml</p>
</div>
<p><br/><br />
Thirdly, I modified the Spring configuration to inject the JAXB Introductions annotation reader into the JAXB marshaller.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
&nbsp;&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
&nbsp;&nbsp;xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
&nbsp;&nbsp;xmlns:util=&quot;http://www.springframework.org/schema/util&quot;
&nbsp;&nbsp;xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd&quot;&gt;

&nbsp;&nbsp;&lt;context:component-scan base-package=&quot;net.thoughtforge.marshaller&quot;/&gt;
&nbsp;&nbsp;
&nbsp;&nbsp;&lt;bean id=&quot;jaxb2Marshaller&quot; class=&quot;org.springframework.oxm.jaxb.Jaxb2Marshaller&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;classesToBeBound&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;list&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;value&gt;net.thoughtforge.model.Person&lt;/value&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/list&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;jaxbContextProperties&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;map&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;entry&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;key&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;util:constant static-field=&quot;com.sun.xml.bind.api.JAXBRIContext.ANNOTATION_READER&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/key&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class=&quot;org.jboss.jaxb.intros.IntroductionsAnnotationReader&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;constructor-arg ref=&quot;jaxbIntroductions&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/entry&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/map&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;schema&quot; value=&quot;classpath:schema/person.xsd&quot;/&gt;
&nbsp;&nbsp;&lt;/bean&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id=&quot;jaxbIntroductions&quot; class=&quot;org.jboss.jaxb.intros.IntroductionsConfigParser&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory-method=&quot;parseConfig&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;constructor-arg&gt;&lt;value&gt;classpath:marshaller-mapping.xml&lt;/value&gt;&lt;/constructor-arg&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;
&lt;/beans&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 9 : applicationContext-marshaller.xml</p>
</div>
<p><br/><br />
Finally, I removed the JAXB annotations from the model class (Person.java).</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.model;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Calendar;

public class Person implements Serializable {

&nbsp;&nbsp;private static final long serialVersionUID = 8465162879793776395L;

&nbsp;&nbsp;private Calendar dateOfBirth;
&nbsp;&nbsp;
&nbsp;&nbsp;private String firstName;
&nbsp;&nbsp;
&nbsp;&nbsp;private BigDecimal height;
&nbsp;&nbsp;
&nbsp;&nbsp;private String lastName;
&nbsp;&nbsp;
&nbsp;&nbsp;private BigDecimal weight;

&nbsp;&nbsp;public Calendar getDateOfBirth() {
&nbsp;&nbsp;&nbsp;&nbsp;return dateOfBirth;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setDateOfBirth(Calendar dateOfBirth) {
&nbsp;&nbsp;&nbsp;&nbsp;this.dateOfBirth = dateOfBirth;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getFirstName() {
&nbsp;&nbsp;&nbsp;&nbsp;return firstName;
&nbsp;&nbsp;}

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

&nbsp;&nbsp;public BigDecimal getHeight() {
&nbsp;&nbsp;&nbsp;&nbsp;return height;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setHeight(BigDecimal height) {
&nbsp;&nbsp;&nbsp;&nbsp;this.height = height;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getLastName() {
&nbsp;&nbsp;&nbsp;&nbsp;return lastName;
&nbsp;&nbsp;}

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

&nbsp;&nbsp;public BigDecimal getWeight() {
&nbsp;&nbsp;&nbsp;&nbsp;return weight;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setWeight(BigDecimal weight) {
&nbsp;&nbsp;&nbsp;&nbsp;this.weight = weight;
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 10 : Person.java</p>
</div>
<p><br/><br />
Hopefully, this short example will prove useful for those starting out with JAXB and OXM.  For those already familiar with JAXB and OXM, perhaps it has shown you how you can use JAXB without annotations.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/02/04/marshalling-xml-with-spring-ws-and-jaxb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ron Jefferies &#8211; Annals of Kate Oneal</title>
		<link>http://thoughtforge.net/2010/01/27/ron-jefferies-annals-of-kate-oneal/</link>
		<comments>http://thoughtforge.net/2010/01/27/ron-jefferies-annals-of-kate-oneal/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 19:56:52 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Extreme Programming]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=605</guid>
		<description><![CDATA[While I was re-reading JUnit Recipes recently I followed one of the suggested links to Ron Jefferies website on Extreme Programming.  Ron provides some really interesting material on his website but one of the things that I really liked was the &#8216;Annals of Kate Oneal&#8216;.
Anyone who has read one of the Head First series of [...]]]></description>
			<content:encoded><![CDATA[<p>While I was re-reading JUnit Recipes recently I followed one of the suggested links to <a href="http://xprogramming.com" target="_blank">Ron Jefferies website</a> on Extreme Programming.  Ron provides some really interesting material on his website but one of the things that I really liked was the &#8216;<a href="http://xprogramming.com/kate-oneal" target="_blank">Annals of Kate Oneal</a>&#8216;.</p>
<p>Anyone who has read one of the <a href="http://headfirstlabs.com/" target="_blank">Head First</a> series of books will be familiar with a conversational style of writing that introduces concepts progressively through fictitious scenarios.  Ron uses a similar approach with the &#8216;Annals of Kate Oneal&#8217; through which he presents Agile ideas and concepts.</p>
<p>The &#8216;Annals of Kate Oneal&#8217; are presented in a series of bite size stories centered on Kate Oneal, who is advocating Agile methods to a company that has had difficulty using traditional approaches to software development.  As an advocate, Kate is often explaining the advantages of Agile from different perspectives and to different audiences.  She also has to deal with the practical aspects of introducing Agile to a company that has no previous exposure, so is often found in the role of a mentor.</p>
<p>I am not going to describe her tales any further but, if you haven&#8217;t done so already, I do recommend you visit Ron Jefferies website and read the &#8216;Annals of Kate Oneal&#8217;.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/01/27/ron-jefferies-annals-of-kate-oneal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Starting out with Spring and Hibernate JPA</title>
		<link>http://thoughtforge.net/2010/01/21/starting-out-with-spring-and-hibernate-jpa/</link>
		<comments>http://thoughtforge.net/2010/01/21/starting-out-with-spring-and-hibernate-jpa/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 17:06:50 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Spring Framework]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=488</guid>
		<description><![CDATA[More often than not, I am brought onto a project after the project initiation phase has been completed.  By this stage major decisions regarding the development environment and code organisation have already been made.  It would be fairly common that I would refactor and re-organise some of the code and in particular the Hibernate JPA [...]]]></description>
			<content:encoded><![CDATA[<p>More often than not, I am brought onto a project after the project initiation phase has been completed.  By this stage major decisions regarding the development environment and code organisation have already been made.  It would be fairly common that I would refactor and re-organise some of the code and in particular the Hibernate JPA code.</p>
<p>In this post I am going to outline how I prefer to implement and organise the Hibernate JPA code on projects I am involved with (where that option exists).  I will also demonstrate how I implement the persistent entity classes, data access objects, associated configuration and unit tests.  A fairly typical project would utilise Maven, Spring and Hibernate JPA.</p>
<p><strong>Creating the Maven Project</strong></p>
<p>My preferred project structure consists of a root project containing a model module and persistence module with the persistence module having a dependency on the model module.  While this would seem pretty straight forward, one now has to decide if one is going to use annotations or  XML configuration for the ORM mapping.  The reason I prefer to make this decision now is that it affects the dependencies of the model module.</p>
<p>There are arguments for and against using annotations or XML for ORM (any XRM really) but if no precedent has been set I normally try to avoid using annotations in model classes.  This way model classes are very clean and the model module does not have any dependencies on javax.persistence.  I was involved in a project using JPA and JAXB annotations in model classes and they became difficult to work with very quickly.</p>
<p>The persistence module really does encapsulate all the information relating to the persistence mechanism with the exception of (some) transactional characteristics which would ordinarily be defined in service classes within a service module.  Of course the price you pay for this is having some quite large XML files.<br />
<span id="more-488"></span><br />
<strong>Creating the Persistent Entity Classes</strong></p>
<p>For this example, I am going to use a fairly typical security domain model.  A UserToken represents an authorisation token that can be associated to a User or a UserGroup.  A UserGroup is a hierarchical data structure and so can be associated with one parent and\or many child UserGroup&#8217;s.  A UserGroup can be associated with many Users and a User can be associated with many UserGroup&#8217;s.  A UserGroup inherits UserToken&#8217;s from child UserGroup&#8217;s and a User inherits UserTokens from associated UserGroup&#8217;s.</p>
<p>I hope the explanation along with the entity model diagram has given you a good understanding of the entity classes.</p>
<div id="attachment_492" class="wp-caption aligncenter" style="width: 530px"><a href="http://thoughtforge.net/wp-content/uploads/2010/01/figure1.png"><img class="size-full wp-image-492" style="border: 0pt none; margin: 5px;" title="Figure 1 : Entity Model" src="http://thoughtforge.net/wp-content/uploads/2010/01/figure1.png" alt="Figure 1 : Entity Model" width="520" height="250" /></a><p class="wp-caption-text">Figure 1 : Entity Model</p></div>
<p>The entity classes are added to the model module.  I am not going to post code listings for the persistent entity classes as I have made all the code available for <a href="http://thoughtforge.net/wp-content/uploads/2010/01/spring-hibernatejpa-source.zip" target="_blank">download</a>.</p>
<p>It is worth highlighting though that all model classes extend a common super class (PersistentEntity) that typically defines identifier and version properties.  Depending on the requirements, it may also define properties such as dateCreated, dateLastUpdated, tenancy (for multi-tenanted domains) etc.</p>
<p><strong>Creating the JPA Mapping Configuration</strong></p>
<p>For the sake of clarity, I generally separate the JPA mapping configuration into persistence.xml and persistence-mapping.xml (and persistence-query.xml which we will discuss later) files.  I try to use the same persistence.xml configuration in all environments so I move anything that varies into the Spring configuration.  This includes the definition of the data source, dialect etc.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;persistence version=&quot;1.0&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlns=&quot;http://java.sun.com/xml/ns/persistence&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd&quot;&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&lt;persistence-unit name=&quot;thoughtforge&quot; transaction-type=&quot;RESOURCE_LOCAL&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mapping-file&gt;META-INF/persistence-mapping.xml&lt;/mapping-file&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;mapping-file&gt;META-INF/persistence-query.xml&lt;/mapping-file&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;class&gt;net.thoughtforge.model.User&lt;/class&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;class&gt;net.thoughtforge.model.UserGroup&lt;/class&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;class&gt;net.thoughtforge.model.UserToken&lt;/class&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;class&gt;net.thoughtforge.model.UserTokenHolder&lt;/class&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;class&gt;net.thoughtforge.model.PersistentEntity&lt;/class&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;properties&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;cache.provider_class&quot; value=&quot;org.hibernate.cache.NoCacheProvider&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;hibernate.max_fetch_depth&quot; value=&quot;3&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;hibernate.query.factory_class&quot; value=&quot;org.hibernate.hql.classic.ClassicQueryTranslatorFactory&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;hibernate.query.substitutions&quot; value=&quot;true 1, false 0&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;hibernate.show_sql&quot; value=&quot;true&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;hibernate.hbm2ddl.auto&quot; value=&quot;create&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/properties&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/persistence-unit&gt;
&lt;/persistence&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 1 : persistence.xml</p>
</div>
<p>The option exists to further seperate the persistence-mapping.xml file into a file for each class as is normal practice for hibernate .hbm files.</p>
<p>As you can see from the applicationContext-persistence.xml file below, the &#8216;jpaProperties&#8217; property of the entityManagerFactory bean contains all the connection information.  If you are not using a JNDI data source in any of your environments it will be sufficient to use a properties file to contain the connection information for each environment.  If however some of your environments use a JNDI data source and some do not you will obviously have to use seperate Spring configuration files to specify the connection information.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;

&lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
&nbsp;&nbsp;&nbsp;&nbsp;xmlns:tx=&quot;http://www.springframework.org/schema/tx&quot;
&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd&quot;&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id=&quot;entityManagerFactory&quot; class=&quot;org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;jpaDialect&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class=&quot;org.springframework.orm.jpa.vendor.HibernateJpaDialect&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;jpaVendorAdapter&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class=&quot;org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;persistenceUnitName&quot; value=&quot;thoughtforge&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;persistenceUnitManager&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class=&quot;org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;jpaProperties&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;props&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key=&quot;hibernate.dialect&quot;&gt;org.hibernate.dialect.HSQLDialect&lt;/prop&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key=&quot;hibernate.connection.driver_class&quot;&gt;org.hsqldb.jdbcDriver&lt;/prop&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key=&quot;hibernate.connection.password&quot;&gt;&lt;/prop&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key=&quot;hibernate.connection.url&quot;&gt;jdbc:hsqldb:file:target/hsqldb/data&lt;/prop&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;prop key=&quot;hibernate.connection.username&quot;&gt;sa&lt;/prop&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/props&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id=&quot;transactionManager&quot; class=&quot;org.springframework.orm.jpa.JpaTransactionManager&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;entityManagerFactory&quot; ref=&quot;entityManagerFactory&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;tx:annotation-driven/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- JpaTemplate --&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id=&quot;jpaTemplate&quot; class=&quot;org.springframework.orm.jpa.JpaTemplate&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name=&quot;entityManagerFactory&quot; ref=&quot;entityManagerFactory&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;
&lt;/beans&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 2 : applicationContext-persistence.xml</p>
</div>
<p><strong>Creating the Data Access Objects</strong></p>
<p>The data access objects (obviously) reside in the persistence module.  I have a fairly standard PersistentEntityDao interface from which all data access object interfaces extend.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.dao;

import java.util.List;

import net.thoughtforge.model.PersistentEntity;

public interface PersistentEntityDao&lt;Entity extends PersistentEntity&gt; {

&nbsp;&nbsp;&nbsp;&nbsp;Entity findByIndexId(Integer indexId);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Entity&gt; findByNamedQuery(String queryName);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Entity&gt; findByNamedQueryAndParams(String queryName, Object ...params);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Entity findUniqueByNamedQuery(String queryName);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Entity findUniqueByNamedQueryAndParams(String queryName, Object ...params);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Entity merge(Entity persistentEntity);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;void refresh(Entity persistentEntity);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;void remove(Entity persistentEntity);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;void save(Entity persistentEntity);
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 3 : PersistentEntityDao.java</p>
</div>
<p>Specific data access object interfaces would typically then only contain specific finder methods (See UserDao) below:</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.dao;

import net.thoughtforge.model.User;

public interface UserDao extends PersistentEntityDao&lt;User&gt; {

&nbsp;&nbsp;&nbsp;&nbsp;User findByUsername(String username);
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 4 : UserDao.java</p>
</div>
<p>The implementation classes reside in a specific sub-package that is named after the data access mechanism.  For example, a JPA implementation has a &#8216;jpa&#8217; sub-package, a Hibernate implementation has a &#8216;hibernate&#8217; sub-package and a JDBC implementation has a &#8216;jdbc&#8217; sub-package.  I hate seeing sub-packages named impl; generally I feel that the only time this should happen is if there could only be one implementation of an interface which is clearly not the case for data access objects.</p>
<p>Similar to the data access object interfaces, ORM data access objects extend a common super class that exposes common CRUD functionality.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.dao.jpa;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import net.thoughtforge.dao.PersistentEntityDao;
import net.thoughtforge.model.PersistentEntity;

import org.springframework.orm.jpa.JpaTemplate;

public abstract class PersistentEntityDaoImpl&lt;Entity extends PersistentEntity&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;implements PersistentEntityDao&lt;Entity&gt; {

&nbsp;&nbsp;&nbsp;&nbsp;private Class&lt;Entity&gt; entityClass;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;private JpaTemplate jpaTemplate;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;@SuppressWarnings(value=&quot;unchecked&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;public PersistentEntityDaoImpl(JpaTemplate jpaTemplate) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.jpaTemplate = jpaTemplate;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.entityClass = (Class&lt;Entity&gt;) genericSuperclass.getActualTypeArguments()[0];
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;public final Entity findByIndexId(Integer indexId) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (Entity) jpaTemplate.find(entityClass, indexId);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;@SuppressWarnings(&quot;unchecked&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;public final List&lt;Entity&gt; findByNamedQuery(String queryName) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (List&lt;Entity&gt;) jpaTemplate.findByNamedQuery(queryName);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;@SuppressWarnings(&quot;unchecked&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;public final List&lt;Entity&gt; findByNamedQueryAndParams(String queryName, Object ...params) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (List&lt;Entity&gt;) jpaTemplate.findByNamedQuery(queryName, params);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public final Entity findUniqueByNamedQuery(String queryName) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Entity&gt; results = findByNamedQuery(queryName);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (results.isEmpty()) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return results.get(0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public final Entity findUniqueByNamedQueryAndParams(String queryName, Object ...params) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&lt;Entity&gt; results = findByNamedQueryAndParams(queryName, params);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (results.isEmpty()) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return results.get(0);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public final Entity merge(Entity persistentEntity) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (Entity) jpaTemplate.merge(persistentEntity);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;public final void refresh(Entity persistentEntity) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jpaTemplate.refresh(persistentEntity);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public final void remove(Entity persistentEntity) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jpaTemplate.remove(persistentEntity);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public final void save(Entity persistentEntity) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jpaTemplate.persist(persistentEntity);
&nbsp;&nbsp;&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 5 : PersistentEntityDaoImpl.java</p>
</div>
<p>Specific data access object interfaces would typically then only contain specific finder methods (See UserDaoImpl) below:</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.dao.jpa;

import net.thoughtforge.dao.UserDao;
import net.thoughtforge.model.User;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.jpa.JpaTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

@Repository
public class UserDaoImpl extends PersistentEntityDaoImpl&lt;User&gt; implements UserDao {

&nbsp;&nbsp;&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;&nbsp;&nbsp;public UserDaoImpl(JpaTemplate jpaTemplate) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(jpaTemplate);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;public User findByUsername(String username) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return findUniqueByNamedQueryAndParams(&quot;user.findByUsername&quot;, username);
&nbsp;&nbsp;&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 6 : UserDaoImpl.java</p>
</div>
<p>As you can see, I always use named queries and NEVER hard code SQL into data access objects.  The main reasons are that it reduces clutter in the code and maintains all SQL in a single place (persistence-query.xml).  While I have not defined any query hints it is worth pointing out that they are almost always present in any meaningful implementation.</p>
<p>It is also good practice to use namespaces for naming queries.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;

&lt;entity-mappings xmlns=&quot;http://java.sun.com/xml/ns/persistence/orm&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;version=&quot;1.0&quot;&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&lt;named-query name=&quot;userGroup.findByName&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;query&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from UserGroup
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where name = ?
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/query&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/named-query&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&lt;named-query name=&quot;userToken.findByName&quot;&gt;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;query&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from UserToken
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where name = ?
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/query&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/named-query&gt;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;named-query name=&quot;user.findByUsername&quot;&gt;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;query&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from User
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where username = ?
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/query&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/named-query&gt;
&lt;/entity-mappings&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 7 : persistence-query.xml</p>
</div>
<p>The above code examples should suffice to demonstrate the implementation and organisation of the data access objects.  The complete code is available for download.</p>
<p><strong>Testing the Data Access Objects</strong></p>
<p>Spring provides support for writing transactional data access object tests that I always utilise when testing data access objects.  Where possible, I use an embedded database to &#8216;exercise&#8217; my data access objects during testing.  By this I mean that at a minimum I test create, update and delete for every type of persistent entity and invoke every find method (and named query).  I have only included a sample test which should be enough for the purpose of demonstration.</p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
package net.thoughtforge.dao.jpa;

import junit.framework.Assert;
import net.thoughtforge.dao.UserDao;
import net.thoughtforge.model.User;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
&nbsp;&nbsp;&nbsp;&nbsp;&quot;classpath:applicationContext/applicationContext-*.xml&quot;})
@TransactionConfiguration(transactionManager=&quot;transactionManager&quot;, defaultRollback=true)
@Transactional
public class UserDaoImplTest {

&nbsp;&nbsp;private static final String FIRST_NAME = &quot;joe&quot;;
&nbsp;&nbsp;
&nbsp;&nbsp;private static final String LAST_NAME = &quot;bloggs&quot;;
&nbsp;&nbsp;
&nbsp;&nbsp;private static final String PASSWORD = &quot;password&quot;;
&nbsp;&nbsp;
&nbsp;&nbsp;private static final String USERNAME = &quot;joe.bloggs&quot;;
&nbsp;&nbsp;
&nbsp;&nbsp;@Autowired
&nbsp;&nbsp;private UserDao userDao;
&nbsp;&nbsp;
&nbsp;&nbsp;@Before
&nbsp;&nbsp;public void before() {
&nbsp;&nbsp;&nbsp;&nbsp;User user = new User();
&nbsp;&nbsp;&nbsp;&nbsp;user.setFirstName(FIRST_NAME);
&nbsp;&nbsp;&nbsp;&nbsp;user.setLastName(LAST_NAME);
&nbsp;&nbsp;&nbsp;&nbsp;user.setPassword(PASSWORD);
&nbsp;&nbsp;&nbsp;&nbsp;user.setUsername(USERNAME);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;userDao.save(user);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;@Test
&nbsp;&nbsp;public void findByUserName() {
&nbsp;&nbsp;&nbsp;&nbsp;User user = userDao.findByUsername(USERNAME);
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertNotNull(user);
&nbsp;&nbsp;&nbsp;&nbsp;Assert.assertEquals(USERNAME, user.getUsername());
&nbsp;&nbsp;}
}
</pre></pre>
</div>
<p class="wp-caption-text">Listing 8 : UserDaoImplTest.java</p>
</div>
<p>I hope that I have given you a good overview of how I implement and organise Hibernate JPA code.  There are lots of variations on this approach and none are perfect but I always find this approach a good place to start.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/01/21/starting-out-with-spring-and-hibernate-jpa/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Building a Dynamic Tree with JBoss RichFaces and Spring Web Flow</title>
		<link>http://thoughtforge.net/2010/01/19/building-a-dynamic-tree-with-jboss-richfaces-and-spring-web-flow/</link>
		<comments>http://thoughtforge.net/2010/01/19/building-a-dynamic-tree-with-jboss-richfaces-and-spring-web-flow/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 15:51:54 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Rich Faces]]></category>
		<category><![CDATA[Spring Webflow]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=345</guid>
		<description><![CDATA[Recently I was involved in a project that required a user interface that would facilitate the manipulation of a hierarchical data structure.  I was already using JBoss RichFaces so it made perfect sense to utilise the tree and associated components (i.e. recursiveTreeNodesAdaptor and treeNode).  The project was also utilising the Spring Framework and Spring Web [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I was involved in a project that required a user interface that would facilitate the manipulation of a hierarchical data structure.  I was already using <a href="http://www.jboss.org/richfaces" target="_blank">JBoss RichFaces</a> so it made perfect sense to utilise the tree and associated components (i.e. recursiveTreeNodesAdaptor and treeNode).  The project was also utilising the <a href="http://www.springsource.org/about" target="_blank">Spring Framework</a> and <a href="http://www.springsource.org/webflow" target="_blank">Spring Web Flow</a> and these were also incorporated into the eventual solution.</p>
<p>To start with, as any good developer does, I searched for existing solutions to the problem and while I found some useful information I did not find exactly what I was looking for.  With this in mind, when I eventually finished the development of the user interface I decided I would share my implementation and hopefully you will find what follows useful.</p>
<p>To allow you to follow along, I have made the source (maven project) available as a <a href="http://thoughtforge.net/wp-content/uploads/2010/01/dynamic-tree-source.zip" target="_blank">download</a>.  This way, I do not have to worry about explaining everything in minute detail.</p>
<p>For a preview, you can always build the source, deploy to a server and navigate to http://[server]:[port]/dynamic-tree/spring/flow-main replacing the [server] and [port] with appropriate values.<br />
<span id="more-345"></span><br />
<strong>The Data Structure</strong></p>
<p>For the purpose of demonstrating my implementation, I am going to use a simple organisational hierarchy (as discussed in Martin Fowlers book ‘Analysis Patterns’) as illustrated below:<br />
<br/><br />
<div id="attachment_350" class="wp-caption aligncenter" style="width: 225px"><img class="size-full wp-image-350     " style="border: 0pt none; margin: 5px;" title="Data Structure" src="http://thoughtforge.net/wp-content/uploads/2010/01/figure1.PNG" alt="Data Structure" width="215" height="141" /><p class="wp-caption-text">Figure 1 : Data Structure</p></div><br />
<br/><br />
This is a very basic hierarchical data structure but it suffices for my purpose.  The implementation of this class is also very basic and requires little explanation.  To keep things simple, I have not considered the persistence mechanism that was employed.<br />
<br/></p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>package prototype.dynamictree.model;

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

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(&quot;prototype&quot;)
public class Organisation implements Serializable {

&nbsp;&nbsp;private static final long serialVersionUID = -2023156931701914562L;

&nbsp;&nbsp;private List&amp;lt;Organisation&amp;gt; children;

&nbsp;&nbsp;private String description;

&nbsp;&nbsp;private String name;

&nbsp;&nbsp;private Organisation parent;

&nbsp;&nbsp;public void addChild(Organisation child) {
&nbsp;&nbsp;&nbsp;&nbsp;if (child.getParent() == null || !child.getParent().equals(this)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;child.setParent(this);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (children == null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children = new ArrayList&amp;lt;Organisation&amp;gt;();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (!children.contains(child)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children.add(child);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;public void removeChild(Organisation child) {
&nbsp;&nbsp;&nbsp;&nbsp;if (child.getParent() != null &amp;amp;&amp;amp; child.getParent().equals(this)) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;child.setParent(null);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;if (children != null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children.remove(child);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}

&nbsp;&nbsp;public List&amp;lt;Organisation&amp;gt; getChildren() {
&nbsp;&nbsp;&nbsp;&nbsp;if (children == null) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;children = new ArrayList&amp;lt;Organisation&amp;gt;();
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;return Collections.unmodifiableList(children);
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getDescription() {
&nbsp;&nbsp;&nbsp;&nbsp;return description;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setDescription(String description) {
&nbsp;&nbsp;&nbsp;&nbsp;this.description = description;
&nbsp;&nbsp;}

&nbsp;&nbsp;public String getName() {
&nbsp;&nbsp;&nbsp;&nbsp;return name;
&nbsp;&nbsp;}

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

&nbsp;&nbsp;public Organisation getParent() {
&nbsp;&nbsp;&nbsp;&nbsp;return parent;
&nbsp;&nbsp;}

&nbsp;&nbsp;public void setParent(Organisation parent) {
&nbsp;&nbsp;&nbsp;&nbsp;this.parent = parent;
&nbsp;&nbsp;}
}</pre></pre>
</div>
<p class="wp-caption-text">Listing 1 : Organisation.java</p>
</div>
<p><br/><br />
Strictly speaking, a Set would have been a more appropriate data structure for the Organisation&#8217;s children but I encountered strange behaviour by the tree component if Set was used as opposed to List.</p>
<p><strong>Displaying the Hierarchical Data</strong></p>
<p>As already mentioned, I used Spring Web Flow to manage the UI conversations and binding with the entity model.  The first step in the flow creates the root Organisation and sets a default name (Joe Bloggs Inc).  The second step is a view step that renders the hierarchical data using the tree component.<br />
<br/></p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;rich:page
&nbsp;&nbsp;xmlns:a4j=&quot;http://richfaces.org/a4j&quot;
&nbsp;&nbsp;xmlns:rich=&quot;http://richfaces.org/rich&quot;
&nbsp;&nbsp;xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
&nbsp;&nbsp;xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
&nbsp;&nbsp;markupType=&quot;xhtml&quot; sidebarWidth=&quot;100&quot; width=&quot;400&quot;
&nbsp;&nbsp;pageTitle=&quot;Dynamic Tree User Interface&quot;&gt;

&nbsp;&nbsp;&lt;f:view&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:form&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:panel id=&quot;dynamicTreePanel&quot; header=&quot;Dynamic Tree User Interface&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:tree icon=&quot;/image/node.gif&quot; iconLeaf=&quot;/image/node.gif&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:recursiveTreeNodesAdaptor roots=&quot;#{rootOrganisation}&quot; var=&quot;_rootOrganisation&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;#{_rootOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:recursiveTreeNodesAdaptor roots=&quot;#{_rootOrganisation.children}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var=&quot;_childOrganisation&quot; nodes=&quot;#{_childOrganisation.children}&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;#{_childOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:recursiveTreeNodesAdaptor&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:recursiveTreeNodesAdaptor&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:tree&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:panel&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:form&gt;
&nbsp;&nbsp;&lt;/f:view&gt;
&lt;/rich:page&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 2 : dynamicTree.xhtml</p>
</div>
<p><br/><br />
The reason I have used a nested recursiveTreeNodesAdaptor component is that later in the process, I will be associating a different contextMenu component with the root node than other nodes.</p>
<p>Upon executing the flow the following is rendered.<br />
<br/><br />
<div id="attachment_402" class="wp-caption aligncenter" style="width: 588px"><img class="size-full wp-image-402         " style="margin: 5px;" title="Figure 2 : Rendered View" src="http://thoughtforge.net/wp-content/uploads/2010/01/figure2.PNG" alt="Figure 2: rendered View" width="578" height="85" /><p class="wp-caption-text">Figure 2 : Rendered View</p></div><br />
<br/><br />
<strong>Creating the Node Selection Listener</strong></p>
<p>In order to manipulate the tree structure, we will need to be able to determine the currently selected node.  This is achieved by creating a class to listen for the node selection event and configuring this class to receive the event.</p>
<p>The code for the class is straight forward and the listing is as follows:<br />
<br/></p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>package prototype.dynamictree.bean;

import java.io.Serializable;

import org.richfaces.component.html.HtmlTree;
import org.richfaces.event.NodeSelectedEvent;

public class DynamicTree implements Serializable {

&nbsp;&nbsp;private static final long serialVersionUID = 4935795680279034480L;

&nbsp;&nbsp;private Object selectedNodeData;

&nbsp;&nbsp;public void processNodeSelection(NodeSelectedEvent event) {
&nbsp;&nbsp;&nbsp;&nbsp;HtmlTree tree = ((HtmlTree) event.getComponent());

&nbsp;&nbsp;&nbsp;&nbsp;selectedNodeData = tree.getRowData();
&nbsp;&nbsp;}

&nbsp;&nbsp;public Object getSelectedNodeData() {
&nbsp;&nbsp;&nbsp;&nbsp;return selectedNodeData;
&nbsp;&nbsp;}
}</pre></pre>
</div>
<p class="wp-caption-text">Listing 3 : DynamicTree.java</p>
</div>
<p><br/><br />
The method getSelectedNodeData will return the Organisation associated with the selected node.</p>
<p>To configure the class to receive the node selection event (via ajax) the tree component attributes need to be amended as follows:<br />
<br/></p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;rich:page
&nbsp;&nbsp;xmlns:a4j=&quot;http://richfaces.org/a4j&quot;
&nbsp;&nbsp;xmlns:rich=&quot;http://richfaces.org/rich&quot;
&nbsp;&nbsp;xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
&nbsp;&nbsp;xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
&nbsp;&nbsp;markupType=&quot;xhtml&quot; sidebarWidth=&quot;100&quot; width=&quot;400&quot;
&nbsp;&nbsp;pageTitle=&quot;Dynamic Tree User Interface&quot;&gt;

&nbsp;&nbsp;&lt;f:view&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:form&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:panel id=&quot;dynamicTreePanel&quot; header=&quot;Dynamic Tree User Interface&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:tree ajaxSubmitSelection=&quot;true&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ajaxSingle=&quot;true&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nodeSelectListener=&quot;#{dynamicTree.processNodeSelection}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rightClickSelection=&quot;true&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;icon=&quot;/image/node.gif&quot; iconLeaf=&quot;/image/node.gif&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:recursiveTreeNodesAdaptor roots=&quot;#{rootOrganisation}&quot; var=&quot;_rootOrganisation&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;#{_rootOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:recursiveTreeNodesAdaptor roots=&quot;#{_rootOrganisation.children}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var=&quot;_childOrganisation&quot; nodes=&quot;#{_childOrganisation.children}&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;#{_childOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:recursiveTreeNodesAdaptor&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:recursiveTreeNodesAdaptor&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:tree&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:panel&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:form&gt;
&nbsp;&nbsp;&lt;/f:view&gt;
&lt;/rich:page&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 4 : dynamicTree.xhtml</p>
</div>
<p><br/><br />
<strong>Adding Support for Creating Child Nodes</strong></p>
<p>Now that we are being notified of the node selection event we will be able to add child nodes to the tree component.  This will achieved by adding 2 context menu components (one for the root node and one for all others) and a modal dialog.<br />
<br/></p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;rich:page
&nbsp;&nbsp;xmlns:a4j=&quot;http://richfaces.org/a4j&quot;
&nbsp;&nbsp;xmlns:rich=&quot;http://richfaces.org/rich&quot;
&nbsp;&nbsp;xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
&nbsp;&nbsp;xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
&nbsp;&nbsp;markupType=&quot;xhtml&quot; sidebarWidth=&quot;100&quot; width=&quot;400&quot;
&nbsp;&nbsp;pageTitle=&quot;Dynamic Tree User Interface&quot;&gt;

&nbsp;&nbsp;&lt;a4j:loadStyle src=&quot;/css/style.css&quot;/&gt;

&nbsp;&nbsp;&lt;f:view&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:form&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:panel id=&quot;dynamicTreePanel&quot; header=&quot;Dynamic Tree User Interface&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:tree ajaxSubmitSelection=&quot;true&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ajaxSingle=&quot;true&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nodeSelectListener=&quot;#{dynamicTree.processNodeSelection}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rightClickSelection=&quot;true&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;icon=&quot;/image/node.gif&quot; iconLeaf=&quot;/image/node.gif&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:recursiveTreeNodesAdaptor roots=&quot;#{rootOrganisation}&quot; var=&quot;_rootOrganisation&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;#{_rootOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:componentControl disableDefault=&quot;true&quot; event=&quot;oncontextmenu&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for=&quot;rootContextMenu&quot; operation=&quot;show&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:recursiveTreeNodesAdaptor roots=&quot;#{_rootOrganisation.children}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var=&quot;_childOrganisation&quot; nodes=&quot;#{_childOrganisation.children}&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;#{_childOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:componentControl disableDefault=&quot;true&quot; event=&quot;oncontextmenu&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for=&quot;childContextMenu&quot; operation=&quot;show&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:recursiveTreeNodesAdaptor&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:recursiveTreeNodesAdaptor&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:tree&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:panel&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- context menu&#039;s --&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:contextMenu id=&quot;rootContextMenu&quot; attached=&quot;false&quot; submitMode=&quot;ajax&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Add Child&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:support event=&quot;onclick&quot; action=&quot;addChild&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oncomplete=&quot;Richfaces.showModalPanel(&#039;addChildModalPanel&#039;)&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:contextMenu&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:contextMenu id=&quot;childContextMenu&quot; attached=&quot;false&quot; submitMode=&quot;ajax&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Add Child&quot;/&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:support event=&quot;onclick&quot; action=&quot;addChild&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oncomplete=&quot;Richfaces.showModalPanel(&#039;addChildModalPanel&#039;)&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:contextMenu&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- modal panels --&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:modalPanel id=&quot;addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resizeable=&quot;false&quot; height=&quot;200&quot; width=&quot;330&quot;&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;f:facet name=&quot;header&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Add Organisation&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/f:facet&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:panelGrid columns=&quot;2&quot; rendered=&quot;#{addChildModalPanelRendered}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;columnClasses=&quot;verticalAlignTop&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Name:&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:inputText value=&quot;#{addChildOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputLabel value=&quot;Description:&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:inputTextarea value=&quot;#{addChildOrganisation.description}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rows=&quot;5&quot; cols=&quot;30&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:panelGrid&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:panelGroup style=&quot;display:block; text-align:center&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:commandButton action=&quot;addChildModalPanelConfirm&quot; value=&quot;Ok&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onclick=&quot;Richfaces.hideModalPanel(&#039;addChildModalPanel&#039;)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;styleClass=&quot;commandButton&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:commandButton action=&quot;addChildModalPanelCancel&quot; value=&quot;Cancel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onclick=&quot;Richfaces.hideModalPanel(&#039;addChildModalPanel&#039;)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;styleClass=&quot;commandButton&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:panelGroup&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:modalPanel&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:form&gt;
&nbsp;&nbsp;&lt;/f:view&gt;
&lt;/rich:page&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 5 : dynamicTree.xhtml</p>
</div>
<p><br/><br />
<div id="attachment_419" class="wp-caption aligncenter" style="width: 590px"><img class="size-full wp-image-419  " style="margin: 5px;" title="Figure3 : Context Menu" src="http://thoughtforge.net/wp-content/uploads/2010/01/figure3.PNG" alt="Figure3 : Context Menu" width="580" height="91" /><p class="wp-caption-text">Figure3 : Context Menu</p></div><br />
<br/><br />
As you can see, when the user right clicks on a tree node, the appropriate context menu will be displayed.  If the user then clicks on &#8216;Add Child&#8217; the addChild flow transition is invoked (via ajax) which creates a child Organisation object.  On return from this ajax call the dynamicTreePanel and addChildModalPanel will be re-rendered before displaying the modal panel.<br />
<br/><br />
<div id="attachment_420" class="wp-caption aligncenter" style="width: 589px"><img class="size-full wp-image-420  " style="margin: 5px;" title="Figure 4 : Modal Panel" src="http://thoughtforge.net/wp-content/uploads/2010/01/figure4.PNG" alt="Figure 4 : Modal Panel" width="579" height="299" /><p class="wp-caption-text">Figure 4 : Modal Panel</p></div><br />
<br/><br />
When the user clicks on the Ok button, the modal dialog is hidden and the addChildModalPanelConfirm flow transition is invoked.  This transition adds the child Organisation to its parent and again on return from this ajax call the dynamicTreePanel and addChildModalPanel will be re-rendered.<br />
<br/><br />
When the user clicks on the Cancel button, the modal dialog is hidden and the addChildModalPanelCancel flow transition is invoked. On return from this ajax call the dynamicTreePanel and addChildModalPanel will be re-rendered.<br />
<br/><br />
<div id="attachment_426" class="wp-caption aligncenter" style="width: 588px"><img class="size-full wp-image-426 " style="margin: 5px;" title="Figure 5 : Tree with child nodes." src="http://thoughtforge.net/wp-content/uploads/2010/01/figure5.PNG" alt="Figure 5 : Tree with child nodes." width="578" height="141" /><p class="wp-caption-text">Figure 5 : Tree with child nodes.</p></div><br />
<br/><br />
I&#8217;m sure the wide awake among you have also noticed the addChildModalPanelRendered property.  This property is used to make sure the components that refer to a child Organisation are not rendered if no child organisation exists in the current conversation (i.e. when we are not actually adding a child organisation).<br />
<br/><br />
<strong>Adding Support for Editing Node Data</strong></p>
<p>Now that we are able to add a child node, it is relatively straight forward to add support for editing a node.  To achieve this, we will have to add 2 menu items to the already existing context menus and add another modal dialog.<br />
<br/></p>
<div id="attachment_350" class="wp-caption aligncenter" style="width: 100%;">
<div style="overflow: auto; height: 250px; width: 100%;">
<pre><pre>
&lt;rich:page
&nbsp;&nbsp;xmlns:a4j=&quot;http://richfaces.org/a4j&quot;
&nbsp;&nbsp;xmlns:rich=&quot;http://richfaces.org/rich&quot;
&nbsp;&nbsp;xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
&nbsp;&nbsp;xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
&nbsp;&nbsp;markupType=&quot;xhtml&quot; sidebarWidth=&quot;100&quot; width=&quot;400&quot;
&nbsp;&nbsp;pageTitle=&quot;Dynamic Tree User Interface&quot;&gt;

&nbsp;&nbsp;&lt;a4j:loadStyle src=&quot;/css/style.css&quot;/&gt;

&nbsp;&nbsp;&lt;f:view&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:form&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:panel id=&quot;dynamicTreePanel&quot; header=&quot;Dynamic Tree User Interface&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:tree ajaxSubmitSelection=&quot;true&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ajaxSingle=&quot;true&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nodeSelectListener=&quot;#{dynamicTree.processNodeSelection}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rightClickSelection=&quot;true&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;icon=&quot;/image/node.gif&quot; iconLeaf=&quot;/image/node.gif&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:recursiveTreeNodesAdaptor roots=&quot;#{rootOrganisation}&quot; var=&quot;_rootOrganisation&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;#{_rootOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:componentControl disableDefault=&quot;true&quot; event=&quot;oncontextmenu&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for=&quot;rootContextMenu&quot; operation=&quot;show&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:recursiveTreeNodesAdaptor roots=&quot;#{_rootOrganisation.children}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var=&quot;_childOrganisation&quot; nodes=&quot;#{_childOrganisation.children}&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;#{_childOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:componentControl disableDefault=&quot;true&quot; event=&quot;oncontextmenu&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for=&quot;childContextMenu&quot; operation=&quot;show&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:treeNode&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:recursiveTreeNodesAdaptor&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:recursiveTreeNodesAdaptor&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:tree&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:panel&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- context menu&#039;s --&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:contextMenu id=&quot;rootContextMenu&quot; attached=&quot;false&quot; submitMode=&quot;ajax&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Add Child&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:support event=&quot;onclick&quot; action=&quot;addChild&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oncomplete=&quot;Richfaces.showModalPanel(&#039;addChildModalPanel&#039;)&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:menuItem&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:menuSeparator/&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Edit&quot;/&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:support event=&quot;onclick&quot; action=&quot;editChild&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, editChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oncomplete=&quot;Richfaces.showModalPanel(&#039;editChildModalPanel&#039;)&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:contextMenu&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:contextMenu id=&quot;childContextMenu&quot; attached=&quot;false&quot; submitMode=&quot;ajax&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Add Child&quot;/&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:support event=&quot;onclick&quot; action=&quot;addChild&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oncomplete=&quot;Richfaces.showModalPanel(&#039;addChildModalPanel&#039;)&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:menuSeparator/&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Edit&quot;/&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:support event=&quot;onclick&quot; action=&quot;editChild&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, editChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oncomplete=&quot;Richfaces.showModalPanel(&#039;editChildModalPanel&#039;)&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:menuItem&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:contextMenu&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- modal panels --&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:modalPanel id=&quot;addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resizeable=&quot;false&quot; height=&quot;200&quot; width=&quot;330&quot;&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;f:facet name=&quot;header&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Add Organisation&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/f:facet&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:panelGrid columns=&quot;2&quot; rendered=&quot;#{addChildModalPanelRendered}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;columnClasses=&quot;verticalAlignTop&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Name:&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:inputText value=&quot;#{addChildOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputLabel value=&quot;Description:&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:inputTextarea value=&quot;#{addChildOrganisation.description}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rows=&quot;5&quot; cols=&quot;30&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:panelGrid&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:panelGroup style=&quot;display:block; text-align:center&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:commandButton action=&quot;addChildModalPanelConfirm&quot; value=&quot;Ok&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onclick=&quot;Richfaces.hideModalPanel(&#039;addChildModalPanel&#039;)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;styleClass=&quot;commandButton&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:commandButton action=&quot;addChildModalPanelCancel&quot; value=&quot;Cancel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onclick=&quot;Richfaces.hideModalPanel(&#039;addChildModalPanel&#039;)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, addChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;styleClass=&quot;commandButton&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:panelGroup&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:modalPanel&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;rich:modalPanel id=&quot;editChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resizeable=&quot;false&quot; height=&quot;200&quot; width=&quot;330&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;f:facet name=&quot;header&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Edit Organisation&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/f:facet&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:panelGrid columns=&quot;2&quot; rendered=&quot;#{editChildModalPanelRendered}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;columnClasses=&quot;verticalAlignTop&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Name:&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:inputText value=&quot;#{editChildOrganisation.name}&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:outputText value=&quot;Description:&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:inputTextarea value=&quot;#{editChildOrganisation.description}&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rows=&quot;5&quot; cols=&quot;30&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:panelGrid&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h:panelGroup style=&quot;display:block; text-align:center&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:commandButton action=&quot;editChildModalPanelConfirm&quot; value=&quot;Ok&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onclick=&quot;Richfaces.hideModalPanel(&#039;editChildModalPanel&#039;)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, editChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;styleClass=&quot;commandButton&quot;/&gt;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;a4j:commandButton action=&quot;editChildModalPanelCancel&quot; value=&quot;Cancel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;onclick=&quot;Richfaces.hideModalPanel(&#039;editChildModalPanel&#039;)&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reRender=&quot;dynamicTreePanel, editChildModalPanel&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;styleClass=&quot;commandButton&quot;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ajaxSingle=&quot;true&quot;/&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:panelGroup&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/rich:modalPanel&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/h:form&gt;
&nbsp;&nbsp;&lt;/f:view&gt;
&lt;/rich:page&gt;
</pre></pre>
</div>
<p class="wp-caption-text">Listing 6 : dynamicTree.xhtml</p>
</div>
<p><br/><br />
As you can see, the context menu&#8217;s operate in the same way as before as does the flow transitions and modal dialogs.  The main difference here is in the flow transition because rather that create a new child Organisation we are editing an existing one.</p>
<p>It is also worth pointing out the use of the ajaxSingle=&#8221;true&#8221; attribute on the Cancel commandButton component.  The reason this is used is so that the model is not updated during the ajax request.</p>
<p><strong>Adding Support for Removing Child Nodes</strong></p>
<p>Similarly, it is relatively straight forward to add support for removing a child node.  To achieve this, we will have to add 2 menu items to the already existing context menus and a transition to the flow step.</p>
<p><strong>What&#8217;s Outstanding?</strong></p>
<p>I did notice during this process is that there are some strange happenings that need to be investigated further.</p>
<ul>
<li>When I use a Set as opposed to a List for the child variable in Organisation.java the tree does not bahave as expected.</li>
<li>When I try to remove the last child node from the root node the tree does not behave as expected</li>
</ul>
<p>I realise there is some duplication in the above that should be removed but I do hope you have found this useful and look forward to your comments.<br />
<br/><br />
Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/01/19/building-a-dynamic-tree-with-jboss-richfaces-and-spring-web-flow/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Practical RichFaces</title>
		<link>http://thoughtforge.net/2010/01/08/practical-richfaces/</link>
		<comments>http://thoughtforge.net/2010/01/08/practical-richfaces/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 17:09:16 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Book Review]]></category>
		<category><![CDATA[Rich Faces]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=306</guid>
		<description><![CDATA[As I had mentioned in a previous post, I recently invested in a couple of books on JBoss RichFaces.  Having read and reviewed JBoss RichFaces 3.3 I set about doing the same for the other book, Practical RichFaces.
The book started out giving the same background information on JSF, RichFaces and Ajax4Jsf but in contrast to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.co.uk/Practical-RichFaces-Max-Katz/dp/1430210559%3FSubscriptionId%3DAKIAIEF6UQB4LZ3JULBQ%26tag%3Dthouforg-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1430210559"><img class="alignright" src="http://ecx.images-amazon.com/images/I/51HNm0uVTTL._SL160_.jpg" alt="" width="130" height="160" /></a>As I had mentioned in a previous post, I recently invested in a couple of books on JBoss RichFaces.  Having read and reviewed <a href="http://thoughtforge.net/2009/12/16/jboss-rich-faces-3-3/" target="_self">JBoss RichFaces 3.3</a> I set about doing the same for the other book, <a href="http://www.amazon.co.uk/Practical-RichFaces-Max-Katz/dp/1430210559%3FSubscriptionId%3DAKIAIEF6UQB4LZ3JULBQ%26tag%3Dthouforg-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1430210559" target="_blank">Practical RichFaces</a>.</p>
<p>The book started out giving the same background information on JSF, RichFaces and Ajax4Jsf but in contrast to JBoss RichFaces 3.3 stated that it will not be using JBoss Seam in the example&#8217;s which I was happy about.  That is of course not a reflection on JBoss Seam but more my desire to read about RichFaces and not the many technologies that might complement it.</p>
<p>In the second chapter, the book suggests installing JBoss Tools and as I have not used this Eclipse plug-in before I decided I would do just that.  It then proceeds to work through a small example to verify the Eclipse\JBoss Tools installation.  This is done in some detail and would be quite useful if looking at RichFaces for the first time.</p>
<p>Some time is then spent introducing the main RichFaces components that support Ajax functionality, namely &lt;a4j:comandLink&gt;, &lt;a4j:commandButton&gt;, &lt;a4j:support&gt; and &lt;a4j:poll&gt;.  These concepts were covered clearly and concisely with good use of appropriate examples.  The remaining a4j components are covered in the chapter that follows.</p>
<p>Having covered the a4j components the book then proceeds to cover the majority of rich components dividing the coverage into input components, output components, data iteration components, selection components and menu components.  The coverage of the input components is brief which is to be expected as it would be difficult to add anything to the JBoss RichFaces reference documentation.  The coverage of the output components is a little more in-depth than the reference documentation and demonstrates, by example, some nice tips and tricks.  The data iteration components, selection components and menu components are covered in roughly the same level of detail as that provided by the reference documentation.</p>
<p>The Scrollable Data Table and Tree are given a chapter of their own which covers the main functionality and usage of these components.  As with <a href="http://thoughtforge.net/2009/12/16/jboss-rich-faces-3-3/" target="_self">JBoss RichFaces 3.3</a> I was disappointed with the level of coverage the Tree component received.  This is one of the more complicated components and I would like to have seen more examples of its usage.</p>
<p>The last chapter on skinning is on a par with <a href="http://thoughtforge.net/2009/12/16/jboss-rich-faces-3-3/" target="_self">JBoss RichFaces 3.3</a> and covers the subject well.</p>
<p>My overall impression was again that I&#8217;m not really sure that this book adds anything to the freely available reference documentation but the tutorial style is certainly easier to read.  I would recommend this book for someone starting out with RichFaces or for someone wanting to read a book end-to-end to get up to speed quickly.  What is really needed for RichFaces is a RichFaces Recipe&#8217;s Book which is packed full of real world examples of using rich faces beyond the simple examples available on the RichFaces demo website.</p>
<p>One last comment that I would make on the book is that it got me wondering about the level of proof reading of these books.  There are a number of glaring errors that would have been noticed if reviewed by anyone with RichFaces knowledge who reads this book.  I think these types of mistakes should not make their way to print.</p>
Note: There is a rating embedded within this post, please visit this post to rate it.
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2010/01/08/practical-richfaces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JBoss Rich Faces 3.3</title>
		<link>http://thoughtforge.net/2009/12/16/jboss-rich-faces-3-3/</link>
		<comments>http://thoughtforge.net/2009/12/16/jboss-rich-faces-3-3/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 11:30:54 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Book Review]]></category>
		<category><![CDATA[Rich Faces]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=208</guid>
		<description><![CDATA[I have been developing with JBoss Rich Faces for a couple of years now and recently I decided to invest in a couple of books on the subject to try and obtain a better (more rounded) understanding of the framework.  When purchasing books related to frameworks that already have good reference documentation I&#8217;m always sceptical [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.amazon.co.uk/JBoss-RichFaces-3-3-Demetrio-Filocamo/dp/1847196888%3FSubscriptionId%3DAKIAIEF6UQB4LZ3JULBQ%26tag%3Dthouforg-21%26linkCode%3Dxm2%26camp%3D2025%26creative%3D165953%26creativeASIN%3D1847196888"><img class="alignright" src="http://ecx.images-amazon.com/images/I/51SOeWfRfxL._SL160_.jpg" alt="" width="130" height="160" /></a>I have been developing with JBoss Rich Faces for a couple of years now and recently I decided to invest in a couple of books on the subject to try and obtain a better (more rounded) understanding of the framework.  When purchasing books related to frameworks that already have good reference documentation I&#8217;m always sceptical that the book will provide additional insight above and beyond the freely available references.</p>
<p>One of the books I purchased was &#8216;JBoss Rich Faces 3.3&#8242; which I set about reading from cover to cover.  As with many of these books, it builds a sample application to demonstrate the use of the framework in a &#8216;real world&#8217; application.  In this instance, an advanced contact manager is developed.</p>
<p>The development of the application is demonstrated using Seam, Facelets, Hibernate JPA and Hibernate Validator which may or may not be desirable for the reader.  I personally have no immediate interest in Seam and I found the level of content dedicated to Seam to be excessive.  There are a number of books available on Seam and I would have purchased one of those had I wanted to read about Seam.  I have used Hibernate JPA extensively and given that JPA is a standardised API it&#8217;s inclusion in the examples is welcome (it makes for more realistic examples).</p>
<p>The demonstration application used the AJAX components of Rich Faces extensively and this was one of the areas I wanted to focus on.  Each of the AJAX components is discussed in the context of the contact manager application as well as smaller examples.  This does a good job of relaying the key characteristics of the component and its attributes.  In particular, the book does a reasonably good job of describing how the AJAX support components interact with the JSF lifecycle.</p>
<p>One thing that I would have liked to have seen was a significant working example of using the RichFaces tree components in conjunction with JPA entities.  I have been toiling over this myself for some time now.</p>
<p>I&#8217;m not really sure that this book add&#8217;s anything to the freely available reference documentation but the tutorial style is certainly easier to read, particularly if you want to get up to speed quickly.  Reading the reference documentation end-to-end would be as tedious as watching channel 4&#8217;s Big Brother dominated summer programming.<br />
<br/><br />
Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2009/12/16/jboss-rich-faces-3-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building Twitter with Grails</title>
		<link>http://thoughtforge.net/2009/12/08/building-twitter-with-grails/</link>
		<comments>http://thoughtforge.net/2009/12/08/building-twitter-with-grails/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 18:24:19 +0000</pubDate>
		<dc:creator>John Turner</dc:creator>
				<category><![CDATA[Groovy & Grails]]></category>
		<category><![CDATA[Training & Certification]]></category>

		<guid isPermaLink="false">http://thoughtforge.net/?p=228</guid>
		<description><![CDATA[I have been hearing good things about Groovy and Grails for quite a while now without really knowing much about either.  The aquisition of the company that developed Grails (G2One) by Spring Source in late 2008 has naturally added some weight to the Grails movement.  Having grown tired of standing, eyes glazed over, [...]]]></description>
			<content:encoded><![CDATA[<p>I have been hearing good things about <a href="http://groovy.codehaus.org/" target="_blank">Groovy</a> and <a href="http://www.grails.org/" target="_blank">Grails</a> for quite a while now without really knowing much about either.  The aquisition of the company that developed Grails (G2One) by Spring Source in late 2008 has naturally added some weight to the Grails movement.  Having grown tired of standing, eyes glazed over, as others discuss the advantages delivered by Grails I decided I would learn more.</p>
<p>One of the more popular demonstrations of Grails is that delivered by Graeme Rocher in which he demonstrates building an application similar to Twitter using Grails.  A webinar of this demonstration is available for download from the <a href="http://www.springsource.com/webinars" target="_blank">Spring Source website</a>.</p>
<p>The webinar runs for just over an hour and begins by giving an introduction to Grails, what it is, what it hopes to deliver and how it delivers it.  This includes how Grails leverages existing technologies such as Spring, Hibernate, Sitemesh and Groovy.  Graeme then gives a brief history of Grails explaining its inception in 2005 through to acquisition by Spring in 2008 before using download metrics to give an indication of the current adoption of Grails (70,000 downloads per month at the end of 2008).</p>
<p>The core of the webinar is focused on the demonstration of building Twitter with Grails.  Graeme starts by introducing the Grails command line interface and uses it to build the initial project directory and file structure.  He gives an tour of the directory structure explaining what goes where before proceeding to install the Spring Security (acegi) plugin for Grails.  The functionality provided by this plugin includes the generation of the authentication domain model, authentication manager and login\registration process (user interface and controllers).</p>
<p>Graeme then demonstrates the creation of additional domain model objects to which he adds associations and constraints.  In order to manipulate the additional domain objects, Graeme creates a controller and associated view (.gsp file).  This controller and view facilitates posting a tweet and displaying a history of tweets.</p>
<p>Graeme then proceeds to install and demonstrate the use of the Searchable plugin which facilitates searching for domain objects using criteria queries.  This also requires overriding the default view of the searchable plugin.  The Searchable plugin and associated view modifications allow the user to add people who they are interested in hearing tweets from.</p>
<p>If someone who the current user is interested in adds a tweet, a JMS message is sent to notify them (update their tweet history) that a new tweet has been added.  The JMS functionality is delivered via an activemq plugin which is installed through the Grails command line interface.</p>
<p>Graeme then demonstrates exposing the same tweets via RSS and XML using the same controller that handles web requests.</p>
<p>The key features of Grails are specified as:</p>
<ul>
<li>Plugins to let you rapidly compose an application</li>
<li>Plugins that use convention over configuration</li>
<li>Not only a web framework but an entire platform (JMS support etc.)</li>
<li>Plugins to enable testing (Selenium, Fitness, Code Coverage etc.)</li>
<li>Rich Grails (Flex, GWT, Grails UI\Yahoo UI etc.)</li>
<li>Secure Grails (Spring Security, JSecurity OpenID)</li>
<li>Integrate Grails (Search, Jasper Reports, JMS)</li>
</ul>
<p>This was a good introduction to Grails, the command line interface, project conventions and the plugin system.  It has piqued my interest sufficiently that I will spend a bit more time (when I have it!) progressing through some of the many Grails tutorials.<br />
<br/><br />
Note: There is a rating embedded within this post, please visit this post to rate it.</p>
]]></content:encoded>
			<wfw:commentRss>http://thoughtforge.net/2009/12/08/building-twitter-with-grails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
