<?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>Andy Gibson &#187; Apprentice</title>
	<atom:link href="http://www.andygibson.net/blog/tag/apprentice/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.andygibson.net/blog</link>
	<description>Open Source Projects &#38; Technical Writings</description>
	<lastBuildDate>Tue, 07 Feb 2012 14:19:07 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language></language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CDI Conversations part 2</title>
		<link>http://www.andygibson.net/blog/tutorial/cdi-conversations-part-2/</link>
		<comments>http://www.andygibson.net/blog/tutorial/cdi-conversations-part-2/#comments</comments>
		<pubDate>Tue, 21 Sep 2010 13:07:43 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Apprentice]]></category>
		<category><![CDATA[CDI]]></category>
		<category><![CDATA[Conversation]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[JSF]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1279</guid>
		<description><![CDATA[This article will look at using the Conversation scope defined in JSR 299 (Java Contexts and Dependency Injection), and released as part of Java EE 6. For now, we&#8217;ll stick to non-data driven examples as we explore the ins and outs of the Conversation scope. We&#8217;ll finish up by creating a workspace manager so we [...]]]></description>
			<content:encoded><![CDATA[<p>This article will look at using the Conversation scope defined in JSR 299 (Java Contexts and Dependency Injection), and released as part of Java EE 6. For now, we&#8217;ll stick to non-data driven examples as we explore the ins and outs of the Conversation scope. We&#8217;ll finish up by creating a workspace manager so we can list all the active conversations and switch between them.<br />
<span id="more-1279"></span><br />
A Conversation is like a numbered bucket in the session that exists until either the end of the users session, the conversation times out, or the server side code deliberately ends the conversation. The benefits of a conversational scope are many, letting us easily create pages that can be opened in multiple tabs without having to juggle the state on the client without filling the session with data that will last as long as the user session should we forget to remove it.</p>
<p>We&#8217;ll start by creating a project from the <a href="http://www.andygibson.net/blog/projects/knappsack" target="_blank">knappsack</a><code>jee6-servlet-basic</code>  archetype. This gives us all the features of Java EE 6 without too much code to get in the way.  We&#8217;ll start by creating a backing bean that is request scoped and looking at how that is used and what effect request scope has.</p>
<pre class="brush: java;">
import java.io.Serializable;

import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named(&quot;bean&quot;)
@RequestScoped
public class BackingBean implements Serializable {

	private Long value = new Long(0);

	public Long getValue() {
		return value;
	}

	public void setValue(Long value) {
		this.value = value;
	}

        public String getMessage() {
            return &quot;The value is : &quot;+value;
        }
}
</pre>
<p>Simple enough, now lets add a page called <code>listEdit.xhtml</code>that lets us enter the value, post the value back and see what the message is. </p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;ui:composition xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
	xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot;
	xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
	xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
	template=&quot;/WEB-INF/templates/template.xhtml&quot;&gt;
	&lt;ui:define name=&quot;content&quot;&gt;
		&lt;h:form id=&quot;form&quot;&gt;
            Value : &lt;h:inputText value=&quot;#{bean.value}&quot; /&gt;
			&lt;h:commandButton value=&quot;Submit Value&quot; action=&quot;submit&quot; /&gt;
			&lt;br /&gt;
			&lt;br /&gt;
            Message : #{bean.message}
   &lt;/h:form&gt;

	&lt;/ui:define&gt;
&lt;/ui:composition&gt;
</pre>
<p>Edit <code>home.xhtml</code> to include a link to this page :</p>
<pre class="brush: xml;">
&lt;a href=&quot;listEdit.jsf&quot;&gt;Start New List&lt;/a&gt;
</pre>
<p>Open up the home page and click the link to go to the <code>listEdit</code> page. If we enter a value in the input box and click the submit button, predictably, our message says that the value is whatever we entered.</p>
<div class="contentBox alignCenter">
<img src="http://www.andygibson.net/blog/wp-content/uploads/2010/08/request_scoped_bean1.png" alt="Request Scoped Bean Entry Screenshot" title="Request Scoped Bean Entry Screenshot" width="578" height="302" class="alignnone size-full wp-image-1285" />
</div>
<p>What is happening here is that when the form is posted back, the value in the input box is sent back to the <code>bean.value</code> attribute. When the page is rendered back to the user and the message is rendered, it is rendered using this value that we passed back to the server. We pass the state of the attribute from the server to the client, and then back to the server, and we can do that all day long using just the request scope without any problems. This is a stateless page and doesn&#8217;t require any state to be held on the server.</p>
<p>Let&#8217;s add something a bit more stateful to the page such as a list of values that we have added previously. In our backing bean, add the following field and getter method and a method to add the value.</p>
<pre class="brush: java;">
private List&lt;Long&gt; values = new ArrayList&lt;Long&gt;();
..
..
..
public List&lt;Long&gt; getValues() {
	return values;
}

public void addToList() {
	values.add(value);
}
</pre>
<p>Now we will add the list of values to our page to be displayed.</p>
<pre class="brush: xml;">
&lt;ui:define name=&quot;content&quot;&gt;
	&lt;h:form id=&quot;form&quot;&gt;
		Value : &lt;h:inputText value=&quot;#{bean.value}&quot; /&gt;
		&lt;h:commandButton value=&quot;Submit Value&quot; action=&quot;#{bean.addToList}&quot; /&gt;
		&lt;br /&gt;
		&lt;br /&gt;
		Message : #{bean.message}
		&lt;h2&gt;Added Values&lt;/h2&gt;
		&lt;ui:repeat var=&quot;v_value&quot; value=&quot;#{bean.values}&quot;&gt;
			#{v_value}&lt;br /&gt;
		&lt;/ui:repeat&gt;
	&lt;/h:form&gt;
&lt;/ui:define&gt;
</pre>
<p>If we refresh our page, enter a number and click submit, you will see that the number appears at the bottom of the page where it should. When we click the submit button on the form the value is assigned to the <code>value</code> attribute. When the <code>addToList</code> method is called, the <code>value</code> attribute is added to the list. When the page is rendered, the latest value is used to generate the message and for the list of items we return the list containing one item, the new value.</p>
<p>So far so good. Let&#8217;s enter a new number and add it to the list. When we click the button the second time, the only number in the list of numbers is the one we just entered. The first value is gone! The problem is that the second time we posted the value the bean was re-constructed from scratch and had no idea whatsoever about the first value we added to the list. There was nothing on the form to tell the bean about the first number even though we displayed it on the page. The backing bean keeps forgetting our list of numbers from one request to the next, or in other words, our application is missing some state.</p>
<p>As per part 1, there are a number of ways we can get around this problem. We could save the list to the database each time we post, which is over kill for this simple task.   We could push the state down to the client, say using a comma delimited list of existing numbers pushed into a hidden field. When the form is posted, the comma delimited list is sent back to the server where the numbers are unpacked and the list is rebuilt on the server side and the state is restored.<br />
Both of these two methods are doable but what happens when we have more information on the server that we need to keep hold of? Do we have to keep adding add each piece of information to the client state manually, including passing it around from one page to the next for multi-page processes? What if it is a list of entity objects we want to hold on to? Do we just save the Ids on the client and keep re-loading them from the database each time?<br />
These solutions are impractical from the perspective of building a maintainable app quickly. However, note that these solutions are completely possible with JSF and CDI. It just offers better alternatives, but the opportunity to get under the hood and use more lower level solutions in the interests of optimizing the application are always there.  This is an important factor since if you have a widely used conversational page that is creating a bottle neck, you can refactor it down to use a more stateless approach. </p>
<p>Since this article is all about conversations, obviously, we are going to solve our problems using the conversation scope. We will change our bean to be <code>@ConversationScoped</code> and <code>@Inject</code> a <code>Conversation</code> instance we&#8217;ll be using. We&#8217;ll then start the conversation for the page when our bean is constructed. This is an example and typically you don&#8217;t start conversations in bean construction but it serves our purpose here.<br />
<small><b>Tip</b> : Conversations are typically started at specific points on certain initialization methods, starting it on bean construction is bad because you never know when another task might use an instance of that bean</small></p>
<pre class="brush: java;">

@Named(&quot;bean&quot;)
@ConversationScoped
public class BackingBean implements Serializable {
	...
	...
	...
	@Inject
	private Conversation conversation;
	...
	...
	@PostConstruct
	public void postConstruct() {
		conversation.begin();
	}

	public Conversation getConversation() {
		return conversation;
	}
	...
	...
}
</pre>
<p>Reload our page and you can see how you can enter and submit as many numbers as you want to the page and the list state is managed.</p>
<div class="contentBox alignCenter">
<a target="_blank" href="http://www.andygibson.net/blog/wp-content/uploads/2010/08/conv_2_num_list.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/08/conv_2_num_list-300x248.png" alt="Conversation Number List Screenshot" title="Conversation Number List Screenshot" width="300" height="248" /></a>
</div>
<p>Conversations are just a natural extension of the existing scopes in current web applications. They also become very natural to use. Let&#8217;s add another page that lets us review our list of numbers before &#8216;confirming&#8217; them. Add the following new button at the bottom of our page : </p>
<pre class="brush: xml;">
	&lt;h:commandButton action=&quot;review&quot; value=&quot;Review Numbers&quot;/&gt;
</pre>
<p>Because the <code>action</code> attribute is set to <code>review</code> we will create a new page called <code>review.xhtml</code> that will display the numbers. Our first concern obviously is &#8216;where does it get the list of numbers from?&#8217;, well the answer is, from the same place it got the numbers from last time, using the expression <code>#{bean.values}</code>.</p>
<p><code>review.xhtml</code></p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;ui:composition xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
	xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot;
	xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
	xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
	template=&quot;/WEB-INF/templates/template.xhtml&quot;&gt;
	&lt;ui:define name=&quot;content&quot;&gt;
		&lt;h:form id=&quot;form&quot;&gt;
			&lt;h1&gt;Please Confirm The Values : &lt;/h1&gt;
			&lt;h2&gt;Added Values&lt;/h2&gt;
			&lt;ui:repeat var=&quot;v_value&quot; value=&quot;#{bean.values}&quot;&gt;
			#{v_value}&lt;br /&gt;
			&lt;/ui:repeat&gt;
			&lt;h:commandButton action=&quot;#{bean.confirm}&quot; value=&quot;Confirm&quot;/&gt;
		&lt;/h:form&gt;
	&lt;/ui:define&gt;
&lt;/ui:composition&gt;
</pre>
<p>The way to think about this is to imagine what happens when the page is rendered. JSF will look for the value <code>beans.values</code> which the CDI implementation can provide. Since this page is being rendered in an active conversation, CDI will look in the active conversation &#8216;bucket&#8217; for a bean called <code>bean</code>. Since we are coming from the page that adds the numbers, this bean will already exist in the conversation and so the same instance is returned. Should we render this page without an active conversation, by typing in the URL manually, the page will render, but this time, the instance of <code>beans.xml</code> will not already exist and so CDI will create a new instance of it that doesn&#8217;t contain any items.<br />
<small><b>Tip : </b>There are ways to prevent pages rendering without an active conversation which can also help with duplicate form submissions</b></small></p>
<p>Getting back to the page, we just want to add our confirm method to our backing bean. This method ends the conversation and redirects to the home page which is going back to the number entry page. </p>
<pre class="brush: java;">
public void confirm() {
	conversation.end();
	try {
		FacesContext.getCurrentInstance().getExternalContext().redirect(&quot;home.jsf?faces-redirect=true&quot;);
	} catch (IOException e) {
		e.printStackTrace();
	}
}
</pre>
<p>Add the following at the top of either the review or list edit page to see the conversation Id you are currently in : </p>
<pre class="brush: xml;">
Conversation : #{bean.conversation.id}
</pre>
<p>If you run the application, you can add numbers and when you click review, you get a list of all the numbers you just entered on a separate page.</p>
<div class="contentBox alignCenter">
<a target="_blank" href="http://www.andygibson.net/blog/wp-content/uploads/2010/08/conv_2_num_confirm.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/08/conv_2_num_confirm-300x260.png" alt="Conversational Number Confirmation" title="Conversational Number Confirmation" width="300" height="260" /></a>
</div>
<p>If we were managing state ourselves, we would have to pass something to the review page to let is know what the list of numbers was, either a database row key, or the comma delimited values. Again, the more state you have to pass around the less verbose and maintainable the application becomes.  CDI is automatically passing our key (the conversation id) around for us. Under the review button the list edit page, add the following GET link :</p>
<pre class="brush: xml;">
&lt;h:link outcome=&quot;review&quot; value=&quot;Review&quot;/&gt;
</pre>
<p>If you look at the link URL it is <code>http://localhost:8080/conversationdemo/review.jsf?cid=xxx</code> where xxx is some number. CDI automatically creates a URL that propagates the conversation for us. If we didn&#8217;t want to propagate the conversation, we can just add a blank <code>cid</code>  parameter and CDI will leave it alone. This can be useful when you want to launch a page without a conversation from a page that is in a conversation. Add the following link : </p>
<pre class="brush: xml;">
&lt;h:link value=&quot;Start New List&quot; target=&quot;_blank&quot;&gt;
	&lt;f:param name=&quot;cid&quot; /&gt;
&lt;/h:link&gt;
</pre>
<p>This lets you start a fresh new list in a separate window (since we didn&#8217;t specify an outcome it defaults to the current page). If you create a new list and add some numbers you can see that you can manage separate lists independently without doing anything to handle multiple browser windows.</p>
<p>When you have multiple windows open, set the url of one window to the url of other (i.e. <code>http://localhost:8080/conversationdemo/listEdit.jsf?cid=xxx</code> where xxx is the other conversation ID) when you load this page, you see the list from the other conversation so you can just switch conversations using GET requests by specifying a different conversation id. </p>
<h1>Workspace Management</h1>
<p>One cool feature of Seam that had a lot of potential was workspace management which lets you see a list of active conversations and select one. We are going to implement a version of that here by providing the user with a set of links that takes us to the active conversation. Create a new bean that is session scoped that will keep a track of our conversation ids.</p>
<pre class="brush: java;">
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class WorkspaceBean implements Serializable {

	private List&lt;String&gt; conversations = new ArrayList&lt;String&gt;();

	public List&lt;String&gt; getConversations() {
		return conversations;
	}

}
</pre>
<p>This is just a bean that keeps a list of the conversation Ids currently active. When we start a conversation, we need to add that id to the list and when we end a conversation, we need to remove it from the list. </p>
<p>We will inject this session scoped bean into our backing bean and change the <code>postConstruct</code> and <code>confirm</code> methods in the <code>BackingBean</code> class to add and remove the conversation from the list.</p>
<pre class="brush: java;">
@Inject
private WorkspaceBean workspace;

...
...

@PostConstruct
public void postConstruct() {
	conversation.begin();
	workspace.getConversations().add(conversation.getId());
}

public void confirm() {
	workspace.getConversations().remove(conversation.getId());
	conversation.end();

	try {
		FacesContext ctx = FacesContext.getCurrentInstance();
		ctx.getExternalContext().redirect(&quot;home.jsf?faces-redirect=true&quot;);
	} catch (IOException e) {
		e.printStackTrace();
	}
}
</pre>
<p>Now we need some view code to display the list of conversations and provide links to them. Simply add this to the <code>home.xhtml</code> page, and even the <code>listEdit.xhtml</code> or <code>review.xhtml</code> pages if you want : </p>
<pre class="brush: xml;">
	&lt;h1&gt;Workspaces&lt;/h1&gt;
	&lt;ui:repeat var=&quot;v_conv&quot; value=&quot;#{workspaceBean.conversations}&quot;&gt;
		&lt;h:link outcome=&quot;listEdit&quot; value=&quot;Goto Conversation #{v_conv}&quot;&gt;
			&lt;f:param name=&quot;cid&quot; value=&quot;#{v_conv}&quot; /&gt;
		&lt;/h:link&gt;
		&lt;br /&gt;
	&lt;/ui:repeat&gt;
</pre>
<p>This just loops through the conversations and creates a link to the <code>listEdit</code> page and passes the conversation Id as a parameter. Because we pass a value for <code>cid</code> CDI will not try to add the current conversation as the <code>cid</code> value.</p>
<p>That&#8217;s all you need for a workspace demonstration. You can create new lists and if you jump back to the home page, you will see the available conversations and be able to click the link and jump back into the conversation. When you review the list and confirm it and the conversation ends, when you end up back on the front page, that conversation is longer listed. </p>
<div class="contentBox alignCenter">
<a target="_blank" href="http://www.andygibson.net/blog/wp-content/uploads/2010/08/conv_2_workspace.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/08/conv_2_workspace-300x235.png" alt="Conversation Workspace Screenshot" title="Conversation Workspace Screenshot" width="300" height="235" class="alignnone size-medium wp-image-1409" /></a>
</div>
<p>This is a fairly powerful mechanism that is built upon the simplicity of CDI Conversations. There is very little work that is required to use conversations, just inject the <code>Conversation</code> instance and call the <code>begin()</code> and <code>end()</code> methods when you need to start and end the conversation. Conversations also have a minimal impact on our code, mainly just an annotation since the getters and settings and other methods don&#8217;t change. We can also easily revert back to a stateless request scoped solution should we have to which would cause additional code to be required to read/write the list to the client.<br />
Conversations should be used with care, especially in terms of making sure you have strict demarcation boundaries, and careful consideration should be given to determining what you include in a conversation.</p>
<p>You can download the maven project source code for this demo (<a href='http://www.andygibson.net/blog/wp-content/uploads/2010/08/conversationdemo.zip'>Conversation Demo </a>), just unzip it and enter <code>mvn jetty:run</code> and navigate to <a href="http://localhost:8080/conversationdemo/home.jsf">http://localhost:8080/conversationdemo/home.jsf</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/tutorial/cdi-conversations-part-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>JSF Basics</title>
		<link>http://www.andygibson.net/blog/tutorial/jsf-basics/</link>
		<comments>http://www.andygibson.net/blog/tutorial/jsf-basics/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 12:51:19 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Apprentice]]></category>
		<category><![CDATA[CDI]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[JSF]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1372</guid>
		<description><![CDATA[This is a brief tutorial that takes a quick look at some of the very basics of JSF, how we define pages and hook them up to server side objects. Rather than cover the fundamentals of starting a new JSF application, I&#8217;m going to start from one of the Knappsack archetypes which can provide you [...]]]></description>
			<content:encoded><![CDATA[<p>This is a brief tutorial that takes a quick look at some of the very basics of JSF, how we define pages and hook them up to server side objects. Rather than cover the fundamentals of starting a new JSF application, I&#8217;m going to start from one of the Knappsack archetypes which can provide you with a JEE 6 application ready to roll.  In this case, we are going to start with a servlet based example so you can run it using the embedded servlet containers.<br />
<span id="more-1372"></span><br />
To create the new project, we are going to use the following archetype GAV values. You can also read up  on <a href="http://www.andygibson.net/blog/tutorial/getting-started-with-maven-archetypes/" target="_blank">creating a new Knappsack application</a></p>
<pre class="brush: plain;">
groupId = org.fluttercode.knappsack
artifactId=jee6-servlet-basic
version=1.0.5
</pre>
<p>Once you have your project, just run <code>mvn jetty:run</code> in the command line and navigate to <a href="http://localhost:8080/jsfbasics/home.jsf">http://localhost:8080/jsfbasics/home.jsf</a>. Ok, so now we are up and running, lets look at a JSF page and what it contains.</p>
<p>JSF uses a templating language called facelets. JSF 1 originally used JSP as its view language, but for JSF 2.0 Facelets became the defacto standards and was adopted as the standard view definition languages for JSF 2.0. In our application, we have a template file called <code>WEB-INF/templates/template.xhtml</code>. The template just has a lot of boilerplate view code but there are some <code>ui:insert</code> tags that mark places in the template where we should insert content. For example, the main content is inserted in a facelets area called <code>content</code></p>
<pre class="brush: xml;">
&lt;ui:insert name=&quot;content&quot;&gt;Main Content&lt;/ui:insert&gt;
</pre>
<p>These are insertion points which are used by pages that base themselves on this template. One of the great features of facelets is that the template defines the content points, while the page itself is used to define the template used and then push the content into the content points. This is much better than having to include page fragments in a JSP page, using a page decorator or using a template to include the content page. Our main page <code>home.xhtml</code> is one such page that uses this template. </p>
<p><code>home.xhtml</code></p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;ui:composition xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
	xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot;
	xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
	xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
	template=&quot;/WEB-INF/templates/template.xhtml&quot;&gt;

	&lt;ui:define name=&quot;content&quot;&gt;
		&lt;h1&gt;&lt;h:outputText value=&quot;Hello From JSF&quot; /&gt;&lt;/h1&gt;
	&lt;/ui:define&gt;

&lt;/ui:composition&gt;
</pre>
<p>At the very top, in the composition tag, we tell Facelets that we want to use the file <code>template.xhtml</code> as our template page. Next we have a <code>ui:define</code> tag that defines the content that is to be used in the template. Facelets works by having the page pull the template into the page and pushing its content into the slots provided by the template. This is much better than pulling content into the main page using includes, or specifying a template used everywhere and decorating the content with it. This is the best of both worlds. Each page defines which template page it uses and pushes the content into it. </p>
<h2>Our first used component</h2>
<p>In here you can see we have used our first JSF component : </p>
<pre class="brush: xml;">
&lt;h:outputText value=&quot;Hello From JSF&quot; /&gt;
</pre>
<p>This is a standard JSF component that is used to output text. We could have just written the text right in the page, but the goal of this page is to test that the JSF configuration is working and to do that, we need to see if the JSF component is rendered correctly.  You can edit the text in the value and obviously it will change the text displayed on the page.</p>
<h2>Our first backing bean</h2>
<p>Displaying static text isn&#8217;t what web frameworks were built for, what we really want is to display something that comes from some java code. To do this, we will create a backing bean which is a java object that is part of the web application that JSF is aware of. To create backing bean, create a new class and call it <code>PageBean</code>.</p>
<pre class="brush: java;">
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@Named
@RequestScoped
public class PageBean {

	private String message = &quot;Mighty apps from little java beans grow&quot;;

	public String getMessage() {
		return message;
	}

	public void setMessage(String message) {
		this.message = message;
	}
}
</pre>
<p>The code itself is pretty simple. One field with a default value and getters and setters. However, we have a couple of new annotations at the class level. First is the <code>@Named</code> annotation that tells CDI that this bean has a name that be used to refer to this bean using EL expressions. Since we didn&#8217;t supply a name the default name of <code>pageBean</code> is used. The <code>@RequestScope</code> annotation tells CDI that this bean is request scoped so when it is created, it should last till the end of the current request and then be destroyed. This means that the next time we call this page, this bean will be re-created and a fresh version used which again will be destroyed at the end of the request.</p>
<p>Now we are going to change our application to display this message instead.From now on, we will just be showing the code within the <code>ui:define</code> statements:</p>
<pre class="brush: xml;">
	&lt;ui:define name=&quot;content&quot;&gt;
		&lt;h:outputText value=&quot;#{pageBean.message}&quot; /&gt;
	&lt;/ui:define&gt;
&lt;/ui:composition&gt;
</pre>
<p>If we run the application now, you should see the message displayed on the main page:</p>
<div class="alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasic1_motd.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasic1_motd-300x190.png" alt="JSF Basic message of the day screenshot" title="JSF Basic message of the day screenshot" width="300" height="190" /></a>
</div>
<p>Now let&#8217;s take look at a producer method that can be used to display the date and time the page was rendered. First, open up the template file and look for the footer panel at the bottom and change it to :</p>
<pre class="brush: xml;">
&lt;h:panelGroup id=&quot;footer&quot; layout=&quot;block&quot;&gt;This page was rendered at #{currentSysDate}&lt;/h:panelGroup&gt;
</pre>
<p>What is <code>currentSysDate</code> value? Well, we need to go back to our <code>PageBean</code> and define it. We will add a new method that returns a new <code>Date</code> object and we&#8217;ll annotate it with <code>@Named</code> and <code>@Produces</code>. </p>
<pre class="brush: java;">
@Produces @Named(&quot;currentSysDate&quot;)
public Date produceDate() {
	return new Date();
}
</pre>
<p>The <code>Produces</code> and <code>Named</code> annotation tells CDI that this method can be used to produce a value with the name <code>currentSysDate</code>. When our application is deployed, CDI makes a note that this value comes from this method so when our page is rendered and JSF is looking for the value <code>currentSysDate</code>, CDI calls the method and returns the value obtained from this method.</p>
<p>If we refresh the page we can see that our new timestamp function is on there.</p>
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasic_timestamp.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasic_timestamp-300x185.png" alt="JSF Basic Timestamp Screenshot" title="JSF Basic Timestamp Screenshot" width="300" height="185"  /></a>
</div>
<p>This will come in handy later on when we start using AJAX and want to check that the full page has not updated (the timestamp will stay the same because that portion of the page won&#8217;t change). We&#8217;ve shown how we can pull data from the server onto the page so let&#8217;s take a look at how we send data back to the server.</p>
<p>In our <code>home.xhtml</code> page, we&#8217;ll add a text input to edit the message and a button to post it back.</p>
<pre class="brush: java;">
&lt;h:form id=&quot;messageForm&quot;&gt;
	&lt;h:outputText value=&quot;#{pageBean.message}&quot; /&gt;&lt;br/&gt;
	&lt;br/&gt;
	New Message : &lt;h:inputText value=&quot;#{pageBean.message}&quot;/&gt;
	&lt;h:commandButton action=&quot;update&quot; value=&quot;Update&quot;/&gt;
&lt;/h:form&gt;
</pre>
<p>First, we added the <code>h:form</code> tags which gives us an HTML form in which to put input controls. Any data entry in a JSF page needs to be enclosed in a JSF form tag in order to be passed back to the server. We defined an input text box that was bound to the same value as the message display and a command button that is used to post the values back. If we refresh the page, enter a new message and click the button our message changes.</p>
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasic1_form_post.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasic1_form_post-300x184.png" alt="JSF Basic Form Post Screenshot" title="JSF Basic Form Post Screenshot" width="300" height="184"  /></a>
</div>
<p>However, this is the age of Web 2.0, and just posting back a form and displaying the results isn&#8217;t enough, we need to do it with AJAX. AJAX is a mechanism by which the browser makes an asynchronous request to the server and gets a response back. When the response is returned, the browser will call a javascript function that will update part of the page instead of all of it. Sounds complicated, but the nice folks that wrote JSF wrapped all that functionality up in one little tag called <code>f:ajax</code></p>
<p>What we want to do is make our command button an AJAX button which we can do by placing the <code>f:ajax</code> tag as a child tag of the button. All we need to supply the AJAX tag with is the <code>execute</code> and <code>render</code> attributes. This indicates which parts of the page we want to post back to the server, and which parts we want to re-render when the response comes back.  We want to execute the form and re-render the form, so we could use the component id (<code>messageForm</code>) for the attribute values. JSF also provides a couple of shortcuts that we can use. The value <code>@form</code> references the form the button is in so rather than hardcode the form id, the <code>@form</code> value will let us reference the form without doing so by name.</p>
<pre class="brush: java;">
&lt;h:commandButton action=&quot;update&quot; value=&quot;Update&quot;&gt;
	&lt;f:ajax execute=&quot;@form&quot; render=&quot;@form&quot; /&gt;
&lt;/h:commandButton&gt;
</pre>
<p>Notice that now you have an ajax button, the timestamp in the footer doesn&#8217;t change when you post the value back. </p>
<h1>Performing Actions</h1>
<p>So far we have covered displaying information from the server side bean and writing values back, but often we want some user action to execute some code on the server. </p>
<p>Start by adding a <code>Integer</code> attribute on to our <code>PageBean</code> class and two methods, one to increase it, and another to decrease it as well as getters and setters for the value.</p>
<pre class="brush: java;">
	private int value = 0;

	public void increase() {
		value++;
	}

	public void decrease() {
		value--;
	}
</pre>
<p>In the view, we want to display the value and have a couple of buttons to increase and decrease the value. Add the following view code in <code>home.jsf</code> somewhere between the <code>h:form</code> tags :</p>
<pre class="brush: xml;">
&lt;h:panelGroup layout=&quot;block&quot; id=&quot;spinner&quot;&gt;
     &lt;h:commandButton action=&quot;#{pageBean.decrease}&quot; value=&quot;-&quot; /&gt;
     #{pageBean.value}
     &lt;h:commandButton action=&quot;#{pageBean.increase}&quot; value=&quot;+&quot; /&gt;
&lt;/h:panelGroup&gt;
</pre>
<p>Refresh the page and click away, and you&#8217;ll notice something is wrong. Press the increase button and the value goes to 1, click it again and it&#8230;goes to 1. Click the decrease button and it will always go to -1. The problem is an issue of state. Each time we click the button, we post back to the server, and the server creates a new instance of the <code>pageBean</code> and calls the increase or decrease methods. The problem is that each time we create the bean, the value starts at zero and so is only ever increased to 1 or decreased to -1.<br />
Now you may be wondering that since you are displaying the value on the page, isn&#8217;t that enough to post it back to the server, after all, we displayed the message in an input box and it got passed back to the server. The difference is that an input box is known as a JSF value holder, which means it actually holds the value it is bound to on the client and posts it back to the server when the form is posted back. We can see this demonstrated by changing the value text display component to an input text box component:</p>
<pre class="brush: java;">
&lt;h:panelGroup layout=&quot;block&quot; id=&quot;spinner&quot;&gt;
    &lt;h:commandButton action=&quot;#{pageBean.decrease}&quot; value=&quot;-&quot;/&gt;
    &lt;h:inputText value=&quot;#{pageBean.value}&quot;/&gt;
    &lt;h:commandButton action=&quot;#{pageBean.increase}&quot; value=&quot;+&quot; /&gt;
&lt;/h:panelGroup&gt;
</pre>
<p>Now when you click the +/- buttons the value changes beyond -1 and 1. This is because when the page is rendered, the value is stored on the client. When the button is clicked and the form is posted back, the client side value is sent back to the server side attribute and then the increase/decrease method is called with the value that is set. This is fairly common with web forms, and one way of handling state by putting it in client side forms, even as hidden field values.</p>
<p>We can demonstrate this further by manually entering a value into the text input and then clicking a button. Enter 1000 in the input text box and click the increase button. The value should now be 1001. </p>
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasics1_manual_input.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasics1_manual_input-300x184.png" alt="JSF Basics Manual Value Input" title="JSF Basics Manual Value Input" width="300" height="184" /></a>
</div>
<p>When we manually enter a value, we are changing the value held on the client in the value holder represented by the input text box. When we click the increase button we are sending that value back to the server. On postback, the server creates an instance of our <code>PageBean</code> class, sets the value attribute to the value in our text box (1000) and then calls the <code>increase</code> method which increases the value to 1001. Once the method has finished, JSF then must render a response which includes taking the value from the <code>pageBean.value</code> attribute and putting it in our text box which is how the text box shows 1001 after clicking the button. At this point, once our request is complete, the page bean is destroyed as it is only request scoped.</p>
<h2>Validating the value</h2>
<p>If we only want the value to be between 0 and 10, we can add validation annotations onto the value field to enable it to be checked for correctness when we post back the values. In our <code>PageBean</code> class, we&#8217;ll add the annotations as follows : </p>
<pre class="brush: java;">
@Min(value=0)
@Max(value=10)
private int value = 0;
</pre>
<p>We also need some way to display error messages if the user enters an invalid value so we&#8217;ll add a <code>h:message</code> tag. The message tag is used to associate a JSF message with a component and display it. We give the input text box a name and add the message for that component :</p>
<pre class="brush: java;">
&lt;h:panelGroup layout=&quot;block&quot; id=&quot;spinner&quot;&gt;
	  &lt;h:commandButton action=&quot;#{pageBean.decrease}&quot; value=&quot;-&quot;/&gt;
	  &lt;h:inputText value=&quot;#{pageBean.value}&quot; id=&quot;valueInput&quot;/&gt;
	  &lt;h:commandButton action=&quot;#{pageBean.increase}&quot; value=&quot;+&quot; /&gt;
	  &lt;h:message for=&quot;valueInput&quot; styleClass=&quot;errorMessage&quot;/&gt;
&lt;/h:panelGroup&gt;
</pre>
<p> Now refresh the page and enter 1000 into the value text input and click the increase button. You should see an error message next to the text editor because the value is above 10. Try entering the value of -1000 and clicking a button.</p>
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasic1_input_error.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/08/jsfbasic1_input_error-300x185.png" alt="JSF Basic Input Error Screenshot" title="JSF Basic Input Error Screenshot" width="300" height="185"/></a>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/tutorial/jsf-basics/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Knappsack Archetypes Part 2</title>
		<link>http://www.andygibson.net/blog/article/knappsack-archetypes-part-2/</link>
		<comments>http://www.andygibson.net/blog/article/knappsack-archetypes-part-2/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 15:03:07 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Apprentice]]></category>
		<category><![CDATA[Archetypes]]></category>
		<category><![CDATA[CDI]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[Knappsack]]></category>
		<category><![CDATA[Maven]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1097</guid>
		<description><![CDATA[In part 1, we looked at the basic structure and configuration of the project that is common in all the archetypes. This time we&#8217;ll look at the minimal archetype that contains some more functionality and a number of different classes used to implement that functionality. The Java EE 6 Minimal Archetype While there is still [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.andygibson.net/blog/article/knappsack-archetypes-part-1/">part 1</a>, we looked at the basic structure and configuration of the project that is common in all the archetypes. This time we&#8217;ll look at the minimal archetype that contains some more functionality and a number of different classes used to implement that functionality. <span id="more-1097"></span></p>
<h1>The Java EE 6 Minimal Archetype</h1>
<p>While there is still only one web page in the project, there are now a few more classes provided. These have been grouped into packages off the main package folder.</p>
<table>
<tr>
<th>Package</th>
<th>Description</th>
</tr>
<tr>
<td><code>bean</code></td>
<td>The <code>bean</code> package contains the <code>EntityManager</code> producer and also a dao object for fetching and persisting <code>Person</code> objects as a stateless EJB (and a local interface).</td>
</tr>
<tr>
<td><code>model</code></td>
<td>Contains the JPA model for ther application which in this case is just one <code>Person</code> class</td>
</tr>
<tr>
<td><code>qualifier</code></td>
<td>Contains the qualifier used to specify injection points for	the <code>EntityManager</code></td>
</tr>
<tr>
<td><code>view</code></td>
<td>Contains the backing beans for the JSF view. These beans provide server side logic for the JSF pages, usually by invoking functions on the service beans in the <code>bean</code> package. The <code>HelloBean</code> accepts a user entered name and returns a message. The <code>PersonBean</code> has a person entity that can be modified by a JSF page and then persisted to the database. There is also a method to return the list of previously saved people from the database.</td>
</tr>
</table>
<div class="sidenote_right">
<h1>Layered code</h1>
<p>We have a fairly clear separation of concerns with the different packages. The EJBs in the <code>bean</code> and <code>qualifier</code> packages don&#8217;t have any dependency on JSF while the beans in the <code>view</code> package are for JSF support only. Such organization means that you could put the contents of the bean and qualifier packages into a separate jar and re-use them with a different view framework. Technically, because they are also POJOs you could use them in a non-EJB environment.</div>
<h2>Producing Entity Managers</h2>
<p>The <code>EntityManager</code> is produced in the <code>DataRepositoryProducer</code> bean by returning the persistence context that was injected into the stateless bean by the container. When an entity manager needs to be injected into an injection point, this method is used to produce one. It is marked as <code>@ConversationScoped</code> so it can participate in CDI conversations. The <code>@DataRepository</code> annotation is a qualifier annotation used to mark what kind of entity manager you are producing and therefore can only be injected into injection points with the same annotation. This is useful if there are multiple databases used to distinguish between different entity managers produced.</p>
<h2>Service Beans</h2>
<p>In the <code>PersonDao</code> we inject the <code>EntityManager</code> that is then used in the other methods to save and fetch objects. In EJB 3.1 the default transaction attribute is <code>Required</code> for EJB methods so we don&#8217;t need to specify any transaction handling on the methods.</p>
<p />
The <code>PersonDao</code> is injected into the <code>view/PersonBean</code> class so as the view needs to fetch or update data, the dao can be used to provide those functions.</p>
<p />
If there was a mechanism that we could use to provide transactions on CDI (non-EJB) beans, then we wouldn&#8217;t really need EJBs, but as it is, we do. Nothing is stopping us from later changing the EJBs to CDI Managed beans with sufficient transaction support.</p>
<p />
<h2>JPA Model</h2>
<p>The only model class we use is the <code>Person</code> class that has properties for first name, last name and an integer Id value. On the name fields, we have specified a number of validators as well as the column size using annotations. These validators check that the field is not empty, or null and does not have a length greater than 25 characters.</p>
<p>Now we&#8217;ve covered the server side code, let&#8217;s take a look at the JSF page that uses these beans in <code>home.xhtml</code>. </p>
<h2>JSF Content</h2>
<p>The single page in this archetype is split into three different sections that test different parts of the environment.</p>
<p>The first part is producing the hello message from the <code>helloBean</code> class. The class is annotated with <code>@Named("helloBean")</code> which lets us reference this bean from the JSF page. The method <code>getHelloMessage()</code> returns a fixed string which is displayed in the page by using the EL expression <code>#{helloBean.helloMessage}</code>. This tells JSF to	get the <code>helloMessage</code> property from the bean called <code>helloBean</code>. The bean name is resolved using an EL expression resolver that looks up	the bean name in the beans registered with CDI using the <code>@Named</code> annotation.</p>
<p />
If you are using JBoss Developer Tools and have enabled CDI for this application (right click on project, click <i>Configure->Add CDI Support</i>, you can go into the JSF page and ctrl+click on the expression (either the bean name or the property name) and the IDE will go to the point in the code that the expression is defined.</p>
<p />
You can interact with the CDI hello bean by entering your name and clicking the submit button which posts your name back to the backing bean and when the page is re-rendered, your name appears in the message below the submit button. Again, the control is bound to the <code>name</code>	property of the <code>helloBean</code> bean which is then used to return the correct message to the user when the page is re-rendered.</p>
<p/>
The final section uses JSF and CDI to edit an instance of a <code>Person</code> object on the CDI backing bean, with JPA persisting the object and Bean Validation providing validation for the JSF page. JPA also returns a list of the people previously saved. The <code>PersonBean</code> class has the <code>@Named</code> annotation which gives it the name <code>personBean</code> and it is marked with a <code>@RequestScoped</code> annotation. The bean has a person instance that is used as the model for the JSF page input boxes. The text boxes are defined for the first and last names and bound to the person entity on the <code>personBean</code> bean. Each input has a <code>h:message</code> JSF tag that reports errors for that input value. This will report errors on the person bean based on the validators we specified on the model.  In the JSF page, the Add button calls the <code>savePerson</code> method on the <code>personBean</code> backing bean which uses the person dao implementation to persist the <code>person</code> entity in the backing bean. JSF automatically includes validation specified on the JPA model and will report errors back to the user for invalid input.</p>
<p/>Underneath the person data entry, there is a list of names that have already been entered. Just enter a new name and click add to see the new name appear.This is fetched from the backing bean using the dao that is injected into it.</p>
<h1>Using the app for yourself</h1>
<p>If you want to create a new application from this archetype, you will probably want to delete the following items.</p>
<pre>
/bean/PersonDao.java
/bean/PersonDaoLocal.java
/model/Person.java
/view/HelloBean.java
/view/PersonBean.java
</pre>
<p>While you may want to re-use the template, or a modified version of it, you won&#8217;t need the content in the <code>home.xhtml</code> file. You can remove the content surrounded by the <code>&lt;ui:define name="content"&gt;</code> tags.  Alternatively, you can just create a new project using the jee6-basic-archetype which has none of this additional code.</p>
<p>In the next section we&#8217;ll start looking at the JPA model and pre-defined data in the sandbox archetype.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/knappsack-archetypes-part-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Create A New Project With Maven Archetypes</title>
		<link>http://www.andygibson.net/blog/tutorial/getting-started-with-maven-archetypes/</link>
		<comments>http://www.andygibson.net/blog/tutorial/getting-started-with-maven-archetypes/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 16:50:12 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Apprentice]]></category>
		<category><![CDATA[Archetypes]]></category>
		<category><![CDATA[eclips]]></category>
		<category><![CDATA[Knappsack]]></category>
		<category><![CDATA[Maven]]></category>
		<category><![CDATA[Netbeans]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1076</guid>
		<description><![CDATA[Prerequisites Install Maven In this tutorial, we will create a new project using the Knappsack Archetypes and compile and deploy it. For this example, we will use the jee6-basic-archetype. Before you begin, you will need to have installed Maven, but you no longer need to manually install the Knappsack Archetypes as they are in the [...]]]></description>
			<content:encoded><![CDATA[<div class="prereq">
<ul>
<lh>Prerequisites</lh></p>
<li>Install Maven</li>
</ul>
</div>
<p>In this tutorial, we will create a new project using the Knappsack Archetypes and compile and deploy it. For this example, we will use the <code>jee6-basic-archetype</code>.  Before you begin, you will need to have installed Maven, but you no longer need to manually install the Knappsack Archetypes as they are in the Central Maven Repository now, so you just need to make sure your index is up to date.  These instructions will work for any Maven Archetype you have installed and creating new maven projects in general.<br />
<span id="more-1076"></span><br />
Maven archetypes can be thought of as templates that are installed into the Maven environment and can be used to generate new applications from scratch that are pre-configured for certain environments, whether it is Java EE 6, Wicket or Spring. We can create our project using either the command line or an IDE and both Eclipse and Netbeans both have support for Maven. Netbeans has it out of the box while Eclipse requires m2Eclipse to be installed. This tutorial covers all three methods of creating projects from Maven.</p>
<h1>New project from the Command Line</h1>
<ol>
<li>Start by opening up a command prompt and navigating to the directory your project will reside in</li>
<li>The easy way to create a project on the command line is to just type
<pre class="brush: plain;">
mvn archetype:generate
</pre>
<p>We will use the easier version where we don&#8217;t have to specify long command lines that include the group and archetype Ids and versions.
</li>
<li> You will be greeted with a long list of possible archetypes with a number next to them and a prompt at the bottom to enter the number of the archetype you want to use.
<pre class="brush: plain;">
4: local -&gt; jee6-minimal-archetype (Minimal Java EE application with a single page demo of CDI, JSF, JPA and Validation to ...
5: local -&gt; jee6-basic-archetype (Basic Java EE application with just configuration for CDI, JSF, JPA and a sample empty page.)
6: local -&gt; jee6-sandbox-archetype (Sandbox project for Java EE 6 with CDI, JSF, JPA and a sample model and test data to play ....
7: local -&gt; jee6-sandbox-demo-archetype (Complete demo example using CDI, JSF, JPA and validation showcasing a number of ...
8: remote -&gt; docbkx-quickstart-archetype (null)
9: remote -&gt; j2me-simple (Maven 2 Archetype for midlet application using j2me-maven-plugin)
10: remote -&gt; vaadin-archetype-clean (This archetype generates a simple Vaadin application as a Maven project...
...
...
...
...
Choose a number: 65:
</pre>
<p>Hint : Your locally installed ones should be near the start of the list. The default number (in this case 65) is the quickstart archetype to produce and empty maven project.
</li>
<li>Enter the number of the Knappsack archetype you want to use and press enter.</li>
<li>You will then be asked to enter a number of different properties for the project :
<pre class="brush: plain;">
Define value for property 'groupId': : com.yourcompany
Define value for property 'artifactId': : yourprojectname
Define value for property 'version': 1.0-SNAPSHOT:
Define value for property 'package': com.yourcompany:
Confirm properties configuration:
groupId: com.yourcompany
artifactId: yourprojectname
version: 1.0-SNAPSHOT
package: com.yourcompany
Y:
</pre>
<p>Here we assumed the version is the default SNAPSHOT version and that the default package is the same as the groupId value.
</li>
<li>Once complete, if you look in the directory you will see a new directory called <code>yourprojectname</code>. Move into this directory and if you have <code>JBOSS_HOME</code> set up you can deploy the project straight away.
<pre class="brush: plain;">
mvn clean package jboss:hard-deploy
</pre>
<p>Start up JBoss if it isn&#8217;t already and go to <a href="http://localhost:8080/yourprojectname/home.jsf">http://localhost:8080/yourprojectname/home.jsf</a>.
</li>
<li>You can now import this project into an IDE such as Eclipse or Netbeans as these IDEs recognize Maven projects</li>
</ol>
<p>Alternatively, you can use the command line to enter one long command, or as I do, put it in a script or batch file that I can edit in a text editor and run it from there. Here&#8217;s an example to get you started which you can copy and paste:</p>
<pre class="brush: plain;">
mvn archetype:generate -DarchetypeGroupId=org.fluttercode.knappsack -DarchetypeArtifactId=jee6-sandbox-demo-archetype -DinteractiveMode=false -DarchetypeVersion=1.0.4 -DgroupId=org.application -DartifactId=sandboxdemo -Dpackage=org.application
</pre>
<h1>Creating a project in an IDE</h1>
<p>Creating a Maven project in an IDE is much easier, although sometimes not by much. Typically, you choose to create a new project in the IDE and select maven as the type of project you want to create. </p>
<h2>Netbeans</h2>
<ol>
<li>Select <em>File->New Project</em> and in the first list, select <em>Maven</em> and on the right hand side, select <em>Maven Project</em> (<b>not</b> <em>Maven Web Application</em>). Click Next.</li>
<li>Here we will pick our archetype to create our application from. In the list, expand the <em>Archetypes from Local Repository</em> item in the list. If you don&#8217;t see the archetypes there, you might need to refresh the index in the IDE. Close the new project window to do this.
<ol>
<li>Select <em>Window->Other->Maven Repository Browser</em> to open the repository browser. </li>
<li>In the repository browser window, right click on the repository and select <em>Update Index</em>.</li>
</ol>
<p>Now you should be able to start the new project from scratch and see the missing archetypes.</p>
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/07/netbeans_select_archetype.png" target="_blank"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/07/netbeans_select_archetype-300x182.png" alt="Netbeans Select Archetype Screenshot" title="Netbeans Select Archetype" width="300" height="182" /></a>
</div>
<p>Once you have selected the archetype, click finish to setup the project properties.
</li>
<li>The project properties are the group and archetype Id for the new project as well as the optional default package name.
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/07/netbeans_project_properties.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/07/netbeans_project_properties-300x156.png" alt="netbeans project properties screenshot" title="netbeans project properties screenshots" width="300" height="156" /></a>
</div>
<p>You will also configure the project location here and click <em>Finish</em> when done.
</li>
<li>Once complete, Netbeans will create your project and open it up.  To run it, click <em>Run->Run Main Project</em> and it will prompt you for a Java EE 6 server to use. Select one and click ok. Remember that you need to change the datasource name in <code>persistence.xml</code> so it is not looking for the JBoss default datasource name. </li>
</ol>
<h2>Eclipse</h2>
<p>First make sure you have m2Eclipse installed and are running Eclipse under a JDK instead of a JRE. For more details see this  <a href="http://www.andygibson.net/tutorial/installing-and-configuring-eclipse/">Installing and configuring Eclipse tutorial</a>.</p>
<ol>
<li>In Eclipse, click on <em>File->New->Other..</em> to bring up the dialog for new projects and start typing &#8220;maven&#8221; in the search box</p>
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/07/eclipse_new_maven_project.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/07/eclipse_new_maven_project-300x186.png" alt="Eclipse New Maven Project Screenshot" title="Eclipse New Maven Project Screenshot" width="300" height="186" /></a>
</div>
<p>Select the maven project item from the list and click <em>Next</em>.
</li>
<li> This page lets you determine where the project will reside. Leave the defaults, but make sure the &#8220;Create simple project&#8221; option is <b>un</b>checked and click <em>Next</em>.</li>
<li>Here we will pick our archetype which in this case is our Knappsack jee6 minimal archetype. Start typing &#8220;knappsack&#8221; in the list and you will see the list of available Knappsack archetypes. Again, it is possible that the IDE&#8217;s index of the local repository is not up to date and needs a refresh. You will need to cancel the project creation window to do this.
<ol>
<li>Select <em>Window->Show View->Other</em> and in the view selection , start typing &#8220;Maven&#8221; until you see the window &#8220;Maven Repositories&#8221;. Select this to open up the view.</li>
<li>In the Maven Repositories view, expand the <em>Local Repositories</em> item and right click click on the <em>Local Repository (pathname)</em> item and select <em>Rebuild Index</em>. Confirm that you want to rebuild the index and wait a few moments.</li>
<li>Restart the project creation and this time you should see the archetypes you are looking for.</li>
</ol>
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/07/eclipse_select_knappsack.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/07/eclipse_select_knappsack-300x268.png" alt="Eclipse Select Archetype" title="Eclipse Select Archetype" width="300" height="268" /></a>
</div>
<p>Select the archetype you want to create and click <em>Next</em>.
</li>
<li>Now we need to enter the project configuration information, what our project is called, give it a group id, version and default package.
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/07/eclipse_project_properties.png"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/07/eclipse_project_properties-300x268.png" alt="Eclipse new Maven Project Properties" title="Eclipse new Maven Project Properties" width="300" height="268" /></a>
</div>
<p>Once the above information is entered you can click <em>Finish</em> and Eclipse will work away at creating your project
</li>
<li>To run the project, the easiest way is to install a server in Eclipse (see <a href="http://www.fluttercode.com/tutorial/installing-servers-into-eclipse/">Tutorial on adding servers in Eclipse</a>) and add the new project to the server. Start the server and navigate to your main page to see it in action.
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/tutorial/getting-started-with-maven-archetypes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Knappsack Archetypes Part 1</title>
		<link>http://www.andygibson.net/blog/article/knappsack-archetypes-part-1/</link>
		<comments>http://www.andygibson.net/blog/article/knappsack-archetypes-part-1/#comments</comments>
		<pubDate>Sun, 01 Aug 2010 16:28:53 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Apprentice]]></category>
		<category><![CDATA[CDI]]></category>
		<category><![CDATA[EJB]]></category>
		<category><![CDATA[Java EE]]></category>
		<category><![CDATA[JPA]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[Knappsack]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1093</guid>
		<description><![CDATA[This set of articles will document the contents of the Java EE archetypes for Maven. The archetypes come in four flavors, basic,minimal, sandbox and sandbox demo with each one being based on the previous one. In part 1, we&#8217;ll give an overview of the archetypes and the structure and configuration used in all of the [...]]]></description>
			<content:encoded><![CDATA[<p>This set of articles will document the contents of the Java EE archetypes for Maven. The archetypes come in four flavors, basic,minimal, sandbox and sandbox demo with each one being based on the previous one. In part 1, we&#8217;ll give an overview of the archetypes and the structure and configuration used in all of the archetypes.<span id="more-1093"></span></p>
<h1>The Java EE 6 Archetypes</h1>
<p>These Maven archetypes will help developers to get up and running with a new Java EE project quickly by creating the project structure that includes pre-defined configuration files. This lets developers create a project, remove parts they don&#8217;t need, and tweak those they want to keep. The balance is to provide something useful without burdening developers with a bunch of unwanted code and configuration. The basic and minimal archetypes serve this purpose. The basic archetype contains virtually no content, just configuration and a JSF page to confirm that it is working. The minimal archetype contains just a single page of content that demonstrates that JSF, JPA, CDI and validation are working. There are also two additional archetypes for servlet containers that can be used to run core features of Java EE 6 in a servlet contain such as Tomcat or Jetty.</p>
<p>The sandbox archetype takes things a bit further by adding a simple JPA model pre-populated with data. This gives developers a sandbox to play in with everything configured and data to use so they can test out ideas or play around with different pieces of Java EE. I also plan on using it as the foundation project for tutorials and articles on Java EE 6 that developers can follow along with. It removes the need to create and document creating a project with a data model and example data for each tutorial. With a pre-built tutorial project we can dive right in to the meat of the tutorial without the boilerplate.</p>
<p>The sandbox-demo archetype takes the sandbox application and extends it into a full featured application (albeit a contrived one) that demonstrates a number of features of Java EE 6, and gives developers an idea on how to get started developing applications using the Java EE stack. The demo is by no means perfect, it is mostly the bare minimum required to implement the necessary functionality. Again, it provides a good project to launch tutorials from by showing developers how to fix those little problems in the demo application. The demo also fills a gap in demonstrating to new developers how to work with these different technologies and integrate them.</p>
<p>These articles will cover the different archetypes and explain the functionality and features in each. We&#8217;ll start by covering the very basics, which is the creation of the project structure and configuration in the basic archetype which is also shared with all of the archetypes.</p>
<h1>The jee6-basic-archetype</h1>
<p>The basic archetype is a Maven project that is configured and ready to deploy in a Java EE 6 container. It contains the configuration files necessary to start up the Java EE services such as CDI, JPA and JSF as well as the dependencies in the <code>pom.xml</code> file.</p>
<p/>
In the root directory of the new project, we have the <code>pom.xml</code> file and a <code>readme.txt</code> which contains a description of the project and notes on how to deploy it.<br />
The <code>src/main/resources/</code> folder contains resources that the application may need. The <code>META-INF</code> sub folder contains the <code>persistence.xml</code> file which defines the JPA datasource name and sets properties for the JPA provider. If you are deploying to JBoss you are all set to go with the <code>DefaultDS</code> datasource, but for Glassfish, you will need to specify the <code>jdbc/__default</code> datasource instead which is commented out in the file, and remove the <code>DefaultDS</code> definition.</p>
<p/>
The main web content resides in the <code>src\main\webapp</code> folder which is structured as so :</p>
<div class="figure" style="width : 90%">
<h1>Web folder structure and content</h1>
<pre>
src/main/webapp			  Top level webapp folder
 |
 |-META-INF
 |    |-context.xml	 	  Configuration file for tomcat
 |
 |-resources			  Resources folder for JSF resources
 |  |-css			  CSS folder for stylesheets
 |     |
 |     |-screen.css	 	  Default stylesheet
 |
 |-WEB-INF			  Standard WEB-INF folder
 |   |-templates	   	  Templates folder for JSF templates
 |   |    |-template.xhtml     	  Default template file
 |   |
 |   |-beans.xml		  Indicates that this archive file has CDI beans
 |   |-faces-config.xml		  Configuration file for JSF
 |   |-web.xml			  web.xml file containing JSF configuration
 |
 |-home.xhtml			  Default home page using the WEB-INF\template\template.xhtml
 |-index.html			  Default file used to redirect to the home.jsf page
</pre>
</div>
<p>The <code>beans.xml</code>,<code>faces-config.xml</code> and the <code>web.xml</code> files have very little in them. The <code>web.xml</code> file provides the definition and mapping for the the faces servlet. The <code>beans.xml</code> is required to signal the container that this archive contains CDI beans and should be processed by the CDI deployer. This file could have other content if you use alternatives, decorators or interceptors.</p>
<div class="sidenote_right">
<h1>Servlet Schema Version</h1>
<p>The schema version for the <code>web.xml </code> defaults to 2.5 because of problems with Eclipse not recognizing the schema as valid when creating the project. For the most part, everything will work the same, but if it must be version 3.0 or later you can change once the project has been created without any problems.
</div>
<p>Pretty much everything in the <code>webapp</code> folder can be used in a new application, and it isn&#8217;t that difficult to rename and move elements (templates, page file names etc) to get everything how you want it set up. In general, xml files shouldn&#8217;t be moved or renamed, but everything else can be.  </p>
<p/>
If you are starting a new project, your first steps would be to move/rename/edit the template, <code>home.xhtml</code> and <code>screen.css</code> pages to your liking. You would also want to delete the <code>readme.txt</code> file.</p>
<p/>
The bulk of the content is in the  <code>pom.xml</code> file which specifies all the depencies the project uses, most of which have the scope of <code>provided</code> since we anticipate the server providing the dependencies. </p>
<p/>
All of the archetypes also contain some code for producing an <code>EntityManager</code> in the application using a Stateless EJB implementing a Local interface, and a CDI qualifier to specifying injection points for the entity manager produced. </p>
<ul>
<li><b><code>DataRepository.java</code></b> &#8211; Qualifier for the <code>EntityManager</code> instance.</li>
<li><b><code>DataRepositoryProducer.java</code></b> &#8211; Stateless EJB that produces the <code>EntityManager</code></li>
<li><b><code>DataRepositoryProducerLocal.java</code></b> &#8211; Local interface for the stateless EJB</li>
</ul>
<p>Technically, the Local interface shouldn&#8217;t be needed under EJB 3.1 which is part of Java EE 6, however Weld, the reference implementation of CDI has problems with EJBs without a local interface in that it cannot locate them. To see how to use the produced <code>EntityManager</code>, see the next part which covers the minimal archetype that has a small JPA data model.</p>
<p>This about wraps it up for configuration, there is very little added to the core project that you probably won&#8217;t need for a JSF/CDI/JPA application making the basic archetype a good choice for a new project where you don&#8217;t need the smoke tests to see if everything is setup and working.</p>
<p>Next time we&#8217;ll look at the minimal archetype in detail which contains somewhat more code and functionality to test that JSF/CDI/JPA is working as planned.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/knappsack-archetypes-part-1/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Accessing and Paginating CSV Files with DataValve</title>
		<link>http://www.andygibson.net/blog/tutorial/accessing-and-paginating-csv-files-with-datavalve/</link>
		<comments>http://www.andygibson.net/blog/tutorial/accessing-and-paginating-csv-files-with-datavalve/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 17:07:30 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Apprentice]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[DataValve]]></category>
		<category><![CDATA[JSF]]></category>
		<category><![CDATA[Swing]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1123</guid>
		<description><![CDATA[Prerequisites Install Maven Installing DataValve Into Maven While DataValve is mostly used with database driven back ends, this tutorial shows you how DataValve can turn a comma delimited file into a paginated list of objects that the user can page through. We will then use this data provider in a console application, a Swing application [...]]]></description>
			<content:encoded><![CDATA[<div class="prereq floatRight">
<ul> <lh>Prerequisites</lh></p>
<li>Install Maven</li>
<li><a href="http://www.andygibson.net/blog/tutorial/install-datavalve-into-maven/">Installing DataValve Into Maven</a></li>
</ul>
</div>
<p>While <a href="http://www.andygibson.net/blog/projects/datavalve/">DataValve</a> is mostly used with database driven back ends, this tutorial shows you how DataValve can turn a comma delimited file into a paginated list of objects that the user can page through. We will then use this data provider in a console application, a Swing application and a JSF web page using the DataValve data client interfaces.<br />
 <span id="more-1123"></span><br />
We will start by writing this tutorial as a console application and then demonstrate how the data provider can be used in other applications, even web applications. We&#8217;ll start by creating a new Maven application and then include the dependencies for DataValve. We&#8217;ll then create our comma delimited data provider, define a row mapper class for it, and hook it up to our demo data. We&#8217;ll then attach it to a dataset so we can easily iterate through the data. We will then take our provider and use it in different clients.</p>
<ol>
<li>Create a new Maven application in your IDE and add <code>datavalve-dataset</code>  as a dependency in your <code>pom.xml</code> file.
<pre class="brush: xml;">
	&lt;dependencies&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.fluttercode.datavalve&lt;/groupId&gt;
			&lt;artifactId&gt;datavalve-dataset&lt;/artifactId&gt;
			&lt;version&gt;0.9.0.CR2&lt;/version&gt;
		&lt;/dependency&gt;
	&lt;/dependencies&gt;
</pre>
</li>
<li>Create a new class called <code>Person</code> in the package of your choice. I used <code>org.fluttercode.tutorials.datavalve.csvreader</code> We will only be using one package in this demonstration.</li>
<li>The <code>Person</code> class will be our model which will be populated from the comma delimited file.
<pre class="brush: java;">
public class Person {

	private Integer id;
	private String firstName;
	private String middleName;
	private String lastName;
	private Date dob;
	private String email;
	private String address;
	private String city;
	private String zip;

	public Person() {
	}

	public Person(Integer id, String firstName, String lastName,String middleName,
			Date dob, String email, String address,
			String city, String zip) {
		super();
		this.id = id;
		this.firstName = firstName;
		this.middleName = middleName;
		this.lastName = lastName;
		this.email = email;
		this.dob = dob;
		this.address = address;
		this.city = city;
		this.zip = zip;
	}

	public String getName() {
		return firstName + &quot; &quot; + lastName;
	}

	public String getAddressText() {
		return address+ &quot;,&quot; + city+&quot;,&quot;+zip;
	}

	@Override
	public String toString() {
		return String.format(&quot;Person [id=%d, name=%s, dob=%s,address=%s, email=%s&quot;,
		    id,getName(),dob,getAddressText(),email);
	}

    .... Getters and Setters Omitted ....
}
</pre>
</li>
<li>In order to convert the csv data to an object, we need to create a <code>ColumnarRowMapper</code> instance. This takes a row of data, already converted to an array of string values, builds the model object from it and returns it back to the caller. Create a new class called <code>PersonRowMapper</code>.</li>
<pre class="brush: java;">
public class PersonRowMapper implements ColumnarRowMapper&lt;Person&gt; {

    private static SimpleDateFormat converter = new SimpleDateFormat(
			&quot;MM/dd/yyyy&quot;);

	public Person mapRow(String[] values) {
		Date dob = null;

		try {
			dob = converter.parse(values[5]);
		} catch (ParseException e) {
		}

		return new Person(DataConverter.getInteger(values[0]), values[1],
				values[2], values[3], dob, values[4], values[6], values[7],
				values[8]);
	}
}
</pre>
<p>This row mapper implements the <code>ColumnarRowMapper</code> interface and implements the single method to return a built entity object from the array of column values passed in.</p>
<li>The only other element we need is some test data to run it on which you can download from <a href='http://www.andygibson.net/blog/wp-content/uploads/2010/07/data.zip'>here</a>. Download this file and place it in the package folder with your source code. Depending on your IDE, you may need to refresh the folder in the package explorer so it can pick up the new file in the folder. The example file has 100 rows of data in it.</li>
<li>Create a new class called <code>ProviderFactory</code> which will create our provider and initialize it with the CSV file url.
<pre class="brush: java;">
public class ProviderFactory {

	public static CommaDelimitedProvider&lt;Person&gt; createProvider() {
		URL url = ProviderFactory.class.getResource(&quot;data.csv&quot;);
		CommaDelimitedProvider&lt;Person&gt; provider;
		provider = new CommaDelimitedProvider&lt;Person&gt;(url.getFile());
		provider.setRowMapper(new PersonRowMapper());
		return provider;
	}
}
</pre>
<p>We use a <code>URL</code> to reference the csv file stored in the jar from which we get a <code>File</code> instance that we can pass to our <code>CommaDelimitedProvider</code>. This relies on the <code>data.csv</code> file being in the same location as this class. Alternatively, you can put the file elsewhere and just create a regular <code>File</code> object to it rather than use the <code>URL</code>.
</li>
<li>For the console part of this demo, create a <code>Main</code> class and add a <code>main</code> method containing the code get an instance of the provider, and perform a simple iteration through the data.
<pre class="brush: java;">
public class Main {

	public static void main(String[] args) {
		CommaDelimitedProvider&lt;Person&gt; provider;

		provider= ProviderFactory.createProvider();

		List&lt;Person&gt; results = provider.fetchResults(new DefaultPaginator());
		for (Person p : results) {
			System.out.println(p);
		}
	}
}
</pre>
<p>In this example we are reading all the results at once in memory and displaying the whole list.</li>
</ol>
<h2>Paginating the results</h2>
<p>We can control which results and how many are displayed by using a paginator to control the flow of data. This can be useful if you have a huge file and it would be impractical to read all the results into memory in one go. Datasets have paginators built in and use a reference to a provider to fetch the actual data.</p>
<ol>
<li>In the <code>main</code> method, instead of using the provider directly, create a dataset and pass it a reference to our data provider.
<pre class="brush: java;">
public static void main(String[] args) {
	CommaDelimitedProvider&lt;Person&gt; provider;

	provider = ProviderFactory.createProvider();

	CommaDelimitedDataset&lt;Person&gt; ds = new CommaDelimitedDataset&lt;Person&gt;(provider);
	ds.setMaxRows(10);
	List&lt;Person&gt; results = ds.getResultList();
	for (Person p : results) {
		System.out.println(p);
	}
}
</pre>
<p>We have set the maximum number of rows to 10 so the results returned only contains 10 rows of data at most. We can use this mechanism to control the number of results fetched if they are paginated.</li>
<li>The dataset classes implement the <code>Iterable</code> interface which lets us iterate over the entire set of data. By setting the page size, we can control the batch sizes when the data is fetched in while it is being iterated over. This allows us to control the flow of data, either to reduce the in-memory realization of the source data, or to reduce latency in an otherwise slow data source as the application can process one page of data while the provider is loading the next page of data.
<pre class="brush: java;">
public static void main(String[] args)  {
	CommaDelimitedProvider&lt;Person&gt; provider;
	provider = ProviderFactory.createProvider();

	CommaDelimitedDataset&lt;Person&gt; ds = new CommaDelimitedDataset&lt;Person&gt;(provider);
	ds.setMaxRows(5);
	for (Person p : ds) {
		System.out.println(p);
	}
}
</pre>
</li>
<li>You can see this process in action by extending the comma delimited data provider as an anonymous class and adding logging to the post fetch methods. We do this by modifying the <code>ProviderFactory.createProvider()</code> method :
<pre class="brush: java;">
public static CommaDelimitedProvider&lt;Person&gt; createProvider() {
	URL url = Main.class.getResource(&quot;data.csv&quot;);
	CommaDelimitedProvider&lt;Person&gt; provider = new CommaDelimitedProvider&lt;Person&gt;(url.getFile()) {
		@Override
		protected List&lt;Person&gt; doPostFetchResults(List&lt;Person&gt; results,
				Paginator paginator) {
			int end = paginator.getFirstResult()+paginator.getMaxRows();
			System.out.println(&quot;Fetching results from &quot;+paginator.getFirstResult()+&quot; to &quot;+end);
			return results;
		}
	};
	provider.setRowMapper(new PersonRowMapper());
	return provider;
}
</pre>
</li>
<li>
If you run this now, with the max rows set to 5, in you will see in that log that we iterate through all the records, but we only fetch the results every 5 rows since the max results is set to 5.</p>
<pre class="brush: plain;">
Fetching results from 0 to 5
Person [id=6825, name=JUANITA LAMBERT, address=139 MANNING HWY,CLYO,76604, email=mbeasley@everyma1l.biz
Person [id=5740, name=GREG CABRERA, address=736 GENESSEE BLVD,CORDELE,17433, email=cholder@b1zmail.biz
Person [id=8599, name=ALISSA WISE, address=205 ALICE RD,CAMILLA,14855, email=theyweb@eyec0de.net
Person [id=9282, name=SHARON WINTERS, address=955 COHEN PIKE,TYRONE,811, email=jlogan@hotma1l.com
Person [id=2150, name=KRISTY FRANKS, address=1471 ALEXIS PKWY,BALDWIN,85, email=jgates3@somema1l.com
Fetching results from 5 to 10
Person [id=9927, name=JEFF RICE, address=104 DUNDEE PKWY,HOGANSVILLE,3741, email=diedlots@b1zmail.org
Person [id=7972, name=TAMARA BRYANT, address=1382 WOGAN BLVD,CITY OF CALHOUN,43790, email=hotworn@everyma1l.us
Person [id=5824, name=ALISHA YANG, address=716 HOGANS DR,HARDING,58932, email=foundwrong@hotma1l.net
Person [id=3402, name=JASON NGUYEN, address=527 MICHAEL CRES,FORT STEWART,14664, email=haveothers@ma1l2u.com
Person [id=3620, name=LINDSEY CABRERA, address=1420 LAZELERE HTS,FORT STEWART,21650, email=askeddreams@b1zmail.com
Fetching results from 10 to 15
Person [id=3511, name=ANTHONY MATHEWS, address=1325 OKEY LN,THUNDERBOLT,63656, email=cfarrell@everyma1l.co.uk
Person [id=572, name=JARED FORD, address=722 EUCLID RD,FORSYTH,42014, email=ortrying@b1zmail.co.uk
Person [id=9720, name=AUTUMN WILLIAMS, address=260 HILL PARK,NORCROSS,58355, email=roomwhere@hotma1l.net
Person [id=3447, name=MARION BROWN, address=739 MIDDLE PATH,MACON,9944, email=hwagner@b1zmail.co.uk
Person [id=9356, name=HOPE HAYNES, address=1023 COOPERRIDERS CRES,STATENVILLE,34247, email=sacrificeit@eyec0de.com
Fetching results from 15 to 20
Person [id=2259, name=JEANNIE RANDOLPH, address=672 EDISON PATH,CENTERVILLE,48580, email=wornto@eyec0de.net
Person [id=8264, name=RACHAEL CONLEY, address=1223 STEVENS CT,CARROLLTON,40084, email=smokewhite20@eyec0de.net
</pre>
</li>
</ol>
<h2>Creating a Swing Client</h2>
<p>DataValve provides an interface for data access that can be used by different clients. Lets look at using our provider with a Swing <code>JTable</code>.</p>
<ol>
<li>Start by creating a new class that will be the Swing frame that contains the table and the scroll pane.
<pre class="brush: java;">
public class CsvTableFrame extends JFrame {

	private JTable table;
	private JScrollPane pane;

	public CsvTableFrame(CommaDelimitedProvider&lt;Person&gt; provider) {
		initControls();
		initModel(provider);
	}

        //here we will create the table model and attach the provider
	private void initModel(CommaDelimitedProvider&lt;Person&gt; provider) {
	}

        //construct the gui table and scrollable panel
 	private void initControls() {
		setTitle(&quot;CSV Data&quot;);
		setSize(400, 400);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);

		table = new JTable();
		pane = new JScrollPane(table);
		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		getContentPane().add(pane);
	}
}
</pre>
<p>This will setup the display for showing a frame with a scrollable table in it.
</li>
<li>Now we need to implement the <code>initModel</code> method which will create a <code>ProviderTableModel</code> and attach the provider passed in. The table model class enables us to present our data to the Swing table in a way it understands. The <code>ProviderTableModel</code> implements a method which supplies column values to the model from the data supplied by the provider. The columns are defined in the latter half of the method and determines the order used to supply data to the table for each column.
<pre class="brush: java;">
        //here we will create the table model and attach the provider
	private void initModel(CommaDelimitedProvider&lt;Person&gt; provider) {
		ProviderTableModel&lt;Person&gt; model = new ProviderTableModel&lt;Person&gt;(
				provider) {

			@Override
			protected Object getColumnValue(Person person, int column) {
				switch (column) {
				case 0:
					return person.getId();
				case 1:
					return person.getName();
				case 2:
					return person.getEmail();
				case 3:
					return person.getAddressText();
				default:
					throw new RuntimeException(
							&quot;Unexpected column for person object &quot; + column);
				}
			}
		};

		//add the columns to the model
		model.addColumn(&quot;Id&quot;);
		model.addColumn(&quot;Name&quot;);
		model.addColumn(&quot;Email&quot;);
		model.addColumn(&quot;Address&quot;);

		//assign this model to the table
		table.setModel(model);
	}
</pre>
</li>
<li>The last piece we need to change is in the <code>main</code> method where we will create our provider and then pass it into the creation of our Swing frame.
<pre class="brush: java;">
public static void main(String[] args) {

	CommaDelimitedProvider&lt;Person&gt; provider;

	provider = ProviderFactory.createProvider();

	new CsvTableFrame(provider);

}
</pre>
<p>Creating the <code>CsvTableFrame</code> initializes and shows the Swing window.
</li>
<li>If we run this now, we will get a Swing Window which contains a table with our data in it.
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/07/csv_swing_table.png" target="_blank"><img src="http://www.andygibson.net/blog/wp-content/uploads/2010/07/csv_swing_table-300x163.png" alt="CSV Swing Table DataValve" title="CSV Swing Table DataValve" width="300" height="163" border=0/></a>
</div>
</li>
</ol>
<p>The model controls the flow of the data and even includes built-in caching and look-ahead loading so no matter how big your CSV dataset is, there is no long delay while the data is loaded and converted to Java objects.  In this case, we pass only the provider to the model and the model is responsible for how much data is fetched in each batch. </p>
<p>If you look in the log as you scroll down the list, you will see that it is loading in the data as you scroll. If you go to the end of the list, and start slowly scrolling back up, you won&#8217;t see any more loading messages until you get to the top of the list. This is because the values are cached, but if you have a large dataset, the least recently used items (i.e. those at the top of the table) are removed from the cache and therefore need re-loading when you go back to the start of the list. </p>
<h1>Creating a JSF Client</h1>
<p>The DataValve API allows us to re-use providers with many different clients which we&#8217;ll demonstrate with JSF. </p>
<ol>
<li>Start by creating a new JSF web application, or use the <a href="http://www.andygibson.net/blog/projects/knappsack">Knappsack Archetypes</a> for Maven to get started quickly. Use the basic archetype so there is no existing application in there or alternative <code>Person</code> objects to clash with.</li>
<li>Add the <code>datavalve-dataset</code> API and the <code>datavalve-faces</code> dependencies to the project,
<pre class="brush: xml;">
		&lt;dependency&gt;
			&lt;groupId&gt;org.fluttercode.datavalve&lt;/groupId&gt;
			&lt;artifactId&gt;datavalve-dataset&lt;/artifactId&gt;
			&lt;version&gt;0.9.0.CR2&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.fluttercode.datavalve&lt;/groupId&gt;
			&lt;artifactId&gt;datavalve-faces&lt;/artifactId&gt;
			&lt;version&gt;0.9.0.CR2&lt;/version&gt;
		&lt;/dependency&gt;
</pre>
</li>
<li>For convenience, copy the <code>ProviderFactory.java</code>,<code>Person.java</code> and <code>PersonRowMapper.java</code> classes over to the new project.
</li>
<li>Create a new class called that will be our backing bean that will hold the dataset the JSF page will go against.
<pre class="brush: java;">
@Named(&quot;csvDataset&quot;)
@RequestScoped
public class CsvDatasetBean {

	CommaDelimitedDataset&lt;Person&gt; dataset =
	     new CommaDelimitedDataset&lt;Person&gt;(ProviderFactory.createProvider());

	public CsvDatasetBean() {
		//initialize the dataset settings
		dataset.setMaxRows(10);
	}

	public CommaDelimitedDataset&lt;Person&gt; getDataset() {
		return dataset;
	}
}
</pre>
</li>
<li>Now we have created the backing bean pieces, open <code>home.xhtml</code> to edit it, and replace the hello world text with the following :
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;ui:composition xmlns=&quot;http://www.w3.org/1999/xhtml&quot;
	xmlns:ui=&quot;http://java.sun.com/jsf/facelets&quot;
	xmlns:f=&quot;http://java.sun.com/jsf/core&quot;
	xmlns:h=&quot;http://java.sun.com/jsf/html&quot;
	xmlns:dv=&quot;http://java.sun.com/jsf/composite/datavalve&quot;
	template=&quot;/WEB-INF/templates/template.xhtml&quot;&gt;
	&lt;ui:define name=&quot;content&quot;&gt;
		&lt;h:dataTable value=&quot;#{csvDataset.dataset.resultList}&quot; var=&quot;v_person&quot;&gt;
			&lt;h:column&gt;
				&lt;f:facet name=&quot;header&quot;&gt;ID&lt;/f:facet&gt;
				&lt;h:outputText value=&quot;#{v_person.id}&quot; /&gt;
			&lt;/h:column&gt;

			&lt;h:column&gt;
				&lt;f:facet name=&quot;header&quot;&gt;Name&lt;/f:facet&gt;
				&lt;h:outputText value=&quot;#{v_person.name}&quot; /&gt;
			&lt;/h:column&gt;

			&lt;h:column&gt;
				&lt;f:facet name=&quot;header&quot;&gt;Email&lt;/f:facet&gt;
				&lt;h:outputText value=&quot;#{v_person.email}&quot; /&gt;
			&lt;/h:column&gt;

		&lt;/h:dataTable&gt;
		&lt;h:form&gt;
			&lt;dv:simplePaginator paginator=&quot;#{csvDataset.dataset}&quot; /&gt;
		&lt;/h:form&gt;
	&lt;/ui:define&gt;
&lt;/ui:composition&gt;
</pre>
<p>This page contains a table that takes the results from <code>#{csvDataset.dataset.resultList}</code> and displays the id, name and email fields. The last item wrapped in a form is the <code>datavalve-faces</code> default paginator which allows to you scroll across the data. This is provided as part of <code>datavalve-faces</code> and the namespace is added at the top of the page.  With JSF 2.0 including support for AJAX, you can have AJAX enabled pagination by setting the attributes on the component.</p>
<div class="contentBox alignCenter">
<a href="http://www.andygibson.net/blog/wp-content/uploads/2010/07/csv_jsf_table.png" target="_blank"><img border=0 src="http://www.andygibson.net/blog/wp-content/uploads/2010/07/csv_jsf_table-300x181.png" alt="CSV JSF Table DataValve" title="CSV JSF Table DataValve" width="300" height="181" border=0 /></a>
</div>
</li>
</ol>
<h2>Summary</h2>
<p>This tutorial has shown how to consume csv files in a way that is re-usable across different client applications using DataValve. Alternatively, if you change the implementation of <code>ProviderFactory.createProvider</code> to return a different type of provider (i.e. JDBC, ORM, Hibernate) as long is it returns the same kind of <code>Person</code> object, your code will run unchanged in the clients you create. Given the simplicity of the DataValve interfaces, it is not hard to see how easy it is to create providers for other file types whether they be text or binary based.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/tutorial/accessing-and-paginating-csv-files-with-datavalve/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing DataValve</title>
		<link>http://www.andygibson.net/blog/article/introducing-datavalve/</link>
		<comments>http://www.andygibson.net/blog/article/introducing-datavalve/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 14:05:07 +0000</pubDate>
		<dc:creator>Andy Gibson</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Apprentice]]></category>
		<category><![CDATA[DataValve]]></category>

		<guid isPermaLink="false">http://www.andygibson.net/blog/?p=1105</guid>
		<description><![CDATA[DataValve is a free open source library that facilitates the creation of re-usable view and data access components as well as providing a number of features for pagination, sorting and parameterizing queries. This article defines the problems DataValve aims to solve and how it solves them. The need for DataValve Most data driven applications have [...]]]></description>
			<content:encoded><![CDATA[<p>DataValve is a free open source library that facilitates the creation of re-usable view and data access components as well as providing a number of features for pagination, sorting and parameterizing queries. This article defines the problems DataValve aims to solve and how it solves them.<br />
<span id="more-1105"></span></p>
<h1>The need for DataValve</h1>
<p>Most data driven applications have a need for displaying data that is organized into pages. Whether it is search results or sales reports, dumping a complete set of data results into a web page or a Swing grid is sooner or later going to run into problems as the datasets grow larger. </p>
<p>Visual web frameworks such as Wicket or JSF usually have some components that facilitate pagination and most data access frameworks such as JDBC, Hibernate or JPA have facilities to access results in a paginated manner. Typically however, you need to write your own code to bridge the gap between the view and the data access mechanism.  If you write your own glue code you will probably need to re-write it again and again if you want to re-use the back end code with a different view layer or change the data access mechanism.</p>
<div class="diagram" style="width : 540px">
<h1>Applications With DataValve</h1>
<p><img src="/img/apps_with_dv.png"/>
</div>
<h2>Exotic Data Sources</h2>
<p>There may even be times when you have a sudden request to provide paginated data access to more exotic data sources such as XML, CSV, and binary files, even pulling data from a web service. In such a scenario not only do you have to write most of the pagination yourself, but again, your view layer will need some work to handle the new data access mechanism.  This also includes paginated access to in-memory data that is regularly used, but changes rarely and is cached in memory. </p>
<p>Most of you are probably thinking that this isn&#8217;t a big problem because you write layered code with an interface that can have different implementations. You are right, logical organization of code can help with all these problems, however, at the end of the day, you still have to write something that integrates with the new datasource in the same way as the old datasource in the implementation.</p>
<p>If you are thinking that you will never need to change your view layer or data providers, there are still some problems you might want to consider that DataValve can help with.</p>
<h2>Dynamic Querying</h2>
<p>One common feature in data driven applications is to query a set of data using parameters with the ability to exclude query clauses where the parameter is not set. If you are searching for people, why filter by address if the user didn&#8217;t enter an address? The solutions to get around this problem involve either building the query at run time and ignoring restrictions with missing parameter values or accommodating the potentially null parameter in the query itself which makes it look ugly and can harm performance.</p>
<h2>Ordering data safely</h2>
<p>Another problem is the abstraction of the ordering of data, especially with web applications. You don&#8217;t want to store the actual SQL columns used for sorting data on the web page in case of SQL injection attacks. The best way is to use a key that maps to how you want the data ordered . You would also have to allow for ascending and descending ordering. </p>
<h2>Parameterizing queries</h2>
<p>Dynamic queries should be parameterized to allow variables in the query to be set in a safe manner as opposed to changing the query text which can again lead to SQL injection attacks. Typically though most parameters have to be set manually and many times we add new parameters and forget to set them. The process of adding and assigning parameters can require lengthy boilerplate code. DataValve offers vastly improved parameter handling for queries.</p>
<h1>How DataValve solves all these problems</h1>
<p>DataValve works by using a well defined interface to access and paginate data that comes from a data provider. There are different data providers for each kind of data source (JDBC,ORM,Hibernate,File based) and you can even write your own using an interface with just 2 methods. Because we have a well defined interface to the data, we can create components for the view to connect to that interface. Since we are coupled to the interface only, we can change the implementation and as long as it returns the same kind of entity objects, our view code remains unchanged. The view doesn&#8217;t care whether the list of <code>Person</code> entities comes from a database, an XML file, a web service or an in-memory list. When the dataset is connected up to a different view layer, it is coupled to the same interface and accesses the data in the same defined way.</p>
<p>Here&#8217;s a quick example of how we create a data provider and paginate the results. </p>
<pre class="brush: java;">
DataProvider&lt;Person&gt; provider = new SomeDataProvider&lt;Person&gt;();
Paginator paginator = new DefaultPaginator();
paginator.setMaxRows(10);
pagiantor.setFirstResult(15);
List&lt;Person&gt; results = provider.fetchResults(paginator);
for (Person p : results) {
  //do something with the 10 Person objects from 15-25
}
</pre>
<p>We can also use a <code>Dataset</code> that is a stateful combination of a <code>Paginator</code> and a data provider reference.</p>
<pre class="brush: java;">
DataProvider&lt;Person&gt; provider = new SomeDataProvider&lt;Person&gt;();
ObjectDataset&lt;Person&gt; dataset = new DataProviderDataset(provider);
dataset.setMaxRows(10);
dataset.setFirstResult(35);
List&lt;Person&gt; results = dataset.getResults();
for (Person p : results) {
...some code...
}
</pre>
<p>Each time we call <code>getResults()</code> on the dataset, it will return the same list of results until we move to another page of results or manually invalidate the result set. Every time you call <code>fetchResults</code> on a data provider the list of results is re-fetched each time.  The Dataset also implements the iterator interface so you could iterate over the whole set of data and it would go through each row, but load them in batches as sized by the paginator. </p>
<h1>Queried Results</h1>
<p>Let&#8217;s load a result set that uses some filtering and sorting. </p>
<pre class="brush: java;">
QueryProvider&lt;Person&gt; provider = new JpaDataProvider&lt;Person&gt;(em);
QueryDataset&lt;Person&gt; dataset = new QueryDataset&lt;Person&gt;(provider);

provider.setSelectStatement(&quot;select p from Person p&quot;);
provider.setCountStatement(&quot;select count(p) from Person p&quot;);

//we can also access the provider using
// dataset.getProvider()

//add simple restriction
provider.addRestriction(&quot;p.department.id = 4&quot;);

List&lt;Person&gt; results = dataset.getResultList();
for (Person p : results) {
    System.out.println(p.getName());
}
</pre>
<p>Alternatively, we could specify the parameters using : </p>
<pre class="brush: java;">
//:param is a magic value for this method call only
provider.addRestriction(&quot;p.firstName = :param&quot;,someFirstName);

//alternatively

provider.addRestriction(&quot;p.firstName = :aFirstName&quot;);
provider.addParameter(&quot;aFirstName&quot;,someFirstName);
</pre>
<p>A few things to note here. The second method of using a parameter requires two method calls, but you can change the parameter value later on prior to execution and if <code>aFirstName</code> is null, then the restriction won&#8217;t be included in the executed final query. Typically, restrictions are excluded at the time of query execution, but if you use the first syntax, the restriction is left out immediately if the value is null since you are setting the parameter as a constant and if the value is null, then it will always be null.</p>
<p>Here are some alternative ways of defining parameters, all of which are subject to the rule that if the parameter is null, then the restriction isn&#8217;t added. All these examples can be used with either Hibernate, JPA or JDBC data providers with the only changes being the query specification and the field names in the restrictions. </p>
<pre class="brush: java;">
  //WRONG - if first name is null, then the param value is 'null%' and will be added
  provider.addRestriction(&quot;p.firstName like :param&quot;,criteria.firstName+&quot;%&quot;);

  //CORRECT - this checks one value, but assigns another to the actual parameter
  provider.addRestriction(&quot;p.firstName like :param&quot;,criteria.firstName,criteria.firstName+&quot;%&quot;);
</pre>
<p>This is really useful where we want to use one value for the null check, but assign another value to the actual parameter so we can use &#8217;starts-with&#8217; in searches by adding a wildcard on the end.</p>
<pre class="brush: java;">
  provider.addRestriction(&quot;p.department.id = 4&quot;);
  provider.addRestriction(&quot;or p.managerFlag = 1&quot;);
</pre>
<p>All restrictions are joined together with &#8220;AND&#8221;s unless they actually start with a logical operator. Parenthesis can be introduced into the query, but care must be taken that opening or closing parentheses would not be removed in the event of a null parameter.</p>
<p>If you are using JSF or some other EL enabled environment, you can also use EL expressions directly in the queries as long as you attach an <code>ELParameterResolver</code> to the provider.</p>
<pre class="brush: java;">
  provider.addRestriction(&quot;p.firstName = #{criteria.firstName}&quot;);
  provider.addRestriction(&quot;p.lastName = #{criteria.lastName}&quot;);
</pre>
<p>Again, if these expressions evaluate to null then the restriction is not used. This makes it really easy to create a search criteria bean that hooks up to the JSF front end and back end without any additional glue code. </p>
<h2>Parameter Resolvers</h2>
<p>DataValve has a concept of parameter resolvers that can be used on any data provider that implements the <code>ParameterizedDataset</code> interface. Parameter resolvers are like plugins that provide parameter resolution through code. The <code>ReflectionParameterResolver</code> uses reflection to find parameter values where the property name is the same as the parameter name.</p>
<pre class="brush: java;">
provider.addRestriction(&quot;p.firstName like :firstName&quot;);
provider.addRestriction(&quot;p.lastName like :lastName&quot;);
provider.addParameterResolver(new ReflectionParameterResolver(criteria));
</pre>
<p>Our <code>criteria</code> object has first and last name properties that are used to resolve the parameter values in the restrictions. Again, if the values resolve to null, the restriction is not used when the query is executed. </p>
<p>Also, multiple parameter resolvers can be attached to a provider so you could use an EL parameter resolver and a reflection parameter resolver. This can be useful for mixing it up if you have multiple sources for parameters. You can also combine different combinations of adding restrictions.</p>
<pre class="brush: java;">
provider.addRestriction(&quot;p.firstName like :firstName&quot;);
provider.addRestriction(&quot;p.lastName like :lastName&quot;);
provider.addRestriction(&quot;p.salesRep.id = #{currentUser.id}&quot;);
provider.addRestriction(&quot;p.dept.id = &quot;,selectedDepartment.getId());
provider.addParameterResolver(new ReflectionParameterResolver(criteria));
provider.addParameterResolver(new ElParameterResolver());
</pre>
<h1>Ordering Results</h1>
<p>Configuring the order is simple, we add the order key values and associate information with each key to indicates how the ordering is executed which in most cases, it is the list of fields we use to order.</p>
<pre class="brush: java;">
provider.getOrderKeyMap().put(&quot;name&quot;,&quot;p.lastName,p.firstName&quot;);
provider.getOrderKeyMap().put(&quot;age&quot;,&quot;p.dateOfBirth&quot;);
provider.getOrderKeyMap().put(&quot;id&quot;,&quot;p.id&quot;);
</pre>
<p>To order data when we fetch it from the provider, we need to assign a key order value on the paginator used to fetch the data from the provider.</p>
<pre class="brush: java;">
Paginator paginator = new DefaultPaginator();
paginator.setOrderKey(&quot;name&quot;); //order by the persons name
paginator.setOrderAscending(false);
List&lt;Person&gt; orderedList = provider.fetchResults(paginator);
</pre>
<p>If you are using  a dataset, you can just set the <code>orderKey</code> and <code>orderAscending</code> properties on the dataset instead. These key values can be embedded in your web page and passed back to the server side components without having to worry about SQL injection. If the order key is not recognized as one of the available values in the order key map then no order is used and no SQL is injected.</p>
<h1>State management</h1>
<p>Paginators and data providers are separate instances while object datasets  are made up of a paginator with a data provider reference that keeps a hold of the most recent set of results. The reason for this is so you can modify the degree of statelessness used. </p>
<p>You can make the whole thing stateless with the paginator info being passed between the client and the server. With Wicket, Seam, CDI and Spring Web Flow you might want to keep the paginator state on the server side but keep refreshing the results each time you postback. This can be done by keeping it in a Conversation, a Spring web flow, or a Wicket page. If you want to go fully stateful, you can use the Dataset which includes the paginator and the data provider and caches the recent resultset and put it in a Wicket page, a conversation or a page flow. By default, the JSF Components for paginating a DataValve result set is stateless.</p>
<h1>Client Side</h1>
<p>Briefly, lets look at the options for creating clients for DataValve datasets. There are components for a simple JSF paginator and a sortable column header for JSF 2.0 in the <code>datavalve-faces</code> module, and a <code>SortableDataProvider</code> for Wicket. For Swing, there is a special <code>TableModel </code> that caches and pre-emptively loads data for display in a Swing <code>JTable</code>. This means you can easily navigate thousands of rows of data in a Swing Table without having a long initial load time or taking up a lot of memory for object storage. </p>
<p>In the DataValve download there are demos for each of these examples in projects that are easy to run using the Jetty plugin for Maven so no server is required.  The Wicket demo even demonstrates how different pieces of server side code can be reused with JDBC, CSV and Hibernate driven data providers.</p>
<h1>Get Started</h1>
<p>In addition to the <a href="http://www.andygibson.net/blog/projects/DataValve">DataValve project page</a> you can see the documentation in <a href="html/index.html">HTML</a>, <a href="html_single/index.html">Single HTML</a>, or <a href="pdf/index.pdf">PDF</a>.   The download includes source that can be <a href="http://www.andygibson.net/blog/tutorial/install-datavalve-into-maven/">built and installed with maven</a> as well as pre-built binaries.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.andygibson.net/blog/article/introducing-datavalve/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

